feat(kimi): forward prompt_cache_key on the Kimi Coding Plan presets - #597
Conversation
Kimi's Chat Completions API documents prompt_cache_key as required for Kimi Code Plan cache hits (a stable session/task id, unchanged across exit and resume). Opt the canonical `kimi` OAuth and `kimi-code` API-key presets into the existing openai-chat forwarding flag so the caller-supplied key reaches https://api.kimi.com/coding/v1. The adapter never invents a key: it forwards what the internal request already carries (Codex's session key on /v1/responses, or the session-scoped key the Claude /v1/messages inbound derives), an absent field stays absent, and an explicit provider-level `promptCacheKey: false` still opts out. All other OpenAI-compatible presets remain deny-by-default because strict backends reject the OpenAI-specific field. Also persist the flag through providerConfigSeed / enrichProviderFromRegistry like the sibling scalars (parallelToolCalls, modelSuffixBracketStrip): key-pool 429 rotation rebuilds the provider from the persisted config rather than the routed one, so without seeding the retried request would silently drop the key on exactly the quota-sensitive turns that need affinity most. Evidence: https://platform.kimi.com/docs/api/chat Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughKimi OAuth and API-key presets now preserve and forward caller-supplied ChangesKimi prompt-cache affinity
Estimated code review effort: 3 (Moderate) | ~20 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c16336a27a
ℹ️ 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".
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs-site/src/content/docs/guides/providers.md`:
- Around line 93-96: Update the canonical Kimi Coding Plan preset documentation
for the kimi and kimi-code configurations to state that opencodex forwards only
a caller-supplied stable prompt_cache_key and never generates one. Explicitly
document that if the upstream provider rejects the field, the rest of the
request and configuration remain unchanged, and keep the wording synchronized
with the CLI/API behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 2563ce11-1e53-4d27-bee2-414472a8fdc0
📒 Files selected for processing (10)
docs-site/src/content/docs/guides/providers.mddocs-site/src/content/docs/ja/guides/providers.mddocs-site/src/content/docs/ko/guides/providers.mddocs-site/src/content/docs/ru/guides/providers.mddocs-site/src/content/docs/zh-cn/guides/providers.mdsrc/providers/derive.tssrc/providers/registry.tsstructure/04_transports-and-sidecars.mdtests/openai-chat-hardening.test.tstests/provider-registry-parity.test.ts
Generalize the promptCacheKey preservation from the previous commit: the narrow registry backfill in rotateProviderTransportOn429 covered only that one scalar, while every OTHER registry backfill routedProviderConfig merges at request time was still lost when the four 429-failover sites in src/server/responses/core.ts assigned the persisted-config snapshot to route.provider wholesale. Concretely: kimi-code's noTemperatureModels / modelReasoningEfforts / modelSuffixBracketStrip merges, NVIDIA NIM's parallelToolCalls: false, and a registry-pinned baseUrl all silently reverted on the rotated retry and later continuations in the turn. rotateProviderTransportOn429 now takes the request's routed provider and swaps ONLY the API key onto it before re-applying transport metadata, mirroring the OAuth-401 replay path (which already spreads route.provider). The registry lookup becomes unnecessary and is removed. Other failover paths were audited and are sound: Codex multi-account retry strips runtime fields off route.provider, and the Anthropic account pool spreads route.provider directly. Regression coverage: the existing Kimi unit test keeps asserting the wire body on both attempts; a new unit test proves arbitrary registry-backfilled fields survive rotation; a new e2e test on the kimi-code preset asserts prompt_cache_key is present on BOTH the initial attempt and the post-rotation retry (verified to fail against the pre-fix behavior). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review verdict: approve / merge-readyReviewed tip BugsNo shippable defects found.
SecurityNo medium+ findings in this diff.
Residual (non-blocking): live A/B in the PR body showed no short-run cache win vs Kimi’s automatic prefix cache — retained for documented Code Plan contract / affinity under pool rotation, which the e2e covers. Open CodeRabbit / Codex0 open threads.
VerdictLGTM — safe to merge to |
|
Thanks for the PR, @olddonkey — clean Kimi Coding Plan |
What
Opt the canonical Kimi Coding Plan presets (
kimiOAuth andkimi-codeAPI key, both targetinghttps://api.kimi.com/coding/v1) into the existing openai-chatpromptCacheKeyforwarding flag, so the request's stableprompt_cache_keyreaches Kimi's Chat Completions body.Why
Kimi's Chat Completions docs (https://platform.kimi.com/docs/api/chat) document
prompt_cache_keyas required to improve cache hit rates for Kimi Code Plan: a stable session/task id, unchanged across exit and resume. Codex already sends one on every/v1/responsesrequest (and the Claude/v1/messagesinbound derives a session-scoped one), but opencodex previously dropped it for Kimi because forwarding is deny-by-default — strict OpenAI-compatible backends reject the field.How
src/providers/registry.ts:promptCacheKey: trueon thekimiandkimi-codeentries. The pre-existing machinery does the rest: registry→config scalar backfill (src/router.ts) and conditional forwarding in the openai-chat adapter, which only forwards a key already on the internal request — the adapter never invents one, and an explicit provider-levelpromptCacheKey: falsestill opts out.src/providers/derive.ts: persist the flag throughproviderConfigSeed/enrichProviderFromRegistry, mirroring the sibling scalars (parallelToolCalls,modelSuffixBracketStrip). Without this, key-pool 429 rotation — which rebuilds the provider from the persisted config rather than the routed one — would silently drop the key on exactly the quota-sensitive retries that need affinity most.moonshotopen platform, Fireworks-served) are intentionally left deny-by-default; field support there is unverified.structure/04_transports-and-sidecars.md.Tests
tests/openai-chat-hardening.test.ts: both presets forward a caller-supplied key end-to-end throughrouteModel→buildRequest(config omits the flag, so this pins the registry backfill, not a config tautology); an explicitpromptCacheKey: falsestill suppresses it.tests/provider-registry-parity.test.ts: both registry entries carry the flag, andproviderConfigSeed/enrichment persist it (the 429-rotation guarantee).bun testgreen on the touched suites plus the kimi-adjacent sweep (hardening, parity, key-failover, payload, reasoning-effort, adapter-usage, inbound);tsc --noEmitclean.Live verification
The implemented route was exercised against Kimi K3 through
routeModel→ the openai-chat adapter, with the only A/B variable being whether the provider forwarded the same caller-supplied key.429s, or5xxresponses.This verifies that Kimi accepts the field and that forwarding it introduced no observable cache or latency regression in the tested workload. It deliberately does not claim a short-run cache improvement: Kimi's automatic prefix cache hit every control follow-up too. The change is retained to satisfy Kimi Code Plan's documented stable session/task-key requirement and preserve affinity in deployment conditions not reproduced by this local A/B.
🤖 Generated with Claude Code
Summary by CodeRabbit
prompt_cache_keyto outbound chat requests (OAuthkimiand API-keykimi-code), deny-by-default for other providers.prompt_cache_keyacross 429-driven key-rotation retries and honors provider-level opt-out (omits the field when disabled).