-
Notifications
You must be signed in to change notification settings - Fork 6.3k
feat(tui): load conversation and session history #8627
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
|
The following comment was made by an LLM, it may be inaccurate: Based on my search, I found several related PRs that are addressing similar functionality: Potentially Related PRs:
These PRs should be reviewed to ensure there's no duplicate work, particularly #6656 and #8535 which appear to implement similar pagination/history loading features. The current PR (#8627) may supersede or need to be coordinated with these existing PRs. |
Comparison with Related PRsPR #6138 (configurable message_limit)
PR #6656 (cursor pagination)
PR #8535 (bi-directional cursor pagination)
Why Timestamp-Based is More ElegantThis PR uses timestamps as immutable anchors rather than message ID cursors: Advantages over cursor-based approaches:
Why explicit loading vs auto-scroll:
Server API Enhancement Benefits Web ClientAs noted in the PR description, the web client currently reloads all messages when loading more. The Addressing the Three Issues
This implementation provides an elegant, non-disruptive solution that solves the core problems without the complexity of RFC-compliant pagination or memory management that may not be necessary for most users. |
|
Have not yet tested, but I like the idea, if it works I would totally be in favour. Little bit suspicious of those 2 failing checks, though. I'm sure you can sort those out, though. ;) |
The failing tests are due to another commit: Commit 779610d from PR #7360 by turculaurentiu91, merged January 15, 2026 at 08:12 UTC, uses platform.openLink() on line 300 of packages/desktop/src/index.tsx, but platform isn't created until line 304 inside the render() function. This causes typecheck error: Cannot find name 'platform'. |
|
I haven't looked at the failures too deeply yet. If it's just the CI system spazzing out and throwing a fit - which does occur sometimes - then it could be safe to disregard, just worth taking a look to gain some confidence that that's what's happened. |
Implements progressive history loading with two distinct modes for accessing older messages in long-running sessions. ## Implementation **Server API Enhancement** Added two optional parameters to Session.messages(): - ts_before: Unix timestamp for loading messages older than a specific point - breakpoint: Boolean flag controlling whether to stop at compaction summaries **Client Load Functions** - loadConversationHistory(): Loads messages up to the next compaction summary - loadFullSessionHistory(): Loads entire remaining session history without stopping Both functions use the earliest loaded message timestamp as an anchor point, eliminating the need for index tracking or offset calculations. **UI Integration** Displays "Load more messages" when 100+ messages are present, offering two clickable options. Toast notifications show the count of messages loaded. Uses a synthetic message pattern for clean, reactive positioning. ## Design Decisions **Timestamp-Based Anchoring** Uses message timestamps as immutable reference points rather than maintaining counts or offsets. This eliminates state tracking complexity and race conditions. **Truthiness Pattern for Breakpoint** The breakpoint parameter uses standard boolean coercion (z.coerce.boolean). Omitting the parameter (undefined) is falsy and loads everything. Sending true stops at compaction summaries. This follows the established pattern used by other boolean parameters like 'roots'. **Two Loading Modes** - Conversation history: Stops at compaction summaries to show context - Full history: Loads all remaining messages for complete reconstruction **Non-Disruptive** All parameters are optional. Existing functionality remains unchanged. Zero breaking changes to any existing code paths. ## Technical Details The server iterates through messages in reverse chronological order, skipping messages newer than ts_before. When breakpoint is truthy and a compaction message is encountered, iteration stops. Results are reversed before returning to maintain chronological order. The client prepends loaded messages to the beginning of the existing array, maintaining sort order with oldest messages first. ## Files Changed - packages/opencode/src/session/index.ts - Core loading logic - packages/opencode/src/server/server.ts - HTTP endpoint parameters - packages/opencode/src/cli/cmd/tui/context/sync.tsx - Load functions - packages/opencode/src/cli/cmd/tui/routes/session/index.tsx - UI - packages/sdk/* - Generated SDK types Total: 176 lines added across 7 files
225aea3 to
f1d8f7d
Compare
Resolves #6137, #4918, #7380
Related to #6548
Problem
Users cannot access message history beyond the initial 100 messages loaded on session init. This makes OpenCode history for long-running sessions incomplete:
Solution
Functional Core: ~38 lines (22% of changes)
Elegant, non-disruptive implementation that adds on-demand message loading with two modes accessed via a "Load more messages" UI when 100+ messages are present:
Only pulls the missing messages - does not reload the entire session, only the missing messages due to the
ts_beforeimplementation.Zero breaking changes - All parameters optional, existing functionality completely unchanged.
Message roll-off maintained - There is a system in the client today that once the messages reach over 100 messages, one message is rolled-off with each new message. This roll-off strategy works perfectly with this feature. A user can load their conversation or their session history and continue their session and the last message will roll off as a new message comes in. If for some reason the user wants to bring back the earliest messages again, they can click the load button at the top to load them all back in, but this natural pruning system is important to maintain and this solution fits perfectly with the entire existing system.
Implementation
Uses timestamp-based anchoring (immutable reference points) rather than offset/count tracking, eliminating state management complexity and race conditions.
Server API Enhancement - Added optional parameters to
Session.messages():ts_before: Unix timestamp for loading messages older than a specific pointbreakpoint: Boolean controlling whether to stop at compaction summariesThis enhances the robustness of the server messaging system by providing precise temporal queries rather than simple limits. The
ts_beforeparameter acts as an immutable anchor point that naturally handles concurrent updates and message insertion without index drift.Client - Two load functions that prepend older messages to the existing array, maintaining chronological order. Toast notifications show message counts.
Total addition: 176 lines across 7 files
Technical Details
breakpointparameter for full history (undefined = falsy)z.coerce.boolean()pattern consistent with other boolean parameters likerootsTesting
Verified with sessions containing 1000+ messages:
Additional Consideration
The server Session.messages() enhancement with ts_before & breakpoint would greatly benefit the web client implementation, which currently reloads all messages when loading more. The timestamp-based approach would allow incremental loading without re-fetching existing messages.
Screenshots
Option to load conversation (next breakpoint) or full session (all breakpoints)

Loading conversation history

Loading full session history
