From 8ba16ab294d3696da9e7bf20731c03a518269e59 Mon Sep 17 00:00:00 2001 From: Michael Lam Date: Sat, 16 May 2026 21:44:18 -0700 Subject: [PATCH] fix: reuse compact live thinking card --- CHANGELOG.md | 4 ++++ static/ui.js | 7 ++++++- tests/test_ui_tool_call_cleanup.py | 7 +++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93fb8cdd..3597d75b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Compact live Thinking cards now reuse the same timeline card across sequential tool calls, preventing repeated Thinking cards from stacking during one multi-tool turn. + ## [v0.51.82] — 2026-05-17 — Release BF (stage-375 — 2-PR batch — table renderer pipe protection + Catppuccin appearance skin) ### Added diff --git a/static/ui.js b/static/ui.js index 5a33723d..c8cf2662 100644 --- a/static/ui.js +++ b/static/ui.js @@ -7040,7 +7040,7 @@ function finalizeThinkingCard(){ const summary=group.querySelector('.tool-call-group-summary'); if(summary) summary.setAttribute('aria-expanded','false'); } - const active=group.querySelector('.agent-activity-thinking[data-thinking-active="1"]'); + const active=turn.querySelector('.agent-activity-thinking[data-thinking-active="1"]'); if(active) active.removeAttribute('data-thinking-active'); _syncToolCallGroupSummary(group); } @@ -7095,6 +7095,11 @@ function appendThinking(text='', options){ } const thinkingText=String(text||'').trim()||'Thinking…'; let row=blocks.querySelector('.agent-activity-thinking[data-thinking-active="1"]'); + if(!row){ + const thinkingCards=Array.from(blocks.querySelectorAll('.agent-activity-thinking')); + row=thinkingCards.filter(el=>el.closest('.assistant-turn-blocks')===blocks).pop()||null; + if(row) row.setAttribute('data-thinking-active','1'); + } if(!row){ row=_thinkingActivityNode(thinkingText, false); row.setAttribute('data-thinking-active','1'); diff --git a/tests/test_ui_tool_call_cleanup.py b/tests/test_ui_tool_call_cleanup.py index e647b353..d8d0a9d3 100644 --- a/tests/test_ui_tool_call_cleanup.py +++ b/tests/test_ui_tool_call_cleanup.py @@ -307,6 +307,13 @@ class TestToolCallGroupingStatic: assert "body.querySelector" in live_tool_fn and "data-live-tid" in live_tool_fn, ( "tool_complete must still update its current live Activity burst by tool id." ) + finalize_fn = _function_body(UI_JS, "finalizeThinkingCard") + assert "turn.querySelector('.agent-activity-thinking[data-thinking-active=\"1\"]')" in finalize_fn, ( + "Compact Thinking cards live directly in assistant-turn blocks, so finalization must clear the active marker from the whole turn, not only the tool group." + ) + assert "thinkingCards.filter" in live_thinking_fn and "setAttribute('data-thinking-active','1')" in live_thinking_fn, ( + "Compact live thinking should reactivate the latest existing Thinking card instead of stacking a new card after every tool boundary." + ) close_activity_fn = _function_body(MESSAGES_JS, "_closeCurrentLiveActivityGroup") assert "data-live-activity-current" in close_activity_fn, ( "Visible interim assistant boundaries should close the previous live Activity burst."