A reasoning model's reply keeps only what follows its think marker - #707
Merged
WaylandYang merged 2 commits intoSep 14, 2026
Merged
WaylandYang merged 2 commits into
WaylandYang merged 2 commits into
Conversation
Signed-off-by: Aniruddha Adak <aniruddhaadak80@users.noreply.github.com>
aniruddhaadak80
force-pushed
the
fix/reasoning-reply-keeps-only-the-answer
branch
from
September 14, 2026 15:56
fbe2795 to
55a0290
Compare
Contributor
|
@aniruddhaadak80 thanks. You couldn't link locally, so I ran it on a merge with current One thing the PR leaves open, which I'll note on #690 as well: the chat loop streams through 🤖 Generated with Claude Code |
This was referenced Sep 14, 2026
Merged
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.
A reasoning model configured for extraction returns its thinking inline:
settings/testcame back as"OK</think>OK"(#690).utopia_extract::json_blocktakes everything from the first{to the last}, so a brace inside the reasoning cuts the wrong span — and only by luck has it not happened yet on the recall bench.Why strip in
LlmClientExtraction, adjudication, governance batch looks, mappings, type resolution and the settings connectivity test all read
LlmClient::chat. One cut there fixes every non-streaming consumer at once, instead of patching each parser.</think>is a protocol marker, not vocabulary; cutting before the last one guards against the answer itself quoting it; replies without the marker return untouched, so non-reasoning models see no change.The endpoint's separate
reasoning_contentfield needed no handling: this client only ever readsmessage.content, so that field is already ignored.What changed
utopia-llmLlmClient::chatreturns the reply after the last</think>(strip_reasoning).utopia-extractjson_blockalso skips past the last</think>before scanning for{. This is the backstop, not duplication: its contract is already to tolerate preamble (fences, prose), and thechat_toolspath never passes throughchat.chat_stream,chat_tools_stream) deliberately untouched: deltas are yielded live to the UI, cutting the first half would desync already-emitted text.Not in this PR (needs real infra)
Addresses #690
Verification
a_reasoning_reply_keeps_only_what_follows_think(mock-socket throughchat(), braces planted in the thinking to catch the span hazard),a_reply_without_a_think_marker_is_untouched(non-reasoning replies byte-identical),strip_reasoning_cuts_before_the_last_marker,strip_reasoning_fixes_the_settings_test_echo(the exactOK</think>OKshape),parse_response_ignores_a_think_block_before_the_json(an unclosed{in the thinking makes the uncut span unparseable, so.unwrap()fails pre-fix and yields one entity post-fix).cargo fmt --all --checkclean.cargo test/clippycannot link locally. Relying on CI (backendjob) as proof; the string logic was additionally sanity-checked with an equivalent Node script (cut/uncut span parse behaviour confirmed). If CI flags anything I will follow up on the same branch.