feat(ui): compact 'Agent activity between turns' card — drop tool noise, show only final result#269
Merged
Merged
Conversation
…se, show only final result PR #268 hid the running tool list from the main card. The "Agent activity between turns" spontaneous card had the same problem one layer deeper — it accumulated every assistant message (including bare `tool_use` blocks that rendered as `🔧 Bash`/`🔧 Read` lines) into a numbered list, exactly the play-by-play we just hid from the main card. Apply the same UX bet here: - `extractSpontaneousSnippet`: tool_use-only assistant messages now return null. Text snippets (the agent's actual conclusion) still survive. Mixed messages still surface the text and ignore the adjacent tool_use, same as before. - `formatSpontaneousCardBody`: render only the LATEST snippet (the conclusion of the burst), not a numbered list of all snippets. When N>1 were coalesced, append a small `_(N events coalesced; showing latest)_` footer so the user knows there was more activity if they want to dig into pm2 logs or the web UI. Side effects: - A between-turn burst that produced ONLY tool calls (no agent text) no longer triggers a card at all — the buffer stays empty, the 30 s flush is a no-op. This is the correct outcome: nothing user-meaningful to report. - The continuation-turn render path (handleContinuationTurn) was already covered by PR #268 since it goes through the same card-builder.ts surface. No change needed there. Tests: - extractSpontaneousSnippet: assert tool_use-only returns null, text+tool_use still returns the text, multi-tool_use returns null. - formatSpontaneousCardBody: assert single-snippet renders without a numbered prefix; N>1 renders the latest snippet plus the coalesced-count footer, and the earlier snippets are NOT in the body. 290/290 vitest pass. Build + lint clean (2 pre-existing warnings). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
5 tasks
floodsung
added a commit
that referenced
this pull request
May 14, 2026
…on (#271) The spontaneous between-turn card was leading every body with an italic `Agent activity between turns (background task return, teammate ping, or /goal evaluator):` caption. Users called it out as visual clutter — and the underlying signal (this is a between-turn burst, not a regular turn) should come from card chrome anyway, not from a long preamble. Drop the caption; carry the signal in the card header instead. - New `CardStatus = 'agent_activity'` — rendered as a blue header with the title "Agent activity" + 🔵 icon. Distinct from `running` / `thinking` (also blue but titled "Running…"/"Thinking…") and from `complete` (green) so users can tell at a glance whether the card is a live turn, a finished reply, or a between-turn burst. - `flushSpontaneous` now uses the new status; `formatSpontaneousCardBody` returns just the latest snippet (and the coalesced-count footer for N>1 bursts) — no italic caption. - Add a guard in `flushSpontaneous`: if the buffer somehow has zero snippets (e.g. tool-only burst that got fully filtered by the text-only extractor in #269), skip the card entirely. The empty card case is now unreachable but the guard is cheap insurance. - Mirror the new status into v1 + v2 card builders, the Telegram sender's STATUS_EMOJI/STATUS_LABEL maps, and the web frontend CardStatus union. Drop the now-unused SPONTANEOUS_CARD_HEADER export and the regression tests that pinned its phrasing. Tests - card-builder + card-builder-v2: add an agent_activity render test asserting blue header + "Agent activity" title + no body caption. - message-bridge: rewrite formatSpontaneousCardBody tests to assert the body is exactly the latest snippet, with no italic caption and no "between turns" / "long-running" substrings. 291 / 291 vitest pass. Build + lint clean (2 pre-existing warnings). Co-authored-by: Flood Sung <floodsung@xvirobotics.ai> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
SimonYeyi
pushed a commit
to SimonYeyi/metabot
that referenced
this pull request
May 26, 2026
…se, show only final result (xvirobotics#269) PR xvirobotics#268 hid the running tool list from the main card. The "Agent activity between turns" spontaneous card had the same problem one layer deeper — it accumulated every assistant message (including bare `tool_use` blocks that rendered as `🔧 Bash`/`🔧 Read` lines) into a numbered list, exactly the play-by-play we just hid from the main card. Apply the same UX bet here: - `extractSpontaneousSnippet`: tool_use-only assistant messages now return null. Text snippets (the agent's actual conclusion) still survive. Mixed messages still surface the text and ignore the adjacent tool_use, same as before. - `formatSpontaneousCardBody`: render only the LATEST snippet (the conclusion of the burst), not a numbered list of all snippets. When N>1 were coalesced, append a small `_(N events coalesced; showing latest)_` footer so the user knows there was more activity if they want to dig into pm2 logs or the web UI. Side effects: - A between-turn burst that produced ONLY tool calls (no agent text) no longer triggers a card at all — the buffer stays empty, the 30 s flush is a no-op. This is the correct outcome: nothing user-meaningful to report. - The continuation-turn render path (handleContinuationTurn) was already covered by PR xvirobotics#268 since it goes through the same card-builder.ts surface. No change needed there. Tests: - extractSpontaneousSnippet: assert tool_use-only returns null, text+tool_use still returns the text, multi-tool_use returns null. - formatSpontaneousCardBody: assert single-snippet renders without a numbered prefix; N>1 renders the latest snippet plus the coalesced-count footer, and the earlier snippets are NOT in the body. 290/290 vitest pass. Build + lint clean (2 pre-existing warnings). Co-authored-by: Flood Sung <floodsung@xvirobotics.ai> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
SimonYeyi
pushed a commit
to SimonYeyi/metabot
that referenced
this pull request
May 26, 2026
…on (xvirobotics#271) The spontaneous between-turn card was leading every body with an italic `Agent activity between turns (background task return, teammate ping, or /goal evaluator):` caption. Users called it out as visual clutter — and the underlying signal (this is a between-turn burst, not a regular turn) should come from card chrome anyway, not from a long preamble. Drop the caption; carry the signal in the card header instead. - New `CardStatus = 'agent_activity'` — rendered as a blue header with the title "Agent activity" + 🔵 icon. Distinct from `running` / `thinking` (also blue but titled "Running…"/"Thinking…") and from `complete` (green) so users can tell at a glance whether the card is a live turn, a finished reply, or a between-turn burst. - `flushSpontaneous` now uses the new status; `formatSpontaneousCardBody` returns just the latest snippet (and the coalesced-count footer for N>1 bursts) — no italic caption. - Add a guard in `flushSpontaneous`: if the buffer somehow has zero snippets (e.g. tool-only burst that got fully filtered by the text-only extractor in xvirobotics#269), skip the card entirely. The empty card case is now unreachable but the guard is cheap insurance. - Mirror the new status into v1 + v2 card builders, the Telegram sender's STATUS_EMOJI/STATUS_LABEL maps, and the web frontend CardStatus union. Drop the now-unused SPONTANEOUS_CARD_HEADER export and the regression tests that pinned its phrasing. Tests - card-builder + card-builder-v2: add an agent_activity render test asserting blue header + "Agent activity" title + no body caption. - message-bridge: rewrite formatSpontaneousCardBody tests to assert the body is exactly the latest snippet, with no italic caption and no "between turns" / "long-running" substrings. 291 / 291 vitest pass. Build + lint clean (2 pre-existing warnings). Co-authored-by: Flood Sung <floodsung@xvirobotics.ai> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
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.
Summary
Apply the PR #268 UX bet ("hide intermediate tool noise, show only the final result") one layer deeper — to the spontaneous "Agent activity between turns" card that coalesces teammate /
/goal/ background-task pings every 30 s.Before
When 5 between-turn events fired during a quiet window, the card listed every one as a numbered item:
`🔧 Bash` / `🔧 Read` are exactly the per-tool play-by-play we just hid from the live card — surfacing them between turns put it right back.
After
Only the latest text snippet (the agent's conclusion of the burst) makes it into the card. The footer tells users how many events were coalesced if they want to dig into `pm2 logs metabot` or the web UI for the play-by-play.
Changes
Test plan
🤖 Generated with Claude Code