Skip to content

tui: add debug-flag duplicate-widget diagnostics for issue #426 - #660

Closed
SHYXIN wants to merge 1 commit into
huggingface:mainfrom
SHYXIN:fix/issue-426-transcript-duplicate-diagnostics
Closed

tui: add debug-flag duplicate-widget diagnostics for issue #426#660
SHYXIN wants to merge 1 commit into
huggingface:mainfrom
SHYXIN:fix/issue-426-transcript-duplicate-diagnostics

Conversation

@SHYXIN

@SHYXIN SHYXIN commented Aug 26, 2026

Copy link
Copy Markdown

What

Implements the temporary diagnostics suggested in issue #426 (assistant response rendered twice in a long TUI transcript). This is Path A — instrumentation only, no behavior change. It does not fix the underlying race (that is Path B, deferred per the issue's "keep open for additional reports" guidance).

Why

#426 reports a duplicate assistant row in sessions exceeding the 200-item mounted window, with structured (thinking + text) finalization. The durable JSONL and event pipeline contain a single copy, so the symptom is presentation-only. The issue's "Suggested next steps" ask for temporary diagnostics that:

  • assert/log when multiple visible widgets represent the same canonical assistant item
  • record assistant / ChatItem / mounted-widget identities, transcript window bounds, and active streaming widget identity
  • capture whether a full redraw, structured finalization, window shift, resize, or duplicate end event preceded the symptom

Changes

  • TranscriptView._redraw() now takes a reason argument labeling the trigger: window_shift, state_update, append_page_to_latest, append_overscan_shift, structured_finalization.
  • Gated by env var TAU_DEBUG_TRANSCRIPT_DUP=1 (read once at import). When set, a post-refresh check (_schedule_duplicate_diagnostic) inspects the mounted children and logs a WARNING on tau.tui.transcript_dup whenever two or more visible widgets wrap the same canonical ChatItem (by id(item)), recording window bounds, item/role/widget details, the active streaming item id, and the trigger stack.
  • The WARNING is also written to a file; the path is printed at launch:
    [tau] transcript duplicate diagnostics enabled -> <temp>/tau_transcript_dup.log
  • No effect unless the env var is set — production behavior is unchanged.
  • Added dev-notes/transcript-duplicate-diagnostics.md documenting the diagnostic and how to use it.

How to use

TAU_DEBUG_TRANSCRIPT_DUP=1 uv run tau chat <session-id>
# at launch: [tau] transcript duplicate diagnostics enabled -> <temp>/tau_transcript_dup.log
# after a session, check:
grep "tau.tui.transcript_dup" "$TEMP/tau_transcript_dup.log"

In normal operation the logger stays silent (no false positives). If a duplicate is observed, capture the full warning (including reason) and attach it to #426.

Verification

  • ruff clean, mypy clean.
  • TUI test suite passes; the 6 failures on Windows are pre-existing path-separator issues in unrelated sidebar/export tests (reproduced on clean main), not caused by this change.
  • A forced-duplicate check confirms the detector fires with the expected fields.

Note

This keeps the issue open for real-world reports. If async pruning is confirmed as the cause from collected logs, a serialized/awaited DOM reconciliation (Path B) can follow without conflicting with this instrumentation.

…e#426

TranscriptView._redraw now takes a 'reason' labeling the trigger
(window_shift, state_update, append_page_to_latest, append_overscan_shift,
structured_finalization). When TAU_DEBUG_TRANSCRIPT_DUP is set, a post-refresh
check logs a WARNING whenever two or more visible widgets wrap the same canonical
ChatItem (by id(item)), recording window bounds, item/role/widget details, the
active streaming item id, and the trigger stack.

Serves issue huggingface#426's diagnostics ask (assert/log duplicate assistant rendering and
capture the preceding trigger). No behavior change unless the env var is set.
@SHYXIN
SHYXIN requested a review from alejandro-ao as a code owner August 26, 2026 02:17
@SHYXIN

SHYXIN commented Aug 26, 2026

Copy link
Copy Markdown
Author

Closing in favor of #632, which provides the actual fix (Path B) for the duplicate-rendering bug described in #426. This PR was the temporary Path A diagnostics (env-gated duplicate detection); with #632 landing, the instrumentation is no longer needed. Issue #426 can stay open until #632 merges.

@SHYXIN SHYXIN closed this Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant