fix(app): hydrate timeline message parents#35269
Open
Hona wants to merge 1 commit into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a timeline rendering regression where sessions whose initial message page contains only assistant messages could mount with a blank/zero-height virtual timeline. It does this by ensuring missing user “root” parents are hydrated via the single-message endpoint before the initial page is published, while preserving the original history cursor and maintaining correct behavior under concurrent live events and retries.
Changes:
- Add a readiness predicate (
isTimelineReady) so the session view can remain “not ready” during assistant-only initial loads while parent hydration is still in progress. - Enhance server-side session message loading to backfill missing user parents for assistant messages (using
/session/:sessionID/message/:messageID) before applying the page. - Expand unit + E2E coverage with regression and performance benchmarks for the orphan-parent hydration path, and extend the E2E mock server to serve single-message requests.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| packages/app/src/pages/session/timeline/model.ts | Adjusts timeline “ready” gating to account for assistant-only initial loads while history/parent hydration is active. |
| packages/app/src/pages/session/timeline/model.test.ts | Adds unit coverage for the new timeline readiness logic. |
| packages/app/src/context/server-session.ts | Backfills missing user parents for assistant messages during initial page loads; preserves event correctness across retries. |
| packages/app/src/context/server-session.test.ts | Adds unit tests covering parent backfill behavior, optimistic interaction, caching boundaries, and retry/event preservation. |
| packages/app/e2e/utils/mock-server.ts | Adds support for the single-message endpoint and flexible message delay behavior for E2E scenarios. |
| packages/app/e2e/regression/session-timeline-history-root.spec.ts | New regression E2E covering the reproduced assistant-only initial page shape and ensuring no blank timeline during lifecycle transitions. |
| packages/app/e2e/performance/timeline/session-parent-hydration-benchmark.spec.ts | New performance benchmark measuring click-to-first-correct DOM paint in the orphan-parent hydration path. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Reproduction
The reported session had one user message followed by 14 assistant messages. The initial two-message page therefore contained only assistants. Timeline projection starts from user messages, so the virtual timeline mounted with a
0pxheight and zero rows until older history happened to load.The regression fixture reproduces that exact 1+14 shape at the reported narrow viewport, holds older history pending, and exercises both completion-to-idle and idle-before-aborted-message ordering. No private transcript content is included.
Performance
Production Playwright results against the same
upstream/devcommit:The common path remains neutral. The reproduced orphan path improves by 87.6 ms, about 39.5%. These are click-to-first-correct DOM observations, not standardized browser INP.
Test Plan
bun run test:unitfrompackages/app: 523 passedbun run test:browserfrompackages/app: 26 passedbun typecheckfrompackages/appbun run typecheck:e2efrompackages/app