feat(registry): register Kimi k3[1m] 1M-context model as built-in#4404
feat(registry): register Kimi k3[1m] 1M-context model as built-in#4404Bahamutnelson wants to merge 2 commits into
Conversation
The upstream Kimi Code API accepts the model name k3[1m] (the 1M-context variant of Kimi K3), but the proxy rejected it with "unknown provider for model k3[1m]" because the model is not present in either the embedded models.json catalog or the remote catalog fetched from router-for-me/models. Follow the existing WithCodexBuiltins/WithXAIBuiltins pattern: inject a hard-coded Kimi built-in via a new WithKimiBuiltins helper applied in GetKimiModels, so the definition survives remote catalog refreshes. Metadata mirrors kimi-k3: 1048576 context length, 65536 max completion tokens, thinking levels low/high/max.
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
This pull request targeted The base branch has been automatically changed to |
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 574541e3a6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ContextLength: 1048576, | ||
| MaxCompletionTokens: 65536, | ||
| Thinking: &ThinkingSupport{ | ||
| Levels: []string{"low", "high", "max"}, |
There was a problem hiding this comment.
Map Claude medium/xhigh efforts for K3
With k3[1m] exposed through the Claude-compatible Kimi path, Claude Code requests that set /effort medium or /effort xhigh will be parsed as unsupported levels and then clamped by ValidateConfig to the nearest lower supported value from this list (medium→low, xhigh→high). Kimi’s K3 Claude Code guidance maps those same efforts upward (medium→high, xhigh→max; see https://www.kimi.com/code/docs/third-party-tools/other-coding-agents.html), so users selecting those efforts get a weaker reasoning mode than requested unless this builtin is accompanied by Kimi-specific effort mapping/clamping.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Addressed in 7baf4e9.
ThinkingSupport gains a declarative LevelMapping field, resolved before level validation (strict same-family paths map instead of erroring) and inside clampLevel (covering budget-derived and auto-derived levels). The k3[1m] built-in now declares medium -> high and xhigh -> max per Kimi's K3 guidance, so Claude Code users get the requested reasoning mode instead of a silent downgrade.
Covered by TestKimiK31MClaudeEffortMapsUpward (medium→high, xhigh→max, low/high/max unchanged), TestKimiK31MClaudeBudgetMapsUpward (budget 8192 → medium → high) and TestKimiK31MNativeStrictPathMapsInsteadOfError.
Claude Code requests with effort "medium" or "xhigh" were clamped down to "low"/"high" for k3[1m]: the nearest-level clamp prefers the lower level on ties, while Kimi's K3 guidance maps those same efforts upward (medium -> high, xhigh -> max). Add a declarative LevelMapping field to ThinkingSupport, resolved before level validation (so strict same-family paths map instead of erroring) and inside clampLevel (covering budget-derived and auto-derived levels). Declare the K3 mapping on the k3[1m] built-in. Addresses PR router-for-me#4404 review feedback.
|
Client compatibility note (Claude Code users): recent Claude Code versions natively parse the oauth-model-alias:
kimi:
- name: "k3[1m]"
alias: "k3"
fork: trueVerified locally: with this alias, |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7baf4e9cb0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| Thinking: &ThinkingSupport{ | ||
| Levels: []string{"low", "high", "max"}, |
There was a problem hiding this comment.
Emit K3 effort as reasoning_effort
For OpenAI/chat-completions requests routed to Kimi (i.e. not the Claude /v1/messages delegation), adding Thinking here makes ApplyThinking consume a client reasoning_effort and the existing Kimi applier then delete it and emit the K2.x-shaped thinking.effort. Kimi Code documents K3 effort as top-level reasoning_effort: low/high/max (https://www.kimi.com/code/docs/en/kimi-code/models), so a request like {"model":"k3[1m]","reasoning_effort":"low"} is forwarded with the wrong field shape and can be rejected or ignored instead of selecting low effort; K3 needs a model-specific Kimi output path.
Useful? React with 👍 / 👎.
| LevelMapping: map[string]string{ | ||
| "medium": "high", | ||
| "xhigh": "max", | ||
| }, |
There was a problem hiding this comment.
Map all documented K3 effort aliases
Kimi Code's K3 mapping table also accepts ultra as max and minimum/light as low (https://www.kimi.com/code/docs/en/kimi-code/models). Because this map only adds medium and xhigh, requests from OpenAI/Kimi-compatible clients that send reasoning_effort:"ultra" or thinking.effort:"light" reach ValidateConfig as unsupported levels; clampLevel cannot clamp unknown labels, so the proxy returns a validation error instead of forwarding the documented K3 effort.
Useful? React with 👍 / 👎.
Summary
Kimi K3 has a dedicated 1M-context variant with its own model ID:
k3[1m]. It is documented in the official Kimi Code docs (Using in Other Coding Agents): plans Allegretto and above can usek3[1m]with a 1,048,576-token context window, while plaink3/kimi-k3is limited to 262,144 tokens.The proxy currently rejects requests for it:
Root cause
Model → provider resolution does an exact-name lookup in the model registry (
util.GetProviderName). The kimi catalog is seeded from the embeddedinternal/registry/models/models.jsonand then wholesale replaced by the remote catalog (router-for-me/models) at startup and on every periodic refresh. Neither containsk3[1m], so the name is unregistered. Adding it tomodels.jsonalone would not be durable — the next remote refresh would silently drop it again.The fix
Follows the existing
WithCodexBuiltins/WithXAIBuiltinspattern: a newWithKimiBuiltins()helper injects a hard-codedk3[1m]definition insideGetKimiModels(), so the registration survives remote catalog refreshes.Metadata mirrors
kimi-k3:context_length1048576,max_completion_tokens65536, thinking levelslow/high/max.The
[/]characters are safe end-to-end: thinking-suffix parsing only handles(...), the registry does verbatim name lookups, and the kimi executor forwards the model name in the JSON request body (never in a URL path).Verification (tested live, works)
https://api.kimi.com/coding/v1/messageswith a Kimi Code OAuth token returned HTTP 200 fork3,k3[1m], andkimi-k3alike (2026-07-17, account with 1M-tier plan).POST /v1/messages {"model":"k3[1m]","max_tokens":1,...}→ HTTP 200, response"model":"k3[1m]"; regression checkkimi-k3→ HTTP 200; thinking suffix formk3[1m](high)→ HTTP 200.input_tokensas reported by the API) through the patched proxy tok3[1m]returned HTTP 200 — above the 262,144 limit of the plaink3variant, confirming the 1M window is actually served on a 1M-tier account.oauth-model-aliasentries attach cleanly to the builtin name — with a local entrykimi: [{name: "k3[1m]", alias: <custom-alias>, fork: true}], a request to the alias was routed to the kimi credential and answered HTTP 200 with"model":"k3[1m]"(before the patch, aliasing this name failed withunknown provider).GET /v1/modelson the patched instance listsk3[1m]alongside the existing kimi models, including after the remote catalog refresh that runs at startup.go vet ./internal/registry/,go test ./internal/registry/ ./internal/thinking/...,go build ./...all green (go1.26.0). Tests added for the builtin's metadata and its inclusion inGetKimiModels().Notes
kimi-k3definition but does not addk3[1m]).k3[1m]to therouter-for-me/modelsrepo too; this builtin keeps this repo correct regardless.