Skip to content

fix(room): give a reloaded run's work band to the reply the history shows - #610

Merged
91jaeminjo merged 1 commit into
mainfrom
refactor/602-bands-on-replayed-messages
Oct 9, 2026
Merged

91jaeminjo merged 1 commit into
mainfrom
refactor/602-bands-on-replayed-messages

Conversation

@91jaeminjo

Copy link
Copy Markdown
Collaborator

Summary

On a reloaded thread, a run's work band now goes to the replies the timeline
actually shows. Before, replayToTrackers re-derived "which reply spoke" from
the stored events (non-blank content plus a stored TEXT_MESSAGE_END). That
copy of the history replay's rule had drifted from the original, so the band
landed in the wrong place:

  • A reply cut off by RUN_ERROR / RUN_FINISHED before its end. The
    history replay commits the partial reply (commitPartialTextOnTerminal),
    but its band fell back to the run's no-response tile.
  • A reply another reply opened over. It is never committed, but it still
    took the band, which then pointed at a tile that never renders.

replayToTrackers now takes the ThreadHistory and hands a run's work only
to a reply in history.messages with non-blank text. The assistant-role
check stays where it was, on the AG-UI TEXT_MESSAGE_START event.

Changes

  • historical_replay.dart: takes ThreadHistory; one speaking set built
    from history.messages replaces the per-run ended / spoke sets. Doc
    comment updated to match.
  • thread_view_state.dart: passes history instead of history.runs.
  • Tests:
    • Replay tests build their history through the real client
      (storedHistory) instead of passing raw bundles.
    • New live/reload parity test: a reply the run fails partway through.
    • New replay tests: a reply the history does not show takes no band; a
      call left open when the stored events run out is failed. The second
      pins endedOn, which no test covered before.
    • Removed nine replay tests that pinned no decision another test does not
      already pin. Checked by breaking replayToTrackers 19 different ways:
      every break caught before the removal is still caught after.
    • Corrected two parity-test comments that still described the old rule.

Notes

  • The backend gives every assistant message a fresh uuid4() id, so a
    message id shared across runs, which would make one run's band overwrite
    another's, is not handled.
  • thread_view_state_test.dart's "a send from a disposed view does not
    throw" still prints a signal warning: … read after disposed. It predates
    this change, and there is no cheap fix.

Test Plan

  • flutter test test/modules/room: 1639 pass
  • flutter analyze: no issues
  • Manual testing: reload a thread whose run errored mid-reply and check
    that the reply carries its work band

Related Issues

Related to #602

🤖 Generated with Claude Code

…hows

On reload, replayToTrackers decided which reply took a run's work band by
re-deriving it from the stored events: a reply with non-blank content whose
TEXT_MESSAGE_END was stored. That copy of the history replay's rule had
drifted from it, so the band landed in the wrong place in two cases:

- a reply cut off by RUN_ERROR or RUN_FINISHED before its end is committed
  by the history replay, but its band fell back to the run's no-response
  tile;
- a reply whose stream another reply opened over is never committed, but
  it still took the band, which then named a tile that never renders.

replayToTrackers now takes the ThreadHistory and hands a run's work only to
a reply in its messages with non-blank text, so the band follows the
replies the timeline shows.

Tests that fed the function raw bundles now build the history through the
real client. Adds a live/reload parity test for the cut-off reply, and
replay tests for the reply the history drops and for a call left open when
a run's stored events run out. Drops replay tests that pinned no decision
another test does not already pin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@91jaeminjo
91jaeminjo merged commit 8a7fccd into main Oct 9, 2026
6 checks passed
@91jaeminjo
91jaeminjo deleted the refactor/602-bands-on-replayed-messages branch October 9, 2026 21:29
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