#2099·agentscope

feat(webui): support loading older messages on scroll-to-top with cursor pagination

Author: DavdGaoCreated Jul 16, 2026Updated Sep 16, 2026
LabelsHelp Wantedstale-issue

Background

PR #2081 introduces cursor-based pagination for the list_messages API, returning a has_more boolean alongside the messages. When has_more is true, older messages exist before the current page and can be fetched by passing the oldest message's ID as the before cursor parameter.

Currently, the frontend (useMessages.ts) fetches messages once on session load with no pagination parameters and does not consume the has_more field. Users with long conversation histories can only see the most recent page of messages with no way to load earlier content.

This issue tracks the frontend integration of the paginated messages API, triggered by scrolling to the top of the message list.

Changes

  • In useMessages.ts, capture the has_more flag from the initial sessionApi.messages() response and expose it as part of the hook's return value.
  • Implement a loadMore function that calls sessionApi.messages(sessionId, agentId, { before: oldestMsgId }) and prepends the returned messages to the existing list. Update has_more from each subsequent response.
  • In ChatContent.tsx, add a scroll event listener on the scrollAreaRef that detects when the user has scrolled near the top (e.g., scrollTop < 100). When this threshold is crossed and has_more is true, trigger loadMore.
  • After prepending older messages, preserve the user's scroll position by calculating the height delta and adjusting scrollTop accordingly, so the viewport does not jump to the top of the newly loaded content.
  • Add a loading indicator at the top of the message list while older messages are being fetched, to provide visual feedback and prevent duplicate load triggers.
  • Debounce or guard against concurrent loadMore calls to avoid race conditions during rapid scrolling.

Depends on

  • PR #2081 (cursor-based pagination backend)

Affected files

  • examples/web_ui/frontend/src/hooks/useMessages.tshas_more state, loadMore function, and return value
  • examples/web_ui/frontend/src/components/chat/ChatContent.tsx — scroll-to-top detection, load trigger, scroll position preservation, and loading indicator
  • examples/web_ui/frontend/src/api/session.ts — already updated in PR #2081; verify MessagesResponse includes has_more and messages() accepts before parameter

Part of #2094

Source: agentscope-ai/agentscope