fix(chat): keep a mid-turn message out of the running round's anchor - #708
Open
Adam-Dalloul wants to merge 1 commit into
Open
fix(chat): keep a mid-turn message out of the running round's anchor#708Adam-Dalloul wants to merge 1 commit into
Adam-Dalloul wants to merge 1 commit into
Conversation
A message sent mid-turn is a user turn the agent writes into the MIDDLE of a round, and both rules that hide the persisted copy of the reply being streamed locate that round by its newest persisted user turn. Once the agent records the steered message, the viewer's persisted-tail strip anchors on it and stops stripping the reply's first half; and the backend can no longer stamp `in_flight_user_turn_id` at all, because `apply_in_flight_message_id` matches the pending prompt against the transcript TAIL and the tail is now that message, so the cross-client suppression switches itself off in the middle of the round it exists for. Either way the already-persisted first half lands beside the live copy of the same text, and `mergeConsecutiveAssistantTurns` glues the two into one bubble: the run-on reply the mid-turn split was added to prevent, back again for every turn that is actually steered. Both anchors now step over the detail's own copies of this turn's mid-turn messages, reusing the set `suppressPersistedSteeredPrompts` already matches by content and injection instant so that one rule decides what a steered copy is. The step is gated on the live message holding a block from BEFORE the first interruption: a session that adopted a snapshot mid-turn holds no steering block at all, so a steer arriving afterwards can be the first thing it ever saw of the turn, and hiding the persisted first half there would put it nowhere. Six of the new tests fail without the change; the other five pin the behaviour that must not move (an earlier round's identical words, an unsteered turn, the backend's stamp while it is there).
This was referenced Sep 10, 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.
Sending a message mid-turn shows it as a user bubble and splits the assistant
group so the two replies do not concatenate. Once the agent writes that message
into its own transcript, both rules that hide the persisted copy of the reply
being streamed lose track of the round, and the reply's first half renders twice.
The viewer's persisted-tail strip anchors on the newest persisted user turn, which
is now the steered message, so it stops stripping the first half of the reply the
live stream is re-showing.
The cross-client suppression anchors on
in_flight_user_turn_id, which the backendstops stamping entirely:
apply_in_flight_message_idmatches the pending promptagainst the transcript tail, and the tail is the steered message.
Both now step over the detail's own copies of this turn's mid-turn messages, reusing
the set
suppressPersistedSteeredPromptsalready matches by content and injectioninstant. The step is gated on the live message holding a block from before the first
interruption, so a session that adopted a snapshot mid-turn (no steering block, so
the steer can be the first thing it saw of the turn) keeps the persisted first half
rather than hiding it with nothing in its place.
Eleven tests: six fail without the change, five pin what must not move (an earlier
round's identical words, an unsteered turn, the backend's stamp while it is there,
the same words steered twice in one turn, a steer that carried an attachment).