Fix stale thinking dot placeholders#3876
Conversation
|
| Filename | Overview |
|---|---|
| static/ui.js | Single-line fix in finalizeThinkingCard(): replaces a class-presence check (always true) with a DOM-content check, correctly enabling removal of empty spinner rows. |
| tests/test_issue3869_thinking_dots.py | New regression test that performs static source-text assertions on finalizeThinkingCard. Brace-counting parser is fragile but safe for this function's current structure; covers both empty-spinner removal and real-card preservation. |
| CHANGELOG.md | Adds an Unreleased entry documenting the stale thinking-dot fix with the issue reference. No issues. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[finalizeThinkingCard called] --> B{isSimplifiedToolCalling?}
B -- yes --> C[Find live worklog group in liveAssistantTurn]
C --> D[removeAttribute data-thinking-active / data-live-thinking on all active nodes]
D --> E[_syncToolCallGroupSummary]
B -- no --> F[Find thinkingRow by ID]
F --> G{row exists?}
G -- no --> H[return]
G -- yes --> I{row.querySelector '.thinking-card'?}
I -- null: empty spinner --> J{data-thinking-active === '1'?}
J -- yes --> K[row.remove / return]
J -- no --> L[fall through to finalize]
I -- found: real content --> L
L --> M[Optionally reset scroll to top]
M --> N[removeAttribute id + data-thinking-active / return]
style K fill:#f66,color:#fff
style I fill:#6af,color:#000
Reviews (1): Last reviewed commit: "Fix stale thinking dot placeholders" | Re-trigger Greptile
| // If the row is still just a spinner (no thinking content rendered), | ||
| // remove it entirely — it's the initial waiting dots. | ||
| const hasContent=row.querySelector('.thinking-card') || row.classList.contains('thinking-card-row'); | ||
| const hasContent=!!row.querySelector('.thinking-card'); |
There was a problem hiding this comment.
Missing before/after UI evidence per contribution guidelines
AGENTS.md requires "before/after evidence and test relevant desktop, narrow, and mobile states" for UI/UX changes. The PR description explicitly acknowledges that no browser screenshot was captured, citing DOM-only verification. Even for a finalization-only regression, a short screen recording or screenshot pair showing that dot-only rows disappear (and real Thinking Cards still appear) after the change would satisfy the guideline and make the fix independently verifiable.
Context Used: AGENTS.md (source)
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Thanks, fair point. I updated the PR body with a dedicated UI Evidence section.
For this narrow fix, the before evidence is the reporter screenshot in #3869. The after evidence is the DOM-finalization invariant now pinned by tests/test_issue3869_thinking_dots.py: dot-only legacy thinking rows are removed on finalizeThinkingCard(), while real Worklog Thinking Cards keep their content and only lose live/active markers. CI browser-smoke is also green.
I intentionally did not restart the user's local 8787/8788 runtime or record a provider-specific video for this one-line finalization fix.
|
Pulled the branch into a read-only worktree and read the full Why the old check was dead codeThe thinking placeholder row is always created with the class // ui.js, appendThinking()
row=document.createElement('div');
row.id='thinkingRow';
row.className='thinking-card-row';So in the master version: const hasContent=row.querySelector('.thinking-card') || row.classList.contains('thinking-card-row');the right-hand const hasContent=!!row.querySelector('.thinking-card');
Scope looks rightThis only touches the legacy ( One note on the tests
Net: minimal, correct, well-scoped fix for #3869. No concerns on the diff itself. |
/#3876) (#3886) Fixes #3869: empty legacy three-dot thinking spinners piled up as stale rows after the agent finished thinking. The live-to-final redesign (#3401) made the thinking-card-row wrapper class unconditional, which broke finalizeThinkingCard()'s dots-only detection — it treated the wrapper class itself as a "has content" signal, so the dots-only removal branch went dead. Narrow hasContent to the actual .thinking-card element so dots-only spinners are removed on finalize while real Worklog Thinking Cards are preserved. Includes #3869 regression coverage (brace-walks finalizeThinkingCard, asserts the narrowed check + that real thinking cards are not removed). Co-authored-by: nesquena-hermes <[email protected]> Co-authored-by: franksong2702 <franksong2702@users.noreply.github.com>
|
Absorbed and shipped in v0.51.341 (Release LE, deployed live) via the release #3886 — your fix and regression test were applied with attribution (your diff was byte-identical to the maintainer-recommended fix on #3869). Closes #3869. Thanks @franksong2702! 🙏 |
Thinking Path
.thinking-cardcontent and adds a regression test so dot-only placeholders cannot pile up again.What Changed
finalizeThinkingCard()so dot-only legacy thinking rows are removed when finalized.Why It Matters
UI Evidence
.thinking-cardchild and are removed whenfinalizeThinkingCard()runs;Contract Routing
Task type: focused UI regression fix.
Touched areas:
static/ui.js, thinking placeholder finalization, regression tests, changelog.Relevant public docs:
AGENTS.mdCONTRIBUTING.mddocs/CONTRACTS.mddocs/rfcs/live-to-final-assistant-replies.mddocs/UIUX-GUIDE.mdDESIGN.mdScope boundaries: no backend schema changes, no Thinking Card redesign, no new animation style.
Evidence needed before claiming done: syntax checks plus regression coverage for dot-only placeholder removal and real Thinking Card preservation.
Verification
node --check static/ui.jsnode --check static/messages.jsgit diff --checkuv run --python /opt/homebrew/bin/python3.12 --with pytest pytest tests/test_issue3869_thinking_dots.py tests/test_ui_tool_call_cleanup.py tests/test_issue1298_cancel_and_activity.py tests/test_regressions.py::test_ui_js_can_upgrade_thinking_spinner_into_live_reasoning_card tests/test_regressions.py::test_messages_js_finalizes_thinking_card_before_tool_card -q41 passedpython3 scripts/scope_undef_gate.pyeslintis not installed on PATH.browser-smoke: passedlint: passedRisks / Follow-ups
Fixes #3869
Model Used
OpenAI GPT-5 Codex via Codex CLI, with local shell, GitHub CLI, and CodeGraph context.