Skip to content

web-ui: surface mid-turn agent posts in the live dock and pre-refresh timeline - #874

Open
irisfeng wants to merge 1 commit into
yc-software:mainfrom
irisfeng:post-speech
Open

web-ui: surface mid-turn agent posts in the live dock and pre-refresh timeline#874
irisfeng wants to merge 1 commit into
yc-software:mainfrom
irisfeng:post-speech

Conversation

@irisfeng

@irisfeng irisfeng commented Aug 31, 2026

Copy link
Copy Markdown

Problem

When the agent posts a message to the conversation mid-turn (the surface tool's action: "post"), that text is effectively invisible in the web UI at the moment it is sent:

  • While the turn streams, run activity carries no text entries, and the live dock has no summary for the surface tool — it shows a generic "Working" line, so the posted text is nowhere in the transcript.
  • After the turn ends, the post sits inside the collapsed N tool calls fold. Only the settled transcript rebuild (which lifts posts into assistant content bubbles) makes the text visible; until that rebuild lands, the only way to read it is to expand the fold. If the rebuild request fails (it is silently swallowed), the text stays buried.

This hurts most for skills/agents that ask the user a question mid-flow and end the turn waiting for the answer: the person staring at the chat sees "Working…" then a collapsed fold, and never learns they were asked anything.

Fix

Treat a surface post as conversation speech as soon as the UI can responsibly show it:

  • postSpeechText(row, allowInFlight) (timeline): a post's text is speech once its result confirms delivery; live contexts may preview the in-flight text; failed or unconfirmed posts stay plain tool rows (consistent with the existing contract that an interrupted post must not claim it was delivered).
  • Live dock (chat): an in-flight post row renders as a message icon + "Posting message" + the first line of the text, instead of the generic step label.
  • Settled-but-pre-refresh timeline (chat): once the turn reaches a terminal status, confirmed posts flush the fold segment and render as work-said bubbles, so the text is visible the moment the turn ends without waiting for the transcript rebuild. The in-flight preview is gated on live work status, so an unconfirmed post never renders as speech inside a settled fold.

Posts also stop inflating the "N tool calls" fold count, which now reflects only actual tool work.

Testing

  • New unit tests for postSpeechText (delivered / in-flight / failed / non-post shapes).
  • Source-structure pins on both render sites and the dock branch, matching the repo's existing chat-source test idiom.
  • plugins/web-ui suite: 597/597 green; tsc + oxlint clean.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

An agent message posted mid-turn through the surface tool (a tool_call with
action:"post") was invisible while its turn streamed: run activity carries no
text entries, the live dock had no surface-tool summary (generic "Working"),
and after the turn ended the text stayed folded under the collapsed
"N tool calls" summary until the settled transcript rebuild replaced it with
a content bubble. If that rebuild failed or lagged, the posted text could only
be found by expanding the fold.

- timeline: postSpeechText(row, allowInFlight) — a post's text is speech once
  its result confirms delivery; live contexts may preview in-flight text;
  failed or unconfirmed posts stay tool rows
- chat: the live dock previews an in-flight post (message icon, "Posting
  message", first line of the text); once the turn ends, confirmed posts
  render as work-said bubbles outside the folds, so the text is visible
  without waiting for the transcript rebuild; the in-flight preview is gated
  on live work status so it never leaks into settled folds
- tests: postSpeechText unit tests plus source pins on both render sites and
  the dock branch (web-ui suite green)
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