Skip to content

fix(web): reuse timeline rows while thinking and plans stream - #24121

Open
Batuhan1999 wants to merge 1 commit into
pingdotgg:mainfrom
Batuhan1999:perf/timeline-streaming-work-fast-path
Open

Batuhan1999 wants to merge 1 commit into
pingdotgg:mainfrom
Batuhan1999:perf/timeline-streaming-work-fast-path

Conversation

@Batuhan1999

@Batuhan1999 Batuhan1999 commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Streaming thinking and proposed-plan text still force full web timeline row derivation on each text update. In a real Codex Plan-mode turn with prior history, repeated updates to one proposed-plan item re-entered full row derivation roughly every 400–600 ms.

#26727 now re-derives a changed reasoning or plan entry in place and keeps the other entries. Two paths it does not cover still rebuild everything:

  • Streamed plan artifacts. Each proposed-plan delta rebuilds the plans array, so the entry reuse check (shallow(input.plans, …)) fails and every entry is re-derived.
  • Rows. Row derivation only reuses rows for assistant message text, so any reasoning or plan text update re-derives every row.

Change

Rebased onto main and trimmed to what #26727 leaves open:

  • Plan statuses, not plan identity. Entries read only each plan's id, kind and status, so entry reuse compares those (samePlanStatuses) instead of the array.
  • Incremental reasoning and plan rows. replaceStreamingMessageRows now also patches the live work row holding a streamed thought, and the proposed-plan row, in place. Settled groups, folded turns and work toggles derive labels from thinking text, so they keep the full rebuild, as do blankness, completion and metadata changes.
  • isStreamingTurnItemTextUpdate accepts streaming reasoning and proposed-plan items for that row check. Entry reuse keeps patching only assistant text and leaves reasoning and plan items to perf(web): long-thread timeline rebuilds 45 → 9 ms, tool updates 12 → 0.3 ms #26727's in-place re-derive.

The entry-level reuse this PR used to add for reasoning and plans is removed; #26727 covers it.

Scope and approval

Fixes #24120

Web and desktop share these projections; native mobile does not use them. No wire or persisted-state changes.

Verification

Head 2e547ee, one commit on current main.

  • Red on main. With this PR's tests and main's session-logic.ts and MessagesTimeline.logic.ts, 5 tests fail and 150 pass: keeps every other entry when streaming proposed_plan text changes, keeps every row not holding streaming reasoning/proposed_plan text when it changes, and the two matches a full derivation when streaming thinking sits in … cases (expanded live group, superseded by a running tool). The reasoning-entry test passes on main, which confirms perf(web): long-thread timeline rebuilds 45 → 9 ms, tool updates 12 → 0.3 ms #26727 covers that part.
  • Green on the head. All 155 focused tests pass: vp test run src/session-logic.test.ts src/components/chat/MessagesTimeline.logic.test.ts (from apps/web). They cover equivalence with full derivation, blank-text transitions, completion, changing Codex plan artifacts, and expanded and superseded work groups.
  • node scripts/check-changed.ts: format, lint, knip, typecheck, tests and react compiler all pass.
  • Not re-run on this head. The differential oracles, live Codex Plan-mode trace and before/after screenshots and recordings in this PR's earlier description were captured on earlier heads that still had the entry-level reuse; they are in the description's edit history. The Electron shell, native mobile, and CPU or frame-time profiling were not checked.

Implemented with Claude Opus 5.5 via Claude Code (running in T3 Code).

🤖 Generated with Claude Code

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Oct 23, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — This production web optimization adds nontrivial incremental fast paths for streaming reasoning and proposed-plan updates across timeline-entry and row derivation. It automatically bypasses full rebuilding based on streamed data while preserving selected row identities, so the processing gate and its broader runtime implications warrant human review.

Needs human approval because:

  • Macroscope's correctness review did not reach a verdict

Notes:

  • The correctness review was unavailable. Eligibility was assessed without its result.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Walkthrough

Session and row projection paths now support incremental updates for streamed reasoning and proposed-plan text. When metadata checks pass, the paths patch matching entries and rows. Tests compare incremental results with full derivations across streaming states.

Changes: Streaming timeline updates

Layer / File(s) Summary
Recognize and patch streamed timeline entries
apps/web/src/test-fixtures.ts, apps/web/src/session-logic.ts, apps/web/src/session-logic.test.ts
Fixtures cover streamed reasoning and proposed-plan items. Session timeline reuse accepts eligible text updates and patches entries by item ID. Tests cover entry identity and proposed-plan status changes.
Patch streamed work rows
apps/web/src/components/chat/MessagesTimeline.logic.ts, apps/web/src/components/chat/MessagesTimeline.logic.test.ts
Row projection patches eligible reasoning and proposed-plan updates. It settles superseded reasoning and falls back to a full rebuild if it cannot patch a changed thought into a live row. Tests compare incremental projections with full derivations across streaming states and row shapes.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related issues

  • Issue 24120 — The issue describes full timeline rebuilds during streamed reasoning and plan updates. This change adds incremental entry and row update paths for those cases.

Suggested labels: bugfix

Suggested reviewers: maria-rcks, juliusmarminge, macroscopeapp

Merge Risk: Minimal · up to db847

The incremental timeline update is mergeable after normal checks; no concrete blocking issue is established.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title "fix(web): reuse timeline rows while thinking and plans stream" matches the changeset. The diff extends the streaming reuse path in session-logic.ts and MessagesTimeline.logic.ts to reasonin…
Linked Issues check Passed Issue #24120 requires a text-only fast path for streaming reasoning and proposed-plan updates, with full derivation when safety checks fail. session-logic.ts now recognizes streamed reasoning and …
Out of Scope Changes check Passed The changes stay within issue #24120. Production changes are limited to web timeline entry and row reuse. The added fixture helpers and tests support the fast path and verify its fallback behavior. No…
Description check Passed The pull request description includes all required sections: Problem, Change, Scope and approval, and Verification. It explains the issue, implementation, linked issue, affected platforms, test result…
Full details: Title check

Explanation

The title "fix(web): reuse timeline rows while thinking and plans stream" matches the changeset. The diff extends the streaming reuse path in session-logic.ts and MessagesTimeline.logic.ts to reasoning and proposed-plan items, so it covers the main change. It follows the conventional commit format from the template and is specific enough for a teammate scanning history.

Full details: Linked Issues check

Explanation

Issue #24120 requires a text-only fast path for streaming reasoning and proposed-plan updates, with full derivation when safety checks fail. session-logic.ts now recognizes streamed reasoning and proposed_plan text changes, patches only the matching entry, and compares plan identity, kind, and status. MessagesTimeline.logic.ts patches the matching work or plan row and returns to full derivation when grouping, blankness, metadata, or row placement cannot remain safe. The added session and timeline tests compare incremental output with full derivation and cover blankness, completion, artifacts, expanded groups, and supersession. The reported focused test suite passes.

Full details: Out of Scope Changes check

Explanation

The changes stay within issue #24120. Production changes are limited to web timeline entry and row reuse. The added fixture helpers and tests support the fast path and verify its fallback behavior. No wire, persisted-state, or native-mobile changes are present in the reviewed change summary.

Full details: Description check

Explanation

The pull request description includes all required sections: Problem, Change, Scope and approval, and Verification. It explains the issue, implementation, linked issue, affected platforms, test results, limitations, and the agent and harness used.

Finishing Touches

🧪 Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between c3d8c7b and db84725.

Files selected for processing: 4

  • apps/web/src/components/chat/MessagesTimeline.logic.test.ts
  • apps/web/src/components/chat/MessagesTimeline.logic.ts
  • apps/web/src/session-logic.test.ts
  • apps/web/src/session-logic.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

juliusmarminge added a commit to Batuhan1999/t3code that referenced this pull request Oct 24, 2026
… identity loss

These tests reproduce pingdotgg#24120. When a streaming reasoning or proposed_plan
item's text changes, every other timeline entry and every row not holding
that item should keep its identity, as streamed assistant text already
does. On main they fail with Object.is identity assertions while deep
parity with a full derivation still holds.

Fixture and tests are pared down from Batuhan1999's PR pingdotgg#24121.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
juliusmarminge added a commit to Batuhan1999/t3code that referenced this pull request Oct 24, 2026
…eline row

Streamed reasoning and proposed-plan text fell out of the entry and row
fast paths, so every coalesced update re-derived the whole timeline.
Both projections now patch only the entry and row holding the streamed
item, and fall back to full derivation whenever blankness, streaming
state, or row placement could change.

Ports the source changes of pingdotgg#24121 onto current main and adds a fallback
parity test across blank and completion transitions.

Refs pingdotgg#24120

Co-Authored-By: Batuhan1999 <Batuhan.Ckr@outlook.de>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@juliusmarminge juliusmarminge changed the title perf(web): streaming thinking and plan text update only their own timeline row fix(web): reuse timeline rows while thinking and plans stream Oct 24, 2026
@juliusmarminge juliusmarminge added bugfix Fix PR opened by an issue lead; enters the PR loop pr:gate-failed A land gate failed labels Oct 27, 2026

@juliusmarminge juliusmarminge left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the careful work and evidence. Main now re-derives changed work entries in place and retains the other entries via #26727 (29f33af). Please rebase and trim the entry-reuse work already covered there, keeping the changes still needed for streamed plan artifacts and incremental reasoning/plan rows; main still falls back to full row derivation for those updates.

…eline row

pingdotgg#26727 re-derives a changed reasoning or plan entry in place, but two paths
still rebuild everything while those stream:

- Each proposed-plan delta rebuilds the plan artifacts, so the entry reuse
  check (shallow plans) fails. Entries read only each plan's id, kind and
  status, so compare those instead.
- Row derivation only reused rows for assistant message text. Patch the
  live work row holding streamed thinking, and the proposed-plan row, in
  place. Settled groups, folded turns and toggles summarize thinking text,
  so they keep the full rebuild.

isStreamingTurnItemTextUpdate now accepts reasoning and proposed-plan
items for the row check; entry reuse keeps patching only assistant text
and leaves the rest to the in-place re-derive.

Fixes pingdotgg#24120

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Batuhan1999
Batuhan1999 force-pushed the perf/timeline-streaming-work-fast-path branch from db84725 to 2e547ee Compare November 11, 2026 08:57
@Batuhan1999

Copy link
Copy Markdown
Contributor Author

Thanks! Rebased onto main as one commit and removed the entry-level reasoning/plan reuse that #26727 covers. What remains:

  • samePlanStatuses: streamed plan artifacts no longer fail the entry reuse check.
  • Incremental live-thought and proposed-plan row patching in MessagesTimeline.logic.ts.

Entry reuse now patches only assistant text and leaves reasoning and plan items to the in-place re-derive. With main's code, 5 of the PR's tests fail (plan entries plus the reasoning/plan row cases) and the reasoning-entry test passes. On the head all 155 pass and check:changed is green. Head: 2e547ee.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Fix PR opened by an issue lead; enters the PR loop pr:gate-failed A land gate failed size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Streaming thinking and plan text rebuilds the whole chat timeline on every update (~20 times a second)

2 participants