Repository navigation
0.83.1: reasoning off picks the lowest accepted level and survives format conversion - #376
Merged
Merged
Conversation
…rmat conversion - tw-dialect: add think::none_fix. A refused `none` is resent with the lowest level the error lists, and without the effort only when it lists none; dropping it made the model reason at its default level. none_rejection is unchanged. - tw-dialect: add params::write_reasoning_none, which writes OpenAI's `none` even where the body carries no effort yet. - Converted hops: `set.reasoning: off` now reaches the upstream. OpenAI Chat and Responses targets get `none` written on the converted body; Gemini targets get reasoning marked as disabled, so the encoder writes a zero thinking budget on 2.5 Flash and reports it dropped elsewhere. The attempt chain and the effort memory read what was sent. - Docs for set.reasoning and the resend; version 0.83.1 with release notes. 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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Fixes two cases where
set.reasoning: offleft the model reasoning, and bumps the version to 0.83.1.Refused
nonemade reasoning go upWhen an upstream rejected the
nonewritten byoff(models that accept onlyminimal/low/medium/high), the resend dropped the effort, so the model reasoned at its default (usuallymedium), and that was remembered for 7 days.tw_dialect::think::none_fix(status, error_body) -> Option<EffortFix>: whennone_rejectionholds,Use(lowest level listed in the error), elseDrop.none_rejectionis unchanged.hop.rseffort_refuseduses it.offdid nothing across a format conversionConverted hops applied
offto the intermediate representation by removing the reasoning config, so an Anthropic or Gemini client routed to an OpenAI Chat/Responses upstream sent no effort at all and the upstream reasoned at its default, while the attempt chain showedsent: null.translate::apply_settakes the target format and reports whether it turned reasoning off. After encoding,translate::reasoning_offwritesnoneon the converted body for Chat (reasoning_effort) and Responses (reasoning.effort), via the newtw_dialect::params::write_reasoning_none, which also fills in the field when the converted body carries no effort (an adaptive Claude request withoutoutput_config.effort).thinkingBudget: 0on Gemini 2.5 Flash; models that cannot turn thinking off (2.5 Pro, Gemini 3) still get no thinking config, and the conversion now reports reasoning as dropped. Smallest non-zero budgets (2.5 Pro) and Gemini 3 minimal levels are not modelled.adjust_effort, the effort memory and the resend already read the outbound body, soAttemptView.effortand remembered fixes now reflect thenonereally sent. Same-format hops and their byte-preserving splice are untouched.The control-plane protocol stays at 54; no API or TS type changes.
Tests
think.rs:none_fixwith a list containingminimal→minimal;low/medium/high→low; no list →Drop; not aboutnone→None.params.rs:write_reasoning_nonefills in and overwrites the OpenAI fields, leaves other formats alone.tests/effort.rs: refusednoneresent withlowand remembered,Dropwithout a list; Anthropic client +off→ Chat getsreasoning_effort: "none"(also adaptive without an effort, and a refusednonethere is resent withminimal); → Responses getsreasoning.effort: "none"; Chat client → Anthropic upstream has no thinking; → Gemini 2.5 Flash getsthinkingBudget: 0; a rule level across conversion is written in Chat, Responses and Anthropic format; each attempt-chaineffortmatches what was sent.Docs (
config.md,config.zh-CN.md) andrelease-notes/0.83.1.mddescribe the change.🤖 Generated with Claude Code