perf(api): Paginate conversation event history#1017
perf(api): Paginate conversation event history#1017sentry-junior[bot] wants to merge 21 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
05abff3 to
21380f1
Compare
Co-Authored-By: David Cramer <david@sentry.io>
Co-Authored-By: David Cramer <david@sentry.io>
Serve bounded backward history pages and stable forward update pages through signed REST cursors. Update the dashboard to merge both directions without gaps, preserve redaction, and expose older transcript history on demand.
Cancel in-flight polling before merging older history so stale responses cannot replace newly loaded pages. Refresh per-model usage through the updates resource and merge it into the active transcript cache.
Merge fresh detail snapshots into the expanded transcript cache so focus refetches, remounts, and invalidations do not discard earlier pages.
Keep conversation state transitions framework-free and pass the active QueryClient from React Query hooks into cache operations.
Treat optional summary fields in the updates response as replacement data so archive and location state cannot remain stale in cached detail.
Load all older REST event pages before copying Markdown and merge them without overwriting newer live state. Only show event-derived totals once the transcript is complete.
026af85 to
bf6dc14
Compare
Refresh the REST detail anchor after an invalid history cursor, update only the paging cursor in the live cache, and continue the requested page read.
Keep an absent previousCursor absent when forward-update recovery refreshes detail, while still replacing stale cursors for partially loaded histories.
Adopt restricted history snapshots over cached available events, and ignore late page responses after another request has completed the transcript.
Deduplicate and sort merged event pages by canonical sequence so cursor recovery cannot leave overlapping transcript windows out of order.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 7dcd256. Configure here.
| "history", | ||
| detail.data?.previousCursor, | ||
| detail.data?.eventHistory.status, | ||
| ], |
There was a problem hiding this comment.
Detail refresh orphans loaded history
Medium Severity
The history infinite query keys on detail.previousCursor. After the conversation grows, a detail refetch (archive invalidation or cursor recovery) issues a new previousCursor for a shifted latest window, which creates a new empty history query and drops already-loaded older pages. The UI then shows only the new detail slice and can re-offer Load earlier events even after history was complete.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 7dcd256. Configure here.


Conversation transcripts now use bounded, cursor-based REST resources instead
of repeatedly loading the complete event history:
GET /api/conversations/:idreturns mutable metadata, the latest boundedevent page, and cursors for both paging directions.
GET /api/conversations/:id/events?before=…returns one older history page.GET /api/conversations/:id/updates?cursor=…returns one forward page througha stable high-water mark, with
hasMorewhen another page remains.Cursors are signed, opaque, direction-specific, and conversation-bound. SQL
reads scan bounded canonical rows while projecting only reporting events, and
subagent pairing remains correct across page boundaries. Each resource
re-evaluates transcript retention and participant access so expired and private
histories keep the existing privacy contract.
The dashboard stores detail, backward history, and forward updates as separate
TanStack Query resources and derives one ordered transcript from their immutable
responses. Earlier pages load on demand, active conversations poll only for
forward deltas, and Markdown export drains remaining history without writing
into another resource's cache. The long mock transcript exercises the same REST
flow, including active polling, end-of-history behavior, and complete export.
Requested by David Cramer via Junior.
--
View Junior Session