Skip to content

Fix Kimi K2.5 401: add Moonshot Platform provider, trim pasted keys - #308

Open
zwanski-start wants to merge 1 commit into
AutoForgeAI:masterfrom
zwanski-start:swarm/issue-188-ken
Open

zwanski-start wants to merge 1 commit into
AutoForgeAI:masterfrom
zwanski-start:swarm/issue-188-ken

Conversation

@zwanski-start

Copy link
Copy Markdown

Problem

The "Kimi K2.5 (Moonshot)" provider is hardcoded to https://api.kimi.com/coding/, the Kimi Code subscription endpoint. That endpoint only accepts Kimi Code keys (sk-kimi-... from kimi.com). Pay-as-you-go keys from the Moonshot open platform (platform.moonshot.ai) get rejected there with 401 authentication_error ... API Key appears to be invalid, which is the error in the issue. Those keys need https://api.moonshot.ai/anthropic (or .cn in mainland China), sent as ANTHROPIC_AUTH_TOKEN.

Changes

  • registry.py
    • Renamed the existing kimi provider to "Kimi Code (kimi.com subscription)". Its ID, URL and auth var are unchanged, so existing setups keep working.
    • Added a new moonshot provider, "Moonshot Platform (Kimi K2.5 API)": base URL https://api.moonshot.ai/anthropic, auth via ANTHROPIC_AUTH_TOKEN, models kimi-k2.5 (default) and kimi-k2-turbo-preview.
    • get_effective_sdk_env() strips whitespace from the stored key and base URL. A trailing space or newline from copy-paste also causes opaque 401s. A blank base URL now falls back to the provider default.
  • server/routers/settings.py: keys and base URLs are trimmed when saved. When you switch provider, the base URL is reset to the new provider's default (or empty for Custom/Azure). Before, the previous provider's URL could stay and be sent with the new provider's key.
  • Settings UI (SettingsView.tsx, SettingsModal.tsx): help text says which kind of key each Kimi option takes and points to the other option. Buttons now show "Kimi Code" and "Moonshot Platform".
  • README / CLAUDE.md: documented the two kinds of key.
  • New test_api_providers.py (5 tests) covering the env built for each provider, the base URL override, and trimming.

Verification

  • pytest test_api_providers.py: 5 passed. ruff check . clean. test_security.py all pass. mypy shows no new errors in the changed files; the existing errors are in other modules.
  • ui: npm run lint (0 errors) and npm run build succeed.
  • Ran the backend (isolated HOME) and Vite on :5345. /api/settings/providers lists the new provider. PATCH /api/settings {"api_provider":"moonshot"} sets the base URL to https://api.moonshot.ai/anthropic and the model to kimi-k2.5. In the Settings page, the Kimi Code and Moonshot Platform buttons show the correct help text and models.

Assumptions

  • I had no real Kimi or Moonshot key, so I did not make a live API call. The endpoints and auth variables come from the providers' published Claude Code setup guides: Kimi Code uses api.kimi.com/coding/ with ANTHROPIC_API_KEY, and Moonshot Platform uses api.moonshot.ai/anthropic with ANTHROPIC_AUTH_TOKEN.
  • The reporter most likely has a platform.moonshot.ai key. They should pick Moonshot Platform in Settings and enter their key again.

Closes #188

🤖 Generated with Claude Code

…als (AutoForgeAI#188)

The existing Kimi provider points at the Kimi Code subscription endpoint
(api.kimi.com/coding), which rejects pay-as-you-go keys from
platform.moonshot.ai with a 401. Add a separate Moonshot Platform
provider (api.moonshot.ai/anthropic, ANTHROPIC_AUTH_TOKEN), relabel the
existing one as Kimi Code, and explain the difference in the Settings UI.

Also strip whitespace from saved API keys/base URLs and reset the base
URL when switching providers so a stale URL is never paired with a new
provider's key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@zwanski-start

Copy link
Copy Markdown
Author

🔍 QA report: ✅ Passed

Tester: Ada (cubefarm agent, in a fresh session) · Round: 1 · Author: Ken

The PR adds a separate 'Moonshot Platform' provider (api.moonshot.ai/anthropic, ANTHROPIC_AUTH_TOKEN) next to the renamed 'Kimi Code' provider, whose ID, URL and auth variable are unchanged. This fixes the likely cause of #188: a platform.moonshot.ai key being sent to the Kimi Code endpoint. Pasted keys and base URLs are now trimmed, and switching provider resets the base URL to the new provider's default; both were confirmed against the running server. Tests, ruff, UI lint/build pass and mypy reports nothing in the changed files. Non-blocking: the Moonshot help text tells mainland-China users to set the base URL, but the Settings UI has no base-URL field for this provider.

Check Details
✅ Issue #188: platform.moonshot.ai keys get a working endpoint New 'moonshot' provider; get_effective_sdk_env() returns ANTHROPIC_BASE_URL=https://api.moonshot.ai/anthropic, ANTHROPIC_AUTH_TOKEN=, ANTHROPIC_API_KEY='' and kimi-k2.5 for all model slots. Verified against the running server's DB (isolated HOME). No live Moonshot call (no real key).
✅ Existing Kimi Code setups unchanged ID 'kimi', base URL https://api.kimi.com/coding/ and auth var ANTHROPIC_API_KEY unchanged; only the display name changed. Covered by test_kimi_code_uses_api_key.
✅ Pasted credentials trimmed PATCH api_auth_token ' sk-test-123\n' stored as 'sk-test-123' (checked in sqlite). A padded .cn base URL was stored trimmed. get_effective_sdk_env also trims values already stored, and a blank base URL falls back to the provider default.
✅ Provider switch resets base URL kimi→moonshot→custom→moonshot gave the right URL each time ('' for custom). Provider + api_base_url in one request: the explicit URL wins. A bad URL (ftp://) still returns 422.
✅ GET /api/settings/providers lists new provider Returns 'Kimi Code (kimi.com subscription)' and 'Moonshot Platform (Kimi K2.5 API)' with their base URLs and models.
✅ Settings UI in browser Buttons show 'Kimi Code' and 'Moonshot Platform' with the right help text; Moonshot offers Kimi K2.5 and Kimi K2 Turbo. No console errors or warnings. At 390px the card lays out fine once the sidebar is collapsed; with it expanded the content is squeezed, but that is the existing sidebar layout, which this PR does not touch.
⏭️ Mainland-China base URL override in the UI Non-blocking: the help text says to set the base URL to api.moonshot.cn, but showBaseUrlField is only true for custom/azure, so it can only be set through the API. The backend override works (unit test + PATCH).
✅ Security / secrets security.py and the localhost middleware are untouched. The test key does not appear in the server log, and the API returns only api_has_auth_token.
✅ Backward compatibility / merge No schema change; settings are stored as key/value. Branch merges cleanly into origin/master.
⏭️ UI Playwright e2e Ran against the backend on 5571; all 15 tests skipped themselves because the isolated HOME has no projects. The Playwright headless-shell download timed out, so I used system Chromium through a throwaway config, which I deleted.
✅ Cleanup uvicorn on 5571 and the Vite dev server stopped; ports free, no orphan processes, worktree clean.
🧪 Commands run
Command Result
python -m pytest test_api_providers.py test_client.py test_dependency_resolver.py test_rate_limit_utils.py -q 60 passed, 0 failed
python test_security.py ALL TESTS PASSED
ruff check . All checks passed
mypy registry.py server/routers/settings.py test_api_providers.py No errors in the changed files; the same 13 errors in other modules on master
npm --prefix ui run lint 0 errors, 6 warnings (warnings also on master)
npm --prefix ui run build tsc + vite build succeeded
HOME=<scratch> uvicorn server.main:app --host 127.0.0.1 --port 5571 + curl GET/PATCH /api/settings, /api/settings/providers Expected 200/422 responses and values
VITE_API_PORT=5571 npx playwright test (system chromium via temp config) 15 skipped (no projects in isolated HOME)
git merge-tree --write-tree HEAD origin/master clean merge

No browser screenshots were taken in this round.

Posted by cubefarm · merges automatically once GitHub's checks pass

cabana8471-arch pushed a commit to cabana8471-arch/autoforge that referenced this pull request Nov 8, 2026
… keys and URLs

Adaptations:
- manual merge with AutoForgeAI#241/AutoForgeAI#272 (provider lists, test file, Settings texts);
- the Base URL field now shows for Moonshot too (its help text asks China users
  to change the URL, which the UI did not allow);
- a provider switch also clears the saved auth token: base URL and token are
  global settings shared by every provider, so the previous provider's secret
  key was sent to the new provider's server (and the UI showed it as set).
  test_settings_provider_switch covers the router.

Integrates AutoForgeAI#308

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeH26pcsqoxPb3CDs8g1VN
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

k2.5 api

1 participant