@convex-dev/agent 0.0.1 → 0.0.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.
Files changed (55) hide show
  1. package/README.md +26 -0
  2. package/dist/commonjs/client/index.d.ts +788 -79
  3. package/dist/commonjs/client/index.d.ts.map +1 -1
  4. package/dist/commonjs/client/index.js +117 -154
  5. package/dist/commonjs/client/index.js.map +1 -1
  6. package/dist/commonjs/component/messages.d.ts +11 -3
  7. package/dist/commonjs/component/messages.d.ts.map +1 -1
  8. package/dist/commonjs/component/messages.js +2 -1
  9. package/dist/commonjs/component/messages.js.map +1 -1
  10. package/dist/commonjs/component/schema.d.ts +18 -12
  11. package/dist/commonjs/component/schema.d.ts.map +1 -1
  12. package/dist/commonjs/component/schema.js +1 -0
  13. package/dist/commonjs/component/schema.js.map +1 -1
  14. package/dist/commonjs/component/vector/index.d.ts.map +1 -1
  15. package/dist/commonjs/component/vector/index.js +1 -1
  16. package/dist/commonjs/component/vector/index.js.map +1 -1
  17. package/dist/commonjs/mapping.d.ts +3 -2
  18. package/dist/commonjs/mapping.d.ts.map +1 -1
  19. package/dist/commonjs/mapping.js +45 -13
  20. package/dist/commonjs/mapping.js.map +1 -1
  21. package/dist/commonjs/validators.d.ts +2736 -76
  22. package/dist/commonjs/validators.d.ts.map +1 -1
  23. package/dist/commonjs/validators.js +72 -7
  24. package/dist/commonjs/validators.js.map +1 -1
  25. package/dist/esm/client/index.d.ts +788 -79
  26. package/dist/esm/client/index.d.ts.map +1 -1
  27. package/dist/esm/client/index.js +117 -154
  28. package/dist/esm/client/index.js.map +1 -1
  29. package/dist/esm/component/messages.d.ts +11 -3
  30. package/dist/esm/component/messages.d.ts.map +1 -1
  31. package/dist/esm/component/messages.js +2 -1
  32. package/dist/esm/component/messages.js.map +1 -1
  33. package/dist/esm/component/schema.d.ts +18 -12
  34. package/dist/esm/component/schema.d.ts.map +1 -1
  35. package/dist/esm/component/schema.js +1 -0
  36. package/dist/esm/component/schema.js.map +1 -1
  37. package/dist/esm/component/vector/index.d.ts.map +1 -1
  38. package/dist/esm/component/vector/index.js +1 -1
  39. package/dist/esm/component/vector/index.js.map +1 -1
  40. package/dist/esm/mapping.d.ts +3 -2
  41. package/dist/esm/mapping.d.ts.map +1 -1
  42. package/dist/esm/mapping.js +45 -13
  43. package/dist/esm/mapping.js.map +1 -1
  44. package/dist/esm/validators.d.ts +2736 -76
  45. package/dist/esm/validators.d.ts.map +1 -1
  46. package/dist/esm/validators.js +72 -7
  47. package/dist/esm/validators.js.map +1 -1
  48. package/package.json +7 -7
  49. package/src/client/index.ts +269 -191
  50. package/src/component/_generated/api.d.ts +5 -0
  51. package/src/component/messages.ts +2 -1
  52. package/src/component/schema.ts +1 -0
  53. package/src/component/vector/index.ts +1 -7
  54. package/src/mapping.ts +60 -19
  55. package/src/validators.ts +102 -9
@@ -4,28 +4,25 @@ import type {
4
4
  DeepPartial,
5
5
  GenerateObjectResult,
6
6
  GenerateTextResult,
7
+ JSONValue,
8
+ RepairTextFunction,
7
9
  StepResult,
8
10
  StreamObjectResult,
9
11
  StreamTextResult,
12
+ TelemetrySettings,
10
13
  Tool,
11
14
  ToolChoice,
12
15
  ToolExecutionOptions,
13
16
  ToolSet,
17
+ Message as UIMessage,
14
18
  } from "ai";
15
19
  import { generateObject, generateText, streamObject, streamText } from "ai";
16
- import { api } from "../component/_generated/api";
17
- import {
18
- SearchOptions,
19
- vContextOptions,
20
- vObjectArgs,
21
- vStorageOptions,
22
- vThreadArgs,
23
- } from "../validators";
24
- import { RunActionCtx, RunMutationCtx, RunQueryCtx, UseApi } from "./types";
25
20
  import { assert } from "convex-helpers";
26
21
  import { ConvexToZod, convexToZod } from "convex-helpers/server/zod";
27
22
  import { internalActionGeneric } from "convex/server";
28
23
  import { Infer, v, Validator } from "convex/values";
24
+ import { z } from "zod";
25
+ import { api } from "../component/_generated/api";
29
26
  import {
30
27
  validateVectorDimension,
31
28
  VectorDimension,
@@ -34,9 +31,21 @@ import {
34
31
  promptOrMessagesToCoreMessages,
35
32
  serializeMessageWithId,
36
33
  serializeNewMessagesInStep,
34
+ serializeObjectResult,
37
35
  serializeStep,
38
36
  } from "../mapping";
39
37
  import { DEFAULT_MESSAGE_RANGE, extractText } from "../shared";
38
+ import {
39
+ CallSettings,
40
+ ProviderMetadata,
41
+ ProviderOptions,
42
+ SearchOptions,
43
+ vContextOptions,
44
+ vSafeObjectArgs,
45
+ vStorageOptions,
46
+ vTextArgs,
47
+ } from "../validators";
48
+ import { RunActionCtx, RunMutationCtx, RunQueryCtx, UseApi } from "./types";
40
49
 
41
50
  export type ContextOptions = {
42
51
  /**
@@ -98,7 +107,7 @@ export class Agent<AgentTools extends ToolSet> {
98
107
  public component: UseApi<typeof api>,
99
108
  public options: {
100
109
  name?: string;
101
- thread: LanguageModelV1;
110
+ chat: LanguageModelV1;
102
111
  textEmbedding?: EmbeddingModelV1<string>;
103
112
  instructions?: string;
104
113
  tools?: AgentTools;
@@ -220,6 +229,7 @@ export class Agent<AgentTools extends ToolSet> {
220
229
  // return this.component.continueThread(ctx, args);
221
230
  return {
222
231
  thread: {
232
+ threadId,
223
233
  generateText: this.generateText.bind(this, ctx, { userId, threadId }),
224
234
  streamText: this.streamText.bind(this, ctx, { userId, threadId }),
225
235
  generateObject: this.generateObject.bind(this, ctx, {
@@ -295,6 +305,9 @@ export class Agent<AgentTools extends ToolSet> {
295
305
  const textIndexes = messageTexts
296
306
  .map((t, i) => (t ? i : undefined))
297
307
  .filter((i) => i !== undefined);
308
+ if (textIndexes.length === 0) {
309
+ return undefined;
310
+ }
298
311
  // Then embed those messages.
299
312
  const textEmbeddings = await this.options.textEmbedding.doEmbed({
300
313
  values: messageTexts.filter((t): t is string => !!t),
@@ -335,7 +348,7 @@ export class Agent<AgentTools extends ToolSet> {
335
348
  threadId: args.threadId,
336
349
  userId: args.userId,
337
350
  agentName: this.options.name,
338
- model: this.options.thread.modelId,
351
+ model: this.options.chat.modelId,
339
352
  messages: args.messages.map(serializeMessageWithId),
340
353
  embeddings: await this.getEmbeddings(args.messages),
341
354
  failPendingSteps: args.failPendingSteps ?? true,
@@ -417,36 +430,20 @@ export class Agent<AgentTools extends ToolSet> {
417
430
  ): Promise<
418
431
  GenerateTextResult<TOOLS & AgentTools, OUTPUT> & GenerationOutputMetadata
419
432
  > {
420
- const { prompt, messages: raw, ...rest } = args;
421
- const messages = promptOrMessagesToCoreMessages({ prompt, messages: raw });
422
- const contextMessages = await this.fetchContextMessages(ctx, {
423
- ...args,
424
- userId,
425
- threadId,
426
- messages,
427
- });
428
- let messageId: string | undefined;
429
- if (threadId) {
430
- const saved = await this.saveMessages(ctx, {
431
- threadId,
432
- userId,
433
- messages: args.saveAllInputMessages ? messages : messages.slice(-1),
434
- pending: true,
435
- parentMessageId: args.parentMessageId,
436
- });
437
- messageId = saved.lastMessageId;
438
- }
433
+ const { args: aiArgs, messageId } = await this.saveMessagesAndFetchContext(
434
+ ctx,
435
+ { ...args, userId, threadId }
436
+ );
439
437
  const toolCtx = { ...ctx, userId, threadId, messageId };
440
438
  const tools = wrapTools(toolCtx, this.options.tools, args.tools) as TOOLS;
439
+ const maxSteps = args.maxSteps ?? this.options.maxSteps;
441
440
  try {
442
441
  const result = await generateText({
443
- model: this.options.thread,
444
- messages: [...contextMessages, ...messages],
445
- system: this.options.instructions,
446
- maxSteps: this.options.maxSteps,
442
+ model: this.options.chat,
443
+ ...aiArgs,
444
+ maxSteps,
447
445
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
448
446
  toolChoice: args.toolChoice as any,
449
- ...rest,
450
447
  tools,
451
448
  onStepFinish: async (step) => {
452
449
  if (threadId && messageId && args.saveOutputMessages !== false) {
@@ -487,35 +484,19 @@ export class Agent<AgentTools extends ToolSet> {
487
484
  ): Promise<
488
485
  StreamTextResult<TOOLS, PARTIAL_OUTPUT> & GenerationOutputMetadata
489
486
  > {
490
- const { prompt, messages: raw, ...rest } = args;
491
- const messages = promptOrMessagesToCoreMessages({ prompt, messages: raw });
492
- const contextMessages = await this.fetchContextMessages(ctx, {
493
- ...args,
494
- userId,
495
- threadId,
496
- messages,
497
- });
498
- let messageId: string | undefined;
499
- if (threadId) {
500
- const saved = await this.saveMessages(ctx, {
501
- threadId,
502
- userId,
503
- messages: args.saveAllInputMessages ? messages : messages.slice(-1),
504
- pending: true,
505
- parentMessageId: args.parentMessageId,
506
- });
507
- messageId = saved.lastMessageId;
508
- }
487
+ const { args: aiArgs, messageId } = await this.saveMessagesAndFetchContext(
488
+ ctx,
489
+ { ...args, userId, threadId }
490
+ );
509
491
  const toolCtx = { ...ctx, userId, threadId, messageId };
510
492
  const tools = wrapTools(toolCtx, this.options.tools, args.tools) as TOOLS;
493
+ const maxSteps = args.maxSteps ?? this.options.maxSteps;
511
494
  const result = streamText({
512
- model: this.options.thread,
513
- messages: [...contextMessages, ...messages],
514
- system: this.options.instructions,
515
- maxSteps: this.options.maxSteps,
495
+ model: this.options.chat,
496
+ ...aiArgs,
497
+ maxSteps,
516
498
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
517
499
  toolChoice: args.toolChoice as any,
518
- ...rest,
519
500
  tools,
520
501
  onChunk: async (chunk) => {
521
502
  // console.log("onChunk", chunk);
@@ -531,14 +512,9 @@ export class Agent<AgentTools extends ToolSet> {
531
512
  }
532
513
  return args.onError?.(error);
533
514
  },
534
- onFinish: async (result) => {
535
- result.response.messages.forEach((message) => {
536
- // console.log("onFinish", message);
537
- });
538
- return args.onFinish?.(result);
539
- },
540
515
  onStepFinish: async (step) => {
541
516
  // console.log("onStepFinish", step);
517
+ // TODO: compare delta to the output. internally drop the deltas when committing
542
518
  if (threadId && messageId) {
543
519
  await this.saveStep(ctx, {
544
520
  threadId,
@@ -552,118 +528,160 @@ export class Agent<AgentTools extends ToolSet> {
552
528
  return { ...result, messageId };
553
529
  }
554
530
 
555
- // TODO: add the crazy number of overloads to get types through
556
- async generateObject<T>(
557
- ctx: RunActionCtx,
558
- { userId, threadId }: { userId?: string; threadId?: string },
559
- args: Omit<Parameters<typeof generateObject>[0], "model"> & {
560
- model?: LanguageModelV1;
561
- } & { parentMessageId?: string } & ContextOptions &
562
- StorageOptions
563
- ): Promise<GenerateObjectResult<T> & GenerationOutputMetadata> {
564
- const { prompt, messages: raw, ...rest } = args;
565
- const messages = promptOrMessagesToCoreMessages({ prompt, messages: raw });
566
- const contextMessages = await this.fetchContextMessages(ctx, {
567
- ...args,
531
+ async saveMessagesAndFetchContext<
532
+ T extends {
533
+ prompt?: string;
534
+ messages?: CoreMessage[] | Omit<UIMessage, "id">[];
535
+ system?: string;
536
+ },
537
+ >(
538
+ ctx: RunActionCtx | RunMutationCtx,
539
+ {
568
540
  userId,
569
541
  threadId,
542
+ parentMessageId,
543
+ saveAllInputMessages,
544
+ system,
545
+ ...args
546
+ }: {
547
+ userId: string | undefined;
548
+ threadId: string | undefined;
549
+ parentMessageId?: string;
550
+ saveAllInputMessages?: boolean;
551
+ saveAnyInputMessages?: boolean;
552
+ } & ContextOptions &
553
+ T
554
+ ): Promise<{
555
+ args: T;
556
+ messageId: string | undefined;
557
+ }> {
558
+ const messages = promptOrMessagesToCoreMessages(args);
559
+ const contextMessages = await this.fetchContextMessages(ctx, {
570
560
  messages,
561
+ parentMessageId,
562
+ userId,
563
+ threadId,
564
+ ...args,
571
565
  });
572
566
  let messageId: string | undefined;
573
567
  if (threadId) {
574
568
  const saved = await this.saveMessages(ctx, {
575
569
  threadId,
576
570
  userId,
577
- messages: args.saveAllInputMessages ? messages : messages.slice(-1),
571
+ messages: saveAllInputMessages ? messages : messages.slice(-1),
578
572
  pending: true,
579
- parentMessageId: args.parentMessageId,
573
+ // We should just fail if you pass in an ID for the message, fail those children
574
+ // failPendingSteps: true,
575
+ parentMessageId,
580
576
  });
581
577
  messageId = saved.lastMessageId;
582
578
  }
583
- const result = (await generateObject({
584
- model: this.options.thread,
585
- messages: [...contextMessages, ...messages],
586
- ...rest,
587
- })) as GenerateObjectResult<T>;
588
- if (threadId && messageId && args.saveOutputMessages !== false) {
589
- // await this.saveObject(ctx, { threadId, messageId, result });
590
- }
591
- return { ...result, messageId };
579
+ const { prompt: _, ...rest } = args;
580
+ return {
581
+ args: {
582
+ ...rest,
583
+ system: system ?? this.options.instructions,
584
+ messages: [...contextMessages, ...messages],
585
+ } as T,
586
+ messageId,
587
+ };
592
588
  }
593
589
 
594
- // async saveObject<T>(
595
- // ctx: RunMutationCtx,
596
- // args: {
597
- // threadId: string;
598
- // messageId: string;
599
- // result: GenerateObjectResult<T>;
600
- // }
601
- // ): Promise<void> {
602
- // await ctx.runMutation(this.component.messages.addObject, {
603
- // threadId: args.threadId,
604
- // step: {
605
- // request: result.request,
606
- // response: {
607
- // ...result.response,
608
- // messages: [
609
- // {
610
- // role: "assistant",
611
-
612
- // content: result.object,
613
- // },
614
- // ],
615
- // },
616
- // finishReason: result.finishReason,
617
- // providerMetadata: result.providerMetadata,
618
- // usage: result.usage,
619
- // warnings: result.warnings,
620
- // },
621
- // });
622
- // }
590
+ async generateObject<T>(
591
+ ctx: RunActionCtx,
592
+ { userId, threadId }: { userId?: string; threadId?: string },
593
+ args: OurObjectArgs<T>
594
+ ): Promise<GenerateObjectResult<T> & GenerationOutputMetadata> {
595
+ const { args: aiArgs, messageId } = await this.saveMessagesAndFetchContext(
596
+ ctx,
597
+ { ...args, userId, threadId }
598
+ );
599
+
600
+ try {
601
+ const result = (await generateObject({
602
+ model: this.options.chat,
603
+ ...aiArgs,
604
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
605
+ } as any)) as GenerateObjectResult<T>;
606
+
607
+ if (threadId && messageId && args.saveOutputMessages !== false) {
608
+ await this.saveObject(ctx, { threadId, messageId, result });
609
+ }
610
+ return { ...result, messageId };
611
+ } catch (error) {
612
+ if (threadId && messageId) {
613
+ await ctx.runMutation(this.component.messages.rollbackMessage, {
614
+ messageId,
615
+ error: (error as Error).message,
616
+ });
617
+ }
618
+ throw error;
619
+ }
620
+ }
623
621
 
624
622
  async streamObject<T>(
625
623
  ctx: RunMutationCtx,
626
624
  { userId, threadId }: { userId?: string; threadId?: string },
627
- args: Omit<Parameters<typeof streamObject<T>>[0], "model"> & {
628
- model?: LanguageModelV1;
629
- } & { parentMessageId?: string } & ContextOptions &
630
- StorageOptions
625
+ args: OurStreamObjectArgs<T>
631
626
  ): Promise<
632
627
  StreamObjectResult<DeepPartial<T>, T, never> & GenerationOutputMetadata
633
628
  > {
634
629
  // TODO: unify all this shared code between all the generate* and stream* functions
635
- const { prompt, messages: raw, ...rest } = args;
636
- const messages = promptOrMessagesToCoreMessages({ prompt, messages: raw });
637
- const contextMessages = await this.fetchContextMessages(ctx, {
638
- ...args,
639
- userId,
640
- threadId,
641
- messages,
642
- });
643
- let messageId: string | undefined;
644
- if (threadId) {
645
- const saved = await this.saveMessages(ctx, {
646
- threadId,
647
- userId,
648
- messages: args.saveAllInputMessages ? messages : messages.slice(-1),
649
- pending: true,
650
- parentMessageId: args.parentMessageId,
651
- });
652
- messageId = saved.lastMessageId;
653
- }
654
- const result = streamObject<T>({
655
- model: this.options.thread,
656
- messages: [...contextMessages, ...messages],
657
- ...rest,
630
+ const { args: aiArgs, messageId } = await this.saveMessagesAndFetchContext(
631
+ ctx,
632
+ { ...args, userId, threadId }
633
+ );
634
+ const stream = streamObject<T>({
635
+ model: this.options.chat,
636
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
637
+ ...(aiArgs as any),
658
638
  onError: async (error) => {
659
639
  console.error("onError", error);
660
640
  return args.onError?.(error);
661
641
  },
662
642
  onFinish: async (result) => {
663
- // console.log("onFinish", result);
643
+ if (threadId && messageId && args.saveOutputMessages !== false) {
644
+ await this.saveObject(ctx, {
645
+ threadId,
646
+ messageId,
647
+ result: {
648
+ object: result.object,
649
+ finishReason: "stop",
650
+ usage: result.usage,
651
+ warnings: result.warnings,
652
+ request: await stream.request,
653
+ response: result.response,
654
+ providerMetadata: result.providerMetadata,
655
+ experimental_providerMetadata:
656
+ result.experimental_providerMetadata,
657
+ logprobs: undefined,
658
+ toJsonResponse: stream.toTextStreamResponse,
659
+ },
660
+ });
661
+ }
662
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
663
+ return args.onFinish?.(result as any);
664
664
  },
665
665
  }) as StreamObjectResult<DeepPartial<T>, T, never>;
666
- return { ...result, messageId };
666
+ return { ...stream, messageId };
667
+ }
668
+
669
+ async saveObject(
670
+ ctx: RunMutationCtx,
671
+ args: {
672
+ threadId: string;
673
+ messageId: string;
674
+ result: GenerateObjectResult<unknown>;
675
+ }
676
+ ): Promise<void> {
677
+ const step = serializeObjectResult(args.result);
678
+ await ctx.runMutation(this.component.messages.addStep, {
679
+ threadId: args.threadId,
680
+ messageId: args.messageId,
681
+ failPendingSteps: false,
682
+ embeddings: await this.getEmbeddings([step.messages[0].message]),
683
+ step,
684
+ });
667
685
  }
668
686
 
669
687
  mergedContextOptions(opts: ContextOptions): ContextOptions {
@@ -717,7 +735,7 @@ export class Agent<AgentTools extends ToolSet> {
717
735
  /**
718
736
  *
719
737
  */
720
- asAction(spec: { contextOptions?: ContextOptions; maxSteps?: number }) {
738
+ asAction(spec?: { contextOptions?: ContextOptions; maxSteps?: number }) {
721
739
  return internalActionGeneric({
722
740
  args: {
723
741
  userId: v.optional(v.string()),
@@ -725,6 +743,7 @@ export class Agent<AgentTools extends ToolSet> {
725
743
  contextOptions: v.optional(vContextOptions),
726
744
  storageOptions: v.optional(vStorageOptions),
727
745
  maxRetries: v.optional(v.number()),
746
+ parentMessageId: v.optional(v.string()),
728
747
 
729
748
  createThread: v.optional(
730
749
  v.object({
@@ -734,67 +753,59 @@ export class Agent<AgentTools extends ToolSet> {
734
753
  summary: v.optional(v.string()),
735
754
  })
736
755
  ),
737
- continueThread: v.optional(
738
- v.object({
739
- threadId: v.string(),
740
- userId: v.optional(v.string()),
741
- })
742
- ),
743
- generateText: v.optional(vThreadArgs),
744
- streamText: v.optional(vThreadArgs),
745
- generateObject: v.optional(vObjectArgs),
746
- streamObject: v.optional(
747
- v.object({ ...vObjectArgs.fields, schema: v.any() })
748
- ),
756
+ generateText: v.optional(vTextArgs),
757
+ streamText: v.optional(vTextArgs),
758
+ generateObject: v.optional(vSafeObjectArgs),
759
+ streamObject: v.optional(vSafeObjectArgs),
749
760
  },
750
761
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
751
762
  handler: async (ctx, args): Promise<any> => {
752
763
  const contextOptions =
753
- spec.contextOptions && this.mergedContextOptions(spec.contextOptions);
754
- const maxSteps = spec.maxSteps ?? this.options.maxSteps;
755
- const maxRetries = args.maxRetries;
764
+ spec?.contextOptions &&
765
+ this.mergedContextOptions(spec.contextOptions);
766
+ const maxSteps = spec?.maxSteps ?? this.options.maxSteps;
756
767
  const commonArgs = {
757
768
  userId: args.userId,
758
769
  threadId: args.threadId,
770
+ parentMessageId: args.parentMessageId,
759
771
  ...contextOptions,
760
772
  ...args.storageOptions,
761
773
  };
762
774
  if (args.createThread) {
763
- return this.createThread(ctx, {
775
+ const { threadId } = await this.createThread(ctx, {
764
776
  userId: args.createThread.userId,
765
777
  parentThreadIds: args.createThread.parentThreadIds,
766
778
  title: args.createThread.title,
767
779
  summary: args.createThread.summary,
768
780
  });
769
- } else if (args.continueThread) {
770
- return this.continueThread(ctx, {
771
- threadId: args.continueThread.threadId,
772
- userId: args.continueThread.userId,
773
- });
781
+ return threadId;
774
782
  } else if (args.generateText) {
775
- return this.generateText(ctx, commonArgs, {
783
+ const value = await this.generateText(ctx, commonArgs, {
776
784
  ...args.generateText,
777
785
  maxSteps: args.generateText.maxSteps ?? maxSteps,
778
- maxRetries,
779
786
  });
787
+ return value.text;
780
788
  } else if (args.streamText) {
781
- return this.streamText(ctx, commonArgs, {
789
+ const value = await this.streamText(ctx, commonArgs, {
782
790
  ...args.streamText,
783
791
  maxSteps: args.streamText.maxSteps ?? maxSteps,
784
- maxRetries,
785
792
  });
793
+ return value.text;
786
794
  } else if (args.generateObject) {
787
- return this.generateObject(ctx, commonArgs, {
788
- ...args.generateObject,
789
- output: args.generateObject.output ?? "string",
790
- maxRetries,
795
+ const value = await this.generateObject(ctx, commonArgs, {
796
+ ...(args.generateObject as GenerateObjectArgs<unknown>),
791
797
  });
798
+ return value.object;
792
799
  } else if (args.streamObject) {
793
- return this.streamObject(ctx, commonArgs, {
794
- ...args.streamObject,
795
- output: args.streamObject.output ?? "string",
796
- maxRetries,
800
+ const value = await this.streamObject(ctx, commonArgs, {
801
+ ...(args.streamObject as StreamObjectArgs<unknown>),
797
802
  });
803
+ return value.object;
804
+ } else {
805
+ throw new Error(
806
+ "No action specified. Maybe try :" +
807
+ 'generateText: { prompt: "Hello world" }'
808
+ );
798
809
  }
799
810
  },
800
811
  });
@@ -918,16 +929,80 @@ type TextArgs<
918
929
  } & ContextOptions &
919
930
  StorageOptions;
920
931
 
921
- type ObjectArgs<
922
- T extends {
923
- model: LanguageModelV1;
924
- },
925
- > = Omit<T, "model"> & {
926
- model?: LanguageModelV1;
927
- } & ContextOptions &
928
- StorageOptions;
932
+ type BaseGenerateObjectOptions = StorageOptions &
933
+ ContextOptions &
934
+ CallSettings & {
935
+ model?: LanguageModelV1;
936
+ parentMessageId?: string;
937
+ system?: string;
938
+ prompt?: string;
939
+ messages?: CoreMessage[];
940
+ experimental_repairText?: RepairTextFunction;
941
+ experimental_telemetry?: TelemetrySettings;
942
+ providerOptions?: ProviderOptions;
943
+ experimental_providerMetadata?: ProviderMetadata;
944
+ };
945
+
946
+ type GenerateObjectObjectOptions<T extends Record<string, unknown>> =
947
+ BaseGenerateObjectOptions & {
948
+ output: "object";
949
+ mode?: "auto" | "json" | "tool";
950
+ schema: z.Schema<T>;
951
+ schemaName?: string;
952
+ schemaDescription?: string;
953
+ };
954
+
955
+ type GenerateObjectArrayOptions<T> = BaseGenerateObjectOptions & {
956
+ output: "array";
957
+ mode?: "auto" | "json" | "tool";
958
+ schema: z.Schema<T>;
959
+ schemaName?: string;
960
+ schemaDescription?: string;
961
+ };
962
+
963
+ type GenerateObjectWithEnumOptions<T extends string> =
964
+ BaseGenerateObjectOptions & {
965
+ output: "enum";
966
+ enum: Array<T>;
967
+ mode?: "auto" | "json" | "tool";
968
+ };
969
+
970
+ type GenerateObjectNoSchemaOptions = BaseGenerateObjectOptions & {
971
+ schema?: undefined;
972
+ mode?: "json";
973
+ };
974
+
975
+ type GenerateObjectArgs<T> =
976
+ T extends Record<string, unknown>
977
+ ? GenerateObjectObjectOptions<T>
978
+ : T extends Array<unknown>
979
+ ? GenerateObjectArrayOptions<T>
980
+ : T extends string
981
+ ? GenerateObjectWithEnumOptions<T>
982
+ : GenerateObjectNoSchemaOptions;
983
+
984
+ type StreamObjectArgs<T> =
985
+ T extends Record<string, unknown>
986
+ ? GenerateObjectObjectOptions<T>
987
+ : T extends Array<unknown>
988
+ ? GenerateObjectArrayOptions<T>
989
+ : GenerateObjectNoSchemaOptions;
990
+
991
+ type OurObjectArgs<T> = GenerateObjectArgs<T> &
992
+ Pick<
993
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
994
+ Parameters<typeof generateObject<any>>[0],
995
+ "experimental_repairText" | "abortSignal"
996
+ >;
997
+
998
+ type OurStreamObjectArgs<T> = StreamObjectArgs<T> &
999
+ Pick<
1000
+ Parameters<typeof streamObject<T>>[0],
1001
+ "onError" | "onFinish" | "abortSignal"
1002
+ >;
929
1003
 
930
1004
  interface Thread<AgentTools extends ToolSet> {
1005
+ threadId: string;
931
1006
  generateText<TOOLS extends ToolSet, OUTPUT = never, OUTPUT_PARTIAL = never>(
932
1007
  args: TextArgs<
933
1008
  AgentTools,
@@ -950,10 +1025,13 @@ interface Thread<AgentTools extends ToolSet> {
950
1025
  >;
951
1026
  // TODO: add all the overloads
952
1027
  generateObject<T>(
953
- args: ObjectArgs<Parameters<typeof generateObject>[0]>
1028
+ args: OurObjectArgs<T>
954
1029
  ): Promise<GenerateObjectResult<T> & GenerationOutputMetadata>;
1030
+ generateObject(
1031
+ args: GenerateObjectNoSchemaOptions
1032
+ ): Promise<GenerateObjectResult<JSONValue> & GenerationOutputMetadata>;
955
1033
  streamObject<T>(
956
- args: ObjectArgs<Parameters<typeof streamObject<T>>[0]>
1034
+ args: OurStreamObjectArgs<T>
957
1035
  ): Promise<
958
1036
  StreamObjectResult<DeepPartial<T>, T, never> & GenerationOutputMetadata
959
1037
  >;
@@ -169,6 +169,7 @@ export type Mounts = {
169
169
  | string
170
170
  | string
171
171
  | string;
172
+ error?: string;
172
173
  fileId?: string;
173
174
  id?: string;
174
175
  message?:
@@ -293,6 +294,7 @@ export type Mounts = {
293
294
  | string
294
295
  | string
295
296
  | string;
297
+ error?: string;
296
298
  fileId?: string;
297
299
  id?: string;
298
300
  message?:
@@ -1058,6 +1060,7 @@ export type Mounts = {
1058
1060
  | string
1059
1061
  | string
1060
1062
  | string;
1063
+ error?: string;
1061
1064
  fileId?: string;
1062
1065
  id?: string;
1063
1066
  message?:
@@ -1230,6 +1233,7 @@ export type Mounts = {
1230
1233
  | string
1231
1234
  | string
1232
1235
  | string;
1236
+ error?: string;
1233
1237
  fileId?: string;
1234
1238
  id?: string;
1235
1239
  message?:
@@ -1359,6 +1363,7 @@ export type Mounts = {
1359
1363
  | string
1360
1364
  | string
1361
1365
  | string;
1366
+ error?: string;
1362
1367
  fileId?: string;
1363
1368
  id?: string;
1364
1369
  message?: