History and replay

Open in

History in AI Transport comes from the Ably channel itself. Every message - user prompts, agent responses, lifecycle events - persists on the channel. Clients load history on connect and paginate backward through the conversation. There is no separate database to maintain.

How it works

The client transport loads history using view.loadOlder() with untilAttach for gapless continuity. This ensures no gap between historical messages and live messages arriving through the real-time subscription.

loadOlder() returns Promise<void> - it expands the view window internally rather than returning a paginated result. The useView hook exposes the loaded conversation as nodes, along with hasOlder and loadOlder for pagination:

JavaScript

1

2

3

4

5

6

const { nodes, hasOlder, loadOlder } = useView(transport, { limit: 30 })

// Load the next page of older messages
if (hasOlder) {
  await loadOlder()
}

Minimal code

The useView hook handles history loading on mount:

JavaScript

1

const { nodes, hasOlder, loadOlder } = useView(transport, { limit: 30 })

This loads 30 messages when the component mounts. nodes contains the decoded conversation. hasOlder indicates whether more history is available. loadOlder() fetches the next page.

Scroll-back pattern

Load more messages as the user scrolls up. The useView hook provides everything needed for infinite scroll:

JavaScript

1

2

3

4

5

6

7

const { nodes, hasOlder, loading, loadOlder } = useView(transport, { limit: 30 })

function handleScrollToTop() {
  if (hasOlder && !loading) {
    loadOlder()
  }
}

loading is true while a history page is being fetched. Use it to show a spinner at the top of the conversation. When hasOlder is false, the user has reached the beginning of the conversation.

History and branching

History includes branch information. Messages carry parent and forkOf headers that indicate which conversation branch they belong to. When history is loaded, the conversation tree reconstructs branches from these headers, placing each message on the correct branch.

This means loading history does not just produce a flat list of messages. It rebuilds the full tree structure, including any points where the conversation forked due to edits, regenerations, or explicit branching.