Pagination
Cursor-based enumeration on the wire client — the flatten vs *Frames pattern, and how to page memoryList and graphFetch.
Pagination lives on BrainClient. BrainHttpClient does not expose memoryList,
graphFetch, or the typed-graph list* verbs. See
Wire client.
Two forms per enumeration
| Flatten | Raw frames | Returns |
|---|---|---|
memoryList | memoryListFrames | MemoryListItem[] |
graphFetch | graphFetchFrames | { nodes, edges } |
listEntities | listEntitiesFrames | EntityListItem[] |
listStatements | listStatementsFrames | StatementView[] |
listRelationsFrom | listRelationsFromFrames | RelationView[] |
listRelationsTo | listRelationsToFrames | RelationView[] |
listSchemas | listSchemasFrames | SchemaListItemWire[] |
statementHistory | statementHistoryFrames | StatementView[] |
The flatten form is the common case: it drains every streamed frame and concatenates the items for you.
const memories = await client.memoryList({
sort: MemoryListSort.CreatedAt,
dir: MemoryListDir.Desc,
limit: 100, // server validates to 1..=100
cursor: new Uint8Array(), // empty = first page
kinds: [], // empty = all kinds
includeTombstoned: false,
timeAxis: MemoryListTimeAxis.CreatedAt,
fromUnixNanos: 0n,
toUnixNanos: 0n,
salienceMin: 0,
salienceMax: 1,
textContains: "",
actAs: null,
});Driving the cursor yourself
Use a *Frames method when you want to page incrementally — render a page, then
fetch the next. Each frame carries nextCursor, cumulativeCount, and isFinal;
a non-empty nextCursor means more pages remain.
let cursor = new Uint8Array(); // empty on the first page
for (;;) {
const [frame] = await client.memoryListFrames({
sort: MemoryListSort.CreatedAt,
dir: MemoryListDir.Desc,
limit: 50,
cursor,
kinds: [],
includeTombstoned: false,
timeAxis: MemoryListTimeAxis.CreatedAt,
fromUnixNanos: 0n,
toUnixNanos: 0n,
salienceMin: 0,
salienceMax: 1,
textContains: "",
actAs: null,
});
for (const item of frame.items) render(item);
if (frame.isFinal || frame.nextCursor.length === 0) break;
cursor = frame.nextCursor; // opaque continuation token
}The cursor is an opaque Uint8Array — pass it back verbatim, don't parse it. An
empty cursor requests the first page; a non-empty nextCursor from a frame
requests the following page.
graphFetch
graphFetch exports the caller's whole typed graph the same way, but pages
{ nodes, edges }. Its limit validates server-side to 1..=500. Nodes and
edges may repeat across pages (completeness, not disjointness) — dedup by id if
you need a unique set.
const { nodes, edges } = await client.graphFetch({
limit: 500,
cursor: new Uint8Array(),
includeStatements: true,
includeMemories: true,
includeTombstoned: false,
actAs: null,
});Was this page helpful?
Retries
Retry policies for both clients — the HTTP client's built-in policy for idempotent verbs, the wire client's withRetry combinator, and how deadlines cancel a call.
Python SDK overview
brain-db-sdk — the Python client for Brain. Two clients (HTTP + native wire), one verb vocabulary, zero third-party runtime dependencies.