fix(js): don't treat <thinking> inside code blocks as thinking tags#235
Open
gadenbuie wants to merge 2 commits into
Open
fix(js): don't treat <thinking> inside code blocks as thinking tags#235gadenbuie wants to merge 2 commits into
gadenbuie wants to merge 2 commits into
Conversation
Track fenced code block state during streaming so that <thinking> tags encountered inside ``` or ~~~ blocks are emitted as plain content rather than parsed as thinking blocks. Also exclude inline backtick spans from thinking-tag detection in the non-streaming (splitThinkingBlocks) path. Previously, a chunk boundary where the prior chunk ended with a non-newline character (e.g. a backtick) and the next chunk began with <thinking> would incorrectly enter thinking mode because `before.trim() === ""` was the only guard — the newline-boundary check was missing.
cpsievert
approved these changes
May 27, 2026
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.
Summary
Fixes a bug in the streaming
<thinking>-tag state machine where<thinking>appearing inside a fenced code block (```or~~~) or an inline backtick span was incorrectly treated as the start of a thinking/reasoning block, causing that content to disappear from the visible output into an invisible panel.Two related bugs are fixed:
Fenced code block exclusion (streaming). The state machine now enters a "fence" mode when it encounters a fenced code block opener, treating all content until the matching closer as plain text. Fence state is persisted across chunk boundaries so split chunks work correctly.
Chunk-boundary false positive. A chunk ending with a non-whitespace character (e.g., a backtick in
`<thinking>`) followed by a new chunk starting with<thinking>previously entered thinking mode incorrectly becausebefore.trim() === ""was the only guard. The fix also requires a newline boundary to precede the tag.Inline code span exclusion (non-streaming). The full-message path now also excludes inline backtick spans (
`...`) from thinking-tag detection, matching the existing fenced-block exclusion.Four new test cases cover: (1) chunk-boundary false positive, (2) valid cross-chunk
<thinking>after a real newline, (3) inline code span exclusion, and (4) fenced code block exclusion during streaming.Verification
Construct a message that includes
<thinking>inside a fenced code block, e.g. from a model that uses XML-style reasoning syntax or by appending a chunk manually:Previously the content inside the fence would vanish into an invisible thinking panel. After this fix, it renders as plain code content.