Repository navigation
fix(core,cli): close tool_use↔tool_result invariant across all failure paths #4176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
wenshao
merged 20 commits into
QwenLM:main
from
wenshao:fix/persist-partial-tool-use-on-stream-error
May 21, 2026
Merged
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
fe35e37
fix(core): persist partial assistant turn when stream errors mid tool…
wenshao b2d332e
test(core): cover thinking+tool_use mid-stream throw in partial-histo…
wenshao 3de3241
fix(core,cli): close tool_use↔tool_result invariant at failure points
wenshao b2fed61
fix(core,cli): close tool_use↔tool_result invariant at failure points
wenshao fc4d57b
fix(core,cli): close tool_use↔tool_result invariant at failure points
wenshao db344a4
fix(core): roll back partial assistant push on retryable mid-stream e…
wenshao 29859cd
Merge remote-tracking branch 'origin/main' into fix/persist-partial-t…
wenshao 7f1c561
fix(core): clear pendingPartialAssistantTurnIndex on history replacement
wenshao 08216d9
fix(core,cli): close mimo-v2.5-pro review gaps on partial-tool_use re…
wenshao 2dbfc4e
fix(core): defer chat-recording flush until partial-turn rollback dec…
wenshao fd12639
fix(core,cli): close 4 deepseek-v4-pro review threads on PR #4176
wenshao 2880de5
fix(core): close 3 review threads on partial-tool_use repair (PR #4176)
wenshao ce68749
fix(core): close 6 review threads on partial-tool_use repair (PR #4176)
wenshao c8fa314
fix(core,cli): close 10 review threads on partial-tool_use repair (PR…
wenshao c30bba6
fix(core,cli): close 3 review threads on partial-tool_use repair (PR …
wenshao 06a6951
test(cli): route existing dedup tests through fast-path accessor (PR …
wenshao b27085a
refactor(core,cli): address yiliang114 review observations (PR #4176)
wenshao a8ac579
Merge remote-tracking branch 'origin/main' into fix/persist-partial-t…
wenshao 2985881
refactor(core): consolidate partial-tool_use repair docs into one des…
wenshao e2033ec
refactor(core): further trim partial-tool_use repair comments (PR #4176)
wenshao File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
fix(core,cli): close tool_use↔tool_result invariant at failure points
Extends the partial-history fix in fe35e37 to cover the residual race paths surfaced in PR #4176 review: - Race A: Ctrl+Y while in-flight tool hasn't finished. History is [user, model(tool_use)] — `stripOrphanedUserEntriesFromHistory` only pops trailing user entries, so the retry payload lands as a fresh user turn after the orphan tool_use and API rejects. Meanwhile the scheduler's `onAllToolCallsComplete` is single-shot and gated on `isResponding`, so the eventual tool_result is silently swallowed. - Race B: process crash / OOM / SIGKILL between the partial-tool_use push and the React scheduler's tool_result submission. On `--resume` the dangling model(tool_use) wedges the first API call. - Race C: external tooling / manual JSONL edits leaving the same dangling shape. The fix has three pieces working together: 1. `repairOrphanedToolUseTurns(history)` in geminiChat.ts walks history left-to-right and synthesizes an `error`-typed functionResponse for every functionCall whose id is not echoed back in the next user turn. Appends to an existing user turn when present, otherwise inserts a new one. Returns the injected (callId, name) list. 2. `GeminiClient.repairOrphanedToolUseTurnsInHistory()` wraps the helper and is called from three points: - `startChat()` after loading the transcript (Race B/C, --resume). - `sendMessageStream` Retry branch after stripOrphans (Race A). - `sendMessageStream` UserQuery/Cron branch (defensive belt-and- suspenders for anything that slipped past 1 and 2). 3. `handleCompletedTools` in useGeminiStream.ts dedupes against chat.history before submitting tool_results — if a synthetic functionResponse for the same callId is already present (planted by the repair pass), the in-flight scheduler's late result is dropped and the call is `markToolsAsSubmitted` so the UI advances. Same trade-off upstream Claude Code's `StreamingToolExecutor.discard()` makes — late real results are dropped on the wire after synthesis, the model sees the synthetic error and can retry the tool if it still wants the result. Together with the partial-history push from fe35e37, every tool_use that ever streamed to the consumer is guaranteed to have a matching tool_result on the wire — regardless of whether the stream errored, the user retried mid-flight, the process crashed, or the session is later resumed. This is the qwen-code analogue of upstream Claude Code's `yieldMissingToolResultBlocks` (query.ts:123-149), but split across the core/cli boundary because the React tool scheduler runs out-of-band from the stream loop (so the synthesis path can't atomically discard in-flight tools the way upstream's StreamingToolExecutor can; the history-dedup at handleCompletedTools fills that gap instead). Tests: - 8 new repair-helper tests in geminiChat.test.ts cover Race A, Race B, partial coverage of parallel tool_use, idempotence on already-paired history, no-op on tool-free history, caller- supplied reason text, multiple non-adjacent dangling rounds, and routes through the GeminiChat instance-method wrapper. - client.test.ts mocks updated for the new GeminiChat method. - All 88 geminiChat tests pass; 131 client tests pass; 91 useGeminiStream tests pass.
- Loading branch information
commit 3de3241a2c2cb82560db01558c81b09103b80c5e
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
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
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
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
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.