Files
molecule-ai-workspace-templ…/tests
infra-runtime-be 66e3b7edb3
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 16s
CI / Adapter unit tests (push) Successful in 1m23s
CI / Template validation (static) (push) Successful in 1m27s
CI / Adapter unit tests (pull_request) Successful in 1m25s
CI / Template validation (static) (pull_request) Successful in 1m30s
CI / Template validation (runtime) (push) Successful in 10m27s
CI / Template validation (runtime) (pull_request) Successful in 9m52s
CI / validate (pull_request) Successful in 6s
CI / validate (push) Successful in 5s
feat(claude-code): route Kimi K2.6 to api.kimi.com/coding per official spec
Kimi (Kimi-For-Coding / K2.6) was structurally unreachable from the
claude-code runtime: the `kimi-` model prefix matched the `moonshot`
provider, which set ANTHROPIC_BASE_URL=https://api.moonshot.ai/anthropic
and projected KIMI_API_KEY -> ANTHROPIC_AUTH_TOKEN. Both are wrong per
kimi.com's official Claude Code integration doc
(kimi.com/code/docs/en/third-party-tools/other-coding-agents.html):
  - the sk-kimi-* key (KIMI_API_KEY in SSOT) authenticates ONLY against
    https://api.kimi.com/coding/ — the legacy api.moonshot.ai/anthropic
    surface 401s it (invalid_authentication_error);
  - that gateway authenticates with the x-api-key header, which the
    Anthropic SDK / claude CLI emits from ANTHROPIC_API_KEY, NOT the
    Bearer ANTHROPIC_AUTH_TOKEN.

So a Kimi pick on claude-code 401'd every LLM call.

Fix (config + minimal adapter, scoped to this template — adapter.py and
config.yaml are template-local, COPY'd in the Dockerfile; zero blast
radius on other runtimes):

- config.yaml: repoint the existing kimi- provider entry (renamed
  moonshot -> kimi-coding) to base_url https://api.kimi.com/coding/
  (trailing slash, per the doc) and add a new optional per-provider
  field `auth_token_env: ANTHROPIC_API_KEY` so the boot-time vendor-key
  projection writes KIMI_API_KEY into ANTHROPIC_API_KEY (x-api-key)
  instead of the default ANTHROPIC_AUTH_TOKEN (Bearer). Renaming the
  existing entry (vs adding a parallel one) keeps the kimi- model-prefix
  matcher working with the least change; still 7 providers total.
- config.yaml: add a selectable "Kimi K2.6" model catalog entry
  (id kimi-for-coding — the gateway's own served-model name, mirroring
  the proven OpenClaw kimi-for-coding route; the gateway routes to K2.6
  regardless of the wire model id). kimi-k2.5 / kimi-k2 retained as
  aliases hitting the same gateway for back-compat.
- adapter.py: _normalize_provider parses the optional `auth_token_env`
  (default ANTHROPIC_AUTH_TOKEN — preserves MiniMax/GLM/DeepSeek
  behavior bit-for-bit); _project_vendor_auth projects into that
  per-provider target and is idempotent on it (explicit operator value
  still wins).

Wire-verified before commit: POST https://api.kimi.com/coding/v1/messages
with x-api-key=<SSOT KIMI_API_KEY> + anthropic-version + claude-cli UA
-> HTTP 200, model=kimi-for-coding, real completion. The shipped routing
produces exactly this wire shape.

Tests: added 4 tests (Kimi -> ANTHROPIC_API_KEY projection, operator
override idempotency, _normalize_provider auth_token_env parse,
prevalidate routing matrix incl. kimi-for-coding); updated the
moonshot-named fixtures/assertions to the new kimi-coding contract.
Full suite 85 passed.
2026-05-16 04:56:49 -07:00
..