From d415cc02163cc78bee1eefd8c5ae163b50222285 Mon Sep 17 00:00:00 2001 From: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com> Date: Mon, 6 Jul 2026 19:23:43 -0300 Subject: [PATCH] fix(translator): strip thinking for NVIDIA glm-5.2 (port from 9router#2023) (#6413) strip thinking for NVIDIA glm-5.2 (port #2023) (net +1/-0, test OK). Integrated into release/v3.8.46. --- CHANGELOG.md | 1 + open-sse/translator/paramSupport.ts | 9 ++++++--- tests/unit/nvidia-minimax-thinking-strip.test.ts | 13 +++++++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a27b649775..5211b391e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ ### 🐛 Bug Fixes +- **fix(translator):** strip the Claude-style `thinking` field for **NVIDIA `z-ai/glm-5.2`**. NVIDIA's OpenAI-compatible wrapper 400s on `thinking` (a Claude-format client routed here leaves a `thinking:{type:"adaptive"}`); the existing strip rule only dropped `reasoning`. Same class already handled for `minimax-m2.7`. Regression guard: `tests/unit/nvidia-minimax-thinking-strip.test.ts` (+glm-5.2 case). (thanks @phidinhmanh) - **fix(translator):** suppress the streamed `` close marker for the **Antigravity IDE** client. On thinking-only turns Antigravity rendered a bare `` as the sole visible content, tripping its loop-detection and wasting requests. Antigravity's UA (`vscode/ (Antigravity/)`) is added to the marker-suppress allowlist (alongside OpenCode); Claude Code / Cursor still get the marker, and `x-omniroute-thinking-marker: on` force-restores it. Regression guard: `tests/unit/think-close-marker-suppress-5245.test.ts`. (thanks @abdofallah) - **fix(executors):** strip nested `reasoning_content` from messages for **Mistral**. Mistral's API returns `422 extra_forbidden` when an assistant message carries `reasoning_content` (replayed thinking from a prior turn, e.g. via the Codex `/responses` path); the generic top-level 400 field-downgrade retry never covered the nested per-message field. `DefaultExecutor` now strips it for provider `mistral` only, so DeepSeek (which requires replayed `reasoning_content`) is unaffected. Regression guard: `tests/unit/mistral-strip-reasoning-content-1649.test.ts`. (thanks @xxy9468615) - **fix(executors):** strip the `client_metadata` passthrough field on the **OpenCode** path. OpenCode upstreams (e.g. `kimi-k2.6` via opencode-go) reject it with `400 "Extra inputs are not permitted, field: 'client_metadata'"`; the DefaultExecutor strip only covered cerebras/mistral and `OpencodeExecutor` extends `BaseExecutor` directly, so nothing removed it there. Regression guard: `tests/unit/opencode-strip-client-metadata-1442.test.ts`. (thanks @yanpaing007) diff --git a/open-sse/translator/paramSupport.ts b/open-sse/translator/paramSupport.ts index a0a3a70bab..30a32e2b5c 100644 --- a/open-sse/translator/paramSupport.ts +++ b/open-sse/translator/paramSupport.ts @@ -29,9 +29,12 @@ const STRIP_RULES: StripRule[] = [ /claude/i.test(m) && !/claude.*(opus|sonnet).*4\.6/i.test(m), drop: ["thinking", "reasoning_effort"], }, - // NVIDIA NIM z-ai/glm-5.2: OpenAI-compatible wrapper rejects the `reasoning` - // body field → HTTP 400 "Unsupported parameter(s): `reasoning`". #6102 drop pattern. - { provider: "nvidia", match: /z-ai\/glm-5\.2\b/i, drop: ["reasoning"] }, + // NVIDIA NIM z-ai/glm-5.2: OpenAI-compatible wrapper rejects BOTH the `reasoning` + // body field (#6102) and the Claude-style `thinking` field. A Claude-format + // client (e.g. Claude Code) routed here leaves a `thinking:{type:"adaptive"}` + // that the wrapper 400s on — same class already handled for minimax-m2.7 below. + // 9router#2023. + { provider: "nvidia", match: /z-ai\/glm-5\.2\b/i, drop: ["reasoning", "thinking"] }, // NVIDIA NIM minimaxai/minimax-m2.7: NVIDIA's OpenAI-compatible wrapper // (format:"openai") does not accept the Claude-style `thinking` body field // and returns 400 "Unsupported parameter(s): thinking". Upstream #2268. diff --git a/tests/unit/nvidia-minimax-thinking-strip.test.ts b/tests/unit/nvidia-minimax-thinking-strip.test.ts index 4c67616f39..78fb71f8e2 100644 --- a/tests/unit/nvidia-minimax-thinking-strip.test.ts +++ b/tests/unit/nvidia-minimax-thinking-strip.test.ts @@ -24,6 +24,19 @@ test("stripUnsupportedParams: nvidia + minimaxai/minimax-m2.7 drops thinking", ( assert.equal(body.model, "minimaxai/minimax-m2.7", "model must not be touched"); }); +test("stripUnsupportedParams: nvidia + z-ai/glm-5.2 drops thinking AND reasoning (port from 9router#2023)", () => { + const body: Record = { + model: "z-ai/glm-5.2", + thinking: { type: "adaptive" }, + reasoning: { effort: "high" }, + max_tokens: 512, + }; + stripUnsupportedParams("nvidia", "z-ai/glm-5.2", body); + assert.equal(body.thinking, undefined, "thinking must be stripped for NVIDIA glm-5.2"); + assert.equal(body.reasoning, undefined, "reasoning must still be stripped for NVIDIA glm-5.2"); + assert.equal(body.max_tokens, 512, "other params must survive"); +}); + test("stripUnsupportedParams: nvidia + other model KEEPS thinking (regression guard)", () => { const body: Record = { thinking: { type: "adaptive" } }; stripUnsupportedParams("nvidia", "some-other-model", body);