@convex-dev/agent 0.1.18-alpha.1 → 0.2.0-alpha.2
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/client/createTool.d.ts +31 -10
- package/dist/client/createTool.d.ts.map +1 -1
- package/dist/client/createTool.js +25 -10
- package/dist/client/createTool.js.map +1 -1
- package/dist/client/defaultComponent.d.ts +11 -0
- package/dist/client/defaultComponent.d.ts.map +1 -0
- package/dist/client/defaultComponent.js +7 -0
- package/dist/client/defaultComponent.js.map +1 -0
- package/dist/client/definePlaygroundAPI.d.ts +174 -199
- package/dist/client/definePlaygroundAPI.d.ts.map +1 -1
- package/dist/client/definePlaygroundAPI.js +17 -35
- package/dist/client/definePlaygroundAPI.js.map +1 -1
- package/dist/client/files.d.ts +6 -3
- package/dist/client/files.d.ts.map +1 -1
- package/dist/client/files.js +7 -7
- package/dist/client/files.js.map +1 -1
- package/dist/client/index.d.ts +152 -589
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +138 -222
- package/dist/client/index.js.map +1 -1
- package/dist/client/messages.d.ts +538 -0
- package/dist/client/messages.d.ts.map +1 -0
- package/dist/client/messages.js +91 -0
- package/dist/client/messages.js.map +1 -0
- package/dist/client/search.d.ts +30 -7
- package/dist/client/search.d.ts.map +1 -1
- package/dist/client/search.js +20 -3
- package/dist/client/search.js.map +1 -1
- package/dist/client/streaming.d.ts +3 -2
- package/dist/client/streaming.d.ts.map +1 -1
- package/dist/client/streaming.js.map +1 -1
- package/dist/client/threads.d.ts +46 -0
- package/dist/client/threads.d.ts.map +1 -0
- package/dist/client/threads.js +49 -0
- package/dist/client/threads.js.map +1 -0
- package/dist/client/types.d.ts +39 -42
- package/dist/client/types.d.ts.map +1 -1
- package/dist/component/_generated/api.d.ts +437 -75
- package/dist/component/messages.d.ts +254 -55
- package/dist/component/messages.d.ts.map +1 -1
- package/dist/component/messages.js +29 -25
- package/dist/component/messages.js.map +1 -1
- package/dist/component/schema.d.ts +1459 -158
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +8 -14
- package/dist/component/schema.js.map +1 -1
- package/dist/component/streams.d.ts +180 -6
- package/dist/component/streams.d.ts.map +1 -1
- package/dist/mapping.d.ts +11 -15
- package/dist/mapping.d.ts.map +1 -1
- package/dist/mapping.js +191 -61
- package/dist/mapping.js.map +1 -1
- package/dist/react/deltas.d.ts +0 -3
- package/dist/react/deltas.d.ts.map +1 -1
- package/dist/react/deltas.js +140 -44
- package/dist/react/deltas.js.map +1 -1
- package/dist/react/optimisticallySendMessage.d.ts.map +1 -1
- package/dist/react/optimisticallySendMessage.js +2 -1
- package/dist/react/optimisticallySendMessage.js.map +1 -1
- package/dist/react/toUIMessages.d.ts +5 -4
- package/dist/react/toUIMessages.d.ts.map +1 -1
- package/dist/react/toUIMessages.js +103 -40
- package/dist/react/toUIMessages.js.map +1 -1
- package/dist/validators.d.ts +1978 -1210
- package/dist/validators.d.ts.map +1 -1
- package/dist/validators.js +90 -54
- package/dist/validators.js.map +1 -1
- package/package.json +32 -28
- package/src/client/createTool.ts +69 -38
- package/src/client/defaultComponent.ts +17 -0
- package/src/client/definePlaygroundAPI.ts +29 -43
- package/src/client/files.ts +7 -8
- package/src/client/index.test.ts +20 -18
- package/src/client/index.ts +228 -434
- package/src/client/messages.ts +191 -0
- package/src/client/search.ts +30 -6
- package/src/client/streaming.ts +4 -3
- package/src/client/threads.ts +78 -0
- package/src/client/types.ts +50 -72
- package/src/component/_generated/api.d.ts +437 -75
- package/src/component/messages.test.ts +182 -40
- package/src/component/messages.ts +30 -32
- package/src/component/schema.ts +8 -14
- package/src/mapping.ts +230 -94
- package/src/react/deltas.ts +165 -52
- package/src/react/optimisticallySendMessage.ts +4 -1
- package/src/react/toUIMessages.test.ts +154 -36
- package/src/react/toUIMessages.ts +136 -57
- package/src/validators.test.ts +2 -101
- package/src/validators.ts +111 -68
- package/dist/client/listMessages.d.ts +0 -22
- package/dist/client/listMessages.d.ts.map +0 -1
- package/dist/client/listMessages.js +0 -25
- package/dist/client/listMessages.js.map +0 -1
- package/src/client/listMessages.ts +0 -38
- package/src/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
|
@@ -30,6 +30,29 @@ describe("agent", () => {
|
|
|
30
30
|
stepOrder: 1,
|
|
31
31
|
});
|
|
32
32
|
});
|
|
33
|
+
test("getMaxMessage works for a specific order", async () => {
|
|
34
|
+
const t = convexTest(schema, modules);
|
|
35
|
+
const thread = await t.mutation(api.threads.createThread, {
|
|
36
|
+
userId: "test",
|
|
37
|
+
});
|
|
38
|
+
const { messages } = await t.mutation(api.messages.addMessages, {
|
|
39
|
+
threadId: thread._id as Id<"threads">,
|
|
40
|
+
messages: [
|
|
41
|
+
{ message: { role: "user", content: "hello" } },
|
|
42
|
+
{ message: { role: "assistant", content: "step 1" } },
|
|
43
|
+
{ message: { role: "user", content: "hello2" } },
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
const maxMessage = await t.run(async (ctx) => {
|
|
47
|
+
return await getMaxMessage(ctx, thread._id as Id<"threads">, 0);
|
|
48
|
+
});
|
|
49
|
+
expect(maxMessage).toMatchObject({
|
|
50
|
+
_id: messages.at(1)!._id,
|
|
51
|
+
order: 0,
|
|
52
|
+
stepOrder: 1,
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
33
56
|
test("getMaxMessages works when there are tools involved", async () => {
|
|
34
57
|
const t = convexTest(schema, modules);
|
|
35
58
|
const thread = await t.mutation(api.threads.createThread, {
|
|
@@ -78,7 +101,7 @@ describe("agent", () => {
|
|
|
78
101
|
});
|
|
79
102
|
});
|
|
80
103
|
|
|
81
|
-
test("ordering is incremented on subsequent calls to addMessages", async () => {
|
|
104
|
+
test("ordering is incremented on subsequent calls to addMessages for user messages", async () => {
|
|
82
105
|
const t = convexTest(schema, modules);
|
|
83
106
|
const thread = await t.mutation(api.threads.createThread, {
|
|
84
107
|
userId: "test",
|
|
@@ -109,7 +132,7 @@ describe("agent", () => {
|
|
|
109
132
|
});
|
|
110
133
|
});
|
|
111
134
|
|
|
112
|
-
test("
|
|
135
|
+
test("ordering is incremented on subsequent calls to addMessages for assistant messages", async () => {
|
|
113
136
|
const t = convexTest(schema, modules);
|
|
114
137
|
const thread = await t.mutation(api.threads.createThread, {
|
|
115
138
|
userId: "test",
|
|
@@ -127,8 +150,72 @@ describe("agent", () => {
|
|
|
127
150
|
stepOrder: 0,
|
|
128
151
|
});
|
|
129
152
|
const { messages: messages2 } = await t.mutation(api.messages.addMessages, {
|
|
153
|
+
threadId: thread._id as Id<"threads">,
|
|
154
|
+
messages: [{ message: { role: "assistant", content: "hello" } }],
|
|
155
|
+
});
|
|
156
|
+
const maxMessage2 = await t.run(async (ctx) => {
|
|
157
|
+
return await getMaxMessage(ctx, thread._id as Id<"threads">);
|
|
158
|
+
});
|
|
159
|
+
expect(maxMessage2).toMatchObject({
|
|
160
|
+
_id: messages2.at(-1)!._id,
|
|
161
|
+
order: 0,
|
|
162
|
+
stepOrder: 1,
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
test("order is incremented for user messages on to addMessages for the same promptMessageId", async () => {
|
|
167
|
+
const t = convexTest(schema, modules);
|
|
168
|
+
const thread = await t.mutation(api.threads.createThread, {
|
|
169
|
+
userId: "test",
|
|
170
|
+
});
|
|
171
|
+
const { messages } = await t.mutation(api.messages.addMessages, {
|
|
130
172
|
threadId: thread._id as Id<"threads">,
|
|
131
173
|
messages: [{ message: { role: "user", content: "hello" } }],
|
|
174
|
+
});
|
|
175
|
+
const maxMessage = await t.run(async (ctx) => {
|
|
176
|
+
return await getMaxMessage(ctx, thread._id as Id<"threads">);
|
|
177
|
+
});
|
|
178
|
+
expect(maxMessage).toMatchObject({
|
|
179
|
+
_id: messages.at(-1)!._id,
|
|
180
|
+
order: 0,
|
|
181
|
+
stepOrder: 0,
|
|
182
|
+
});
|
|
183
|
+
const { messages: messages2 } = await t.mutation(api.messages.addMessages, {
|
|
184
|
+
threadId: thread._id as Id<"threads">,
|
|
185
|
+
messages: [{ message: { role: "user", content: "hello" } }],
|
|
186
|
+
agentName: "test",
|
|
187
|
+
promptMessageId: messages.at(-1)!._id as Id<"messages">,
|
|
188
|
+
});
|
|
189
|
+
const maxMessage2 = await t.run(async (ctx) => {
|
|
190
|
+
return await getMaxMessage(ctx, thread._id as Id<"threads">);
|
|
191
|
+
});
|
|
192
|
+
expect(maxMessage2).toMatchObject({
|
|
193
|
+
_id: messages2.at(-1)!._id,
|
|
194
|
+
order: 1,
|
|
195
|
+
stepOrder: 0,
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test("sub order is incremented on subsequent calls to addMessages for the same promptMessageId", async () => {
|
|
200
|
+
const t = convexTest(schema, modules);
|
|
201
|
+
const thread = await t.mutation(api.threads.createThread, {
|
|
202
|
+
userId: "test",
|
|
203
|
+
});
|
|
204
|
+
const { messages } = await t.mutation(api.messages.addMessages, {
|
|
205
|
+
threadId: thread._id as Id<"threads">,
|
|
206
|
+
messages: [{ message: { role: "user", content: "hello" } }],
|
|
207
|
+
});
|
|
208
|
+
const maxMessage = await t.run(async (ctx) => {
|
|
209
|
+
return await getMaxMessage(ctx, thread._id as Id<"threads">);
|
|
210
|
+
});
|
|
211
|
+
expect(maxMessage).toMatchObject({
|
|
212
|
+
_id: messages.at(-1)!._id,
|
|
213
|
+
order: 0,
|
|
214
|
+
stepOrder: 0,
|
|
215
|
+
});
|
|
216
|
+
const { messages: messages2 } = await t.mutation(api.messages.addMessages, {
|
|
217
|
+
threadId: thread._id as Id<"threads">,
|
|
218
|
+
messages: [{ message: { role: "assistant", content: "hello" } }],
|
|
132
219
|
agentName: "test",
|
|
133
220
|
promptMessageId: messages.at(-1)!._id as Id<"messages">,
|
|
134
221
|
});
|
|
@@ -142,6 +229,83 @@ describe("agent", () => {
|
|
|
142
229
|
});
|
|
143
230
|
});
|
|
144
231
|
|
|
232
|
+
test("adding multiple messages at a promptMessageId skips later messages", async () => {
|
|
233
|
+
const t = convexTest(schema, modules);
|
|
234
|
+
const thread = await t.mutation(api.threads.createThread, {
|
|
235
|
+
userId: "test",
|
|
236
|
+
});
|
|
237
|
+
const { messages } = await t.mutation(api.messages.addMessages, {
|
|
238
|
+
threadId: thread._id as Id<"threads">,
|
|
239
|
+
messages: [{ message: { role: "user", content: "hello" } }],
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
const { messages: messages2 } = await t.mutation(api.messages.addMessages, {
|
|
243
|
+
threadId: thread._id as Id<"threads">,
|
|
244
|
+
messages: [
|
|
245
|
+
{ message: { role: "user", content: "hello2" } },
|
|
246
|
+
{ message: { role: "assistant", content: "hello" } },
|
|
247
|
+
],
|
|
248
|
+
agentName: "test",
|
|
249
|
+
});
|
|
250
|
+
expect(messages2.length).toBe(2);
|
|
251
|
+
|
|
252
|
+
const { messages: messages3 } = await t.mutation(api.messages.addMessages, {
|
|
253
|
+
threadId: thread._id as Id<"threads">,
|
|
254
|
+
messages: [
|
|
255
|
+
{
|
|
256
|
+
message: {
|
|
257
|
+
role: "assistant",
|
|
258
|
+
content: [
|
|
259
|
+
{
|
|
260
|
+
type: "tool-call",
|
|
261
|
+
args: { a: 1 },
|
|
262
|
+
toolCallId: "1",
|
|
263
|
+
toolName: "tool",
|
|
264
|
+
},
|
|
265
|
+
],
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
message: {
|
|
270
|
+
role: "tool",
|
|
271
|
+
content: [
|
|
272
|
+
{
|
|
273
|
+
type: "tool-result",
|
|
274
|
+
toolName: "tool",
|
|
275
|
+
result: "foo",
|
|
276
|
+
toolCallId: "1",
|
|
277
|
+
},
|
|
278
|
+
],
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
{ message: { role: "user", content: "bye" } },
|
|
282
|
+
],
|
|
283
|
+
agentName: "test",
|
|
284
|
+
promptMessageId: messages.at(-1)!._id as Id<"messages">,
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
expect(messages3.length).toBe(3);
|
|
288
|
+
|
|
289
|
+
const allMessages = await t.query(api.messages.listMessagesByThreadId, {
|
|
290
|
+
threadId: thread._id as Id<"threads">,
|
|
291
|
+
order: "asc",
|
|
292
|
+
});
|
|
293
|
+
expect(allMessages.page).toHaveLength(6);
|
|
294
|
+
expect(allMessages.page.map((m) => m.order)).toEqual([0, 0, 0, 1, 1, 2]);
|
|
295
|
+
expect(allMessages.page.map((m) => m.stepOrder)).toEqual([
|
|
296
|
+
0, 1, 2, 0, 1, 0,
|
|
297
|
+
]);
|
|
298
|
+
expect(allMessages.page[0]!.message!.role).toBe("user");
|
|
299
|
+
expect(allMessages.page[0]!.message!.content).toBe("hello");
|
|
300
|
+
expect(allMessages.page[1]!.message!.role).toBe("assistant");
|
|
301
|
+
expect(allMessages.page[2]!.message!.role).toBe("tool");
|
|
302
|
+
expect(allMessages.page[3]!.message!.role).toBe("user");
|
|
303
|
+
expect(allMessages.page[3]!.message!.content).toBe("hello2");
|
|
304
|
+
expect(allMessages.page[4]!.message!.role).toBe("assistant");
|
|
305
|
+
expect(allMessages.page[5]!.message!.role).toBe("user");
|
|
306
|
+
expect(allMessages.page[5]!.message!.content).toBe("bye");
|
|
307
|
+
});
|
|
308
|
+
|
|
145
309
|
test("updateMessage updates message content", async () => {
|
|
146
310
|
const t = convexTest(schema, modules);
|
|
147
311
|
const thread = await t.mutation(api.threads.createThread, {
|
|
@@ -155,9 +319,7 @@ describe("agent", () => {
|
|
|
155
319
|
|
|
156
320
|
const updatedMessage = await t.mutation(api.messages.updateMessage, {
|
|
157
321
|
messageId,
|
|
158
|
-
patch: {
|
|
159
|
-
message: { role: "user", content: "updated content" },
|
|
160
|
-
},
|
|
322
|
+
patch: { message: { role: "user", content: "updated content" } },
|
|
161
323
|
});
|
|
162
324
|
|
|
163
325
|
expect(updatedMessage.message).toEqual({
|
|
@@ -173,8 +335,9 @@ describe("agent", () => {
|
|
|
173
335
|
});
|
|
174
336
|
const { messages } = await t.mutation(api.messages.addMessages, {
|
|
175
337
|
threadId: thread._id as Id<"threads">,
|
|
176
|
-
messages: [
|
|
177
|
-
|
|
338
|
+
messages: [
|
|
339
|
+
{ message: { role: "assistant", content: "hello" }, status: "pending" },
|
|
340
|
+
],
|
|
178
341
|
});
|
|
179
342
|
const messageId = messages[0]._id as Id<"messages">;
|
|
180
343
|
|
|
@@ -184,9 +347,7 @@ describe("agent", () => {
|
|
|
184
347
|
// Update to success
|
|
185
348
|
const updatedMessage = await t.mutation(api.messages.updateMessage, {
|
|
186
349
|
messageId,
|
|
187
|
-
patch: {
|
|
188
|
-
status: "success",
|
|
189
|
-
},
|
|
350
|
+
patch: { status: "success" },
|
|
190
351
|
});
|
|
191
352
|
|
|
192
353
|
expect(updatedMessage.status).toBe("success");
|
|
@@ -199,17 +360,15 @@ describe("agent", () => {
|
|
|
199
360
|
});
|
|
200
361
|
const { messages } = await t.mutation(api.messages.addMessages, {
|
|
201
362
|
threadId: thread._id as Id<"threads">,
|
|
202
|
-
messages: [
|
|
203
|
-
|
|
363
|
+
messages: [
|
|
364
|
+
{ message: { role: "assistant", content: "hello" }, status: "pending" },
|
|
365
|
+
],
|
|
204
366
|
});
|
|
205
367
|
const messageId = messages[0]._id as Id<"messages">;
|
|
206
368
|
|
|
207
369
|
const updatedMessage = await t.mutation(api.messages.updateMessage, {
|
|
208
370
|
messageId,
|
|
209
|
-
patch: {
|
|
210
|
-
status: "failed",
|
|
211
|
-
error: "Something went wrong",
|
|
212
|
-
},
|
|
371
|
+
patch: { status: "failed", error: "Something went wrong" },
|
|
213
372
|
});
|
|
214
373
|
|
|
215
374
|
expect(updatedMessage.status).toBe("failed");
|
|
@@ -277,9 +436,7 @@ describe("agent", () => {
|
|
|
277
436
|
await expect(
|
|
278
437
|
t.mutation(api.messages.updateMessage, {
|
|
279
438
|
messageId: "invalidId" as Id<"messages">,
|
|
280
|
-
patch: {
|
|
281
|
-
message: { role: "user", content: "test" },
|
|
282
|
-
},
|
|
439
|
+
patch: { message: { role: "user", content: "test" } },
|
|
283
440
|
}),
|
|
284
441
|
).rejects.toThrow();
|
|
285
442
|
});
|
|
@@ -308,10 +465,7 @@ describe("agent", () => {
|
|
|
308
465
|
// Verify messages are actually deleted
|
|
309
466
|
const remainingMessages = await t.query(
|
|
310
467
|
api.messages.listMessagesByThreadId,
|
|
311
|
-
{
|
|
312
|
-
threadId: thread._id as Id<"threads">,
|
|
313
|
-
order: "asc",
|
|
314
|
-
},
|
|
468
|
+
{ threadId: thread._id as Id<"threads">, order: "asc" },
|
|
315
469
|
);
|
|
316
470
|
expect(remainingMessages.page).toHaveLength(1);
|
|
317
471
|
expect(remainingMessages.page[0]._id).toBe(messageIds[1]);
|
|
@@ -343,10 +497,7 @@ describe("agent", () => {
|
|
|
343
497
|
// Verify the valid message was deleted
|
|
344
498
|
const remainingMessages = await t.query(
|
|
345
499
|
api.messages.listMessagesByThreadId,
|
|
346
|
-
{
|
|
347
|
-
threadId: thread._id as Id<"threads">,
|
|
348
|
-
order: "asc",
|
|
349
|
-
},
|
|
500
|
+
{ threadId: thread._id as Id<"threads">, order: "asc" },
|
|
350
501
|
);
|
|
351
502
|
expect(remainingMessages.page).toHaveLength(0);
|
|
352
503
|
});
|
|
@@ -395,10 +546,7 @@ describe("agent", () => {
|
|
|
395
546
|
// Verify only messages from order 0 were deleted
|
|
396
547
|
const remainingMessages = await t.query(
|
|
397
548
|
api.messages.listMessagesByThreadId,
|
|
398
|
-
{
|
|
399
|
-
threadId: thread._id as Id<"threads">,
|
|
400
|
-
order: "asc",
|
|
401
|
-
},
|
|
549
|
+
{ threadId: thread._id as Id<"threads">, order: "asc" },
|
|
402
550
|
);
|
|
403
551
|
|
|
404
552
|
expect(remainingMessages.page).toHaveLength(3); // Should have messages from order 1 and 2
|
|
@@ -417,7 +565,7 @@ describe("agent", () => {
|
|
|
417
565
|
messages: [
|
|
418
566
|
{ message: { role: "user", content: "step 0" } },
|
|
419
567
|
{ message: { role: "assistant", content: "step 1" } },
|
|
420
|
-
{ message: { role: "
|
|
568
|
+
{ message: { role: "assistant", content: "step 2" } },
|
|
421
569
|
{ message: { role: "assistant", content: "step 3" } },
|
|
422
570
|
],
|
|
423
571
|
});
|
|
@@ -438,10 +586,7 @@ describe("agent", () => {
|
|
|
438
586
|
// Verify only step 1 and 2 were deleted (step 3 is excluded by upperBoundInclusive: false)
|
|
439
587
|
const remainingMessages = await t.query(
|
|
440
588
|
api.messages.listMessagesByThreadId,
|
|
441
|
-
{
|
|
442
|
-
threadId: thread._id as Id<"threads">,
|
|
443
|
-
order: "asc",
|
|
444
|
-
},
|
|
589
|
+
{ threadId: thread._id as Id<"threads">, order: "asc" },
|
|
445
590
|
);
|
|
446
591
|
|
|
447
592
|
expect(remainingMessages.page).toHaveLength(2);
|
|
@@ -501,10 +646,7 @@ describe("agent", () => {
|
|
|
501
646
|
// Verify original message is still there
|
|
502
647
|
const remainingMessages = await t.query(
|
|
503
648
|
api.messages.listMessagesByThreadId,
|
|
504
|
-
{
|
|
505
|
-
threadId: thread._id as Id<"threads">,
|
|
506
|
-
order: "asc",
|
|
507
|
-
},
|
|
649
|
+
{ threadId: thread._id as Id<"threads">, order: "asc" },
|
|
508
650
|
);
|
|
509
651
|
expect(remainingMessages.page).toHaveLength(1);
|
|
510
652
|
});
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
isTool,
|
|
10
10
|
} from "../shared.js";
|
|
11
11
|
import {
|
|
12
|
-
|
|
12
|
+
vMessageEmbeddingsWithDimension,
|
|
13
13
|
vMessageStatus,
|
|
14
14
|
vMessageWithMetadataInternal,
|
|
15
15
|
vPaginationResult,
|
|
@@ -58,9 +58,7 @@ export async function deleteMessage(
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export const deleteByIds = mutation({
|
|
61
|
-
args: {
|
|
62
|
-
messageIds: v.array(v.id("messages")),
|
|
63
|
-
},
|
|
61
|
+
args: { messageIds: v.array(v.id("messages")) },
|
|
64
62
|
returns: v.array(v.id("messages")),
|
|
65
63
|
handler: async (ctx, args) => {
|
|
66
64
|
const deletedMessageIds = await Promise.all(
|
|
@@ -115,8 +113,8 @@ export const deleteByOrder = mutation({
|
|
|
115
113
|
await Promise.all(messages.map((m) => deleteMessage(ctx, m)));
|
|
116
114
|
return {
|
|
117
115
|
isDone: messages.length < 64,
|
|
118
|
-
lastOrder: messages
|
|
119
|
-
lastStepOrder: messages
|
|
116
|
+
lastOrder: messages.at(-1)?.order,
|
|
117
|
+
lastStepOrder: messages.at(-1)?.stepOrder,
|
|
120
118
|
};
|
|
121
119
|
},
|
|
122
120
|
});
|
|
@@ -127,16 +125,13 @@ const addMessagesArgs = {
|
|
|
127
125
|
promptMessageId: v.optional(v.id("messages")),
|
|
128
126
|
agentName: v.optional(v.string()),
|
|
129
127
|
messages: v.array(vMessageWithMetadataInternal),
|
|
130
|
-
embeddings: v.optional(
|
|
131
|
-
pending: v.optional(v.boolean()),
|
|
128
|
+
embeddings: v.optional(vMessageEmbeddingsWithDimension),
|
|
132
129
|
failPendingSteps: v.optional(v.boolean()),
|
|
133
130
|
};
|
|
134
131
|
export const addMessages = mutation({
|
|
135
132
|
args: addMessagesArgs,
|
|
136
133
|
handler: addMessagesHandler,
|
|
137
|
-
returns: v.object({
|
|
138
|
-
messages: v.array(vMessageDoc),
|
|
139
|
-
}),
|
|
134
|
+
returns: v.object({ messages: v.array(vMessageDoc) }),
|
|
140
135
|
});
|
|
141
136
|
async function addMessagesHandler(
|
|
142
137
|
ctx: MutationCtx,
|
|
@@ -149,14 +144,8 @@ async function addMessagesHandler(
|
|
|
149
144
|
assert(thread, `Thread ${args.threadId} not found`);
|
|
150
145
|
userId = thread.userId;
|
|
151
146
|
}
|
|
152
|
-
const {
|
|
153
|
-
|
|
154
|
-
failPendingSteps,
|
|
155
|
-
pending,
|
|
156
|
-
messages,
|
|
157
|
-
promptMessageId,
|
|
158
|
-
...rest
|
|
159
|
-
} = args;
|
|
147
|
+
const { embeddings, failPendingSteps, messages, promptMessageId, ...rest } =
|
|
148
|
+
args;
|
|
160
149
|
const parentMessage = promptMessageId && (await ctx.db.get(promptMessageId));
|
|
161
150
|
if (failPendingSteps) {
|
|
162
151
|
assert(args.threadId, "threadId is required to fail pending steps");
|
|
@@ -187,8 +176,8 @@ async function addMessagesHandler(
|
|
|
187
176
|
stepOrder = maxMessage?.stepOrder ?? parentMessage.stepOrder;
|
|
188
177
|
} else {
|
|
189
178
|
const maxMessage = await getMaxMessage(ctx, threadId);
|
|
190
|
-
order = maxMessage
|
|
191
|
-
stepOrder = -1;
|
|
179
|
+
order = maxMessage?.order ?? -1;
|
|
180
|
+
stepOrder = maxMessage?.stepOrder ?? -1;
|
|
192
181
|
}
|
|
193
182
|
const toReturn: Doc<"messages">[] = [];
|
|
194
183
|
if (embeddings) {
|
|
@@ -209,7 +198,18 @@ async function addMessagesHandler(
|
|
|
209
198
|
threadId,
|
|
210
199
|
});
|
|
211
200
|
}
|
|
212
|
-
|
|
201
|
+
if (message.message.role === "user") {
|
|
202
|
+
if (parentMessage && parentMessage.order === order) {
|
|
203
|
+
// see if there's a later message than the parent message order
|
|
204
|
+
const maxMessage = await getMaxMessage(ctx, threadId);
|
|
205
|
+
order = (maxMessage?.order ?? order) + 1;
|
|
206
|
+
} else {
|
|
207
|
+
order++;
|
|
208
|
+
}
|
|
209
|
+
stepOrder = 0;
|
|
210
|
+
} else {
|
|
211
|
+
stepOrder++;
|
|
212
|
+
}
|
|
213
213
|
const messageId = await ctx.db.insert("messages", {
|
|
214
214
|
...rest,
|
|
215
215
|
...message,
|
|
@@ -219,16 +219,12 @@ async function addMessagesHandler(
|
|
|
219
219
|
order,
|
|
220
220
|
tool: isTool(message.message),
|
|
221
221
|
text: extractText(message.message),
|
|
222
|
-
status: fail ? "failed" :
|
|
223
|
-
error: fail
|
|
222
|
+
status: fail ? "failed" : (message.status ?? "success"),
|
|
223
|
+
error: fail
|
|
224
|
+
? (parentMessage?.error ?? "Parent message failed")
|
|
225
|
+
: undefined,
|
|
224
226
|
stepOrder,
|
|
225
227
|
});
|
|
226
|
-
// Let's just not set the id field and have it set only in explicit cases.
|
|
227
|
-
// if (!message.id) {
|
|
228
|
-
// await ctx.db.patch(messageId, {
|
|
229
|
-
// id: messageId,
|
|
230
|
-
// });
|
|
231
|
-
// }
|
|
232
228
|
if (message.fileIds) {
|
|
233
229
|
await changeRefcount(ctx, [], message.fileIds);
|
|
234
230
|
}
|
|
@@ -263,7 +259,7 @@ function orderedMessagesStream(
|
|
|
263
259
|
.eq("threadId", threadId)
|
|
264
260
|
.eq("status", status)
|
|
265
261
|
.eq("tool", tool);
|
|
266
|
-
if (order) {
|
|
262
|
+
if (order !== undefined) {
|
|
267
263
|
return qq.eq("order", order);
|
|
268
264
|
}
|
|
269
265
|
return qq;
|
|
@@ -435,7 +431,9 @@ export const getMessagesByIds = query({
|
|
|
435
431
|
messageIds: v.array(v.id("messages")),
|
|
436
432
|
},
|
|
437
433
|
handler: async (ctx, args) => {
|
|
438
|
-
return await Promise.all(args.messageIds.map((id) => ctx.db.get(id)))
|
|
434
|
+
return (await Promise.all(args.messageIds.map((id) => ctx.db.get(id)))).map(
|
|
435
|
+
(m) => (m ? publicMessage(m) : null),
|
|
436
|
+
);
|
|
439
437
|
},
|
|
440
438
|
returns: v.array(v.union(v.null(), vMessageDoc)),
|
|
441
439
|
});
|
package/src/component/schema.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
vMessageStatus,
|
|
7
7
|
vUsage,
|
|
8
8
|
vSource,
|
|
9
|
-
|
|
9
|
+
vLanguageModelCallWarning,
|
|
10
10
|
vFinishReason,
|
|
11
11
|
vProviderOptions,
|
|
12
12
|
vProviderMetadata,
|
|
@@ -29,12 +29,8 @@ export const schema = defineSchema({
|
|
|
29
29
|
order: /*DEPRECATED*/ v.optional(v.number()),
|
|
30
30
|
})
|
|
31
31
|
.index("userId", ["userId"])
|
|
32
|
-
.searchIndex("title", {
|
|
33
|
-
searchField: "title",
|
|
34
|
-
filterFields: ["userId"],
|
|
35
|
-
}),
|
|
32
|
+
.searchIndex("title", { searchField: "title", filterFields: ["userId"] }),
|
|
36
33
|
messages: defineTable({
|
|
37
|
-
id: v.optional(v.string()), // external id, e.g. from Vercel AI SDK
|
|
38
34
|
userId: v.optional(v.string()), // useful for searching across threads
|
|
39
35
|
threadId: v.id("threads"),
|
|
40
36
|
order: v.number(),
|
|
@@ -62,9 +58,10 @@ export const schema = defineSchema({
|
|
|
62
58
|
sources: v.optional(v.array(vSource)),
|
|
63
59
|
reasoning: v.optional(v.string()),
|
|
64
60
|
reasoningDetails: v.optional(vReasoningDetails),
|
|
65
|
-
warnings: v.optional(v.array(
|
|
61
|
+
warnings: v.optional(v.array(vLanguageModelCallWarning)),
|
|
66
62
|
finishReason: v.optional(vFinishReason),
|
|
67
63
|
// DEPRECATED
|
|
64
|
+
id: v.optional(v.string()), // external id, e.g. from Vercel AI SDK
|
|
68
65
|
parentMessageId: v.optional(v.id("messages")),
|
|
69
66
|
stepId: v.optional(v.string()),
|
|
70
67
|
files: v.optional(v.array(v.any())),
|
|
@@ -115,10 +112,7 @@ export const schema = defineSchema({
|
|
|
115
112
|
endedAt: v.number(),
|
|
116
113
|
cleanupFnId: v.optional(v.id("_scheduled_functions")),
|
|
117
114
|
}),
|
|
118
|
-
v.object({
|
|
119
|
-
kind: v.literal("aborted"),
|
|
120
|
-
reason: v.string(),
|
|
121
|
-
}),
|
|
115
|
+
v.object({ kind: v.literal("aborted"), reason: v.string() }),
|
|
122
116
|
),
|
|
123
117
|
})
|
|
124
118
|
// There should only be one per "order" index
|
|
@@ -162,9 +156,9 @@ export const schema = defineSchema({
|
|
|
162
156
|
// To authenticate playground usage
|
|
163
157
|
// Delete a key to invalidate it
|
|
164
158
|
// Provide a name to easily identify it / invalidate by name
|
|
165
|
-
apiKeys: defineTable({
|
|
166
|
-
name
|
|
167
|
-
|
|
159
|
+
apiKeys: defineTable({ name: v.optional(v.string()) }).index("name", [
|
|
160
|
+
"name",
|
|
161
|
+
]),
|
|
168
162
|
});
|
|
169
163
|
|
|
170
164
|
export const vv = typedV(schema);
|