revert(vscode-ide-companion): undo #3450 split-stream timestamp sharing#3573
Merged
Conversation
… sharing QwenLM#3450 pinned every assistant/thinking segment in a streamed turn to the same turn-start timestamp so a later user message could not be sorted between two segments of the previous turn (QwenLM#3273). That fix turned out to conflict with the tool-call timeline: tool calls carry their own arrival timestamp, which is strictly greater than the turn-start timestamp, so after QwenLM#3450 every tool call sorted AFTER both assistant segments instead of between them — the exact 'tool call jumped to the end' ordering bug users are now reporting. The two bugs pull the sort key in opposite directions and cannot both be satisfied by a single timestamp strategy. Roll QwenLM#3450 back byte-for- byte on useMessageHandling.ts so the tool-call ordering regression is fixed immediately; replace the test file with two focused cases that pin the conflicting invariants so the next fix (likely a monotonic sequence key shared across messages and tool calls) has a clear target: - tool-call interleave test (passes today): a tool call that arrives between two assistant segments must sort strictly between them. - QwenLM#3273 regression test (it.fails today): all assistant segments of one turn must sort before a user message sent during the turn. Flipped to a normal it() once the proper fix lands. Refs: QwenLM#3273, QwenLM#3450 Co-Authored-By: Qwen-Coder <noreply@qwenlm.ai>
yiliang114
approved these changes
Apr 24, 2026
| assistantIdx < next.length | ||
| ? next[assistantIdx].timestamp | ||
| : (currentStreamTimestampRef.current ?? Date.now()); | ||
| : Date.now(); |
Collaborator
There was a problem hiding this comment.
nit: this fallback changed from currentStreamTimestampRef.current ?? Date.now() to plain Date.now(). The primary path (reading from next[assistantIdx].timestamp) should always be taken during active streaming so this is effectively a no-op — just flagging it so it's on the radar when implementing the monotonic-sequence fix, since the thinking timestamp derivation will need to participate in that scheme too.
wenshao
approved these changes
Apr 24, 2026
wenshao
left a comment
Collaborator
There was a problem hiding this comment.
No issues found. LGTM! ✅ — gpt-5.5 via Qwen Code /review
xaelistic
pushed a commit
to xaelistic/qwen-code
that referenced
this pull request
Jun 7, 2026
… sharing (QwenLM#3573) QwenLM#3450 pinned every assistant/thinking segment in a streamed turn to the same turn-start timestamp so a later user message could not be sorted between two segments of the previous turn (QwenLM#3273). That fix turned out to conflict with the tool-call timeline: tool calls carry their own arrival timestamp, which is strictly greater than the turn-start timestamp, so after QwenLM#3450 every tool call sorted AFTER both assistant segments instead of between them — the exact 'tool call jumped to the end' ordering bug users are now reporting. The two bugs pull the sort key in opposite directions and cannot both be satisfied by a single timestamp strategy. Roll QwenLM#3450 back byte-for- byte on useMessageHandling.ts so the tool-call ordering regression is fixed immediately; replace the test file with two focused cases that pin the conflicting invariants so the next fix (likely a monotonic sequence key shared across messages and tool calls) has a clear target: - tool-call interleave test (passes today): a tool call that arrives between two assistant segments must sort strictly between them. - QwenLM#3273 regression test (it.fails today): all assistant segments of one turn must sort before a user message sent during the turn. Flipped to a normal it() once the proper fix lands. Refs: QwenLM#3273, QwenLM#3450 Co-authored-by: Qwen-Coder <noreply@qwenlm.ai>
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.
TLDR
Roll back #3450 byte-for-byte on
useMessageHandling.ts. #3450 tried to fix #3273 (a later user message sorting between two segments of the previous assistant turn) by pinning every split segment to the same turn-start timestamp, but that strategy conflicts with the tool-call timeline: tool calls carry their own arrival timestamp (strictly greater than the turn-start timestamp), so after #3450 every tool call sorts after both assistant segments instead of between them. The resulting "tool call jumped to the end" symptom is what users are currently reporting. Revert unblocks that regression; two focused tests pin the two conflicting invariants so the next fix has a clear target.Dive Deeper
The webview (
App.tsx) merges text messages (useMessageHandling.messages) and tool-call cards (useToolCallsmap) into a single array and sorts bytimestampfor rendering. Three producers write into that sort key:startStreaming(T_stream)using the extension-sideDate.now()that rides on thestreamStartmessage.useToolCalls.resolveTimestamp, which takes the ACP_meta.timestampwhen present, otherwise the webview'sDate.now()at event-arrival time. Always ≥T_stream.breakAssistantSegment()) — before fix(vscode-ide-companion): preserve split stream message ordering #3450, created with the webview'sDate.now()at chunk-arrival time; after fix(vscode-ide-companion): preserve split stream message ordering #3450, re-usesT_stream.#3273 — under React batching on Linux,
Date.now()inside thesetMessagesreducer ofappendStreamChunkcan be evaluated later than the next-turn user message was pushed. That producesseg2.ts > nextUser.ts, and the sort wedges the new user bubble between seg1 and seg2.#3450 — reused
T_streamfor seg2 soseg1.ts == seg2.ts; since the next user message's timestamp is always >T_stream, it can no longer slip between segments. This closed #3273 but locked every seg2 atT_stream, which is less than any tool call in the same turn — so tool-call cards are now appended at the bottom of the turn instead of between the two segments.The two invariants are genuinely opposed under a single-timestamp sort:
seg1.ts < toolCall.ts < seg2.tsall segs of turn N < any event of turn N+1Satisfying both requires a monotonic sequence number shared across producers (messages, tool calls, plan cards), not just smarter timestamps. That is out of scope for this revert — the goal here is to restore the more-visible tool-call ordering and pin the invariants down in tests so the next PR can be judged against both at once.
This PR touches exactly two files:
useMessageHandling.ts— identical tocfe142e9a^(byte-for-byte).useMessageHandling.test.tsx— rewritten with two focused cases (see Reviewer Test Plan).Reviewer Test Plan
packages/vscode-ide-companion, runnpm run build.npx vitest run src/webview/hooks— all 5 test files / 10 cases green, including the two new ones inuseMessageHandling.test.tsx:assigns the second assistant segment a newer timestamp so a tool call can sort between the two segments— a normalit, passes today.keeps every assistant segment of a turn before a user message that was sent between segments (#3273)— markedit.failsand documents the known regression; will flip to a plainitonce the monotonic-sequence fix lands.it.failstest.Testing Matrix
Linked issues / bugs
Reverts #3450. Re-opens #3273 as a known regression pinned by the
it.failstest; the next PR should close it together with the tool-call interleave invariant.