Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 8 additions & 13 deletions apps/web/src/pages/workspace/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -742,16 +742,14 @@ function ReadyRoom({
lastShown?.role === "assistant" && !streaming && !sending
? suggestedReplies(lastShown.text)
: [];
// Mid-turn by native state, whoever sent the message: this stream saw the message run start and
// not end, or the hub's activity read saw one start after the last end this stream saw.
const agents = activity.data?.agents;
const coordinatorTurnSince = agents?.find(
(agent) => agent.role === "coordinator",
)?.since;
const coordinator = agents?.find((agent) => agent.role === "coordinator");
// Mid-turn by the hub's read: the coordinator's run began after the last end this stream saw.
// The stream's own flag is not used; a frame missed while the tab is hidden leaves it set.
const working =
liveRun.running ||
(coordinatorTurnSince !== undefined &&
Date.parse(coordinatorTurnSince) > (liveRun.endedAt ?? 0));
coordinator !== undefined &&
(liveRun.endedAt === null ||
Date.parse(coordinator.since) > liveRun.endedAt);
Comment on lines 749 to +752

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 · Thinking… now shows up late when a turn starts

message.run.started is not in reloadAfter, so it does not refresh the room or re-read the hub's activity. With liveRun.running dropped, working waits for the next activity poll (POLL_MS, 10s when idle) or a later reload frame such as inference.done or tool.done.

The tab is idle and the coordinator starts a turn, for example on a message from elsewhere. The stream gets message.run.started, but nothing shows the coordinator working for up to 10s.

Resolve this comment. Triage will not finish while it is open.

Comment on lines +751 to +752

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 · Clock skew can hide an entire turn now that the stream flag is gone

liveRun.endedAt is the browser's Date.now(), but coordinator.since is the hub's clock. If the browser clock runs ahead of the hub by more than the gap between turns, since > endedAt stays false for the whole next turn. Before this change, liveRun.running covered that case; now nothing does.

The browser clock is a few seconds ahead of the server and the person sends a follow-up soon after a reply. working stays false for that whole turn.

Resolve this comment. Triage will not finish while it is open.

// The engine treats the first id as history and every later change as a
// send: it pins that turn and reserves space under it. A turn loaded from
// the mirror is not a send. Passing it pins the old message and the reserve
Expand Down Expand Up @@ -1244,11 +1242,8 @@ function ReadyRoom({
for (const dispatch of dispatches) noteDispatch(dispatchRoom, dispatch);
// The document a writer or reviewer run works on, from the coordinator's own hand-off call as
// the hub's activity read saw it start: the latest such call made before the run started.
const coordinatorTools = agents?.find(
(agent) => agent.role === "coordinator",
)?.tools;
if (coordinatorTools !== undefined)
for (const tool of coordinatorTools) {
if (coordinator !== undefined)
for (const tool of coordinator.tools) {
const role = HANDOFF_ROLE[tool.name];
if (role !== undefined && tool.subject !== undefined)
handoffCalls.current.set(`${tool.at}:${tool.name}`, {
Expand Down