Skip to content

Comments

feat(session): add ts_before and breakpoint params to Session.messages API#14666

Closed
ryanwyler wants to merge 3 commits intoanomalyco:devfrom
gignit:feature/load-additional-session-messages
Closed

feat(session): add ts_before and breakpoint params to Session.messages API#14666
ryanwyler wants to merge 3 commits intoanomalyco:devfrom
gignit:feature/load-additional-session-messages

Conversation

@ryanwyler
Copy link
Contributor

Summary

Adds two optional parameters to Session.messages() API for loading messages older than the initial 100-message window:

  • ts_before: Unix timestamp - returns messages created before this point
  • breakpoint: Boolean - when true, stops at the first compaction summary

Problem

Multiple open issues request the ability to access message history beyond the initial 100-message limit:

Current Session.messages() only supports a limit parameter, which returns the N most recent messages. There is no way to retrieve older messages.

Solution

This PR adds the foundational server-side API enhancement required by all proposed solutions. The implementation is minimal (8 lines of core logic) and non-breaking:

Core changes:

  • packages/opencode/src/session/index.ts - Add params to Session.messages() schema and iteration logic
  • packages/opencode/src/server/routes/session.ts - Expose params in HTTP API

Why this approach:

  • Timestamp-based anchoring uses immutable reference points, eliminating state management complexity and race conditions that offset-based pagination would introduce
  • Breakpoint support enables "load conversation history" (stop at compaction) vs "load full session" (ignore compactions) use cases
  • Zero breaking changes - all parameters optional, existing functionality unchanged
  • Prerequisite for all solutions - whether TUI, web client, or SDK consumers implement history loading, they all need this server capability

Usage

# Get messages before a timestamp
GET /session/{id}/message?ts_before=1768609939954

# Get messages before timestamp, stopping at first compaction
GET /session/{id}/message?ts_before=1768609939954&breakpoint=true

# Combine with limit
GET /session/{id}/message?ts_before=1768609939954&limit=50

Testing

Verified against sessions with 170+ messages and multiple compactions:

  • ts_before correctly filters to messages older than timestamp
  • breakpoint=true stops at first compaction part
  • Combined parameters work together
  • Existing behavior unchanged when params omitted

Related PRs

PR #8535 - "bi-directional cursor-based pagination"
Status: Open | Additions: 1,228 lines | Approach: Cursor-based with RFC 5005 Link headers

Aspect This PR PR #8535
Core logic 8 lines ~200+ lines
Parameters ts_before, breakpoint before, after, oldest + Link headers
Scope Server API only Server + TUI + tests
Compaction awareness Yes (breakpoint) No
Complexity Minimal Significant (memory bounding, sliding window, RFC compliance)

Why this PR should still be considered:

  1. Simplicity - Timestamp-based anchoring is fundamentally simpler than cursor management.
  2. Compaction-aware loading - The breakpoint parameter enables "load to last context boundary" which is semantically meaningful for LLM conversations.
  3. Incremental adoption - Can merge independently and immediately benefit SDK consumers, web clients, and alternative TUI implementations.
  4. Not mutually exclusive - These approaches could coexist.

Verdict on #8535: Not mutually exclusive. Timestamps serve "load everything before X" queries; cursors serve "give me the next/previous page" navigation.

Verdict on #6656: Superseded by #8535. Not relevant to this PR's approach.

Verdict on #6138: Complementary but insufficient. Users with 1000+ message sessions still can't access early history.

Recommendation: This PR should merge because:

  1. Minimal risk - 8 lines of additive, non-breaking logic
  2. Immediate value - Unblocks multiple consumers
  3. Unique capability - breakpoint parameter for compaction-aware loading isn't in any other PR
  4. Complements rather than conflicts with cursor-based pagination

…s API

Add optional parameters to Session.messages() for loading older messages:
- ts_before: filter to messages created before this timestamp
- breakpoint: stop at first compaction summary when true

This is a foundational API enhancement that enables clients to implement
pagination and history loading without breaking existing functionality.
Adds TUI integration for loading older messages in sessions with 100+ messages.

Implementation:
- loadConversationHistory(): Loads messages up to next compaction summary
- loadFullSessionHistory(): Loads entire remaining session history

UI Integration:
- Displays 'Load more messages' when 100+ messages present
- Two clickable options for conversation vs full history
- Toast notifications show count of messages loaded
- Uses synthetic message pattern for clean positioning

Depends on the ts_before and breakpoint API parameters added in the previous commit.
@github-actions github-actions bot added needs:compliance This means the issue will auto-close after 2 hours. contributor labels Feb 22, 2026
@github-actions
Copy link
Contributor

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@github-actions
Copy link
Contributor

The following comment was made by an LLM, it may be inaccurate:

Potential Related PRs Found

PR #8535 - "bi-directional cursor-based pagination"

PR #10198 - "add offset parameter for message pagination"

PR #6138 - "add session_list_limit for session picker"

The current PR acknowledges these related efforts and makes a case for why its approach (timestamp-based with breakpoint support) complements rather than duplicates the others.

@ryanwyler
Copy link
Contributor Author

Closing — PR was incorrectly created from gignit/opencode-orig. Re-opening from gignit/opencode with correct commits.

@ryanwyler ryanwyler closed this Feb 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor needs:compliance This means the issue will auto-close after 2 hours.

Projects

None yet

1 participant