diff --git a/changelog.d/fixes/7617-nvidia-strip-cache-key.md b/changelog.d/fixes/7617-nvidia-strip-cache-key.md new file mode 100644 index 0000000000..d3909c9256 --- /dev/null +++ b/changelog.d/fixes/7617-nvidia-strip-cache-key.md @@ -0,0 +1 @@ +- fix(routing): strip `prompt_cache_key` for NVIDIA NIM — Codex CLI injects it, NIM's OpenAI-compatible wrapper 400s on it (#7617) diff --git a/open-sse/translator/paramSupport.ts b/open-sse/translator/paramSupport.ts index ca10d1a223..caad2ab5a3 100644 --- a/open-sse/translator/paramSupport.ts +++ b/open-sse/translator/paramSupport.ts @@ -50,6 +50,11 @@ const STRIP_RULES: StripRule[] = [ // (format:"openai") does not accept the Claude-style `thinking` body field // and returns 400 "Unsupported parameter(s): thinking". Upstream #2268. { provider: "nvidia", match: /minimax-m2\.7/i, drop: ["thinking"] }, + // NVIDIA NIM: OpenAI-compatible wrapper 400s on `prompt_cache_key` (Codex CLI + // injects it natively for its own prompt caching). NIM has no documented + // support for this field (providerSupportsCaching already treats nvidia as + // non-cache-capable) — safe to drop provider-wide, not model-specific. #7617. + { provider: "nvidia", match: /.*/, drop: ["prompt_cache_key"] }, // VolcEngine Ark caps the Kimi coding-plan endpoint at max_tokens <= 32768 // server-side ("integer above maximum value, expected a value <= 32768"), // independent of the model's own catalog ceiling. Confirmed against two diff --git a/tests/unit/nvidia-strip-prompt-cache-key.test.ts b/tests/unit/nvidia-strip-prompt-cache-key.test.ts new file mode 100644 index 0000000000..dd1276a815 --- /dev/null +++ b/tests/unit/nvidia-strip-prompt-cache-key.test.ts @@ -0,0 +1,41 @@ +import { test } from "node:test"; +import assert from "node:assert/strict"; +import { stripUnsupportedParams } from "../../open-sse/translator/paramSupport.ts"; + +test("#7617: stripUnsupportedParams strips prompt_cache_key for nvidia when present", () => { + const body: Record = { + model: "some-nvidia-model", + prompt_cache_key: "codex-cli-session-abc123", + max_tokens: 512, + }; + stripUnsupportedParams("nvidia", "some-nvidia-model", body); + assert.equal( + body.prompt_cache_key, + undefined, + "prompt_cache_key must be stripped for nvidia" + ); + assert.equal(body.max_tokens, 512, "unrelated params must be preserved"); +}); + +test("#7617: stripUnsupportedParams preserves prompt_cache_key for non-nvidia providers (e.g. openai)", () => { + const body: Record = { + model: "gpt-5.4", + prompt_cache_key: "some-cache-key", + }; + stripUnsupportedParams("openai", "gpt-5.4", body); + assert.equal( + body.prompt_cache_key, + "some-cache-key", + "prompt_cache_key must be preserved for non-nvidia providers" + ); +}); + +test("#7617: stripUnsupportedParams is a no-op for nvidia when prompt_cache_key is absent", () => { + const body: Record = { + model: "some-nvidia-model", + max_tokens: 256, + }; + stripUnsupportedParams("nvidia", "some-nvidia-model", body); + assert.equal("prompt_cache_key" in body, false); + assert.equal(body.max_tokens, 256); +});