From 0d2678360f37e142f4eb255fdfbef16a2aa7658f Mon Sep 17 00:00:00 2001 From: Will Gordon Date: Thu, 30 Jul 2026 14:51:53 -0400 Subject: [PATCH] fix(sse): strip Claude effort-suffix ids for any provider serving a real Claude model --- .../handlers/chatCore/claudeEffortVariant.ts | 9 +-- .../chatcore-claude-effort-variant.test.ts | 74 ++++++++++++++++++- 2 files changed, 75 insertions(+), 8 deletions(-) diff --git a/open-sse/handlers/chatCore/claudeEffortVariant.ts b/open-sse/handlers/chatCore/claudeEffortVariant.ts index e2a2a8e188..dac50233ad 100644 --- a/open-sse/handlers/chatCore/claudeEffortVariant.ts +++ b/open-sse/handlers/chatCore/claudeEffortVariant.ts @@ -15,6 +15,7 @@ import { splitClaudeEffortSuffix } from "../../config/providerModels.ts"; import { isClaudeCodeCompatibleProvider } from "../../services/claudeCodeCompatible.ts"; import { FORMATS } from "../../translator/formats.ts"; +import { isKnownClaudeEffortBaseModel } from "../../utils/claudeEffortVariants.ts"; /** * True when the client already supplied an explicit reasoning effort (top-level reasoning_effort, @@ -40,12 +41,10 @@ export function applyClaudeEffortVariant(opts: { let effectiveModel = opts.effectiveModel; let log: string | null = null; - if ( - (provider === "claude" || isClaudeCodeCompatibleProvider(provider)) && - typeof effectiveModel === "string" - ) { + if (typeof effectiveModel === "string") { const { baseModel, effort } = splitClaudeEffortSuffix(effectiveModel); - if (effort) { + const isDirectClaudeLane = provider === "claude" || isClaudeCodeCompatibleProvider(provider); + if (effort && (isDirectClaudeLane || isKnownClaudeEffortBaseModel(baseModel))) { effectiveModel = baseModel; if (body && typeof body === "object" && !Array.isArray(body)) { const claudeBody = body as Record; diff --git a/tests/unit/chatcore-claude-effort-variant.test.ts b/tests/unit/chatcore-claude-effort-variant.test.ts index 03bf40a4c1..0630a3c7bd 100644 --- a/tests/unit/chatcore-claude-effort-variant.test.ts +++ b/tests/unit/chatcore-claude-effort-variant.test.ts @@ -2,8 +2,9 @@ // Characterization of applyClaudeEffortVariant — the Claude effort-suffix normalization extracted // from handleChatCore (chatCore god-file decomposition, #3501). The VS Code "Effort" slider // advertises claude-...-{low,medium,high,xhigh,max}; Anthropic has no such model, so the suffix is -// stripped to the base id and surfaced as reasoning_effort. Locks: the provider gate (claude / -// claude-code-compatible only), the in-place body mutation (model + reasoning_effort), the +// stripped to the base id and surfaced as reasoning_effort. Locks: the direct-Claude-lane +// unconditional strip (claude / claude-code-compatible), the predicate-gated strip for any other +// provider serving a real Claude model, the in-place body mutation (model + reasoning_effort), the // sourceFormat==="claude" skip, the explicit-effort-wins rule, and the returned effectiveModel/log. import { test } from "node:test"; import assert from "node:assert/strict"; @@ -51,7 +52,11 @@ test("sourceFormat 'claude' strips the model but does NOT inject reasoning_effor }); test("an explicit client reasoning_effort wins (not overwritten)", () => { - const body: Record = { model: "claude-sonnet-4-low", reasoning_effort: "high", messages: [] }; + const body: Record = { + model: "claude-sonnet-4-low", + reasoning_effort: "high", + messages: [], + }; const r = applyClaudeEffortVariant({ provider: "claude", effectiveModel: "claude-sonnet-4-low", @@ -105,3 +110,66 @@ test("non-claude provider is a no-op even with an effort suffix", () => { assert.equal(body.reasoning_effort, undefined); assert.equal(r.log, null); }); + +test("non-claude provider serving a real Claude model strips the effort suffix", () => { + const body: Record = { model: "claude-sonnet-5-high", messages: [] }; + const r = applyClaudeEffortVariant({ + provider: "vertex", + effectiveModel: "claude-sonnet-5-high", + body, + sourceFormat: FORMATS.OPENAI, + }); + assert.equal(r.effectiveModel, "claude-sonnet-5"); + assert.equal(body.model, "claude-sonnet-5"); + assert.equal(body.reasoning_effort, "high"); +}); + +test("safety guard: non-claude provider with a non-Claude model ending in a suffix word is left unchanged", () => { + const body: Record = { model: "custom-model-high", messages: [] }; + const r = applyClaudeEffortVariant({ + provider: "some-other-provider", + effectiveModel: "custom-model-high", + body, + sourceFormat: FORMATS.OPENAI, + }); + assert.equal(r.effectiveModel, "custom-model-high"); + assert.equal(body.model, "custom-model-high"); + assert.equal(body.reasoning_effort, undefined); + assert.equal(r.log, null); +}); + +test("claude-code-compatible provider strips even an unregistered model id (direct lane short-circuits the predicate)", () => { + // Proves the "unconditional strip, zero regression" claim: isDirectClaudeLane short-circuits + // the `||`, so isKnownClaudeEffortBaseModel() is never consulted for claude/CC-compatible + // providers — unlike the safety-guard case above, which requires the predicate to pass. + const body: Record = { + model: "totally-unregistered-model-xyz-high", + messages: [], + }; + const r = applyClaudeEffortVariant({ + provider: "anthropic-compatible-cc-default", + effectiveModel: "totally-unregistered-model-xyz-high", + body, + sourceFormat: FORMATS.OPENAI, + }); + assert.equal(r.effectiveModel, "totally-unregistered-model-xyz"); + assert.equal(body.model, "totally-unregistered-model-xyz"); + assert.equal(body.reasoning_effort, "high"); +}); + +test("no-think alias's explicit reasoning_effort:none is not overwritten by a stripped effort suffix", () => { + const body: Record = { + model: "claude-sonnet-5-high", + reasoning_effort: "none", + messages: [], + }; + const r = applyClaudeEffortVariant({ + provider: "vertex", + effectiveModel: "claude-sonnet-5-high", + body, + sourceFormat: FORMATS.OPENAI, + }); + assert.equal(r.effectiveModel, "claude-sonnet-5"); + assert.equal(body.model, "claude-sonnet-5"); + assert.equal(body.reasoning_effort, "none"); +});