revert(core): revert malformed streamed response retry logic - #6783
Conversation
This reverts commit 43d34f7.
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
This is a revert of #6754 (retry malformed streamed responses), which was merged just yesterday. The PR body is a one-liner — "Reverts #6754" — with no template headings and, more importantly, no explanation of why the fix is being backed out.
A few things I noticed while looking at the context:
- The original PR addressed #6666, a real production bug where thinking tags leaked into visible content. That issue is currently closed (closed by @wenshao on 2026-07-12).
- @yiliang114 (the original PR author) also reverted their own related PR #6751 the same day — "Preserve tagged thinking parsing for Qwen3 default provider." That's a clear pattern of backing out the client-side thinking-tag detection approach.
- The revert itself is clean — the split retry budget (
transientMaxRetries: 4/protocolTagLeakMaxRetries: 2) is correctly restored to its pre-#6754 state, and all converter-side detection logic, the separateInvalidStreamErrorfile, and the nameless-tool-call handling are fully removed.
The question is: what changed since yesterday that makes this revert the right call? Was the bug fixed server-side? Did #6754 cause regressions? The PR body doesn't say, and that context matters — both for the review and for anyone who hits #6666 again in the future.
Could you add a short explanation to the PR body? Something like:
- Why the revert is needed (server-side fix? regression? approach change?)
- Whether #6666 is still a risk or if it's resolved through another mechanism
中文说明
这是对 #6754(重试 malformed streamed responses)的 revert,而 #6754 昨天才合并。PR body 只有一行"Reverts #6754",没有模板段落,更重要的是没有解释为什么要撤回这个 fix。
几个背景:
- 原始 PR 修复的是 #6666,一个真实的生产 bug(thinking tags 泄漏到 visible content)。该 issue 目前状态为 closed(由 @wenshao 在 2026-07-12 关闭)。
- @yiliang114(原始 PR 作者)同一天也 revert 了自己相关的 PR #6751("Preserve tagged thinking parsing for Qwen3 default provider")。明显是在系统性地撤回客户端 thinking-tag 检测方案。
- Revert 本身是干净的——分离重试预算(
transientMaxRetries: 4/protocolTagLeakMaxRetries: 2)正确恢复到了 #6754 之前的状态,converter 侧的检测逻辑、独立的InvalidStreamError文件、nameless-tool-call 处理都被完整移除。
问题是:从昨天到现在发生了什么变化,使得 revert 成为正确选择? bug 是在服务端修复了?还是 #6754 引入了回归?PR body 没有说明,这个上下文对 review 和未来遇到 #6666 的人都很重要。
能否在 PR body 加一段简短说明:
- 为什么需要 revert(服务端修复?回归?方案变更?)
- #6666 是否还有风险,还是已经通过其他机制解决了?
— Qwen Code · qwen3.7-max
PR body has been updated with full regression analysis: E2E went from 0 to ~14 failed files / 31 failed tests after #6754 merged. Detection heuristics (hasVisibleThinkingTagLeakSignature, shouldDropMalformedAttempt) misclassify legitimate responses as malformed, silently dropping tool calls. Issue #6666 should be re-addressed with less aggressive heuristics in a follow-up PR.
Code Coverage Summary
CLI Package - Full Text ReportCore Package - Full Text ReportFor detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run. |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
No issues found. LGTM! ✅
— qwen3.7-max via Qwen Code /review
…ction (QwenLM#6794) * Revert "Revert "fix(core): retry malformed streamed responses (QwenLM#6754)" (QwenLM#6783)" This reverts commit ff7d48a. * fix(core): narrow nameless tool-call detection to stop false-positive drops hasNamelessToolCall() flagged any buffer slot lacking a name, including phantom slots (no id, no argument content) created by trailing structural deltas. That tripped shouldDropMalformedAttempt on legitimate tool-call responses, clearing parts and suppressing finish_reason to undefined, which surfaced as 'Model stream ended without a finish reason' and broke E2E suites depending on tool-call emission. Only treat a nameless tool call as malformed when the provider actually started a real call (assigned id or streamed argument content). Genuine QwenLM#6666 nameless attempts (id or args but no name) still drop and retry; phantom slots are skipped by getCompletedToolCalls as before. * fix(core): preserve thinking tag stream boundaries * fix(core): address malformed stream review feedback * fix(core): tighten malformed stream retry signals * fix(core): address remaining stream review feedback * test(core): cover stream review edge cases * fix(core): address stream review regressions * refactor(core): remove duplicate thinking tag state * fix(core): close reverse-order stream validation gaps * fix(core): preserve cross-channel tag evidence * test(core): cover split cross-channel tags * fix(core): close remaining stream routing gaps * fix(core): handle late tool call names * fix(core): preserve active tool call routes * test(core): cover malformed stream edge cases * fix(core): preserve streaming tool call routes * refactor(core): simplify malformed stream validation * docs(core): clarify invalid stream retry budget * fix(core): preserve valid streamed metadata boundaries * fix(core): deduplicate streamed tool metadata * fix(core): preserve streamed protocol line boundaries
What this PR does
Reverts PR #6754 (
fix(core): retry malformed streamed responses), which introduced aggressive thinking-tag leak detection and nameless tool-call dropping logic in the OpenAI→Gemini stream converter. The reverted changes includehasVisibleThinkingTagLeakSignature(),pendingUntrustedResponsePartsbuffering,shouldDropMalformedAttemptsuppression offinish_reason, and thehasNamelessToolCall()method onStreamingToolCallParser.Why it's needed
PR #6754 caused a widespread E2E regression on
main. After it was merged (43d34f739d), the E2E suite went from 0 failures to ~14 failed test files / 31 failed tests across both Linux and macOS. The stream converter's new detection heuristics misclassify legitimate responses as malformed, causing tool calls to be silently dropped (parts.length = 0,finish_reasonsuppressed toundefined). All SDK and CLI E2E tests that depend on tool-call emission are affected —permission-control,tool-control,sdk-mcp-server,subagents,multi-turn,edit,file-system,write_file,utf-bom-encoding,cron-tools,notebook-edit,tool-search, etc. The malformed response retry feature should be re-implemented with less aggressive detection heuristics.Reviewer Test Plan
How to verify
cd packages/core && npx vitest run src/core/openaiContentGenerator/converter.test.ts src/core/geminiChat.test.tsEvidence (Before & After)
N/A — non-UI revert.
Tested on
Environment (optional)
CI E2E runs.
Risk & Scope
Linked Issues
Reverts #6754
中文说明
本 PR 做了什么
回滚 PR #6754(
fix(core): retry malformed streamed responses)。该 PR 在 OpenAI→Gemini 流式转换器中引入了激进的 thinking 标签泄漏检测和无名工具调用丢弃逻辑,包括hasVisibleThinkingTagLeakSignature()、pendingUntrustedResponseParts缓冲、shouldDropMalformedAttempt抑制finish_reason,以及StreamingToolCallParser上的hasNamelessToolCall()方法。为什么需要
PR #6754 在
main分支上引发了大面积 E2E 回归。合入后(43d34f739d),E2E 测试从 0 失败变为 ~14 个文件失败 / 31 个用例失败,Linux 和 macOS 均受影响。流式转换器的新检测启发式算法将合法响应误判为畸形,导致工具调用被静默丢弃(parts.length = 0,finish_reason被抑制为undefined)。所有依赖工具调用发射的 SDK 和 CLI E2E 测试均受影响。畸形响应重试功能应以更保守的检测策略重新实现。风险与范围