fix: print the running tool once, not twice #17

Merged
adrianbonpin merged 1 commits from fix/duplicate-activity-line into prod 2026-10-05 09:49:41 +00:00
Owner

The two screenshots show one bug and one correct case:

  • 17.37.16 is the bug: a tool running before any text arrived printed Reading a page twice, one line above the other.
  • 17.37.24 is the feature working: the answer had started arriving, so the note above it was the only thing saying a page was being read.

Cause

Two surfaces were rendering the same fact, and they only overlapped in one state:

Surface Shown when
The view-level note above the transcript (ChatView) a tool was running
The answer placeholder in the transcript (markdown.ts) a tool was running and no text had arrived yet

So the duplication appeared exactly while a tool ran before the first token, which is the common case for a turn that starts with a search. Once text arrived, the placeholder was gone and only the note remained, which is why the second screenshot looks right.

Fix

One fact, one line. The activity line is now rendered by the transcript itself, on the live message, and the view-level note is gone.

It is deliberately not just a substitute for missing text: it is shown whether or not tokens have arrived, because a tool that starts mid-answer would otherwise be invisible for the rest of the turn. That was the original complaint about hidden tool calls, so the fix had to keep the second screenshot working while removing the first screenshot's duplicate.

The cursor now rides on whichever line is written last, so it trails the text actually arriving rather than sitting on a line of its own.

Rendered output, all four states:

tool running, no text yet      _Reading a page…_ ▍
tool running, answer arriving  _Reading a page…_
                               Yes. grounds.ph is GroundsPH. ▍
same tool again                _Reading a page · the same call again (2)…_ ▍
no tool, still thinking         _Thinking…_ ▍

The repeat wording lives in one exported describeActivity, so both surfaces it used to feed can never drift apart again.

Tests

Ten new, and one honest note about them: a markdown-level test could not have caught the original duplication, because half of it lived in a component. What the tests pin is the single-line behaviour of the one remaining surface (exactly one occurrence of the label, cursor placement, the repeat wording, and no activity line on a finished message). The durable guard against re-adding the second surface is a comment where the note used to be.

  • 497 tests pass, tsc --noEmit, eslint ., vici lint, vici build all clean.
  • Built output deployed, so this is live in the launcher.
The two screenshots show one bug and one correct case: - **17.37.16** is the bug: a tool running before any text arrived printed `Reading a page` twice, one line above the other. - **17.37.24** is the feature working: the answer had started arriving, so the note above it was the only thing saying a page was being read. ## Cause Two surfaces were rendering the same fact, and they only overlapped in one state: | Surface | Shown when | | --- | --- | | The view-level note above the transcript (`ChatView`) | a tool was running | | The answer placeholder in the transcript (`markdown.ts`) | a tool was running **and** no text had arrived yet | So the duplication appeared exactly while a tool ran before the first token, which is the common case for a turn that starts with a search. Once text arrived, the placeholder was gone and only the note remained, which is why the second screenshot looks right. ## Fix One fact, one line. The activity line is now rendered by the transcript itself, on the live message, and the view-level note is gone. It is deliberately **not** just a substitute for missing text: it is shown whether or not tokens have arrived, because a tool that starts mid-answer would otherwise be invisible for the rest of the turn. That was the original complaint about hidden tool calls, so the fix had to keep the second screenshot working while removing the first screenshot's duplicate. The cursor now rides on whichever line is written last, so it trails the text actually arriving rather than sitting on a line of its own. Rendered output, all four states: ``` tool running, no text yet _Reading a page…_ ▍ tool running, answer arriving _Reading a page…_ Yes. grounds.ph is GroundsPH. ▍ same tool again _Reading a page · the same call again (2)…_ ▍ no tool, still thinking _Thinking…_ ▍ ``` The repeat wording lives in one exported `describeActivity`, so both surfaces it used to feed can never drift apart again. ## Tests Ten new, and one honest note about them: a markdown-level test could not have caught the original duplication, because half of it lived in a component. What the tests pin is the single-line behaviour of the one remaining surface (exactly one occurrence of the label, cursor placement, the repeat wording, and no activity line on a finished message). The durable guard against re-adding the second surface is a comment where the note used to be. - 497 tests pass, `tsc --noEmit`, `eslint .`, `vici lint`, `vici build` all clean. - Built output deployed, so this is live in the launcher.
adrianbonpin added 1 commit 2026-10-05 09:46:40 +00:00
adrianbonpin merged commit ff99778e5d into prod 2026-10-05 09:49:41 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: adrianbonpin/lam-agent-vicinae#17