Skip to content

fix(chat): show a message sent mid-turn as a message, not a strip - #636

Open
Adam-Dalloul wants to merge 1 commit into
xintaofei:mainfrom
Adam-Dalloul:fix/steered-messages-in-transcript
Open

fix(chat): show a message sent mid-turn as a message, not a strip#636
Adam-Dalloul wants to merge 1 commit into
xintaofei:mainfrom
Adam-Dalloul:fix/steered-messages-in-transcript

Conversation

@Adam-Dalloul

Copy link
Copy Markdown
Contributor

Messages sent while a turn is streaming are delivered to the agent, but the live view never shows them as messages.

Two things go wrong. The strip above the composer flips to "received" and then sits there for the rest of the turn, so a sent message never appears as one. And because no user turn lands between them, the reply to that message continues inside the same assistant bubble as the previous one, gluing two separate answers together mid-paragraph ("...I'll report both links once CI is green.Not done - those are the two PRs...").

A note that arrives already delivered came in over the native _session/steering push, which means the agent has the text as a user message. It now becomes a steering block on the live message: the assistant turn closes there, the message renders as its own user turn, and the reply to it starts a new turn. This is what project_turns in parsers/acp_native.rs already does with a mid-turn user_message_chunk, so the live view now matches what you get on reload. A detail fetch that lands mid-turn and brings back the agent's own copy is matched on content, keeping the live copy, since only that one sits between the two halves of the reply.

Pending notes are unchanged. The check_user_feedback pull channel reaches the agent as a tool result and never as a user message, so it has no user turn on reload either and stays a strip. Queued messages, which are only sent once the turn ends, are untouched. A note that arrives with no turn running is not adopted and keeps its strip, so nothing can end up showing in neither place.

A message sent while the agent is replying reaches it over the native
_session/steering channel, and the agent records it as a user message.
The live view dropped the echo, so the only trace was the strip above
the composer, which then sat there for the rest of the turn. And with
no user turn between them, the reply to that message continued inside
the same assistant bubble as the one before it, running two separate
answers together mid-paragraph.

A delivered note now becomes a `steering` block on the live message,
which closes the assistant turn at that point, renders the message as
its own user turn, and starts the reply to it as a new turn. That is
what the transcript projection already does with a mid-turn
user_message_chunk, so the live view and a reload agree; a mid-turn
detail fetch that brings back the agent's own copy is matched on
content and the live copy kept, since only it sits in the right place.

Pending notes are untouched: the check_user_feedback pull channel
reaches the agent as a tool result, never as a user message, so those
stay strips. Queued messages, which are not delivered until the turn
ends, are untouched too.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant