fix(streaming): strip Gemma 4 thinking tokens — closes #607 - #648
Conversation
Review: ✅ Approved — ready to mergeVerdict: LGTM Two confirmed bugs fixed in 1. Gemma 4 thinking tokens appear in chat output
Test count: 1362 passing, 4 pre-existing failures in One note (non-blocking): The pattern confirmation from Gemma 4 prompt docs and issue #607 comments looks solid. If Gemma 4 ever emits a variant format (e.g. with different whitespace after No issues. Ready to merge. |
Independent End-to-End Review — PR #648Independent review of the Gemma 4 thinking-token fix. Found and fixed a missed code path. TL;DRNow merge-ready after follow-up commit Issue found: incomplete coverageGemma 4 thinking tokens (
On reload, Follow-up pushed (
|
| Aspect | Status |
|---|---|
| Tests | ✅ 1333 passed, 0 failed |
| Security | ✅ Clean |
| Live streaming fix | ✅ Original PR |
| Auto-title fix | ✅ Original PR |
| Persisted render fix | ✅ Follow-up b162475 |
| Regression tests | ✅ Added for all three code paths |
Merge-ready. Prior approval stands, with the addition of the b162475 follow-up that completes coverage.
Review follow-up: delimiter bug fixed + tests addedDuring end-to-end review I found a critical bug that made this PR inoperative: Bug found: wrong delimiter in ALL paths The original PR used
The actual Gemma 4 format is Cross-reference: the existing What was pushed in the fix commit (f263408):
Test results after fix: 25/25 passed (test_issue607.py x13 + test_sprint38.py x12). Full suite: 4 failed (pre-existing test_sprint34.py OAuth stubs), 1381 passed. CHANGELOG: updated to show correct The fix is pushed to the |
The PR fixed three of four code paths for Gemma 4's asymmetric <|turn>thinking\n...<turn|> delimiter format: - static/messages.js _thinkPairs (live streaming) - api/streaming.py _strip_thinking_markup (auto-title + message extraction) But missed the fourth: static/ui.js renderMessages() which is the entry point when a session is reloaded from persisted history. Without this, a Gemma 4 user refreshing a session would still see raw tokens in chat. Added: - _messageHasReasoningPayload detection regex updated - New extraction block mirroring the existing <think> and <|channel> patterns, parsing the Gemma 4 format into a thinking-card instead of leaving it in the displayed content - 2 regression tests in tests/test_sprint38.py Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…in all paths, add tests — closes #607 The original PR used <|turn>thinking (missing second pipe) in: - api/streaming.py _strip_thinking_markup() - static/messages.js _thinkPairs - static/ui.js (follow-up commit b162475 also had wrong delimiter) This commit fixes all three paths to use the correct <|turn|>thinking\n...<turn|> format per Gemma 4 spec, adds _looks_invalid_generated_title detection, and adds 13 regression tests in tests/test_issue607.py.
f263408 to
8af08e4
Compare
Problem
Gemma 4 emits reasoning output using
<|turn>thinking\n...<turn|>delimiters. The WebUI's thinking-token parser only handled<think>...</think>and the MiniMax channel format, so Gemma 4's raw reasoning text appeared prepended to the answer in chat.Fix
Added the Gemma 4 pattern in two places:
static/messages.js—_thinkPairsarray (controls live streaming display):api/streaming.py—_strip_thinking_markup()(strips from persisted session history and auto-title generation):Testing
Closes #607