@convex-dev/agent 0.1.18 → 0.2.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.
Files changed (122) hide show
  1. package/dist/client/createTool.d.ts +30 -11
  2. package/dist/client/createTool.d.ts.map +1 -1
  3. package/dist/client/createTool.js +24 -10
  4. package/dist/client/createTool.js.map +1 -1
  5. package/dist/client/defaultComponent.d.ts +11 -0
  6. package/dist/client/defaultComponent.d.ts.map +1 -0
  7. package/dist/client/defaultComponent.js +7 -0
  8. package/dist/client/defaultComponent.js.map +1 -0
  9. package/dist/client/definePlaygroundAPI.d.ts +68 -23
  10. package/dist/client/definePlaygroundAPI.d.ts.map +1 -1
  11. package/dist/client/definePlaygroundAPI.js +7 -20
  12. package/dist/client/definePlaygroundAPI.js.map +1 -1
  13. package/dist/client/files.d.ts +14 -4
  14. package/dist/client/files.d.ts.map +1 -1
  15. package/dist/client/files.js +66 -11
  16. package/dist/client/files.js.map +1 -1
  17. package/dist/client/index.d.ts +323 -780
  18. package/dist/client/index.d.ts.map +1 -1
  19. package/dist/client/index.js +445 -543
  20. package/dist/client/index.js.map +1 -1
  21. package/dist/client/messages.d.ts +256 -0
  22. package/dist/client/messages.d.ts.map +1 -0
  23. package/dist/client/messages.js +97 -0
  24. package/dist/client/messages.js.map +1 -0
  25. package/dist/client/search.d.ts +35 -12
  26. package/dist/client/search.d.ts.map +1 -1
  27. package/dist/client/search.js +21 -4
  28. package/dist/client/search.js.map +1 -1
  29. package/dist/client/streaming.d.ts +21 -21
  30. package/dist/client/streaming.d.ts.map +1 -1
  31. package/dist/client/streaming.js +35 -40
  32. package/dist/client/streaming.js.map +1 -1
  33. package/dist/client/threads.d.ts +46 -0
  34. package/dist/client/threads.d.ts.map +1 -0
  35. package/dist/client/threads.js +49 -0
  36. package/dist/client/threads.js.map +1 -0
  37. package/dist/client/types.d.ts +159 -75
  38. package/dist/client/types.d.ts.map +1 -1
  39. package/dist/component/_generated/api.d.ts +261 -209
  40. package/dist/component/messages.d.ts +314 -105
  41. package/dist/component/messages.d.ts.map +1 -1
  42. package/dist/component/messages.js +141 -83
  43. package/dist/component/messages.js.map +1 -1
  44. package/dist/component/schema.d.ts +631 -870
  45. package/dist/component/schema.d.ts.map +1 -1
  46. package/dist/component/schema.js +11 -16
  47. package/dist/component/schema.js.map +1 -1
  48. package/dist/component/streams.d.ts +29 -149
  49. package/dist/component/streams.d.ts.map +1 -1
  50. package/dist/component/streams.js +104 -60
  51. package/dist/component/streams.js.map +1 -1
  52. package/dist/component/threads.d.ts +4 -4
  53. package/dist/component/users.d.ts +3 -3
  54. package/dist/mapping.d.ts +15 -16
  55. package/dist/mapping.d.ts.map +1 -1
  56. package/dist/mapping.js +208 -62
  57. package/dist/mapping.js.map +1 -1
  58. package/dist/parts.d.ts +3 -0
  59. package/dist/parts.d.ts.map +1 -0
  60. package/dist/parts.js +34 -0
  61. package/dist/parts.js.map +1 -0
  62. package/dist/react/SmoothText.d.ts +5 -0
  63. package/dist/react/SmoothText.d.ts.map +1 -0
  64. package/dist/react/SmoothText.js +6 -0
  65. package/dist/react/SmoothText.js.map +1 -0
  66. package/dist/react/deltas.d.ts +3 -5
  67. package/dist/react/deltas.d.ts.map +1 -1
  68. package/dist/react/deltas.js +89 -53
  69. package/dist/react/deltas.js.map +1 -1
  70. package/dist/react/index.d.ts +1 -0
  71. package/dist/react/index.d.ts.map +1 -1
  72. package/dist/react/index.js +31 -11
  73. package/dist/react/index.js.map +1 -1
  74. package/dist/react/optimisticallySendMessage.d.ts.map +1 -1
  75. package/dist/react/optimisticallySendMessage.js +2 -8
  76. package/dist/react/optimisticallySendMessage.js.map +1 -1
  77. package/dist/react/toUIMessages.d.ts +5 -4
  78. package/dist/react/toUIMessages.d.ts.map +1 -1
  79. package/dist/react/toUIMessages.js +103 -40
  80. package/dist/react/toUIMessages.js.map +1 -1
  81. package/dist/react/useSmoothText.d.ts +13 -12
  82. package/dist/react/useSmoothText.d.ts.map +1 -1
  83. package/dist/react/useSmoothText.js +1 -1
  84. package/dist/react/useSmoothText.js.map +1 -1
  85. package/dist/validators.d.ts +751 -1464
  86. package/dist/validators.d.ts.map +1 -1
  87. package/dist/validators.js +39 -80
  88. package/dist/validators.js.map +1 -1
  89. package/package.json +34 -30
  90. package/src/client/createTool.ts +66 -40
  91. package/src/client/defaultComponent.ts +17 -0
  92. package/src/client/definePlaygroundAPI.ts +17 -31
  93. package/src/client/files.ts +94 -17
  94. package/src/client/index.test.ts +28 -38
  95. package/src/client/index.ts +785 -977
  96. package/src/client/messages.ts +205 -0
  97. package/src/client/search.ts +37 -10
  98. package/src/client/streaming.ts +53 -56
  99. package/src/client/threads.ts +78 -0
  100. package/src/client/types.ts +239 -131
  101. package/src/component/_generated/api.d.ts +261 -209
  102. package/src/component/messages.test.ts +182 -40
  103. package/src/component/messages.ts +165 -108
  104. package/src/component/schema.ts +11 -17
  105. package/src/component/streams.ts +180 -69
  106. package/src/mapping.ts +253 -96
  107. package/src/parts.ts +39 -0
  108. package/src/react/SmoothText.tsx +9 -0
  109. package/src/react/deltas.test.ts +38 -42
  110. package/src/react/deltas.ts +116 -65
  111. package/src/react/index.ts +35 -13
  112. package/src/react/optimisticallySendMessage.ts +2 -8
  113. package/src/react/toUIMessages.test.ts +154 -36
  114. package/src/react/toUIMessages.ts +136 -57
  115. package/src/react/useSmoothText.ts +14 -15
  116. package/src/validators.test.ts +1 -117
  117. package/src/validators.ts +57 -107
  118. package/dist/client/listMessages.d.ts +0 -22
  119. package/dist/client/listMessages.d.ts.map +0 -1
  120. package/dist/client/listMessages.js +0 -25
  121. package/dist/client/listMessages.js.map +0 -1
  122. package/src/client/listMessages.ts +0 -38
@@ -1,6 +1,9 @@
1
- import { assert, omit } from "convex-helpers";
1
+ import { assert, omit, pick } from "convex-helpers";
2
2
  import { mergedStream, stream } from "convex-helpers/server/stream";
3
- import { paginationOptsValidator } from "convex/server";
3
+ import {
4
+ paginationOptsValidator,
5
+ type WithoutSystemFields,
6
+ } from "convex/server";
4
7
  import type { ObjectType } from "convex/values";
5
8
  import {
6
9
  DEFAULT_MESSAGE_RANGE,
@@ -9,7 +12,7 @@ import {
9
12
  isTool,
10
13
  } from "../shared.js";
11
14
  import {
12
- vMessageEmbeddings,
15
+ vMessageEmbeddingsWithDimension,
13
16
  vMessageStatus,
14
17
  vMessageWithMetadataInternal,
15
18
  vPaginationResult,
@@ -26,11 +29,6 @@ import {
26
29
  } from "./_generated/server.js";
27
30
  import type { MessageDoc } from "./schema.js";
28
31
  import { schema, v, vMessageDoc } from "./schema.js";
29
- import {
30
- getThread as _getThread,
31
- listThreadsByUserId as _listThreadsByUserId,
32
- updateThread as _updateThread,
33
- } from "./threads.js";
34
32
  import { insertVector, searchVectors } from "./vector/index.js";
35
33
  import {
36
34
  type VectorDimension,
@@ -39,6 +37,8 @@ import {
39
37
  vVectorId,
40
38
  } from "./vector/tables.js";
41
39
  import { changeRefcount } from "./files.js";
40
+ import { getStreamingMessagesWithMetadata } from "./streams.js";
41
+ import { partial } from "convex-helpers/validators";
42
42
 
43
43
  function publicMessage(message: Doc<"messages">): MessageDoc {
44
44
  return omit(message, ["parentMessageId", "stepId", "files"]);
@@ -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[messages.length - 1]?.order,
119
- lastStepOrder: messages[messages.length - 1]?.stepOrder,
116
+ lastOrder: messages.at(-1)?.order,
117
+ lastStepOrder: messages.at(-1)?.stepOrder,
120
118
  };
121
119
  },
122
120
  });
@@ -127,16 +125,15 @@ 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(vMessageEmbeddings),
131
- pending: v.optional(v.boolean()),
128
+ embeddings: v.optional(vMessageEmbeddingsWithDimension),
132
129
  failPendingSteps: v.optional(v.boolean()),
130
+ // A pending message to update. If the pending message failed, abort.
131
+ pendingMessageId: v.optional(v.id("messages")),
133
132
  };
134
133
  export const addMessages = mutation({
135
134
  args: addMessagesArgs,
136
135
  handler: addMessagesHandler,
137
- returns: v.object({
138
- messages: v.array(vMessageDoc),
139
- }),
136
+ returns: v.object({ messages: v.array(vMessageDoc) }),
140
137
  });
141
138
  async function addMessagesHandler(
142
139
  ctx: MutationCtx,
@@ -152,12 +149,12 @@ async function addMessagesHandler(
152
149
  const {
153
150
  embeddings,
154
151
  failPendingSteps,
155
- pending,
156
152
  messages,
157
153
  promptMessageId,
154
+ pendingMessageId,
158
155
  ...rest
159
156
  } = args;
160
- const parentMessage = promptMessageId && (await ctx.db.get(promptMessageId));
157
+ const promptMessage = promptMessageId && (await ctx.db.get(promptMessageId));
161
158
  if (failPendingSteps) {
162
159
  assert(args.threadId, "threadId is required to fail pending steps");
163
160
  const pendingMessages = await ctx.db
@@ -165,30 +162,41 @@ async function addMessagesHandler(
165
162
  .withIndex("threadId_status_tool_order_stepOrder", (q) =>
166
163
  q.eq("threadId", threadId).eq("status", "pending"),
167
164
  )
168
- .collect();
165
+ .order("desc")
166
+ .take(100);
169
167
  await Promise.all(
170
168
  pendingMessages
171
- .filter((m) => !parentMessage || m.order === parentMessage.order)
172
- .map((m) =>
173
- ctx.db.patch(m._id, { status: "failed", error: "Restarting" }),
174
- ),
169
+ .filter((m) => !promptMessage || m.order === promptMessage.order)
170
+ .filter((m) => !pendingMessageId || m._id !== pendingMessageId)
171
+ .map(async (m) => {
172
+ if (m.embeddingId) {
173
+ await ctx.db.delete(m.embeddingId);
174
+ }
175
+ await ctx.db.patch(m._id, {
176
+ status: "failed",
177
+ error: "Restarting",
178
+ embeddingId: undefined,
179
+ });
180
+ }),
175
181
  );
176
182
  }
177
183
  let order, stepOrder;
178
184
  let fail = false;
185
+ let error: string | undefined;
179
186
  if (promptMessageId) {
180
- assert(parentMessage, `Parent message ${promptMessageId} not found`);
181
- if (parentMessage.status === "failed") {
187
+ assert(promptMessage, `Parent message ${promptMessageId} not found`);
188
+ if (promptMessage.status === "failed") {
182
189
  fail = true;
190
+ error = promptMessage.error ?? error ?? "The prompt message failed";
183
191
  }
184
- order = parentMessage.order;
192
+ order = promptMessage.order;
185
193
  // Defend against there being existing messages with this parent.
186
194
  const maxMessage = await getMaxMessage(ctx, threadId, order);
187
- stepOrder = maxMessage?.stepOrder ?? parentMessage.stepOrder;
195
+ stepOrder = maxMessage?.stepOrder ?? promptMessage.stepOrder;
188
196
  } else {
189
197
  const maxMessage = await getMaxMessage(ctx, threadId);
190
- order = maxMessage ? maxMessage.order + 1 : 0;
191
- stepOrder = -1;
198
+ order = maxMessage?.order ?? -1;
199
+ stepOrder = maxMessage?.stepOrder ?? -1;
192
200
  }
193
201
  const toReturn: Doc<"messages">[] = [];
194
202
  if (embeddings) {
@@ -200,7 +208,12 @@ async function addMessagesHandler(
200
208
  for (let i = 0; i < messages.length; i++) {
201
209
  const message = messages[i];
202
210
  let embeddingId: VectorTableId | undefined;
203
- if (embeddings && embeddings.vectors[i]) {
211
+ if (
212
+ embeddings &&
213
+ embeddings.vectors[i] &&
214
+ !fail &&
215
+ message.status !== "failed"
216
+ ) {
204
217
  embeddingId = await insertVector(ctx, embeddings.dimension, {
205
218
  vector: embeddings.vectors[i]!,
206
219
  model: embeddings.model,
@@ -209,26 +222,68 @@ async function addMessagesHandler(
209
222
  threadId,
210
223
  });
211
224
  }
212
- stepOrder++;
213
- const messageId = await ctx.db.insert("messages", {
225
+ const messageDoc = {
214
226
  ...rest,
215
227
  ...message,
216
228
  embeddingId,
217
229
  parentMessageId: promptMessageId,
218
230
  userId,
219
- order,
220
231
  tool: isTool(message.message),
221
232
  text: extractText(message.message),
222
- status: fail ? "failed" : pending ? "pending" : "success",
223
- error: fail ? "Parent message failed" : undefined,
233
+ status: fail ? "failed" : (message.status ?? "success"),
234
+ error: fail ? error : message.error,
235
+ } satisfies Omit<
236
+ WithoutSystemFields<Doc<"messages">>,
237
+ "order" | "stepOrder"
238
+ >;
239
+ // If there is a pending message, we replace that one with the first message
240
+ // and subsequent ones will follow the regular order/subOrder advancement.
241
+ if (i === 0 && pendingMessageId) {
242
+ const pendingMessage = await ctx.db.get(pendingMessageId);
243
+ assert(pendingMessage, `Pending msg ${pendingMessageId} not found`);
244
+ if (pendingMessage.status === "failed") {
245
+ fail = true;
246
+ error =
247
+ `Trying to update a message that failed: ${pendingMessageId}, ` +
248
+ `error: ${pendingMessage.error ?? error}`;
249
+ messageDoc.status = "failed";
250
+ messageDoc.error = error;
251
+ }
252
+ if (message.fileIds) {
253
+ await changeRefcount(
254
+ ctx,
255
+ pendingMessage.fileIds ?? [],
256
+ message.fileIds,
257
+ );
258
+ }
259
+ await ctx.db.replace(pendingMessage._id, {
260
+ ...messageDoc,
261
+ order: pendingMessage.order,
262
+ stepOrder: pendingMessage.stepOrder,
263
+ });
264
+ toReturn.push(pendingMessage);
265
+ continue;
266
+ }
267
+ if (message.message.role === "user") {
268
+ if (promptMessage && promptMessage.order === order) {
269
+ // see if there's a later message than the parent message order
270
+ const maxMessage = await getMaxMessage(ctx, threadId);
271
+ order = (maxMessage?.order ?? order) + 1;
272
+ } else {
273
+ order++;
274
+ }
275
+ stepOrder = 0;
276
+ } else {
277
+ if (order < 0) {
278
+ order = 0;
279
+ }
280
+ stepOrder++;
281
+ }
282
+ const messageId = await ctx.db.insert("messages", {
283
+ ...messageDoc,
284
+ order,
224
285
  stepOrder,
225
286
  });
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
287
  if (message.fileIds) {
233
288
  await changeRefcount(ctx, [], message.fileIds);
234
289
  }
@@ -263,7 +318,7 @@ function orderedMessagesStream(
263
318
  .eq("threadId", threadId)
264
319
  .eq("status", status)
265
320
  .eq("tool", tool);
266
- if (order) {
321
+ if (order !== undefined) {
267
322
  return qq.eq("order", order);
268
323
  }
269
324
  return qq;
@@ -275,51 +330,77 @@ function orderedMessagesStream(
275
330
  );
276
331
  }
277
332
 
278
- export const rollbackMessage = mutation({
333
+ export const finalizeMessage = mutation({
279
334
  args: {
280
335
  messageId: v.id("messages"),
281
- error: v.optional(v.string()),
336
+ result: v.union(
337
+ v.object({ status: v.literal("success") }),
338
+ v.object({ status: v.literal("failed"), error: v.string() }),
339
+ ),
282
340
  },
283
341
  returns: v.null(),
284
- handler: async (ctx, { messageId, error }) => {
342
+ handler: async (ctx, { messageId, result }) => {
285
343
  const message = await ctx.db.get(messageId);
286
344
  assert(message, `Message ${messageId} not found`);
287
- const messages = await orderedMessagesStream(
288
- ctx,
289
- message.threadId,
290
- "asc",
291
- message.order,
292
- ).collect();
293
- for (const m of messages) {
294
- if (m.status === "pending") {
295
- await ctx.db.patch(m._id, { status: "failed", error });
345
+ if (message.status !== "pending") {
346
+ console.log(
347
+ "Trying to finalize a message that's already",
348
+ message.status,
349
+ );
350
+ return;
351
+ }
352
+ // See if we can add any in-progress data
353
+ if (message.message === undefined) {
354
+ const messages = await getStreamingMessagesWithMetadata(
355
+ ctx,
356
+ message,
357
+ result,
358
+ );
359
+ if (messages.length > 0) {
360
+ await addMessagesHandler(ctx, {
361
+ messages,
362
+ threadId: message.threadId,
363
+ agentName: message.agentName,
364
+ failPendingSteps: false,
365
+ pendingMessageId: messageId,
366
+ userId: message.userId,
367
+ embeddings: undefined,
368
+ });
369
+ return;
296
370
  }
297
371
  }
298
-
299
- await ctx.db.patch(messageId, {
300
- status: "failed",
301
- error: error,
302
- });
303
- },
304
- });
305
-
306
- export const commitMessage = mutation({
307
- args: {
308
- messageId: v.id("messages"),
372
+ if (result.status === "failed") {
373
+ if (message.embeddingId) {
374
+ await ctx.db.delete(message.embeddingId);
375
+ }
376
+ await ctx.db.patch(messageId, {
377
+ status: "failed",
378
+ error: result.error,
379
+ embeddingId: undefined,
380
+ });
381
+ } else {
382
+ await ctx.db.patch(messageId, { status: "success" });
383
+ }
309
384
  },
310
- returns: v.null(),
311
- handler: commitMessageHandler,
312
385
  });
313
386
 
314
387
  export const updateMessage = mutation({
315
388
  args: {
316
389
  messageId: v.id("messages"),
317
- patch: v.object({
318
- message: v.optional(vMessageDoc.fields.message),
319
- fileIds: v.optional(v.array(v.id("files"))),
320
- status: v.optional(vMessageStatus),
321
- error: v.optional(v.string()),
322
- }),
390
+ patch: v.object(
391
+ partial(
392
+ pick(schema.tables.messages.validator.fields, [
393
+ "message",
394
+ "fileIds",
395
+ "status",
396
+ "error",
397
+ "model",
398
+ "provider",
399
+ "providerOptions",
400
+ "finishReason",
401
+ ]),
402
+ ),
403
+ ),
323
404
  },
324
405
  returns: vMessageDoc,
325
406
  handler: async (ctx, args) => {
@@ -330,9 +411,7 @@ export const updateMessage = mutation({
330
411
  await changeRefcount(ctx, message.fileIds ?? [], args.patch.fileIds);
331
412
  }
332
413
 
333
- const patch: Partial<Doc<"messages">> = {
334
- ...args.patch,
335
- };
414
+ const patch: Partial<Doc<"messages">> = { ...args.patch };
336
415
 
337
416
  if (args.patch.message !== undefined) {
338
417
  patch.message = args.patch.message;
@@ -340,38 +419,18 @@ export const updateMessage = mutation({
340
419
  patch.text = extractText(args.patch.message);
341
420
  }
342
421
 
422
+ if (args.patch.status === "failed") {
423
+ if (message.embeddingId) {
424
+ await ctx.db.delete(message.embeddingId);
425
+ }
426
+ patch.embeddingId = undefined;
427
+ }
428
+
343
429
  await ctx.db.patch(args.messageId, patch);
344
430
  return publicMessage((await ctx.db.get(args.messageId))!);
345
431
  },
346
432
  });
347
433
 
348
- async function commitMessageHandler(
349
- ctx: MutationCtx,
350
- { messageId }: { messageId: Id<"messages"> },
351
- ) {
352
- const message = await ctx.db.get(messageId);
353
- assert(message, `Message ${messageId} not found`);
354
-
355
- const order = message.order!;
356
- const messages = await mergedStream(
357
- [true, false].map((tool) =>
358
- stream(ctx.db, schema)
359
- .query("messages")
360
- .withIndex("threadId_status_tool_order_stepOrder", (q) =>
361
- q
362
- .eq("threadId", message.threadId)
363
- .eq("status", "pending")
364
- .eq("tool", tool)
365
- .eq("order", order),
366
- ),
367
- ),
368
- ["order", "stepOrder"],
369
- ).collect();
370
- for (const message of messages) {
371
- await ctx.db.patch(message._id, { status: "success" });
372
- }
373
- }
374
-
375
434
  export const listMessagesByThreadId = query({
376
435
  args: {
377
436
  threadId: v.id("threads"),
@@ -431,9 +490,7 @@ export const listMessagesByThreadId = query({
431
490
  });
432
491
 
433
492
  export const getMessagesByIds = query({
434
- args: {
435
- messageIds: v.array(v.id("messages")),
436
- },
493
+ args: { messageIds: v.array(v.id("messages")) },
437
494
  handler: async (ctx, args) => {
438
495
  return (await Promise.all(args.messageIds.map((id) => ctx.db.get(id)))).map(
439
496
  (m) => (m ? publicMessage(m) : null),
@@ -6,12 +6,11 @@ import {
6
6
  vMessageStatus,
7
7
  vUsage,
8
8
  vSource,
9
- vLanguageModelV1CallWarning,
9
+ vLanguageModelCallWarning,
10
10
  vFinishReason,
11
11
  vProviderOptions,
12
12
  vProviderMetadata,
13
13
  vReasoningDetails,
14
- vTextStreamPart,
15
14
  } from "../validators.js";
16
15
  import { typedV } from "convex-helpers/validators";
17
16
  import vectorTables, { vVectorId } from "./vector/tables.js";
@@ -29,12 +28,8 @@ export const schema = defineSchema({
29
28
  order: /*DEPRECATED*/ v.optional(v.number()),
30
29
  })
31
30
  .index("userId", ["userId"])
32
- .searchIndex("title", {
33
- searchField: "title",
34
- filterFields: ["userId"],
35
- }),
31
+ .searchIndex("title", { searchField: "title", filterFields: ["userId"] }),
36
32
  messages: defineTable({
37
- id: v.optional(v.string()), // external id, e.g. from Vercel AI SDK
38
33
  userId: v.optional(v.string()), // useful for searching across threads
39
34
  threadId: v.id("threads"),
40
35
  order: v.number(),
@@ -60,11 +55,13 @@ export const schema = defineSchema({
60
55
  usage: v.optional(vUsage),
61
56
  providerMetadata: v.optional(vProviderMetadata), // Received from model
62
57
  sources: v.optional(v.array(vSource)),
58
+ warnings: v.optional(v.array(vLanguageModelCallWarning)),
59
+ finishReason: v.optional(vFinishReason),
60
+ // Likely deprecated soon
63
61
  reasoning: v.optional(v.string()),
64
62
  reasoningDetails: v.optional(vReasoningDetails),
65
- warnings: v.optional(v.array(vLanguageModelV1CallWarning)),
66
- 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
@@ -135,7 +129,7 @@ export const schema = defineSchema({
135
129
  // the indexes work like: 0 <first> 1 <second> 2 <third> 3 ...
136
130
  start: v.number(), // inclusive
137
131
  end: v.number(), // exclusive
138
- parts: v.array(vTextStreamPart),
132
+ parts: v.array(v.any()),
139
133
  }).index("streamId_start_end", ["streamId", "start", "end"]),
140
134
 
141
135
  memories: defineTable({
@@ -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: v.optional(v.string()),
167
- }).index("name", ["name"]),
159
+ apiKeys: defineTable({ name: v.optional(v.string()) }).index("name", [
160
+ "name",
161
+ ]),
168
162
  });
169
163
 
170
164
  export const vv = typedV(schema);