Skip to content

Restore server-side message pagination on HTTP endpoint#21580

Merged
Jasonnnz merged 5 commits into
mainfrom
feature/msg-pagination
Mar 25, 2026
Merged

Restore server-side message pagination on HTTP endpoint#21580
Jasonnnz merged 5 commits into
mainfrom
feature/msg-pagination

Conversation

@Jasonnnz
Copy link
Copy Markdown
Contributor

@Jasonnnz Jasonnnz commented Mar 25, 2026

Summary

Restores server-side message pagination that was lost during the WebSocket→HTTP transport migration (#16207). The daemon's GET /v1/messages endpoint now honors beforeTimestamp for cursor-based pagination, enabling the client to load older messages when scrolling up. Uses Option A: only paginate when beforeTimestamp is present, so initial load and reconnect behavior is unchanged (zero regression risk).

Changes

Milestone PRs (merged into feature branch)

Project issue

Closes #21550

Test plan

  • cd assistant && bun test src/__tests__/list-messages-attachments.test.ts — all 17 tests pass
  • Open a conversation with 100+ messages, scroll up — verify older messages load progressively
  • Verify scroll position stays stable during page loads
  • Open a short conversation (<50 messages) — verify no pagination sentinel appears
  • Kill daemon mid-pagination — verify spinner clears after ~60s

Open with Devin

Jasonnnz and others added 4 commits March 25, 2026 14:05
…istory pagination (#21562)

Co-authored-by: Vellum Assistant <assistant@vellum.ai>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: wire server-side pagination into handleListMessages HTTP endpoint

Part of #21550

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: gate pagination fields behind isPaginated and regenerate openapi spec

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Vellum Assistant <assistant@vellum.ai>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: remove trim-after-pagination and add 60s safety timeout for stuck loading state

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use minimal state clear instead of resetMessagePagination() on timeout

Replace resetMessagePagination() in the 60s timeout handler with a
targeted clear of isLoadingMoreMessages + loadMoreTimeoutTask. This
preserves the user's scroll position, historyCursor, and hasMoreHistory
so they can retry by scrolling up, rather than collapsing the visible
window.

Also update doc comments to reflect the 30s/60s two-stage timeout
behavior and the accepted misclassification tradeoff.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Vellum Assistant <assistant@vellum.ai>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Part of #21550. Adds 9 test cases covering backward compatibility, cursor
pagination, strict exclusivity, hasMore logic, metadata correctness, empty
conversations, and input validation.

Co-authored-by: Vellum Assistant <assistant@vellum.ai>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Jasonnnz
Copy link
Copy Markdown
Contributor Author

@codex review

1 similar comment
@Jasonnnz
Copy link
Copy Markdown
Contributor Author

@codex review

devin-ai-integration[bot]

This comment was marked as resolved.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 53aa620718

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1144 to +1146
if (beforeTimestamp !== undefined) {
conditions.push(lt(messages.createdAt, beforeTimestamp));
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include message-id tie-breaker in pagination filter

The pagination query filters only on created_at < beforeTimestamp, so if multiple messages share the same millisecond as the page boundary, the next page permanently skips the remaining same-timestamp messages. This is a real data-loss-in-pagination case for legacy/imported conversations where duplicate millisecond timestamps exist, and the commit already exposes oldestMessageId but never uses it to disambiguate cursors. Please paginate with a stable (created_at, id) cursor (and request-side beforeMessageId) to avoid dropped history rows.

Useful? React with 👍 / 👎.

@Jasonnnz Jasonnnz merged commit 390db07 into main Mar 25, 2026
10 checks passed
@Jasonnnz Jasonnnz deleted the feature/msg-pagination branch March 25, 2026 20:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Restore server-side message pagination on HTTP endpoint

1 participant