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
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.