-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathchatSnapshot.ts
More file actions
59 lines (54 loc) · 2.16 KB
/
Copy pathchatSnapshot.ts
File metadata and controls
59 lines (54 loc) · 2.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/**
* Persisted chat-snapshot blob. Written by `chat.agent` to S3 after every
* turn completes (when no `hydrateMessages` hook is registered) and read
* back at the start of the next run to seed the accumulator. Also read by
* the Sessions dashboard to render the full conversation transcript
* without re-streaming `session.out` from `seq_num=0`.
*
* S3 key suffix: `sessions/{sessionId}/snapshot.json`. The webapp's
* presigned-URL service prefixes this with `packets/{projectRef}/{envSlug}/`.
*
* `lastOutEventId` is the S2 seq_num (as a string) of the snapshot's
* final `turn-complete` control record. Used to resume `session.out`
* replay from precisely after the snapshot, and as the trim-chain seed
* for the agent's next turn.
*
* The `version` field is a forward-compat lever: readers that don't
* recognise a version silently fall back to no-snapshot behaviour.
*/
import { z } from "zod";
import type { UIMessage } from "ai";
export type ChatSnapshotV1<TUIMessage extends UIMessage = UIMessage> = {
version: 1;
savedAt: number;
messages: TUIMessage[];
lastOutEventId?: string;
/**
* Committed `.in` consume cursor (S2 seq_num, stringified) as of this
* snapshot's turn-complete. Lets the next boot seed the `.in` resume
* cursor without scanning `session.out` for the latest turn-complete
* header. Absent on snapshots written before this field existed —
* readers fall back to the scan.
*/
lastInEventId?: string;
};
/**
* Zod schema for `ChatSnapshotV1` with the message shape kept opaque
* (`unknown[]`). The agent runtime types messages strictly via the
* generic parameter; readers that need stricter validation can layer
* their own UIMessage parser on top.
*/
export const ChatSnapshotV1Schema = z.object({
version: z.literal(1),
savedAt: z.number(),
messages: z.array(z.unknown()),
lastOutEventId: z.string().optional(),
lastInEventId: z.string().optional(),
});
/**
* S3 key suffix for a session's snapshot blob. The webapp's presigned
* URL routes prefix this with `packets/{projectRef}/{envSlug}/`.
*/
export function chatSnapshotKeySuffix(sessionId: string): string {
return `sessions/${sessionId}/snapshot.json`;
}