diff --git a/CHANGELOG.md b/CHANGELOG.md index 231f94f7b3c..080fb8e5a17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- **PR #2408** by @Michaelyklam (fixes #2404) — Auto-compression cards now close the current live Activity burst before rendering, so post-compression tools start a fresh `Activity` row instead of joining the pre-compression tool group across a real timeline/context boundary. + ## [v0.51.77] — 2026-05-16 — Release BA (stage-370 — 1-PR follow-up — live Activity grouping boundary fix) ### Fixed diff --git a/static/ui.js b/static/ui.js index 1152a0b0e7c..297072d248c 100644 --- a/static/ui.js +++ b/static/ui.js @@ -4718,6 +4718,13 @@ function ensureActivityGroup(inner, opts){ if(live) _startActivityElapsedTimer(group); return group; } +function closeCurrentLiveActivityGroup(){ + const turn=$('liveAssistantTurn'); + if(!turn) return; + turn.querySelectorAll('.tool-call-group[data-live-tool-call-group="1"][data-live-activity-current="1"]').forEach(group=>{ + group.removeAttribute('data-live-activity-current'); + }); +} function _compressionStateForCurrentSession(){ const state=window._compressionUi; if(!state||!S.session||state.sessionId!==S.session.session_id) return null; @@ -4845,6 +4852,7 @@ function appendLiveCompressionCard(state){ } const inner=_assistantTurnBlocks(turn); if(!inner) return false; + closeCurrentLiveActivityGroup(); const node=_compressionCardsNode(state); if(!node) return false; node.setAttribute('data-live-compression-card','1'); diff --git a/tests/test_ui_tool_call_cleanup.py b/tests/test_ui_tool_call_cleanup.py index cee72ab3dc4..e647b35392c 100644 --- a/tests/test_ui_tool_call_cleanup.py +++ b/tests/test_ui_tool_call_cleanup.py @@ -327,6 +327,19 @@ def test_live_visible_interim_text_splits_tool_bursts_not_thinking(self): "Tool starts must not split consecutive tools into one-tool Activity rows." ) + def test_live_compression_card_splits_current_tool_activity_burst(self): + compression_fn = _function_body(UI_JS, "appendLiveCompressionCard") + close_fn = _function_body(UI_JS, "closeCurrentLiveActivityGroup") + assert "closeCurrentLiveActivityGroup();" in compression_fn, ( + "Auto-compression cards should close the current live Activity burst so later tools start a fresh group." + ) + assert "data-live-activity-current" in close_fn, ( + "The live compression boundary helper must clear the current Activity marker." + ) + assert "removeAttribute('data-live-activity-current')" in close_fn, ( + "Closing a live Activity burst should leave the row rendered but stop later tools from reusing it." + ) + class TestToolCardDesignTokens: def test_root_defines_shared_layout_design_tokens(self):