Skip to content

Commit 7fd80d5

Browse files
committed
docs(ai-chat): page the load example in the migration guide
The example ignored opts while the page told the frontend to load with a limit, so the documented storage could not load older pages and would fail the conformance suite's paging checks.
1 parent ca6de3c commit 7fd80d5

1 file changed

Lines changed: 31 additions & 9 deletions

File tree

‎docs/ai-chat/migrating-from-hydrate-messages.mdx‎

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,40 @@ With `hydrateMessages`, your hook was the source of truth for history and the ru
5151
}
5252
if (!chat) return { messages: [], state: null };
5353

54-
const rows = await db.message.findMany({
55-
where: { chatId },
56-
orderBy: { position: "asc" },
57-
});
54+
const cursors = {
55+
lastOutEventId: chat.session?.lastEventId ?? undefined,
56+
lastInEventId: chat.session?.lastInEventId ?? undefined,
57+
};
58+
59+
let before: number | undefined;
60+
if (opts?.before) {
61+
const anchor = await db.message.findUnique({
62+
where: { chatId_id: { chatId, id: opts.before } },
63+
});
64+
if (!anchor) return { messages: [], state: chat.transcriptState, cursors };
65+
before = anchor.position;
66+
}
67+
const where = { chatId, ...(before !== undefined ? { position: { lt: before } } : {}) };
68+
69+
let rows;
70+
let nextCursor: string | undefined;
71+
if (opts?.limit) {
72+
const page = await db.message.findMany({
73+
where,
74+
orderBy: { position: "desc" },
75+
take: opts.limit + 1,
76+
});
77+
rows = page.slice(0, opts.limit).reverse();
78+
if (page.length > opts.limit) nextCursor = rows[0]?.id;
79+
} else {
80+
rows = await db.message.findMany({ where, orderBy: { position: "asc" } });
81+
}
5882

5983
return {
6084
messages: rows.map((row) => row.message),
6185
state: chat.transcriptState,
62-
cursors: {
63-
lastOutEventId: chat.session?.lastEventId ?? undefined,
64-
lastInEventId: chat.session?.lastInEventId ?? undefined,
65-
},
86+
cursors,
87+
nextCursor,
6688
nonFinalIds: rows.filter((row) => row.status === "partial").map((row) => row.id),
6789
};
6890
},
@@ -73,7 +95,7 @@ With `hydrateMessages`, your hook was the source of truth for history and the ru
7395
};
7496
```
7597

76-
With `opts.limit`, return the most recent messages and a `nextCursor` (the id of the oldest returned message) when earlier ones exist; `opts.before` pages backwards from that id. The runtime never passes them, but the [history read](/ai-chat/transcript-storage#reading-the-transcript) your frontend uses does.
98+
The runtime calls `load` with no options and wants the whole conversation. The [history read](/ai-chat/transcript-storage#reading-the-transcript) your frontend uses passes `limit`, and later `before`, so the example fetches one row more than the page to learn whether earlier messages exist and returns the oldest included id as `nextCursor`.
7799
</Step>
78100

79101
<Step title="Implement save">

0 commit comments

Comments
 (0)