@trigger.dev/sdk 4.5.15 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commonjs/imports/ai-runtime-cjs.cjs.map +1 -1
- package/dist/commonjs/imports/ai-runtime.js +2 -0
- package/dist/commonjs/v3/ai-shared.d.ts +15 -0
- package/dist/commonjs/v3/ai-shared.js +35 -1
- package/dist/commonjs/v3/ai-shared.js.map +1 -1
- package/dist/commonjs/v3/ai.d.ts +311 -25
- package/dist/commonjs/v3/ai.js +1633 -380
- package/dist/commonjs/v3/ai.js.map +1 -1
- package/dist/commonjs/v3/auth.d.ts +10 -4
- package/dist/commonjs/v3/auth.js.map +1 -1
- package/dist/commonjs/v3/chat-client.d.ts +11 -2
- package/dist/commonjs/v3/chat-client.js +227 -111
- package/dist/commonjs/v3/chat-client.js.map +1 -1
- package/dist/commonjs/v3/chat-react.d.ts +88 -0
- package/dist/commonjs/v3/chat-react.js +130 -1
- package/dist/commonjs/v3/chat-react.js.map +1 -1
- package/dist/commonjs/v3/chat-server.d.ts +42 -6
- package/dist/commonjs/v3/chat-server.js +52 -7
- package/dist/commonjs/v3/chat-server.js.map +1 -1
- package/dist/commonjs/v3/chat.d.ts +92 -10
- package/dist/commonjs/v3/chat.js +328 -73
- package/dist/commonjs/v3/chat.js.map +1 -1
- package/dist/commonjs/v3/chatSnapshotIo.d.ts +2 -0
- package/dist/commonjs/v3/chatSnapshotIo.js +173 -0
- package/dist/commonjs/v3/chatSnapshotIo.js.map +1 -0
- package/dist/commonjs/v3/chatVersionSkew.d.ts +12 -0
- package/dist/commonjs/v3/chatVersionSkew.js +30 -0
- package/dist/commonjs/v3/chatVersionSkew.js.map +1 -0
- package/dist/commonjs/v3/externalDeploymentId.d.ts +23 -0
- package/dist/commonjs/v3/externalDeploymentId.js +43 -0
- package/dist/commonjs/v3/externalDeploymentId.js.map +1 -0
- package/dist/commonjs/v3/retry.d.ts +4 -0
- package/dist/commonjs/v3/retry.js +22 -13
- package/dist/commonjs/v3/retry.js.map +1 -1
- package/dist/commonjs/v3/sessions.d.ts +15 -2
- package/dist/commonjs/v3/sessions.js +12 -1
- package/dist/commonjs/v3/sessions.js.map +1 -1
- package/dist/commonjs/v3/shared.js +30 -36
- package/dist/commonjs/v3/shared.js.map +1 -1
- package/dist/commonjs/v3/test/index.d.ts +1 -0
- package/dist/commonjs/v3/test/index.js +3 -1
- package/dist/commonjs/v3/test/index.js.map +1 -1
- package/dist/commonjs/v3/test/mock-chat-agent.d.ts +47 -4
- package/dist/commonjs/v3/test/mock-chat-agent.js +116 -10
- package/dist/commonjs/v3/test/mock-chat-agent.js.map +1 -1
- package/dist/commonjs/v3/test/test-session-handle.js +6 -0
- package/dist/commonjs/v3/test/test-session-handle.js.map +1 -1
- package/dist/commonjs/v3/test/transcript-storage-tests.d.ts +40 -0
- package/dist/commonjs/v3/test/transcript-storage-tests.js +258 -0
- package/dist/commonjs/v3/test/transcript-storage-tests.js.map +1 -0
- package/dist/commonjs/v3/transcriptStorage.d.ts +261 -0
- package/dist/commonjs/v3/transcriptStorage.js +374 -0
- package/dist/commonjs/v3/transcriptStorage.js.map +1 -0
- package/dist/commonjs/version.js +1 -1
- package/dist/esm/imports/ai-runtime.d.ts +2 -2
- package/dist/esm/imports/ai-runtime.js +2 -2
- package/dist/esm/imports/ai-runtime.js.map +1 -1
- package/dist/esm/v3/ai-shared.d.ts +15 -0
- package/dist/esm/v3/ai-shared.js +33 -0
- package/dist/esm/v3/ai-shared.js.map +1 -1
- package/dist/esm/v3/ai.d.ts +311 -25
- package/dist/esm/v3/ai.js +1625 -377
- package/dist/esm/v3/ai.js.map +1 -1
- package/dist/esm/v3/auth.d.ts +10 -4
- package/dist/esm/v3/auth.js.map +1 -1
- package/dist/esm/v3/chat-client.d.ts +11 -2
- package/dist/esm/v3/chat-client.js +228 -112
- package/dist/esm/v3/chat-client.js.map +1 -1
- package/dist/esm/v3/chat-react.d.ts +88 -0
- package/dist/esm/v3/chat-react.js +127 -1
- package/dist/esm/v3/chat-react.js.map +1 -1
- package/dist/esm/v3/chat-server.d.ts +42 -6
- package/dist/esm/v3/chat-server.js +53 -8
- package/dist/esm/v3/chat-server.js.map +1 -1
- package/dist/esm/v3/chat.d.ts +92 -10
- package/dist/esm/v3/chat.js +329 -74
- package/dist/esm/v3/chat.js.map +1 -1
- package/dist/esm/v3/chatSnapshotIo.d.ts +2 -0
- package/dist/esm/v3/chatSnapshotIo.js +165 -0
- package/dist/esm/v3/chatSnapshotIo.js.map +1 -0
- package/dist/esm/v3/chatVersionSkew.d.ts +12 -0
- package/dist/esm/v3/chatVersionSkew.js +27 -0
- package/dist/esm/v3/chatVersionSkew.js.map +1 -0
- package/dist/esm/v3/externalDeploymentId.d.ts +23 -0
- package/dist/esm/v3/externalDeploymentId.js +38 -0
- package/dist/esm/v3/externalDeploymentId.js.map +1 -0
- package/dist/esm/v3/retry.d.ts +4 -0
- package/dist/esm/v3/retry.js +14 -8
- package/dist/esm/v3/retry.js.map +1 -1
- package/dist/esm/v3/sessions.d.ts +15 -2
- package/dist/esm/v3/sessions.js +11 -1
- package/dist/esm/v3/sessions.js.map +1 -1
- package/dist/esm/v3/shared.js +17 -23
- package/dist/esm/v3/shared.js.map +1 -1
- package/dist/esm/v3/test/index.d.ts +1 -0
- package/dist/esm/v3/test/index.js +1 -0
- package/dist/esm/v3/test/index.js.map +1 -1
- package/dist/esm/v3/test/mock-chat-agent.d.ts +47 -4
- package/dist/esm/v3/test/mock-chat-agent.js +118 -12
- package/dist/esm/v3/test/mock-chat-agent.js.map +1 -1
- package/dist/esm/v3/test/test-session-handle.js +6 -0
- package/dist/esm/v3/test/test-session-handle.js.map +1 -1
- package/dist/esm/v3/test/transcript-storage-tests.d.ts +40 -0
- package/dist/esm/v3/test/transcript-storage-tests.js +255 -0
- package/dist/esm/v3/test/transcript-storage-tests.js.map +1 -0
- package/dist/esm/v3/transcriptStorage.d.ts +261 -0
- package/dist/esm/v3/transcriptStorage.js +360 -0
- package/dist/esm/v3/transcriptStorage.js.map +1 -0
- package/dist/esm/version.js +1 -1
- package/docs/ai-chat/actions.mdx +55 -23
- package/docs/ai-chat/anatomy.mdx +47 -27
- package/docs/ai-chat/backend.mdx +125 -48
- package/docs/ai-chat/background-injection.mdx +122 -19
- package/docs/ai-chat/client-protocol.mdx +5 -4
- package/docs/ai-chat/compaction.mdx +13 -7
- package/docs/ai-chat/custom-agents.mdx +23 -0
- package/docs/ai-chat/fast-starts.mdx +27 -20
- package/docs/ai-chat/frontend.mdx +19 -14
- package/docs/ai-chat/how-it-works.mdx +1 -1
- package/docs/ai-chat/lifecycle-hooks.mdx +6 -2
- package/docs/ai-chat/migrating-from-a-route-handler.mdx +16 -14
- package/docs/ai-chat/migrating-from-hydrate-messages.mdx +299 -0
- package/docs/ai-chat/patterns/database-persistence.mdx +24 -9
- package/docs/ai-chat/patterns/native-compaction.mdx +310 -0
- package/docs/ai-chat/patterns/persistence-and-replay.mdx +34 -23
- package/docs/ai-chat/patterns/skills.mdx +7 -10
- package/docs/ai-chat/patterns/version-upgrades.mdx +79 -6
- package/docs/ai-chat/pending-messages.mdx +3 -3
- package/docs/ai-chat/prompt-caching.mdx +23 -25
- package/docs/ai-chat/quick-start.mdx +11 -11
- package/docs/ai-chat/reference.mdx +69 -10
- package/docs/ai-chat/sessions.mdx +6 -1
- package/docs/ai-chat/side-channels.mdx +1 -1
- package/docs/ai-chat/testing.mdx +2 -1
- package/docs/ai-chat/tools.mdx +18 -13
- package/docs/ai-chat/transcript-storage.mdx +247 -0
- package/docs/ai-chat/upgrade-guide.mdx +2 -2
- package/docs/apikeys.mdx +27 -45
- package/docs/config/extensions/custom.mdx +14 -1
- package/docs/config/extensions/syncEnvVars.mdx +6 -0
- package/docs/deploy-environment-variables.mdx +23 -2
- package/docs/deployment/overview.mdx +4 -8
- package/docs/deployment/preview-branches.mdx +4 -4
- package/docs/deployment/version-skew-protection.mdx +62 -0
- package/docs/github-integration.mdx +1 -1
- package/docs/introduction.mdx +58 -152
- package/docs/manual-setup.mdx +7 -7
- package/docs/mcp-tools.mdx +9 -0
- package/docs/quick-start.mdx +3 -3
- package/docs/realtime/auth.mdx +1 -1
- package/docs/reports.mdx +157 -0
- package/docs/self-hosting/security.mdx +17 -0
- package/docs/tasks/scheduled.mdx +24 -0
- package/docs/triggering.mdx +1 -1
- package/docs/troubleshooting-zod.mdx +158 -0
- package/docs/troubleshooting.mdx +1 -1
- package/package.json +4 -4
- package/skills/trigger-authoring-chat-agent/SKILL.md +41 -29
- package/skills/trigger-chat-agent-advanced/SKILL.md +54 -19
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { emptyTranscriptState, reduceTranscriptChanges, } from "../transcriptStorage.js";
|
|
2
|
+
function message(id, text, role = "user") {
|
|
3
|
+
return { id, role, parts: [{ type: "text", text }] };
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* The contract every `TranscriptStorage` has to meet, as a test suite. Point
|
|
7
|
+
* it at a factory for your storage and run it under vitest or jest:
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { runTranscriptStorageTests } from "@trigger.dev/sdk/ai/test";
|
|
11
|
+
* runTranscriptStorageTests(() => myTranscriptStorage(testDatabaseUrl));
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* The factory runs once per test. Return a fresh, empty storage, or one
|
|
15
|
+
* whose chats are isolated by the `chatId` option.
|
|
16
|
+
*/
|
|
17
|
+
export function runTranscriptStorageTests(makeStorage, options = {}) {
|
|
18
|
+
const globals = globalThis;
|
|
19
|
+
const api = options.api ?? {
|
|
20
|
+
describe: globals.describe,
|
|
21
|
+
it: globals.it,
|
|
22
|
+
expect: globals.expect,
|
|
23
|
+
};
|
|
24
|
+
if (!api.describe || !api.it || !api.expect) {
|
|
25
|
+
throw new Error("runTranscriptStorageTests: no test API found. Enable `globals: true` in your test " +
|
|
26
|
+
"config or pass `{ api: { describe, it, expect } }`.");
|
|
27
|
+
}
|
|
28
|
+
const { describe, it, expect } = api;
|
|
29
|
+
const baseChatId = options.chatId ?? "transcript-conformance";
|
|
30
|
+
const clientData = options.clientData;
|
|
31
|
+
const ctx = (chatId, turn = 0) => ({
|
|
32
|
+
chatId,
|
|
33
|
+
clientData,
|
|
34
|
+
turn,
|
|
35
|
+
trigger: "submit-message",
|
|
36
|
+
runId: "run_conformance",
|
|
37
|
+
ctx: {},
|
|
38
|
+
});
|
|
39
|
+
const scope = (chatId) => ({ chatId, clientData });
|
|
40
|
+
const ids = (messages) => messages.map((m) => m.id);
|
|
41
|
+
const expected = new WeakMap();
|
|
42
|
+
const save = async (storage, context, changeset) => {
|
|
43
|
+
let perChat = expected.get(storage);
|
|
44
|
+
if (!perChat) {
|
|
45
|
+
perChat = new Map();
|
|
46
|
+
expected.set(storage, perChat);
|
|
47
|
+
}
|
|
48
|
+
const transcript = reduceTranscriptChanges(perChat.get(context.chatId) ?? emptyTranscriptState(), changeset.changes);
|
|
49
|
+
perChat.set(context.chatId, transcript);
|
|
50
|
+
await storage.save(context, { ...changeset, transcript });
|
|
51
|
+
};
|
|
52
|
+
describe("TranscriptStorage conformance", () => {
|
|
53
|
+
it("loads an unknown chat as an empty transcript", async () => {
|
|
54
|
+
const storage = await makeStorage();
|
|
55
|
+
const loaded = await storage.load(scope(`${baseChatId}-empty`));
|
|
56
|
+
expect(loaded.messages).toEqual([]);
|
|
57
|
+
expect(loaded.state).toBeNull();
|
|
58
|
+
expect(loaded.nextCursor).toBeUndefined();
|
|
59
|
+
});
|
|
60
|
+
it("appends puts in changeset order and replaces a known id in place", async () => {
|
|
61
|
+
const storage = await makeStorage();
|
|
62
|
+
const chatId = `${baseChatId}-put`;
|
|
63
|
+
await save(storage, ctx(chatId), {
|
|
64
|
+
reason: "turn-complete",
|
|
65
|
+
changes: [
|
|
66
|
+
{ op: "put", message: message("u1", "one") },
|
|
67
|
+
{ op: "put", message: message("a1", "two", "assistant") },
|
|
68
|
+
{ op: "put", message: message("u2", "three") },
|
|
69
|
+
],
|
|
70
|
+
});
|
|
71
|
+
await save(storage, ctx(chatId, 1), {
|
|
72
|
+
reason: "turn-complete",
|
|
73
|
+
changes: [{ op: "put", message: message("a1", "two, edited", "assistant") }],
|
|
74
|
+
});
|
|
75
|
+
const loaded = await storage.load(scope(chatId));
|
|
76
|
+
expect(ids(loaded.messages)).toEqual(["u1", "a1", "u2"]);
|
|
77
|
+
expect(loaded.messages[1]).toEqual(message("a1", "two, edited", "assistant"));
|
|
78
|
+
});
|
|
79
|
+
it("removes by id and ignores an unknown id", async () => {
|
|
80
|
+
const storage = await makeStorage();
|
|
81
|
+
const chatId = `${baseChatId}-remove`;
|
|
82
|
+
await save(storage, ctx(chatId), {
|
|
83
|
+
reason: "turn-complete",
|
|
84
|
+
changes: [
|
|
85
|
+
{ op: "put", message: message("u1", "one") },
|
|
86
|
+
{ op: "put", message: message("a1", "two", "assistant") },
|
|
87
|
+
{ op: "put", message: message("u2", "three") },
|
|
88
|
+
],
|
|
89
|
+
});
|
|
90
|
+
await save(storage, ctx(chatId, 1), {
|
|
91
|
+
reason: "action",
|
|
92
|
+
changes: [
|
|
93
|
+
{ op: "remove", id: "a1" },
|
|
94
|
+
{ op: "remove", id: "never-existed" },
|
|
95
|
+
],
|
|
96
|
+
});
|
|
97
|
+
expect(ids((await storage.load(scope(chatId))).messages)).toEqual(["u1", "u2"]);
|
|
98
|
+
});
|
|
99
|
+
it("truncates after an id and ignores an unknown id", async () => {
|
|
100
|
+
const storage = await makeStorage();
|
|
101
|
+
const chatId = `${baseChatId}-truncate`;
|
|
102
|
+
await save(storage, ctx(chatId), {
|
|
103
|
+
reason: "turn-complete",
|
|
104
|
+
changes: ["u1", "a1", "u2", "a2"].map((id) => ({
|
|
105
|
+
op: "put",
|
|
106
|
+
message: message(id, id),
|
|
107
|
+
})),
|
|
108
|
+
});
|
|
109
|
+
await save(storage, ctx(chatId, 1), {
|
|
110
|
+
reason: "action",
|
|
111
|
+
changes: [{ op: "truncateAfter", afterId: "never-existed" }],
|
|
112
|
+
});
|
|
113
|
+
expect((await storage.load(scope(chatId))).messages).toHaveLength(4);
|
|
114
|
+
await save(storage, ctx(chatId, 1), {
|
|
115
|
+
reason: "action",
|
|
116
|
+
changes: [{ op: "truncateAfter", afterId: "a1" }],
|
|
117
|
+
});
|
|
118
|
+
expect(ids((await storage.load(scope(chatId))).messages)).toEqual(["u1", "a1"]);
|
|
119
|
+
});
|
|
120
|
+
it("appends after a truncate at the end of the transcript", async () => {
|
|
121
|
+
const storage = await makeStorage();
|
|
122
|
+
const chatId = `${baseChatId}-truncate-append`;
|
|
123
|
+
await save(storage, ctx(chatId), {
|
|
124
|
+
reason: "turn-complete",
|
|
125
|
+
changes: ["u1", "a1", "u2", "a2"].map((id) => ({
|
|
126
|
+
op: "put",
|
|
127
|
+
message: message(id, id),
|
|
128
|
+
})),
|
|
129
|
+
});
|
|
130
|
+
await save(storage, ctx(chatId, 1), {
|
|
131
|
+
reason: "action",
|
|
132
|
+
changes: [
|
|
133
|
+
{ op: "truncateAfter", afterId: "u2" },
|
|
134
|
+
{ op: "put", message: message("a2b", "regenerated", "assistant") },
|
|
135
|
+
],
|
|
136
|
+
});
|
|
137
|
+
expect(ids((await storage.load(scope(chatId))).messages)).toEqual(["u1", "a1", "u2", "a2b"]);
|
|
138
|
+
});
|
|
139
|
+
it("round-trips state and clears it with null", async () => {
|
|
140
|
+
const storage = await makeStorage();
|
|
141
|
+
const chatId = `${baseChatId}-state`;
|
|
142
|
+
await save(storage, ctx(chatId), {
|
|
143
|
+
reason: "turn-complete",
|
|
144
|
+
changes: [
|
|
145
|
+
{ op: "put", message: message("u1", "one") },
|
|
146
|
+
{ op: "state", value: { v: 1, summary: "so far" } },
|
|
147
|
+
],
|
|
148
|
+
});
|
|
149
|
+
expect((await storage.load(scope(chatId))).state).toEqual({ v: 1, summary: "so far" });
|
|
150
|
+
await save(storage, ctx(chatId, 1), {
|
|
151
|
+
reason: "turn-complete",
|
|
152
|
+
changes: [{ op: "put", message: message("u2", "two") }],
|
|
153
|
+
});
|
|
154
|
+
expect((await storage.load(scope(chatId))).state).toEqual({ v: 1, summary: "so far" });
|
|
155
|
+
await save(storage, ctx(chatId, 2), {
|
|
156
|
+
reason: "action",
|
|
157
|
+
changes: [{ op: "state", value: null }],
|
|
158
|
+
});
|
|
159
|
+
expect((await storage.load(scope(chatId))).state).toBeNull();
|
|
160
|
+
});
|
|
161
|
+
it("keeps the latest cursors it was given", async () => {
|
|
162
|
+
const storage = await makeStorage();
|
|
163
|
+
const chatId = `${baseChatId}-cursors`;
|
|
164
|
+
await save(storage, ctx(chatId), {
|
|
165
|
+
reason: "turn-complete",
|
|
166
|
+
changes: [{ op: "put", message: message("u1", "one") }],
|
|
167
|
+
cursors: { lastOutEventId: "10", lastInEventId: "2" },
|
|
168
|
+
});
|
|
169
|
+
await save(storage, ctx(chatId, 1), {
|
|
170
|
+
reason: "turn-complete",
|
|
171
|
+
changes: [{ op: "put", message: message("u2", "two") }],
|
|
172
|
+
cursors: { lastOutEventId: "20", lastInEventId: "4" },
|
|
173
|
+
});
|
|
174
|
+
const loaded = await storage.load(scope(chatId));
|
|
175
|
+
expect(loaded.cursors?.lastOutEventId).toBe("20");
|
|
176
|
+
expect(loaded.cursors?.lastInEventId).toBe("4");
|
|
177
|
+
});
|
|
178
|
+
it("keeps a partial answer's non-final status when the storage reports it", async () => {
|
|
179
|
+
const storage = await makeStorage();
|
|
180
|
+
const chatId = `${baseChatId}-final`;
|
|
181
|
+
await save(storage, ctx(chatId), {
|
|
182
|
+
reason: "turn-error",
|
|
183
|
+
changes: [
|
|
184
|
+
{ op: "put", message: message("u1", "one") },
|
|
185
|
+
{ op: "put", message: message("a1", "partial", "assistant"), final: false },
|
|
186
|
+
],
|
|
187
|
+
});
|
|
188
|
+
const partial = await storage.load(scope(chatId));
|
|
189
|
+
if (partial.nonFinalIds !== undefined) {
|
|
190
|
+
expect(partial.nonFinalIds).toEqual(["a1"]);
|
|
191
|
+
}
|
|
192
|
+
await save(storage, ctx(chatId, 1), {
|
|
193
|
+
reason: "turn-complete",
|
|
194
|
+
changes: [{ op: "put", message: message("a1", "the finished answer", "assistant") }],
|
|
195
|
+
});
|
|
196
|
+
const finalized = await storage.load(scope(chatId));
|
|
197
|
+
expect(ids(finalized.messages)).toEqual(["u1", "a1"]);
|
|
198
|
+
if (finalized.nonFinalIds !== undefined) {
|
|
199
|
+
expect(finalized.nonFinalIds).toEqual([]);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
it("converges when the same changeset is saved twice", async () => {
|
|
203
|
+
const storage = await makeStorage();
|
|
204
|
+
const chatId = `${baseChatId}-replay`;
|
|
205
|
+
const changeset = {
|
|
206
|
+
reason: "turn-complete",
|
|
207
|
+
changes: [
|
|
208
|
+
{ op: "put", message: message("u1", "one") },
|
|
209
|
+
{ op: "put", message: message("a1", "two", "assistant") },
|
|
210
|
+
{ op: "state", value: { v: 1 } },
|
|
211
|
+
],
|
|
212
|
+
cursors: { lastOutEventId: "7" },
|
|
213
|
+
};
|
|
214
|
+
await save(storage, ctx(chatId), changeset);
|
|
215
|
+
await save(storage, ctx(chatId), changeset);
|
|
216
|
+
const loaded = await storage.load(scope(chatId));
|
|
217
|
+
expect(ids(loaded.messages)).toEqual(["u1", "a1"]);
|
|
218
|
+
expect(loaded.state).toEqual({ v: 1 });
|
|
219
|
+
});
|
|
220
|
+
it("pages from the most recent message backwards with limit and before", async () => {
|
|
221
|
+
const storage = await makeStorage();
|
|
222
|
+
const chatId = `${baseChatId}-paging`;
|
|
223
|
+
await save(storage, ctx(chatId), {
|
|
224
|
+
reason: "turn-complete",
|
|
225
|
+
changes: ["m1", "m2", "m3", "m4", "m5"].map((id) => ({
|
|
226
|
+
op: "put",
|
|
227
|
+
message: message(id, id),
|
|
228
|
+
})),
|
|
229
|
+
});
|
|
230
|
+
const last = await storage.load(scope(chatId), { limit: 2 });
|
|
231
|
+
expect(ids(last.messages)).toEqual(["m4", "m5"]);
|
|
232
|
+
expect(last.nextCursor).toBe("m4");
|
|
233
|
+
const middle = await storage.load(scope(chatId), { limit: 2, before: last.nextCursor });
|
|
234
|
+
expect(ids(middle.messages)).toEqual(["m2", "m3"]);
|
|
235
|
+
expect(middle.nextCursor).toBe("m2");
|
|
236
|
+
const first = await storage.load(scope(chatId), { limit: 2, before: middle.nextCursor });
|
|
237
|
+
expect(ids(first.messages)).toEqual(["m1"]);
|
|
238
|
+
expect(first.nextCursor).toBeUndefined();
|
|
239
|
+
});
|
|
240
|
+
it("keeps chats apart", async () => {
|
|
241
|
+
const storage = await makeStorage();
|
|
242
|
+
await save(storage, ctx(`${baseChatId}-a`), {
|
|
243
|
+
reason: "turn-complete",
|
|
244
|
+
changes: [{ op: "put", message: message("u1", "in a") }],
|
|
245
|
+
});
|
|
246
|
+
await save(storage, ctx(`${baseChatId}-b`), {
|
|
247
|
+
reason: "turn-complete",
|
|
248
|
+
changes: [{ op: "put", message: message("u1", "in b") }],
|
|
249
|
+
});
|
|
250
|
+
expect((await storage.load(scope(`${baseChatId}-a`))).messages[0]).toEqual(message("u1", "in a"));
|
|
251
|
+
expect((await storage.load(scope(`${baseChatId}-b`))).messages[0]).toEqual(message("u1", "in b"));
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=transcript-storage-tests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript-storage-tests.js","sourceRoot":"","sources":["../../../../src/v3/test/transcript-storage-tests.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { type TaskRunContext, type TranscriptSnapshotEntry } from "@trigger.dev/core/v3";
|
|
2
|
+
import type { ModelMessage, UIMessage } from "ai";
|
|
3
|
+
/**
|
|
4
|
+
* One change to a transcript. Ops address messages by id; position is the
|
|
5
|
+
* storage's own concern.
|
|
6
|
+
*
|
|
7
|
+
* - `put` upserts by `message.id`: an unknown id appends, a known id is
|
|
8
|
+
* replaced in place. `final` is false when the runtime captured a partial
|
|
9
|
+
* assistant message from an errored or stopped turn; it defaults to true.
|
|
10
|
+
* - `remove` deletes by id and is a no-op for an unknown id.
|
|
11
|
+
* - `truncateAfter` drops every message ordered after `afterId` (a rollback)
|
|
12
|
+
* and is a no-op when `afterId` is unknown.
|
|
13
|
+
* - `state` replaces the opaque runtime record; `null` clears it.
|
|
14
|
+
*/
|
|
15
|
+
export type TranscriptChange = {
|
|
16
|
+
op: "put";
|
|
17
|
+
message: UIMessage;
|
|
18
|
+
final?: boolean;
|
|
19
|
+
} | {
|
|
20
|
+
op: "remove";
|
|
21
|
+
id: string;
|
|
22
|
+
} | {
|
|
23
|
+
op: "truncateAfter";
|
|
24
|
+
afterId: string;
|
|
25
|
+
} | {
|
|
26
|
+
op: "state";
|
|
27
|
+
value: unknown | null;
|
|
28
|
+
};
|
|
29
|
+
export type TranscriptChangeReason = "turn-start" | "turn-complete" | "turn-error" | "action" | "compaction" | "recovery";
|
|
30
|
+
export type TranscriptCursors = {
|
|
31
|
+
lastOutEventId?: string;
|
|
32
|
+
lastInEventId?: string;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* What the runtime hands to `save`: the ordered changes since the last save
|
|
36
|
+
* (one transaction where the backend supports it), the whole transcript as
|
|
37
|
+
* it stands after those changes, and the stream cursors the next boot should
|
|
38
|
+
* resume from. A row-per-message store applies `changes`; a store that keeps
|
|
39
|
+
* the conversation as one document writes `transcript` as-is and needs no
|
|
40
|
+
* state of its own. Cursors are runtime-computed and persisted opaquely; a
|
|
41
|
+
* storage never interprets them.
|
|
42
|
+
*/
|
|
43
|
+
export type TranscriptChangeset = {
|
|
44
|
+
reason: TranscriptChangeReason;
|
|
45
|
+
changes: TranscriptChange[];
|
|
46
|
+
transcript: TranscriptState;
|
|
47
|
+
cursors?: TranscriptCursors;
|
|
48
|
+
};
|
|
49
|
+
/** The tenant scope of a read. A render read has no run, so this is all `load` gets. */
|
|
50
|
+
export type TranscriptScope<TClientData = unknown> = {
|
|
51
|
+
chatId: string;
|
|
52
|
+
clientData: TClientData;
|
|
53
|
+
};
|
|
54
|
+
/** The run context of a write. Supplied by the runtime; always in-run. */
|
|
55
|
+
export type TranscriptStorageContext<TClientData = unknown> = TranscriptScope<TClientData> & {
|
|
56
|
+
turn: number;
|
|
57
|
+
trigger: "submit-message" | "regenerate-message" | "action";
|
|
58
|
+
runId: string;
|
|
59
|
+
ctx: TaskRunContext;
|
|
60
|
+
};
|
|
61
|
+
export type TranscriptLoadOptions = {
|
|
62
|
+
/** Return at most this many messages, the most recent ones. */
|
|
63
|
+
limit?: number;
|
|
64
|
+
/** Return messages ordered before this message id (a `nextCursor` from a previous page). */
|
|
65
|
+
before?: string;
|
|
66
|
+
};
|
|
67
|
+
export type TranscriptLoadResult<TUIMessage extends UIMessage = UIMessage> = {
|
|
68
|
+
messages: TUIMessage[];
|
|
69
|
+
state: unknown | null;
|
|
70
|
+
cursors?: TranscriptCursors;
|
|
71
|
+
/** The id to pass as `before` for the previous page; absent on the last page. */
|
|
72
|
+
nextCursor?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Ids among `messages` that were saved with `final: false` (a partial
|
|
75
|
+
* answer). A storage that keeps `final` returns them so a partial stays
|
|
76
|
+
* partial when a continuation saves it again unchanged; a storage that
|
|
77
|
+
* does not keep `final` may leave this out.
|
|
78
|
+
*/
|
|
79
|
+
nonFinalIds?: string[];
|
|
80
|
+
};
|
|
81
|
+
/** What `loadContext` receives on every turn and action. */
|
|
82
|
+
export type LoadContextEvent<TClientData = unknown, TUIMessage extends UIMessage = UIMessage> = {
|
|
83
|
+
chatId: string;
|
|
84
|
+
/** The turn number (0-indexed). */
|
|
85
|
+
turn: number;
|
|
86
|
+
trigger: "submit-message" | "regenerate-message" | "action";
|
|
87
|
+
/** The messages the frontend sent for this turn. Empty for actions. */
|
|
88
|
+
incomingMessages: TUIMessage[];
|
|
89
|
+
/** The runtime's transcript before this turn, including any tail it recovered. */
|
|
90
|
+
previousMessages: TUIMessage[];
|
|
91
|
+
clientData?: TClientData;
|
|
92
|
+
continuation: boolean;
|
|
93
|
+
previousRunId?: string;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* A persistence adapter for a `chat.agent` transcript. The runtime calls
|
|
97
|
+
* `load` once at a continuation boot and `save` after every change to the
|
|
98
|
+
* conversation. Both are best-effort from the runtime's point of view: an
|
|
99
|
+
* error is logged and the turn continues.
|
|
100
|
+
*
|
|
101
|
+
* `loadContext` is optional. Its presence declares that the application
|
|
102
|
+
* owns the model's context: the runtime calls it on every turn and action
|
|
103
|
+
* and uses what it returns as the conversation, instead of the transcript
|
|
104
|
+
* it accumulated. Tail recovery still runs and `save` is still called.
|
|
105
|
+
*/
|
|
106
|
+
export type TranscriptStorage<TClientData = unknown> = {
|
|
107
|
+
load<TUIMessage extends UIMessage = UIMessage>(scope: TranscriptScope<TClientData>, opts?: TranscriptLoadOptions): Promise<TranscriptLoadResult<TUIMessage>>;
|
|
108
|
+
save(ctx: TranscriptStorageContext<TClientData>, changeset: TranscriptChangeset): Promise<void>;
|
|
109
|
+
loadContext?<TUIMessage extends UIMessage = UIMessage>(scope: TranscriptScope<TClientData>, event: LoadContextEvent<TClientData, TUIMessage>): Promise<TUIMessage[]> | TUIMessage[];
|
|
110
|
+
};
|
|
111
|
+
/** An in-memory transcript: ordered entries plus the opaque state record. */
|
|
112
|
+
export type TranscriptState<TUIMessage extends UIMessage = UIMessage> = {
|
|
113
|
+
entries: TranscriptSnapshotEntry<TUIMessage>[];
|
|
114
|
+
state: unknown | null;
|
|
115
|
+
};
|
|
116
|
+
export declare function emptyTranscriptState<TUIMessage extends UIMessage = UIMessage>(): TranscriptState<TUIMessage>;
|
|
117
|
+
/**
|
|
118
|
+
* Apply changes to a transcript, in order. Pure: returns a new state and
|
|
119
|
+
* never mutates the input. Replaying the same changes converges, which is
|
|
120
|
+
* what lets a storage retry a failed write without checking what landed.
|
|
121
|
+
*/
|
|
122
|
+
export declare function reduceTranscriptChanges<TUIMessage extends UIMessage = UIMessage>(prev: TranscriptState<TUIMessage>, changes: readonly TranscriptChange[]): TranscriptState<TUIMessage>;
|
|
123
|
+
/**
|
|
124
|
+
* What the runtime remembers about the transcript it last handed to
|
|
125
|
+
* `save`: the ids in order and a fingerprint per message, so the next
|
|
126
|
+
* changeset can be derived from the accumulator without asking the storage.
|
|
127
|
+
*/
|
|
128
|
+
export type TranscriptShadow = {
|
|
129
|
+
ids: string[];
|
|
130
|
+
fingerprints: Map<string, string>;
|
|
131
|
+
/** Ids last saved with `final: false`. Everything else was saved final. */
|
|
132
|
+
nonFinal: Set<string>;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Build the shadow for `messages`. An id is non-final when this save says so
|
|
136
|
+
* (`nonFinalIds`) or when it was non-final before and its content has not
|
|
137
|
+
* changed: a partial answer stays partial until the message itself changes.
|
|
138
|
+
*/
|
|
139
|
+
export declare function createTranscriptShadow(messages: readonly UIMessage[], nonFinalIds?: ReadonlySet<string>, previous?: TranscriptShadow): TranscriptShadow;
|
|
140
|
+
/**
|
|
141
|
+
* Derive the changes that take `shadow` to `next`.
|
|
142
|
+
*
|
|
143
|
+
* The common prefix (by id) is compared message by message and a changed
|
|
144
|
+
* message becomes an in-place `put`. Past the prefix, everything the shadow
|
|
145
|
+
* still had is dropped with one `truncateAfter` on the last common id (or
|
|
146
|
+
* one `remove` per message when there is no common prefix) and everything
|
|
147
|
+
* `next` has is appended with `put`, in order. Applying the result with
|
|
148
|
+
* {@link reduceTranscriptChanges} reproduces `next` exactly, including
|
|
149
|
+
* order, for any two lists.
|
|
150
|
+
*/
|
|
151
|
+
export declare function diffTranscript(shadow: TranscriptShadow, next: readonly UIMessage[], options?: {
|
|
152
|
+
nonFinalIds?: ReadonlySet<string>;
|
|
153
|
+
}): {
|
|
154
|
+
changes: TranscriptChange[];
|
|
155
|
+
shadow: TranscriptShadow;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* The built-in storage: the transcript in the platform's object store, read by
|
|
159
|
+
* the Sessions dashboard and the transcript API.
|
|
160
|
+
*
|
|
161
|
+
* One object per conversation, rewritten each turn, holding the transcript plus
|
|
162
|
+
* the runtime state. Once a conversation has been compacted, it keeps roughly
|
|
163
|
+
* the last hundred messages rather than all of them, so the object stops
|
|
164
|
+
* growing with the conversation. An app that needs the full history keeps its
|
|
165
|
+
* own transcript storage.
|
|
166
|
+
*/
|
|
167
|
+
export declare function snapshotTranscriptStorage(): TranscriptStorage<unknown>;
|
|
168
|
+
/** The storage `chat.agent` uses when none is configured: {@link snapshotTranscriptStorage}. */
|
|
169
|
+
export declare const defaultStorage: TranscriptStorage<unknown>;
|
|
170
|
+
export type MemoryTranscriptStorage = TranscriptStorage<unknown> & {
|
|
171
|
+
/** The stored transcript for a chat, or `undefined` when nothing has been saved. */
|
|
172
|
+
transcript(chatId: string): (TranscriptState & {
|
|
173
|
+
cursors?: TranscriptCursors;
|
|
174
|
+
}) | undefined;
|
|
175
|
+
/** Every changeset `save` received, in order. */
|
|
176
|
+
readonly changesets: Array<{
|
|
177
|
+
ctx: TranscriptStorageContext<unknown>;
|
|
178
|
+
changeset: TranscriptChangeset;
|
|
179
|
+
}>;
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* A storage that keeps every transcript in process memory. The reference
|
|
183
|
+
* implementation for the conformance tests, and a way to inspect exactly
|
|
184
|
+
* what the runtime hands a storage.
|
|
185
|
+
*/
|
|
186
|
+
export declare function memoryTranscriptStorage(): MemoryTranscriptStorage;
|
|
187
|
+
type ModelLaneInjection = {
|
|
188
|
+
afterId: string;
|
|
189
|
+
messages: ModelMessage[];
|
|
190
|
+
};
|
|
191
|
+
/**
|
|
192
|
+
* What the runtime keeps in the storage's `state` slot: the parts of the
|
|
193
|
+
* model's context that cannot be rebuilt from the transcript. Opaque to a
|
|
194
|
+
* storage; only the runtime reads it.
|
|
195
|
+
*
|
|
196
|
+
* `compaction` is the whole model lane after a compaction, covering the
|
|
197
|
+
* transcript prefix ending at `throughId`. It is used as long as `throughId`
|
|
198
|
+
* still exists in the transcript, so a rollback or truncation that removes it
|
|
199
|
+
* rebuilds the lane from the transcript instead. Editing a message before
|
|
200
|
+
* `throughId` in place is unsupported and does not invalidate the lane.
|
|
201
|
+
* `injections` are conversational messages `chat.inject` added, anchored
|
|
202
|
+
* after the transcript message they followed.
|
|
203
|
+
*/
|
|
204
|
+
export type TranscriptRuntimeState = {
|
|
205
|
+
v: 1;
|
|
206
|
+
compaction?: {
|
|
207
|
+
modelMessages: ModelMessage[];
|
|
208
|
+
throughId: string;
|
|
209
|
+
};
|
|
210
|
+
injections?: ModelLaneInjection[];
|
|
211
|
+
/** `chat.inject` messages queued but not yet drained into a turn when the save happened. */
|
|
212
|
+
queued?: ModelMessage[];
|
|
213
|
+
};
|
|
214
|
+
/**
|
|
215
|
+
* The slice of a transcript worth storing, which is the last `keep` messages
|
|
216
|
+
* once a conversation has compacted, and all of it before that.
|
|
217
|
+
*
|
|
218
|
+
* Expressed relative to the compaction watermark rather than as a plain tail,
|
|
219
|
+
* because everything after the watermark is live context that the next boot
|
|
220
|
+
* converts and must never be dropped. The runtime stamps the watermark at the
|
|
221
|
+
* newest message on each compacted save, so in practice the two coincide and
|
|
222
|
+
* this keeps the last `keep`; the watermark-relative form is what keeps it
|
|
223
|
+
* correct if a watermark ever lands earlier in the transcript.
|
|
224
|
+
*
|
|
225
|
+
* Without a watermark nothing is dropped: every entry is still context.
|
|
226
|
+
*
|
|
227
|
+
* This is what stops the object rewritten each turn from growing with the
|
|
228
|
+
* conversation. An app that needs the whole history keeps its own transcript
|
|
229
|
+
* storage.
|
|
230
|
+
*/
|
|
231
|
+
export declare function trimTranscriptForSnapshot<TEntry extends {
|
|
232
|
+
id: string;
|
|
233
|
+
}>(entries: TEntry[], state: unknown, opts: {
|
|
234
|
+
keep: number;
|
|
235
|
+
}): TEntry[];
|
|
236
|
+
/**
|
|
237
|
+
* Rewrite runtime state so it still describes the transcript window being
|
|
238
|
+
* persisted.
|
|
239
|
+
*
|
|
240
|
+
* A compaction watermark that has moved out of the window becomes `""`, which
|
|
241
|
+
* is how a restored lane says "the compacted messages cover everything before
|
|
242
|
+
* this window". Left as-is, the watermark would name an entry the window does
|
|
243
|
+
* not contain, and restoring the lane would discard the compacted messages and
|
|
244
|
+
* re-convert the window from scratch — an agent that has silently forgotten the
|
|
245
|
+
* conversation. Injections anchored outside the window go too: the span they
|
|
246
|
+
* belonged to is already inside the compacted lane.
|
|
247
|
+
*/
|
|
248
|
+
export declare function normalizeRuntimeStateForWindow(state: unknown, windowIds: Iterable<string>): unknown;
|
|
249
|
+
export declare function parseTranscriptRuntimeState(value: unknown): TranscriptRuntimeState | undefined;
|
|
250
|
+
/**
|
|
251
|
+
* Rebuild the model lane for a transcript at boot. Uses the persisted
|
|
252
|
+
* compacted lane while the transcript still contains its `throughId`
|
|
253
|
+
* boundary, then converts the rest of the transcript, re-inserting persisted
|
|
254
|
+
* injections after the messages they followed.
|
|
255
|
+
*/
|
|
256
|
+
export declare function restoreModelLane<TUIMessage extends UIMessage>(messages: TUIMessage[], state: TranscriptRuntimeState | undefined, convert: (messages: TUIMessage[]) => Promise<ModelMessage[]>): Promise<{
|
|
257
|
+
messages: ModelMessage[];
|
|
258
|
+
compacted: boolean;
|
|
259
|
+
injections: ModelLaneInjection[];
|
|
260
|
+
}>;
|
|
261
|
+
export {};
|