@convex-dev/agent 0.6.3 → 0.6.4

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 (71) hide show
  1. package/dist/UIMessages.d.ts.map +1 -1
  2. package/dist/UIMessages.js.map +1 -1
  3. package/dist/client/definePlaygroundAPI.d.ts +69 -64
  4. package/dist/client/definePlaygroundAPI.d.ts.map +1 -1
  5. package/dist/client/definePlaygroundAPI.js +8 -5
  6. package/dist/client/definePlaygroundAPI.js.map +1 -1
  7. package/dist/client/index.d.ts +12 -1
  8. package/dist/client/index.d.ts.map +1 -1
  9. package/dist/client/index.js +11 -2
  10. package/dist/client/index.js.map +1 -1
  11. package/dist/client/saveInputMessages.d.ts.map +1 -1
  12. package/dist/client/saveInputMessages.js.map +1 -1
  13. package/dist/client/types.d.ts.map +1 -1
  14. package/dist/component/apiKeys.js +5 -5
  15. package/dist/component/apiKeys.js.map +1 -1
  16. package/dist/component/files.d.ts.map +1 -1
  17. package/dist/component/files.js +13 -11
  18. package/dist/component/files.js.map +1 -1
  19. package/dist/component/messages.d.ts.map +1 -1
  20. package/dist/component/messages.js +37 -27
  21. package/dist/component/messages.js.map +1 -1
  22. package/dist/component/streams.d.ts.map +1 -1
  23. package/dist/component/streams.js +22 -17
  24. package/dist/component/streams.js.map +1 -1
  25. package/dist/component/threads.js +7 -7
  26. package/dist/component/threads.js.map +1 -1
  27. package/dist/component/users.js +2 -2
  28. package/dist/component/users.js.map +1 -1
  29. package/dist/component/vector/index.d.ts.map +1 -1
  30. package/dist/component/vector/index.js +14 -8
  31. package/dist/component/vector/index.js.map +1 -1
  32. package/dist/deltas.d.ts +16 -27
  33. package/dist/deltas.d.ts.map +1 -1
  34. package/dist/deltas.js +269 -286
  35. package/dist/deltas.js.map +1 -1
  36. package/dist/mapping.d.ts +9 -3
  37. package/dist/mapping.d.ts.map +1 -1
  38. package/dist/mapping.js +16 -14
  39. package/dist/mapping.js.map +1 -1
  40. package/dist/react/useStreamingUIMessages.d.ts.map +1 -1
  41. package/dist/react/useStreamingUIMessages.js +42 -26
  42. package/dist/react/useStreamingUIMessages.js.map +1 -1
  43. package/dist/react/useUIMessages.d.ts +1 -0
  44. package/dist/react/useUIMessages.d.ts.map +1 -1
  45. package/dist/react/useUIMessages.js +7 -3
  46. package/dist/react/useUIMessages.js.map +1 -1
  47. package/package.json +2 -1
  48. package/src/UIMessages.ts +1 -2
  49. package/src/client/approval.test.ts +25 -6
  50. package/src/client/createTool.ts +1 -1
  51. package/src/client/definePlaygroundAPI.ts +33 -17
  52. package/src/client/index.test.ts +91 -0
  53. package/src/client/index.ts +25 -1
  54. package/src/client/saveInputMessages.ts +4 -1
  55. package/src/client/streaming.integration.test.ts +39 -117
  56. package/src/client/types.ts +4 -17
  57. package/src/component/apiKeys.ts +5 -5
  58. package/src/component/files.test.ts +1 -1
  59. package/src/component/files.ts +14 -12
  60. package/src/component/messages.ts +40 -28
  61. package/src/component/streams.ts +33 -17
  62. package/src/component/threads.ts +7 -7
  63. package/src/component/users.ts +2 -2
  64. package/src/component/vector/index.ts +14 -7
  65. package/src/deltas.test.ts +373 -392
  66. package/src/deltas.ts +339 -378
  67. package/src/mapping.test.ts +296 -18
  68. package/src/mapping.ts +17 -11
  69. package/src/react/useStreamingUIMessages.ts +62 -34
  70. package/src/react/useUIMessages.test.ts +80 -1
  71. package/src/react/useUIMessages.ts +11 -3
@@ -34,6 +34,7 @@ import {
34
34
  import { schema, v } from "./schema.js";
35
35
  import { insertVector, searchVectors } from "./vector/index.js";
36
36
  import {
37
+ getVectorIdInfo,
37
38
  validateVectorDimension,
38
39
  type VectorTableId,
39
40
  vVectorId,
@@ -50,9 +51,10 @@ export async function deleteMessage(
50
51
  ctx: MutationCtx,
51
52
  messageDoc: Doc<"messages">,
52
53
  ) {
53
- await ctx.db.delete(messageDoc._id);
54
+ await ctx.db.delete("messages", messageDoc._id);
54
55
  if (messageDoc.embeddingId) {
55
- await ctx.db.delete(messageDoc.embeddingId);
56
+ const { tableName } = getVectorIdInfo(ctx, messageDoc.embeddingId);
57
+ await ctx.db.delete(tableName, messageDoc.embeddingId);
56
58
  }
57
59
  if (messageDoc.fileIds) {
58
60
  await changeRefcount(ctx, messageDoc.fileIds, []);
@@ -65,7 +67,7 @@ export const deleteByIds = mutation({
65
67
  handler: async (ctx, args) => {
66
68
  const deletedMessageIds = await Promise.all(
67
69
  args.messageIds.map(async (id) => {
68
- const message = await ctx.db.get(id);
70
+ const message = await ctx.db.get("messages", id);
69
71
  if (message) {
70
72
  await deleteMessage(ctx, message);
71
73
  return id;
@@ -157,7 +159,7 @@ async function addMessagesHandler(
157
159
  let userId = args.userId;
158
160
  const threadId = args.threadId;
159
161
  if (!userId && args.threadId) {
160
- const thread = await ctx.db.get(args.threadId);
162
+ const thread = await ctx.db.get("threads", args.threadId);
161
163
  assert(thread, `Thread ${args.threadId} not found`);
162
164
  userId = thread.userId;
163
165
  }
@@ -172,7 +174,8 @@ async function addMessagesHandler(
172
174
  hideFromUserIdSearch,
173
175
  ...rest
174
176
  } = args;
175
- const promptMessage = promptMessageId && (await ctx.db.get(promptMessageId));
177
+ const promptMessage =
178
+ promptMessageId && (await ctx.db.get("messages", promptMessageId));
176
179
  if (failPendingSteps) {
177
180
  assert(args.threadId, "threadId is required to fail pending steps");
178
181
  const pendingMessages = await ctx.db
@@ -188,9 +191,10 @@ async function addMessagesHandler(
188
191
  .filter((m) => !pendingMessageId || m._id !== pendingMessageId)
189
192
  .map(async (m) => {
190
193
  if (m.embeddingId) {
191
- await ctx.db.delete(m.embeddingId);
194
+ const { tableName } = getVectorIdInfo(ctx, m.embeddingId);
195
+ await ctx.db.delete(tableName, m.embeddingId);
192
196
  }
193
- await ctx.db.patch(m._id, {
197
+ await ctx.db.patch("messages", m._id, {
194
198
  status: "failed",
195
199
  error: "Restarting",
196
200
  embeddingId: undefined,
@@ -257,7 +261,7 @@ async function addMessagesHandler(
257
261
  // If there is a pending message, we replace that one with the first message
258
262
  // and subsequent ones will follow the regular order/subOrder advancement.
259
263
  if (i === 0 && pendingMessageId) {
260
- const pendingMessage = await ctx.db.get(pendingMessageId);
264
+ const pendingMessage = await ctx.db.get("messages", pendingMessageId);
261
265
  assert(pendingMessage, `Pending msg ${pendingMessageId} not found`);
262
266
  if (pendingMessage.status === "failed") {
263
267
  fail = true;
@@ -274,12 +278,12 @@ async function addMessagesHandler(
274
278
  message.fileIds,
275
279
  );
276
280
  }
277
- await ctx.db.replace(pendingMessage._id, {
281
+ await ctx.db.replace("messages", pendingMessage._id, {
278
282
  ...messageDoc,
279
283
  order: pendingMessage.order,
280
284
  stepOrder: pendingMessage.stepOrder,
281
285
  });
282
- toReturn.push((await ctx.db.get(pendingMessage._id))!);
286
+ toReturn.push((await ctx.db.get("messages", pendingMessage._id))!);
283
287
  continue;
284
288
  }
285
289
  if (message.message.role === "user") {
@@ -306,7 +310,7 @@ async function addMessagesHandler(
306
310
  await changeRefcount(ctx, [], message.fileIds);
307
311
  }
308
312
  // TODO: delete the associated stream data for the order/stepOrder
309
- toReturn.push((await ctx.db.get(messageId))!);
313
+ toReturn.push((await ctx.db.get("messages", messageId))!);
310
314
  }
311
315
  // Atomically finish the stream if requested, preventing UI flickering
312
316
  // from separate mutations for message save and stream finish (issue #181).
@@ -375,7 +379,7 @@ export const finalizeMessage = mutation({
375
379
  },
376
380
  returns: v.null(),
377
381
  handler: async (ctx, { messageId, result }) => {
378
- const message = await ctx.db.get(messageId);
382
+ const message = await ctx.db.get("messages", messageId);
379
383
  assert(message, `Message ${messageId} not found`);
380
384
  if (message.status !== "pending") {
381
385
  console.debug(
@@ -406,15 +410,16 @@ export const finalizeMessage = mutation({
406
410
  }
407
411
  if (result.status === "failed") {
408
412
  if (message.embeddingId) {
409
- await ctx.db.delete(message.embeddingId);
413
+ const { tableName } = getVectorIdInfo(ctx, message.embeddingId);
414
+ await ctx.db.delete(tableName, message.embeddingId);
410
415
  }
411
- await ctx.db.patch(messageId, {
416
+ await ctx.db.patch("messages", messageId, {
412
417
  status: "failed",
413
418
  error: result.error,
414
419
  embeddingId: undefined,
415
420
  });
416
421
  } else {
417
- await ctx.db.patch(messageId, { status: "success" });
422
+ await ctx.db.patch("messages", messageId, { status: "success" });
418
423
  }
419
424
  },
420
425
  });
@@ -439,7 +444,7 @@ export const updateMessage = mutation({
439
444
  },
440
445
  returns: vMessageDoc,
441
446
  handler: async (ctx, args) => {
442
- const message = await ctx.db.get(args.messageId);
447
+ const message = await ctx.db.get("messages", args.messageId);
443
448
  assert(message, `Message ${args.messageId} not found`);
444
449
 
445
450
  if (args.patch.fileIds) {
@@ -456,13 +461,14 @@ export const updateMessage = mutation({
456
461
 
457
462
  if (args.patch.status === "failed") {
458
463
  if (message.embeddingId) {
459
- await ctx.db.delete(message.embeddingId);
464
+ const { tableName } = getVectorIdInfo(ctx, message.embeddingId);
465
+ await ctx.db.delete(tableName, message.embeddingId);
460
466
  }
461
467
  patch.embeddingId = undefined;
462
468
  }
463
469
 
464
- await ctx.db.patch(args.messageId, patch);
465
- return publicMessage((await ctx.db.get(args.messageId))!);
470
+ await ctx.db.patch("messages", args.messageId, patch);
471
+ return publicMessage((await ctx.db.get("messages", args.messageId))!);
466
472
  },
467
473
  });
468
474
 
@@ -540,7 +546,8 @@ export const cloneMessageBatch = internalMutation({
540
546
  }
541
547
  let embeddingId: VectorTableId | undefined = undefined;
542
548
  if (m.embeddingId) {
543
- const vector = await ctx.db.get(m.embeddingId);
549
+ const { tableName } = getVectorIdInfo(ctx, m.embeddingId);
550
+ const vector = await ctx.db.get(tableName, m.embeddingId);
544
551
  assert(vector, `Vector ${m.embeddingId} not found`);
545
552
  const dimension = vector.vector.length;
546
553
  validateVectorDimension(dimension);
@@ -636,7 +643,7 @@ async function listMessagesByThreadIdHandler(
636
643
  const statuses = args.statuses ?? vMessageStatus.members.map((m) => m.value);
637
644
  const last =
638
645
  args.upToAndIncludingMessageId &&
639
- (await ctx.db.get(args.upToAndIncludingMessageId));
646
+ (await ctx.db.get("messages", args.upToAndIncludingMessageId));
640
647
  assert(
641
648
  !last || last.threadId === args.threadId,
642
649
  "upToAndIncludingMessageId must be a message in the thread",
@@ -679,9 +686,9 @@ async function listMessagesByThreadIdHandler(
679
686
  export const getMessagesByIds = query({
680
687
  args: { messageIds: v.array(v.id("messages")) },
681
688
  handler: async (ctx, args) => {
682
- return (await Promise.all(args.messageIds.map((id) => ctx.db.get(id)))).map(
683
- (m) => (m ? publicMessage(m) : null),
684
- );
689
+ return (
690
+ await Promise.all(args.messageIds.map((id) => ctx.db.get("messages", id)))
691
+ ).map((m) => (m ? publicMessage(m) : null));
685
692
  },
686
693
  returns: v.array(v.union(v.null(), vMessageDoc)),
687
694
  });
@@ -793,7 +800,8 @@ export const _fetchSearchMessages = internalQuery({
793
800
  returns: v.array(vMessageDoc),
794
801
  handler: async (ctx, args): Promise<MessageDoc[]> => {
795
802
  const beforeMessage =
796
- args.beforeMessageId && (await ctx.db.get(args.beforeMessageId));
803
+ args.beforeMessageId &&
804
+ (await ctx.db.get("messages", args.beforeMessageId));
797
805
  const { searchAllMessagesForUserId, threadId } = args;
798
806
  assert(
799
807
  searchAllMessagesForUserId || threadId,
@@ -809,6 +817,7 @@ export const _fetchSearchMessages = internalQuery({
809
817
  ? q.eq("embeddingId", embeddingId)
810
818
  : q.eq("embeddingId", embeddingId).eq("threadId", threadId!),
811
819
  )
820
+ // eslint-disable-next-line @convex-dev/no-filter-in-query -- We do not expect many messages with the same embeddingId for different users / threads
812
821
  .filter((q) =>
813
822
  q.and(
814
823
  q.eq(q.field("status"), "success"),
@@ -911,7 +920,8 @@ export const textSearch = query({
911
920
  "Specify userId or threadId",
912
921
  );
913
922
  const targetMessage =
914
- args.targetMessageId && (await ctx.db.get(args.targetMessageId));
923
+ args.targetMessageId &&
924
+ (await ctx.db.get("messages", args.targetMessageId));
915
925
  const order = targetMessage?.order;
916
926
  const text = args.text || targetMessage?.text;
917
927
  if (!text) {
@@ -926,6 +936,7 @@ export const textSearch = query({
926
936
  : q.search("text", text).eq("threadId", args.threadId!),
927
937
  )
928
938
  // Just in case tool messages slip through
939
+ // eslint-disable-next-line @convex-dev/no-filter-in-query -- we can't do this in the search index, but text search ideally isn't for really old orders
929
940
  .filter((q) => {
930
941
  const qq = q.eq(q.field("tool"), false);
931
942
  if (order) {
@@ -964,12 +975,13 @@ export const getMessageSearchFields = query({
964
975
  embedding?: number[] | undefined;
965
976
  embeddingModel?: string | undefined;
966
977
  }> => {
967
- const message = await ctx.db.get(args.messageId);
978
+ const message = await ctx.db.get("messages", args.messageId);
968
979
  const text = message?.text;
969
980
  let embedding = undefined;
970
981
  let embeddingModel = undefined;
971
982
  if (message?.embeddingId) {
972
- const target = await ctx.db.get(message.embeddingId);
983
+ const { tableName } = getVectorIdInfo(ctx, message.embeddingId);
984
+ const target = await ctx.db.get(tableName, message.embeddingId);
973
985
  embedding = target?.vector;
974
986
  embeddingModel = target?.model;
975
987
  }
@@ -38,7 +38,7 @@ export const addDelta = mutation({
38
38
  args: deltaValidator,
39
39
  returns: v.boolean(),
40
40
  handler: async (ctx, args) => {
41
- const stream = await ctx.db.get(args.streamId);
41
+ const stream = await ctx.db.get("streamingMessages", args.streamId);
42
42
  if (!stream) {
43
43
  console.warn("Stream not found", args.streamId);
44
44
  return false;
@@ -101,7 +101,9 @@ export const create = mutation({
101
101
  internal.streams.timeoutStream,
102
102
  { streamId },
103
103
  );
104
- await ctx.db.patch(streamId, { state: { ...state, timeoutFnId } });
104
+ await ctx.db.patch("streamingMessages", streamId, {
105
+ state: { ...state, timeoutFnId },
106
+ });
105
107
  return streamId;
106
108
  },
107
109
  });
@@ -197,7 +199,7 @@ async function abortById(
197
199
  finalDelta?: WithoutSystemFields<Doc<"streamDeltas">>;
198
200
  },
199
201
  ) {
200
- const stream = await ctx.db.get(args.streamId);
202
+ const stream = await ctx.db.get("streamingMessages", args.streamId);
201
203
  if (!stream) {
202
204
  throw new Error(`Stream not found: ${args.streamId}`);
203
205
  }
@@ -208,7 +210,7 @@ async function abortById(
208
210
  return false;
209
211
  }
210
212
  await cleanupTimeoutFn(ctx, stream);
211
- await ctx.db.patch(args.streamId, {
213
+ await ctx.db.patch("streamingMessages", args.streamId, {
212
214
  state: { kind: "aborted", reason: args.reason },
213
215
  });
214
216
  return true;
@@ -219,7 +221,10 @@ async function cleanupTimeoutFn(
219
221
  stream: Doc<"streamingMessages">,
220
222
  ) {
221
223
  if (stream.state.kind === "streaming" && stream.state.timeoutFnId) {
222
- const timeoutFn = await ctx.db.system.get(stream.state.timeoutFnId);
224
+ const timeoutFn = await ctx.db.system.get(
225
+ "_scheduled_functions",
226
+ stream.state.timeoutFnId,
227
+ );
223
228
  if (timeoutFn?.state.kind === "pending") {
224
229
  await ctx.scheduler.cancel(stream.state.timeoutFnId);
225
230
  }
@@ -246,7 +251,7 @@ export async function finishHandler(
246
251
  if (args.finalDelta) {
247
252
  await ctx.db.insert("streamDeltas", args.finalDelta);
248
253
  }
249
- const stream = await ctx.db.get(args.streamId);
254
+ const stream = await ctx.db.get("streamingMessages", args.streamId);
250
255
  if (!stream) {
251
256
  throw new Error(`Stream not found: ${args.streamId}`);
252
257
  }
@@ -262,7 +267,7 @@ export async function finishHandler(
262
267
  api.streams.deleteStreamAsync,
263
268
  { streamId: args.streamId },
264
269
  );
265
- await ctx.db.patch(args.streamId, {
270
+ await ctx.db.patch("streamingMessages", args.streamId, {
266
271
  state: { kind: "finished", endedAt: Date.now(), cleanupFnId },
267
272
  });
268
273
  }
@@ -279,7 +284,7 @@ async function heartbeatStream(
279
284
  ctx: MutationCtx,
280
285
  args: { streamId: Id<"streamingMessages"> },
281
286
  ): Promise<void> {
282
- const stream = await ctx.db.get(args.streamId);
287
+ const stream = await ctx.db.get("streamingMessages", args.streamId);
283
288
  if (!stream) {
284
289
  console.warn("Stream not found", args.streamId);
285
290
  return;
@@ -294,7 +299,10 @@ async function heartbeatStream(
294
299
  if (!stream.state.timeoutFnId) {
295
300
  throw new Error("Stream has no timeout function");
296
301
  }
297
- const timeoutFn = await ctx.db.system.get(stream.state.timeoutFnId);
302
+ const timeoutFn = await ctx.db.system.get(
303
+ "_scheduled_functions",
304
+ stream.state.timeoutFnId,
305
+ );
298
306
  if (!timeoutFn) {
299
307
  throw new Error("Timeout function not found");
300
308
  }
@@ -307,7 +315,7 @@ async function heartbeatStream(
307
315
  internal.streams.timeoutStream,
308
316
  { streamId: args.streamId },
309
317
  );
310
- await ctx.db.patch(args.streamId, {
318
+ await ctx.db.patch("streamingMessages", args.streamId, {
311
319
  state: { kind: "streaming", lastHeartbeat: Date.now(), timeoutFnId },
312
320
  });
313
321
  }
@@ -316,12 +324,12 @@ export const timeoutStream = internalMutation({
316
324
  args: { streamId: v.id("streamingMessages") },
317
325
  returns: v.null(),
318
326
  handler: async (ctx, args) => {
319
- const stream = await ctx.db.get(args.streamId);
327
+ const stream = await ctx.db.get("streamingMessages", args.streamId);
320
328
  if (!stream || stream.state.kind !== "streaming") {
321
329
  console.warn("Stream not found", args.streamId);
322
330
  return;
323
331
  }
324
- await ctx.db.patch(args.streamId, {
332
+ await ctx.db.patch("streamingMessages", args.streamId, {
325
333
  state: { kind: "aborted", reason: "timeout" },
326
334
  });
327
335
  },
@@ -338,15 +346,23 @@ async function deletePageForStreamId(
338
346
  numItems: MAX_DELTAS_PER_REQUEST,
339
347
  cursor: args.cursor ?? null,
340
348
  });
341
- await Promise.all(deltas.page.map((d) => ctx.db.delete(d._id)));
349
+ await Promise.all(
350
+ deltas.page.map((d) => ctx.db.delete("streamDeltas", d._id)),
351
+ );
342
352
  if (deltas.isDone) {
343
- const stream = await ctx.db.get(args.streamId);
353
+ const stream = await ctx.db.get("streamingMessages", args.streamId);
344
354
  if (stream) {
345
355
  await cleanupTimeoutFn(ctx, stream);
346
356
  if (stream.state.kind === "finished" && stream.state.cleanupFnId) {
347
- await ctx.scheduler.cancel(stream.state.cleanupFnId);
357
+ const scheduledFunction = await ctx.db.system.get(
358
+ "_scheduled_functions",
359
+ stream.state.cleanupFnId,
360
+ );
361
+ if (scheduledFunction?.state.kind === "pending") {
362
+ await ctx.scheduler.cancel(stream.state.cleanupFnId);
363
+ }
348
364
  }
349
- await ctx.db.delete(args.streamId);
365
+ await ctx.db.delete("streamingMessages", args.streamId);
350
366
  }
351
367
  }
352
368
  return deltas;
@@ -434,7 +450,7 @@ export const deleteAllStreamsForThreadIdAsync = mutation({
434
450
  },
435
451
  );
436
452
  } else {
437
- await ctx.db.delete(args.threadId);
453
+ await ctx.db.delete("threads", args.threadId);
438
454
  }
439
455
  return result;
440
456
  },
@@ -32,7 +32,7 @@ function publicThread(thread: Doc<"threads">): ThreadDoc {
32
32
  export const getThread = query({
33
33
  args: { threadId: v.id("threads") },
34
34
  handler: async (ctx, args) => {
35
- return publicThreadOrNull(await ctx.db.get(args.threadId));
35
+ return publicThreadOrNull(await ctx.db.get("threads", args.threadId));
36
36
  },
37
37
  returns: v.union(vThreadDoc, v.null()),
38
38
  });
@@ -66,7 +66,7 @@ export const createThread = mutation({
66
66
  ...args,
67
67
  status: "active",
68
68
  });
69
- return publicThread((await ctx.db.get(threadId))!);
69
+ return publicThread((await ctx.db.get("threads", threadId))!);
70
70
  },
71
71
  returns: vThreadDoc,
72
72
  });
@@ -84,10 +84,10 @@ export const updateThread = mutation({
84
84
  patch: v.object(partial(pick(vThread.fields, threadFieldsSupportingPatch))),
85
85
  },
86
86
  handler: async (ctx, args) => {
87
- const thread = await ctx.db.get(args.threadId);
87
+ const thread = await ctx.db.get("threads", args.threadId);
88
88
  assert(thread, `Thread ${args.threadId} not found`);
89
- await ctx.db.patch(args.threadId, args.patch);
90
- return publicThread((await ctx.db.get(args.threadId))!);
89
+ await ctx.db.patch("threads", args.threadId, args.patch);
90
+ return publicThread((await ctx.db.get("threads", args.threadId))!);
91
91
  },
92
92
  returns: vThreadDoc,
93
93
  });
@@ -231,9 +231,9 @@ async function deletePageForThreadIdHandler(
231
231
  });
232
232
  await Promise.all(messages.page.map((m) => deleteMessage(ctx, m)));
233
233
  if (messages.isDone) {
234
- const thread = await ctx.db.get(args.threadId);
234
+ const thread = await ctx.db.get("threads", args.threadId);
235
235
  if (thread) {
236
- await ctx.db.delete(args.threadId);
236
+ await ctx.db.delete("threads", args.threadId);
237
237
  }
238
238
  }
239
239
  return {
@@ -227,7 +227,7 @@ async function deletePageForUserId(
227
227
 
228
228
  if (streamResult.isDone) {
229
229
  // Streams are done, delete the thread and reset for next thread
230
- await ctx.db.delete(threadInProgress);
230
+ await ctx.db.delete("threads", threadInProgress);
231
231
  threadInProgress = null;
232
232
  messagesCursor = null;
233
233
  streamsInProgress = false;
@@ -256,7 +256,7 @@ export const getThreadUserId = internalQuery({
256
256
  },
257
257
  returns: v.union(v.string(), v.null()),
258
258
  handler: async (ctx, args) => {
259
- const thread = await ctx.db.get(args.threadId);
259
+ const thread = await ctx.db.get("threads", args.threadId);
260
260
  return thread?.userId ?? null;
261
261
  },
262
262
  });
@@ -11,6 +11,7 @@ import {
11
11
  import schema from "../schema.js";
12
12
  import {
13
13
  type EmbeddingsWithoutDenormalizedFields,
14
+ getVectorIdInfo,
14
15
  getVectorTableName,
15
16
  type VectorDimension,
16
17
  vEmbeddingsWithoutDenormalizedFields,
@@ -84,7 +85,7 @@ export const deleteBatchForThread = mutation({
84
85
  numItems: args.limit,
85
86
  maximumRowsRead: 300,
86
87
  });
87
- await Promise.all(vectors.page.map((v) => ctx.db.delete(v._id)));
88
+ await Promise.all(vectors.page.map((v) => ctx.db.delete(tableName, v._id)));
88
89
  return {
89
90
  isDone: vectors.isDone,
90
91
  continueCursor: vectors.continueCursor,
@@ -108,7 +109,7 @@ export const insertBatch = mutation({
108
109
  args.vectors.map(async ({ messageId, ...v }) => {
109
110
  const embeddingId = await insertVector(ctx, args.vectorDimension, v);
110
111
  if (messageId) {
111
- await ctx.db.patch(messageId, { embeddingId });
112
+ await ctx.db.patch("messages", messageId, { embeddingId });
112
113
  }
113
114
  return embeddingId;
114
115
  }),
@@ -180,12 +181,13 @@ export const updateBatch = mutation({
180
181
  returns: v.null(),
181
182
  handler: async (ctx, args) => {
182
183
  await Promise.all(
183
- args.vectors.map((embedding) =>
184
- ctx.db.patch(embedding.id, {
184
+ args.vectors.map((embedding) => {
185
+ const { tableName } = getVectorIdInfo(ctx, embedding.id);
186
+ return ctx.db.patch(tableName, embedding.id, {
185
187
  model: embedding.model,
186
188
  vector: embedding.vector,
187
- }),
188
- ),
189
+ });
190
+ }),
189
191
  );
190
192
  },
191
193
  });
@@ -196,6 +198,11 @@ export const deleteBatch = mutation({
196
198
  },
197
199
  returns: v.null(),
198
200
  handler: async (ctx, args) => {
199
- await Promise.all(args.ids.map((id) => ctx.db.delete(id)));
201
+ await Promise.all(
202
+ args.ids.map((id) => {
203
+ const { tableName } = getVectorIdInfo(ctx, id);
204
+ return ctx.db.delete(tableName, id);
205
+ }),
206
+ );
200
207
  },
201
208
  });