@convex-dev/agent 0.1.16-alpha.1 → 0.1.16-alpha.3

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 (59) hide show
  1. package/README.md +26 -15
  2. package/dist/client/createTool.d.ts +2 -2
  3. package/dist/client/createTool.d.ts.map +1 -1
  4. package/dist/client/createTool.js.map +1 -1
  5. package/dist/client/files.js +2 -2
  6. package/dist/client/files.js.map +1 -1
  7. package/dist/client/index.d.ts +12 -11
  8. package/dist/client/index.d.ts.map +1 -1
  9. package/dist/client/index.js +58 -36
  10. package/dist/client/index.js.map +1 -1
  11. package/dist/client/search.d.ts +2 -3
  12. package/dist/client/search.d.ts.map +1 -1
  13. package/dist/client/search.js +2 -1
  14. package/dist/client/search.js.map +1 -1
  15. package/dist/client/types.d.ts +7 -9
  16. package/dist/client/types.d.ts.map +1 -1
  17. package/dist/component/messages.d.ts +1 -1
  18. package/dist/component/messages.d.ts.map +1 -1
  19. package/dist/component/messages.js +5 -5
  20. package/dist/component/messages.js.map +1 -1
  21. package/dist/component/schema.d.ts.map +1 -1
  22. package/dist/component/schema.js.map +1 -1
  23. package/dist/mapping.d.ts.map +1 -1
  24. package/dist/mapping.js +3 -1
  25. package/dist/mapping.js.map +1 -1
  26. package/dist/validators.js +1 -2
  27. package/dist/validators.js.map +1 -1
  28. package/package.json +1 -1
  29. package/src/client/createTool.ts +9 -6
  30. package/src/client/files.ts +8 -8
  31. package/src/client/index.test.ts +14 -12
  32. package/src/client/index.ts +156 -116
  33. package/src/client/listMessages.ts +1 -1
  34. package/src/client/search.ts +14 -14
  35. package/src/client/streaming.ts +7 -7
  36. package/src/client/types.ts +29 -23
  37. package/src/component/apiKeys.ts +1 -1
  38. package/src/component/files.test.ts +1 -1
  39. package/src/component/files.ts +6 -6
  40. package/src/component/messages.test.ts +6 -6
  41. package/src/component/messages.ts +44 -43
  42. package/src/component/schema.ts +1 -2
  43. package/src/component/streams.ts +27 -27
  44. package/src/component/threads.test.ts +4 -4
  45. package/src/component/threads.ts +4 -4
  46. package/src/component/users.test.ts +2 -2
  47. package/src/component/users.ts +4 -4
  48. package/src/component/vector/index.ts +11 -11
  49. package/src/component/vector/tables.ts +6 -6
  50. package/src/mapping.test.ts +4 -4
  51. package/src/mapping.ts +18 -17
  52. package/src/react/deltas.test.ts +16 -16
  53. package/src/react/deltas.ts +13 -13
  54. package/src/react/index.ts +11 -11
  55. package/src/react/optimisticallySendMessage.ts +2 -2
  56. package/src/react/toUIMessages.test.ts +10 -10
  57. package/src/react/toUIMessages.ts +6 -6
  58. package/src/react/useSmoothText.ts +6 -6
  59. package/src/validators.ts +24 -24
@@ -13,7 +13,13 @@ import type {
13
13
  ToolSet,
14
14
  UserContent,
15
15
  } from "ai";
16
- import { generateObject, generateText, streamObject, streamText } from "ai";
16
+ import {
17
+ embedMany,
18
+ generateObject,
19
+ generateText,
20
+ streamObject,
21
+ streamText,
22
+ } from "ai";
17
23
  import { assert } from "convex-helpers";
18
24
  import {
19
25
  internalActionGeneric,
@@ -76,6 +82,7 @@ import type {
76
82
  TextArgs,
77
83
  Thread,
78
84
  UsageHandler,
85
+ UserActionCtx,
79
86
  } from "./types.js";
80
87
 
81
88
  export { vMessageDoc, vThreadDoc } from "../component/schema.js";
@@ -192,7 +199,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
192
199
  * log the raw request body or response headers to a table, or logs.
193
200
  */
194
201
  rawRequestResponseHandler?: RawRequestResponseHandler;
195
- }
202
+ },
196
203
  ) {}
197
204
 
198
205
  /**
@@ -212,7 +219,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
212
219
  * The userId to associate with the thread. If not provided, the thread will be
213
220
  * anonymous.
214
221
  */
215
- userId?: string;
222
+ userId?: string | null;
216
223
  /**
217
224
  * The title of the thread. Not currently used for anything.
218
225
  */
@@ -231,7 +238,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
231
238
  * Overrides any tools passed in the agent constructor.
232
239
  */
233
240
  tools?: ThreadTools;
234
- }
241
+ },
235
242
  ): Promise<{
236
243
  threadId: string;
237
244
  thread: Thread<ThreadTools extends undefined ? AgentTools : ThreadTools>;
@@ -252,7 +259,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
252
259
  * The userId to associate with the thread. If not provided, the thread will be
253
260
  * anonymous.
254
261
  */
255
- userId?: string;
262
+ userId?: string | null;
256
263
  /**
257
264
  * The title of the thread. Not currently used for anything.
258
265
  */
@@ -271,25 +278,25 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
271
278
  * Overrides any tools passed in the agent constructor.
272
279
  */
273
280
  tools?: ThreadTools;
274
- }
281
+ },
275
282
  ): Promise<{
276
283
  threadId: string;
277
284
  }>;
278
285
  async createThread<ThreadTools extends ToolSet | undefined = undefined>(
279
286
  ctx: ActionCtx | RunMutationCtx,
280
287
  args?: {
281
- userId: string;
288
+ userId: string | null;
282
289
  title?: string;
283
290
  summary?: string;
284
291
  usageHandler?: UsageHandler;
285
292
  tools?: ThreadTools;
286
- }
293
+ },
287
294
  ): Promise<{
288
295
  threadId: string;
289
296
  thread?: Thread<ThreadTools extends undefined ? AgentTools : ThreadTools>;
290
297
  }> {
291
298
  const threadId = await createThread(ctx, this.component, args);
292
- if (!("runAction" in ctx)) {
299
+ if (!("runAction" in ctx) || "workflowId" in ctx) {
293
300
  return { threadId };
294
301
  }
295
302
  const { thread } = await this.continueThread(ctx, {
@@ -323,7 +330,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
323
330
  * If supplied, the userId can be used to search across other threads for
324
331
  * relevant messages from the same user as context for the LLM calls.
325
332
  */
326
- userId?: string;
333
+ userId?: string | null;
327
334
  /**
328
335
  * The usage handler to use for this thread. Overrides any handler
329
336
  * set in the agent constructor.
@@ -334,7 +341,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
334
341
  * Overrides any tools passed in the agent constructor.
335
342
  */
336
343
  tools?: ThreadTools;
337
- }
344
+ },
338
345
  ): Promise<{
339
346
  thread: Thread<ThreadTools extends undefined ? AgentTools : ThreadTools>;
340
347
  }> {
@@ -372,7 +379,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
372
379
  userId?: string | undefined;
373
380
  query: string;
374
381
  limit?: number;
375
- }
382
+ },
376
383
  ): Promise<ThreadDoc[]> {
377
384
  return ctx.runQuery(this.component.threads.searchThreadTitles, {
378
385
  userId,
@@ -405,7 +412,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
405
412
  usageHandler,
406
413
  tools: threadTools,
407
414
  }: {
408
- userId?: string;
415
+ userId?: string | null;
409
416
  threadId?: string;
410
417
  /**
411
418
  * The usage handler to use for this thread. Overrides any handler
@@ -416,24 +423,30 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
416
423
  tools?: ToolSet;
417
424
  },
418
425
  args: TextArgs<AgentTools, TOOLS, OUTPUT, OUTPUT_PARTIAL>,
419
- options?: Options
426
+ options?: Options,
420
427
  ): Promise<
421
428
  GenerateTextResult<TOOLS extends undefined ? AgentTools : TOOLS, OUTPUT> &
422
429
  GenerationOutputMetadata
423
430
  > {
424
431
  const context = await this._saveMessagesAndFetchContext(ctx, args, {
425
- userId: argsUserId,
432
+ userId: argsUserId ?? undefined,
426
433
  threadId,
427
434
  ...options,
428
435
  });
429
436
  const { args: aiArgs, messageId, order, userId } = context;
430
- const toolCtx = { ...ctx, userId, threadId, messageId, agent: this };
437
+ const toolCtx = {
438
+ ...(ctx as UserActionCtx),
439
+ userId,
440
+ threadId,
441
+ messageId,
442
+ agent: this,
443
+ };
431
444
  const tools = wrapTools(
432
445
  toolCtx,
433
- args.tools ?? threadTools ?? this.options.tools
446
+ args.tools ?? threadTools ?? this.options.tools,
434
447
  ) as TOOLS extends undefined ? AgentTools : TOOLS;
435
448
  const saveOutputMessages = this._shouldSaveOutputMessages(
436
- options?.storageOptions
449
+ options?.storageOptions,
437
450
  );
438
451
  const trackUsage = usageHandler ?? this.options.usageHandler;
439
452
  try {
@@ -515,7 +528,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
515
528
  /** Note: to get better type inference, pass tools in the next arg */
516
529
  tools: threadTools,
517
530
  }: {
518
- userId?: string;
531
+ userId?: string | null;
519
532
  threadId?: string;
520
533
  usageHandler?: UsageHandler;
521
534
  tools?: ToolSet;
@@ -540,7 +553,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
540
553
  * iterating over the text, streaming it over HTTP, etc.
541
554
  */
542
555
  saveStreamDeltas?: boolean | StreamingOptions;
543
- }
556
+ },
544
557
  ): Promise<
545
558
  StreamTextResult<
546
559
  TOOLS extends undefined ? AgentTools : TOOLS,
@@ -549,18 +562,24 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
549
562
  GenerationOutputMetadata
550
563
  > {
551
564
  const context = await this._saveMessagesAndFetchContext(ctx, args, {
552
- userId: argsUserId,
565
+ userId: argsUserId ?? undefined,
553
566
  threadId,
554
567
  ...options,
555
568
  });
556
569
  const { args: aiArgs, messageId, order, stepOrder, userId } = context;
557
- const toolCtx = { ...ctx, userId, threadId, messageId, agent: this };
570
+ const toolCtx = {
571
+ ...(ctx as UserActionCtx),
572
+ userId,
573
+ threadId,
574
+ messageId,
575
+ agent: this,
576
+ };
558
577
  const tools = wrapTools(
559
578
  toolCtx,
560
- args.tools ?? threadTools ?? this.options.tools
579
+ args.tools ?? threadTools ?? this.options.tools,
561
580
  ) as TOOLS extends undefined ? AgentTools : TOOLS;
562
581
  const saveOutputMessages = this._shouldSaveOutputMessages(
563
- options?.storageOptions
582
+ options?.storageOptions,
564
583
  );
565
584
  const trackUsage = usageHandler ?? this.options.usageHandler;
566
585
  const streamer =
@@ -586,7 +605,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
586
605
  abortSignal: streamer?.abortController.signal ?? aiArgs.abortSignal,
587
606
  experimental_transform: mergeTransforms(
588
607
  options?.saveStreamDeltas,
589
- args.experimental_transform
608
+ args.experimental_transform,
590
609
  ),
591
610
  onChunk: async (event) => {
592
611
  await streamer?.addParts([event.chunk]);
@@ -662,7 +681,11 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
662
681
  userId: argsUserId,
663
682
  threadId,
664
683
  usageHandler,
665
- }: { userId?: string; threadId?: string; usageHandler?: UsageHandler },
684
+ }: {
685
+ userId?: string | null;
686
+ threadId?: string;
687
+ usageHandler?: UsageHandler;
688
+ },
666
689
  /**
667
690
  * The arguments to the generateObject function, similar to the ai.generateObject function.
668
691
  */
@@ -671,22 +694,22 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
671
694
  * The {@link ContextOptions} and {@link StorageOptions}
672
695
  * options to use for fetching contextual messages and saving input/output messages.
673
696
  */
674
- options?: Options
697
+ options?: Options,
675
698
  ): Promise<GenerateObjectResult<T> & GenerationOutputMetadata> {
676
699
  const context = await this._saveMessagesAndFetchContext(ctx, args, {
677
- userId: argsUserId,
700
+ userId: argsUserId ?? undefined,
678
701
  threadId,
679
702
  ...options,
680
703
  });
681
704
  const { args: aiArgs, messageId, order, userId } = context;
682
705
  const trackUsage = usageHandler ?? this.options.usageHandler;
683
706
  const saveOutputMessages = this._shouldSaveOutputMessages(
684
- options?.storageOptions
707
+ options?.storageOptions,
685
708
  );
686
709
  try {
687
710
  const result = (await generateObject(
688
711
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
689
- aiArgs as any
712
+ aiArgs as any,
690
713
  )) as GenerateObjectResult<T> & GenerationOutputMetadata;
691
714
 
692
715
  if (threadId && messageId && saveOutputMessages) {
@@ -746,7 +769,11 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
746
769
  userId: argsUserId,
747
770
  threadId,
748
771
  usageHandler,
749
- }: { userId?: string; threadId?: string; usageHandler?: UsageHandler },
772
+ }: {
773
+ userId?: string | null;
774
+ threadId?: string;
775
+ usageHandler?: UsageHandler;
776
+ },
750
777
  /**
751
778
  * The arguments to the streamObject function, similar to the ai `streamObject` function.
752
779
  */
@@ -755,20 +782,20 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
755
782
  * The {@link ContextOptions} and {@link StorageOptions}
756
783
  * options to use for fetching contextual messages and saving input/output messages.
757
784
  */
758
- options?: Options
785
+ options?: Options,
759
786
  ): Promise<
760
787
  StreamObjectResult<DeepPartial<T>, T, never> & GenerationOutputMetadata
761
788
  > {
762
789
  // TODO: unify all this shared code between all the generate* and stream* functions
763
790
  const context = await this._saveMessagesAndFetchContext(ctx, args, {
764
- userId: argsUserId,
791
+ userId: argsUserId ?? undefined,
765
792
  threadId,
766
793
  ...options,
767
794
  });
768
795
  const { args: aiArgs, messageId, order, userId } = context;
769
796
  const trackUsage = usageHandler ?? this.options.usageHandler;
770
797
  const saveOutputMessages = this._shouldSaveOutputMessages(
771
- options?.storageOptions
798
+ options?.storageOptions,
772
799
  );
773
800
  const stream = streamObject<T>({
774
801
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -847,7 +874,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
847
874
  * action later that calls `agent.generateAndSaveEmbeddings`.
848
875
  */
849
876
  skipEmbeddings?: boolean;
850
- }
877
+ },
851
878
  ) {
852
879
  const { lastMessageId, messages } = await this.saveMessages(ctx, {
853
880
  threadId: args.threadId,
@@ -886,7 +913,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
886
913
  * action later that calls `agent.generateAndSaveEmbeddings`.
887
914
  */
888
915
  skipEmbeddings?: boolean;
889
- }
916
+ },
890
917
  ): Promise<{
891
918
  lastMessageId: string;
892
919
  messages: MessageDoc[];
@@ -900,25 +927,31 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
900
927
  const { skipEmbeddings, ...rest } = args;
901
928
  if (args.embeddings) {
902
929
  embeddings = args.embeddings;
903
- } else if (skipEmbeddings || !("runAction" in ctx)) {
904
- embeddings = undefined;
905
- if (!skipEmbeddings && this.options.textEmbedding) {
930
+ } else if (!skipEmbeddings && this.options.textEmbedding) {
931
+ if (!("runAction" in ctx)) {
906
932
  console.warn(
907
933
  "You're trying to save messages and generate embeddings, but you're in a mutation. " +
908
934
  "Pass `skipEmbeddings: true` to skip generating embeddings in the mutation and skip this warning. " +
909
935
  "They will be generated lazily when you generate or stream text / objects. " +
910
- "You can explicitly generate them asynchronously by using the scheduler to run an action later that calls `agent.generateAndSaveEmbeddings`."
936
+ "You can explicitly generate them asynchronously by using the scheduler to run an action later that calls `agent.generateAndSaveEmbeddings`.",
937
+ );
938
+ } else if ("workflowId" in ctx) {
939
+ console.warn(
940
+ "You're trying to save messages and generate embeddings, but you're in a workflow. " +
941
+ "Pass `skipEmbeddings: true` to skip generating embeddings in the workflow and skip this warning. " +
942
+ "They will be generated lazily when you generate or stream text / objects. " +
943
+ "You can explicitly generate them asynchronously by using the scheduler to run an action later that calls `agent.generateAndSaveEmbeddings`.",
944
+ );
945
+ } else {
946
+ embeddings = await this.generateEmbeddings(
947
+ ctx,
948
+ {
949
+ userId: args.userId ?? undefined,
950
+ threadId: args.threadId,
951
+ },
952
+ args.messages,
911
953
  );
912
954
  }
913
- } else {
914
- embeddings = await this.generateEmbeddings(
915
- ctx,
916
- {
917
- userId: args.userId,
918
- threadId: args.threadId,
919
- },
920
- args.messages
921
- );
922
955
  }
923
956
  return saveMessages(ctx, this.component, {
924
957
  ...rest,
@@ -944,7 +977,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
944
977
  paginationOpts: PaginationOptions;
945
978
  excludeToolMessages?: boolean;
946
979
  statuses?: MessageStatus[];
947
- }
980
+ },
948
981
  ): Promise<PaginationResult<MessageDoc>> {
949
982
  return listMessages(ctx, this.component, args);
950
983
  }
@@ -964,7 +997,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
964
997
  streamArgs: StreamArgs | undefined;
965
998
  // By default, only streaming messages are included.
966
999
  includeStatuses?: ("streaming" | "finished" | "aborted")[];
967
- }
1000
+ },
968
1001
  ): Promise<SyncStreamsReturnValue | undefined> {
969
1002
  return syncStreams(ctx, this.component, args);
970
1003
  }
@@ -990,7 +1023,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
990
1023
  */
991
1024
  upToAndIncludingMessageId?: string;
992
1025
  contextOptions: ContextOptions | undefined;
993
- }
1026
+ },
994
1027
  ): Promise<MessageDoc[]> {
995
1028
  assert(args.userId || args.threadId, "Specify userId or threadId");
996
1029
  const opts = this._mergedContextOptions(args.contextOptions);
@@ -1001,17 +1034,17 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1001
1034
  assert("runAction" in ctx);
1002
1035
  assert(
1003
1036
  this.options.textEmbedding,
1004
- "A textEmbedding model is required to be set on the Agent that you're doing vector search with"
1037
+ "A textEmbedding model is required to be set on the Agent that you're doing vector search with",
1005
1038
  );
1006
1039
  return {
1007
- vector: (
1040
+ embedding: (
1008
1041
  await this.doEmbed(ctx, {
1009
1042
  userId: args.userId,
1010
1043
  threadId: args.threadId,
1011
1044
  values: [text],
1012
1045
  })
1013
1046
  ).embeddings[0],
1014
- vectorModel: this.options.textEmbedding.modelId,
1047
+ embeddingModel: this.options.textEmbedding.modelId,
1015
1048
  };
1016
1049
  },
1017
1050
  });
@@ -1025,7 +1058,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1025
1058
  */
1026
1059
  async getThreadMetadata(
1027
1060
  ctx: RunQueryCtx,
1028
- args: { threadId: string }
1061
+ args: { threadId: string },
1029
1062
  ): Promise<ThreadDoc> {
1030
1063
  return getThreadMetadata(ctx, this.component, args);
1031
1064
  }
@@ -1044,11 +1077,11 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1044
1077
  patch: Partial<
1045
1078
  Pick<ThreadDoc, (typeof threadFieldsSupportingPatch)[number]>
1046
1079
  >;
1047
- }
1080
+ },
1048
1081
  ): Promise<ThreadDoc> {
1049
1082
  const thread = await ctx.runMutation(
1050
1083
  this.component.threads.updateThread,
1051
- args
1084
+ args,
1052
1085
  );
1053
1086
  return thread;
1054
1087
  }
@@ -1067,7 +1100,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1067
1100
  userId: string | undefined;
1068
1101
  threadId: string | undefined;
1069
1102
  },
1070
- messages: CoreMessage[]
1103
+ messages: CoreMessage[],
1071
1104
  ) {
1072
1105
  if (!this.options.textEmbedding) {
1073
1106
  return undefined;
@@ -1122,7 +1155,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1122
1155
  ctx: RunActionCtx,
1123
1156
  args: {
1124
1157
  messageIds: string[];
1125
- }
1158
+ },
1126
1159
  ) {
1127
1160
  const messages = (
1128
1161
  await ctx.runQuery(this.component.messages.getMessagesByIds, {
@@ -1134,16 +1167,20 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1134
1167
  "Some messages were not found: " +
1135
1168
  args.messageIds
1136
1169
  .filter((id) => !messages.some((m) => m?._id === id))
1137
- .join(", ")
1170
+ .join(", "),
1138
1171
  );
1139
1172
  }
1173
+ await this._generateAndSaveEmbeddings(ctx, messages);
1174
+ }
1175
+
1176
+ async _generateAndSaveEmbeddings(ctx: RunActionCtx, messages: MessageDoc[]) {
1140
1177
  if (messages.some((m) => !m.message)) {
1141
1178
  throw new Error(
1142
1179
  "Some messages don't have a message: " +
1143
- args.messageIds
1144
- .map((id, i) => (!messages[i].message ? id : undefined))
1145
- .filter((id): id is string => id !== undefined)
1146
- .join(", ")
1180
+ messages
1181
+ .filter((m) => !m.message)
1182
+ .map((m) => m._id)
1183
+ .join(", "),
1147
1184
  );
1148
1185
  }
1149
1186
  const messagesMissingEmbeddings = messages.filter((m) => !m.embeddingId);
@@ -1156,17 +1193,17 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1156
1193
  userId: messagesMissingEmbeddings[0]!.userId,
1157
1194
  threadId: messagesMissingEmbeddings[0]!.threadId,
1158
1195
  },
1159
- messagesMissingEmbeddings.map((m) => m!.message!)
1196
+ messagesMissingEmbeddings.map((m) => m!.message!),
1160
1197
  );
1161
1198
  if (!embeddings) {
1162
1199
  if (!this.options.textEmbedding) {
1163
1200
  throw new Error(
1164
- "No embeddings were generated for the messages. You must pass a textEmbedding model to the agent constructor."
1201
+ "No embeddings were generated for the messages. You must pass a textEmbedding model to the agent constructor.",
1165
1202
  );
1166
1203
  }
1167
1204
  throw new Error(
1168
1205
  "No embeddings were generated for these messages: " +
1169
- messagesMissingEmbeddings.map((m) => m!._id).join(", ")
1206
+ messagesMissingEmbeddings.map((m) => m!._id).join(", "),
1170
1207
  );
1171
1208
  }
1172
1209
  await ctx.runMutation(this.component.vector.index.insertBatch, {
@@ -1181,7 +1218,8 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1181
1218
  vector: embeddings.vectors[i],
1182
1219
  }))
1183
1220
  .filter(
1184
- (v): v is Extract<typeof v, { vector: number[] }> => v.vector !== null
1221
+ (v): v is Extract<typeof v, { vector: number[] }> =>
1222
+ v.vector !== null,
1185
1223
  ),
1186
1224
  });
1187
1225
  }
@@ -1214,7 +1252,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1214
1252
  * Defaults to the chat provider for the Agent.
1215
1253
  */
1216
1254
  provider?: string;
1217
- }
1255
+ },
1218
1256
  ): Promise<{ messages: MessageDoc[]; pending?: MessageDoc }> {
1219
1257
  const messages = await serializeNewMessagesInStep(
1220
1258
  ctx,
@@ -1223,12 +1261,12 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1223
1261
  {
1224
1262
  provider: args.provider ?? this.options.chat.provider,
1225
1263
  model: args.model ?? this.options.chat.modelId,
1226
- }
1264
+ },
1227
1265
  );
1228
1266
  const embeddings = await this.generateEmbeddings(
1229
1267
  ctx,
1230
1268
  { userId: args.userId, threadId: args.threadId },
1231
- messages.map((m) => m.message)
1269
+ messages.map((m) => m.message),
1232
1270
  );
1233
1271
  const saved = await ctx.runMutation(this.component.messages.addMessages, {
1234
1272
  userId: args.userId,
@@ -1259,7 +1297,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1259
1297
  provider: string | undefined;
1260
1298
  result: GenerateObjectResult<unknown>;
1261
1299
  metadata?: Omit<MessageWithMetadata, "message">;
1262
- }
1300
+ },
1263
1301
  ): Promise<void> {
1264
1302
  const { messages } = await serializeObjectResult(
1265
1303
  ctx,
@@ -1268,12 +1306,12 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1268
1306
  {
1269
1307
  model: args.model ?? this.options.chat.modelId,
1270
1308
  provider: args.provider ?? this.options.chat.provider,
1271
- }
1309
+ },
1272
1310
  );
1273
1311
  const embeddings = await this.generateEmbeddings(
1274
1312
  ctx,
1275
1313
  { userId: args.userId, threadId: args.threadId },
1276
- messages.map((m) => m.message)
1314
+ messages.map((m) => m.message),
1277
1315
  );
1278
1316
 
1279
1317
  await ctx.runMutation(this.component.messages.addMessages, {
@@ -1302,7 +1340,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1302
1340
  threadId: string;
1303
1341
  messageId: string;
1304
1342
  result: { kind: "error"; error: string } | { kind: "success" };
1305
- }
1343
+ },
1306
1344
  ): Promise<void> {
1307
1345
  const result = args.result;
1308
1346
  if (result.kind === "success") {
@@ -1346,12 +1384,12 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1346
1384
  */
1347
1385
  fileIds?: string[];
1348
1386
  };
1349
- }
1387
+ },
1350
1388
  ): Promise<void> {
1351
1389
  const { message, fileIds } = await serializeMessage(
1352
1390
  ctx,
1353
1391
  this.component,
1354
- args.patch.message
1392
+ args.patch.message,
1355
1393
  );
1356
1394
  await ctx.runMutation(this.component.messages.updateMessage, {
1357
1395
  messageId: args.messageId,
@@ -1376,7 +1414,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1376
1414
  ctx: RunMutationCtx,
1377
1415
  args: {
1378
1416
  messageIds: string[];
1379
- }
1417
+ },
1380
1418
  ): Promise<void> {
1381
1419
  await ctx.runMutation(this.component.messages.deleteByIds, args);
1382
1420
  }
@@ -1391,7 +1429,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1391
1429
  ctx: RunMutationCtx,
1392
1430
  args: {
1393
1431
  messageId: string;
1394
- }
1432
+ },
1395
1433
  ): Promise<void> {
1396
1434
  await ctx.runMutation(this.component.messages.deleteByIds, {
1397
1435
  messageIds: [args.messageId],
@@ -1443,7 +1481,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1443
1481
  startStepOrder?: number;
1444
1482
  endOrder: number;
1445
1483
  endStepOrder?: number;
1446
- }
1484
+ },
1447
1485
  ): Promise<void> {
1448
1486
  await ctx.runMutation(this.component.messages.deleteByOrder, {
1449
1487
  threadId: args.threadId,
@@ -1466,7 +1504,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1466
1504
  args: {
1467
1505
  threadId: string;
1468
1506
  pageSize?: number;
1469
- }
1507
+ },
1470
1508
  ): Promise<void> {
1471
1509
  await ctx.runMutation(this.component.threads.deleteAllForThreadIdAsync, {
1472
1510
  threadId: args.threadId,
@@ -1486,7 +1524,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1486
1524
  args: {
1487
1525
  threadId: string;
1488
1526
  pageSize?: number;
1489
- }
1527
+ },
1490
1528
  ): Promise<void> {
1491
1529
  await ctx.runAction(this.component.threads.deleteAllForThreadIdSync, {
1492
1530
  threadId: args.threadId,
@@ -1515,7 +1553,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1515
1553
  }: {
1516
1554
  userId: string | undefined;
1517
1555
  threadId: string | undefined;
1518
- } & Options
1556
+ } & Options,
1519
1557
  ): Promise<{
1520
1558
  args: T & { model: LanguageModelV1 };
1521
1559
  userId: string | undefined;
@@ -1570,7 +1608,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1570
1608
  userId,
1571
1609
  messages: coreMessages,
1572
1610
  metadata: coreMessages.map((_, i) =>
1573
- i === coreMessages.length - 1 ? { id: args.id } : {}
1611
+ i === coreMessages.length - 1 ? { id: args.id } : {},
1574
1612
  ),
1575
1613
  failPendingSteps: true,
1576
1614
  });
@@ -1585,9 +1623,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1585
1623
  // embeddings yet. This can happen if the message was saved in a mutation
1586
1624
  // where the LLM is not available.
1587
1625
  if (!promptMessage.embeddingId && this.options.textEmbedding) {
1588
- await this.generateAndSaveEmbeddings(ctx, {
1589
- messageIds: [promptMessage._id],
1590
- });
1626
+ await this._generateAndSaveEmbeddings(ctx, [promptMessage]);
1591
1627
  }
1592
1628
  }
1593
1629
 
@@ -1643,29 +1679,29 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1643
1679
  threadId: string | undefined;
1644
1680
  values: string[];
1645
1681
  abortSignal?: AbortSignal;
1646
- headers?: Record<string, string | undefined>;
1647
- }
1682
+ headers?: Record<string, string>;
1683
+ },
1648
1684
  ): Promise<{ embeddings: number[][] }> {
1649
- const embedding = this.options.textEmbedding;
1685
+ const embeddingModel = this.options.textEmbedding;
1650
1686
  assert(
1651
- embedding,
1652
- "a textEmbedding model is required to be set on the Agent that you're doing vector search with"
1687
+ embeddingModel,
1688
+ "a textEmbedding model is required to be set on the Agent that you're doing vector search with",
1653
1689
  );
1654
- const result = await embedding.doEmbed({
1690
+ const result = await embedMany({
1691
+ model: embeddingModel,
1655
1692
  values: options.values,
1656
1693
  abortSignal: options.abortSignal,
1657
1694
  headers: options.headers,
1695
+ maxRetries: this.options.maxRetries,
1658
1696
  });
1659
1697
  if (this.options.usageHandler && result.usage) {
1660
1698
  await this.options.usageHandler(ctx, {
1661
1699
  userId: options.userId,
1662
1700
  threadId: options.threadId,
1663
1701
  agentName: this.options.name,
1664
- model: embedding.modelId,
1665
- provider: embedding.provider,
1666
- providerMetadata: result.rawResponse
1667
- ? { [embedding.provider]: result.rawResponse }
1668
- : undefined,
1702
+ model: embeddingModel.modelId,
1703
+ provider: embeddingModel.provider,
1704
+ providerMetadata: undefined,
1669
1705
  usage: {
1670
1706
  promptTokens: result.usage.tokens,
1671
1707
  completionTokens: 0,
@@ -1682,7 +1718,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1682
1718
  * able to access localhost URLs.
1683
1719
  */
1684
1720
  private async _inlineMessagesFiles(
1685
- messages: CoreMessage[]
1721
+ messages: CoreMessage[],
1686
1722
  ): Promise<CoreMessage[]> {
1687
1723
  // Process each message to convert localhost URLs to base64
1688
1724
  return Promise.all(
@@ -1700,7 +1736,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1700
1736
  if (part.type === "image" && part.image instanceof URL) {
1701
1737
  assert(
1702
1738
  message.role === "user",
1703
- "Images can only be in user messages"
1739
+ "Images can only be in user messages",
1704
1740
  );
1705
1741
  if (this._isLocalhostUrl(part.image)) {
1706
1742
  const imageData = await this._downloadFile(part.image);
@@ -1723,7 +1759,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1723
1759
  }
1724
1760
 
1725
1761
  return part;
1726
- })
1762
+ }),
1727
1763
  );
1728
1764
  if (message.role === "user") {
1729
1765
  return {
@@ -1736,7 +1772,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1736
1772
  content: processedContent as AssistantContent,
1737
1773
  };
1738
1774
  }
1739
- })
1775
+ }),
1740
1776
  );
1741
1777
  }
1742
1778
 
@@ -1888,7 +1924,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1888
1924
  options?: {
1889
1925
  contextOptions?: ContextOptions;
1890
1926
  storageOptions?: StorageOptions;
1891
- }
1927
+ },
1892
1928
  ) {
1893
1929
  const maxSteps = spec?.maxSteps ?? this.options.maxSteps;
1894
1930
  return internalActionGeneric({
@@ -1912,7 +1948,7 @@ export class Agent<AgentTools extends ToolSet = ToolSet> {
1912
1948
  storageOptions ??
1913
1949
  options?.storageOptions ??
1914
1950
  this.options.storageOptions,
1915
- }
1951
+ },
1916
1952
  );
1917
1953
  return {
1918
1954
  object: value.object as T,
@@ -1983,14 +2019,18 @@ export async function createThread(
1983
2019
  ctx: RunMutationCtx,
1984
2020
  component: AgentComponent,
1985
2021
  args?: {
1986
- userId?: string;
2022
+ userId?: string | null;
1987
2023
  title?: string;
1988
2024
  summary?: string;
1989
- }
2025
+ },
1990
2026
  ) {
1991
2027
  const { _id: threadId } = await ctx.runMutation(
1992
2028
  component.threads.createThread,
1993
- { userId: args?.userId, title: args?.title, summary: args?.summary }
2029
+ {
2030
+ userId: args?.userId ?? undefined,
2031
+ title: args?.title,
2032
+ summary: args?.summary,
2033
+ },
1994
2034
  );
1995
2035
  return threadId;
1996
2036
  }
@@ -2004,7 +2044,7 @@ export async function createThread(
2004
2044
  export async function getThreadMetadata(
2005
2045
  ctx: RunQueryCtx,
2006
2046
  component: AgentComponent,
2007
- args: { threadId: string }
2047
+ args: { threadId: string },
2008
2048
  ): Promise<ThreadDoc> {
2009
2049
  const thread = await ctx.runQuery(component.threads.getThread, {
2010
2050
  threadId: args.threadId,
@@ -2017,7 +2057,7 @@ export async function getThreadMetadata(
2017
2057
 
2018
2058
  type SaveMessagesArgs = {
2019
2059
  threadId: string;
2020
- userId?: string;
2060
+ userId?: string | null;
2021
2061
  /**
2022
2062
  * The message that these messages are in response to. They will be
2023
2063
  * the same "order" as this message, at increasing stepOrder(s).
@@ -2060,7 +2100,7 @@ export async function saveMessages(
2060
2100
  * The agent name to associate with the messages.
2061
2101
  */
2062
2102
  agentName?: string;
2063
- }
2103
+ },
2064
2104
  ) {
2065
2105
  let embeddings: MessageEmbeddings | undefined;
2066
2106
  if (args.embeddings) {
@@ -2076,7 +2116,7 @@ export async function saveMessages(
2076
2116
  }
2077
2117
  const result = await ctx.runMutation(component.messages.addMessages, {
2078
2118
  threadId: args.threadId,
2079
- userId: args.userId,
2119
+ userId: args.userId ?? undefined,
2080
2120
  agentName: args.agentName,
2081
2121
  promptMessageId: args.promptMessageId,
2082
2122
  embeddings,
@@ -2088,7 +2128,7 @@ export async function saveMessages(
2088
2128
  message,
2089
2129
  fileIds,
2090
2130
  } as MessageWithMetadata;
2091
- })
2131
+ }),
2092
2132
  ),
2093
2133
  failPendingSteps: args.failPendingSteps ?? false,
2094
2134
  pending: args.pending ?? false,
@@ -2101,7 +2141,7 @@ export async function saveMessages(
2101
2141
 
2102
2142
  type SaveMessageArgs = {
2103
2143
  threadId: string;
2104
- userId?: string;
2144
+ userId?: string | null;
2105
2145
  /**
2106
2146
  * Metadata to save with the messages. Each element corresponds to the
2107
2147
  * message at the same index.
@@ -2146,7 +2186,7 @@ export async function saveMessage(
2146
2186
  * The agent name to associate with the message.
2147
2187
  */
2148
2188
  agentName?: string;
2149
- }
2189
+ },
2150
2190
  ) {
2151
2191
  let embeddings:
2152
2192
  | {
@@ -2162,7 +2202,7 @@ export async function saveMessage(
2162
2202
  }
2163
2203
  const { lastMessageId, messages } = await saveMessages(ctx, component, {
2164
2204
  threadId: args.threadId,
2165
- userId: args.userId,
2205
+ userId: args.userId ?? undefined,
2166
2206
  agentName: args.agentName,
2167
2207
  messages:
2168
2208
  args.prompt !== undefined