Repository navigation
fix(compat): convert OpenAI reasoning effort to each Claude model's own contract - #227
Merged
Merged
Conversation
…wn contract
OpenAI-format requests (Responses and Chat Completions, including the native
Anthropic-protocol paths) forwarded to Claude models other than Opus/Sonnet
5.5 mapped every reasoning effort the same way: xhigh became max and every
effort but low sent thinking {type:enabled, budget_tokens} against a default
max_tokens of 8192. That is rejected by Opus 4.7/4.8/5, Sonnet 5 and Fable
(budget_tokens), by Opus 4.6/Sonnet 4.6/Opus 4.5 at high and above (budget >=
max_tokens), by Opus 4.5 at max, and by Haiku/Sonnet 4.5 (no effort).
The effort is now converted with the effort catalog of the upstream model:
- adaptive families think adaptively at the requested level or the nearest
level they list (xhigh stays xhigh where listed, becomes max on 4.6);
none/minimal use the lowest level with adaptive thinking, as Anthropic
recommends over disabling it;
- budget families (Opus 4.5, Mythos Preview) and Claude models without
effort levels think on a budget from medium up, with 1024 <= budget <
max_tokens guaranteed: a client max_tokens is kept and the budget shrinks,
the default grows by the budget up to 32000; no budget thinking with a
forced tool choice; models without levels never get output_config.effort;
- a request that thinks drops temperature != 1 and top_p < 0.95;
- dotted OpenRouter IDs (claude-opus-4.7) normalise to their family;
- non-Claude upstreams and the 5.5 branch are unchanged.
Production had no such traffic in the last 30 days (read-only ops check).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
OpenAI-format requests forwarded to Claude models other than Opus/Sonnet 5.5 mapped every reasoning effort the same way. This covers Responses and Chat Completions, including the native Anthropic-protocol paths. The single mapping was
xhigh → max, plusthinking {type: enabled, budget_tokens}for every effort except low, with a defaultmax_tokensof 8192.Per the official Messages contract (checked 2026-10-02), that produces 400s:
budget_tokensmaxis not a valid leveloutput_config.effortnot supportedA read-only check of production found no such traffic in the last 30 days, so the bug is latent.
Change
One conversion (
applyReasoningEffort) is driven by the effort catalog for the resolved upstream model. All call sites use it:ForwardAsResponses,ForwardAsChatCompletions, and the two native Anthropic-protocol paths.thinking: adaptiveat the requested level, or the nearest level the family lists (deeper first).xhighstays native where listed and becomesmaxon Opus 4.6 / Sonnet 4.6.1024 ≤ budget < max_tokensguaranteed. A clientmax_output_tokensis kept and the budget shrinks to fit; the default max_tokens grows by the budget, capped at 32000.output_config.effortfor models without levels.temperature ≠ 1andtop_p < 0.95.claude-opus-4.7) normalise to their catalog family. The 5.5 checks stay exact.Known and deferred: the Antigravity transformer ignores
output_config.effortfor native and compat traffic alike. There are 0 Antigravity accounts in production.Verification
TestResponsesToAnthropicReasoningEffortByModelFamily(table across families, including sampling and forced-tool cases, plus the Chat Completions chain);go build ./..., andgo veton the changed packages.Not run: real model calls.
🤖 Generated with Claude Code