@convex-dev/agent 0.2.11-alpha.2 → 0.2.11-alpha.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 (44) hide show
  1. package/README.md +2 -2
  2. package/dist/UIMessages.d.ts +1 -0
  3. package/dist/UIMessages.d.ts.map +1 -1
  4. package/dist/UIMessages.js +51 -0
  5. package/dist/UIMessages.js.map +1 -1
  6. package/dist/client/definePlaygroundAPI.d.ts +20 -20
  7. package/dist/client/index.d.ts +28 -107
  8. package/dist/client/index.d.ts.map +1 -1
  9. package/dist/client/index.js +17 -25
  10. package/dist/client/index.js.map +1 -1
  11. package/dist/client/threads.d.ts +4 -4
  12. package/dist/client/types.d.ts +61 -169
  13. package/dist/client/types.d.ts.map +1 -1
  14. package/dist/component/files.d.ts +4 -4
  15. package/dist/component/messages.d.ts +9 -9
  16. package/dist/component/messages.d.ts.map +1 -1
  17. package/dist/component/messages.js.map +1 -1
  18. package/dist/component/streams.d.ts +2 -6
  19. package/dist/component/streams.d.ts.map +1 -1
  20. package/dist/component/streams.js.map +1 -1
  21. package/dist/component/threads.d.ts +4 -4
  22. package/dist/component/users.d.ts +4 -4
  23. package/dist/deltas.d.ts +0 -1
  24. package/dist/deltas.d.ts.map +1 -1
  25. package/dist/deltas.js +0 -51
  26. package/dist/deltas.js.map +1 -1
  27. package/dist/react/useUIMessages.d.ts.map +1 -1
  28. package/dist/react/useUIMessages.js +1 -2
  29. package/dist/react/useUIMessages.js.map +1 -1
  30. package/package.json +61 -20
  31. package/src/UIMessages.test.ts +273 -0
  32. package/src/UIMessages.ts +64 -0
  33. package/src/client/index.ts +47 -123
  34. package/src/client/types.ts +85 -192
  35. package/src/component/messages.ts +16 -2
  36. package/src/component/streams.ts +8 -1
  37. package/src/deltas.test.ts +0 -272
  38. package/src/deltas.ts +0 -63
  39. package/src/react/useUIMessages.ts +5 -2
  40. package/src/test.ts +17 -0
  41. package/dist/client/_generated/_ignore.d.ts +0 -1
  42. package/dist/client/_generated/_ignore.d.ts.map +0 -1
  43. package/dist/client/_generated/_ignore.js +0 -3
  44. package/dist/client/_generated/_ignore.js.map +0 -1
@@ -0,0 +1,273 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { combineUIMessages } from "./UIMessages.js";
3
+
4
+ describe("combineUIMessages", () => {
5
+ it("combines messages spanning two pages correctly", () => {
6
+ const message1 = {
7
+ id: "msg1",
8
+ key: "msg1-key",
9
+ _creationTime: Date.now(),
10
+ order: 1,
11
+ stepOrder: 1,
12
+ status: "success" as const,
13
+ role: "assistant" as const,
14
+ text: "",
15
+ parts: [
16
+ {
17
+ type: "dynamic-tool" as const,
18
+ state: "input-available" as const,
19
+ toolCallId: "call_123",
20
+ toolName: "calculator",
21
+ input: { operation: "add", a: 2, b: 3 },
22
+ },
23
+ ],
24
+ };
25
+
26
+ const message2 = {
27
+ id: "msg2",
28
+ key: "msg2-key",
29
+ _creationTime: Date.now() + 1,
30
+ order: 1,
31
+ stepOrder: 2,
32
+ status: "success" as const,
33
+ role: "assistant" as const,
34
+ text: "The result is 5.",
35
+ parts: [
36
+ {
37
+ type: "tool-calculator" as const,
38
+ state: "output-available" as const,
39
+ toolCallId: "call_123",
40
+ input: { operation: "add", a: 2, b: 3 },
41
+ output: { result: 5 },
42
+ },
43
+ {
44
+ type: "text" as const,
45
+ text: "The result is 5.",
46
+ state: "done" as const,
47
+ },
48
+ ],
49
+ };
50
+
51
+ const combined = combineUIMessages([message1, message2]);
52
+
53
+ expect(combined).toHaveLength(1);
54
+ expect(combined[0].role).toBe("assistant");
55
+ expect(combined[0].text).toBe("The result is 5.");
56
+ expect(combined[0].parts).toHaveLength(2);
57
+
58
+ const toolPart = combined[0].parts.find(
59
+ (p) => p.type === "tool-calculator",
60
+ );
61
+ expect(toolPart).toMatchObject({
62
+ type: "tool-calculator",
63
+ state: "output-available",
64
+ toolCallId: "call_123",
65
+ input: { operation: "add", a: 2, b: 3 },
66
+ output: { result: 5 },
67
+ });
68
+
69
+ const textPart = combined[0].parts.find((p) => p.type === "text");
70
+ expect(textPart).toMatchObject({
71
+ type: "text",
72
+ text: "The result is 5.",
73
+ state: "done",
74
+ });
75
+ });
76
+
77
+ it("preserves separate messages with different roles", () => {
78
+ const userMessage = {
79
+ id: "user1",
80
+ key: "user1-key",
81
+ _creationTime: Date.now(),
82
+ order: 1,
83
+ stepOrder: 0,
84
+ status: "success" as const,
85
+ role: "user" as const,
86
+ text: "Calculate 2 + 3",
87
+ parts: [{ type: "text" as const, text: "Calculate 2 + 3" }],
88
+ };
89
+
90
+ const assistantMessage = {
91
+ id: "assistant1",
92
+ key: "assistant1-key",
93
+ _creationTime: Date.now() + 1,
94
+ order: 2,
95
+ stepOrder: 0,
96
+ status: "success" as const,
97
+ role: "assistant" as const,
98
+ text: "The result is 5.",
99
+ parts: [
100
+ {
101
+ type: "text" as const,
102
+ text: "The result is 5.",
103
+ state: "done" as const,
104
+ },
105
+ ],
106
+ };
107
+
108
+ const combined = combineUIMessages([userMessage, assistantMessage]);
109
+
110
+ expect(combined).toHaveLength(2);
111
+ expect(combined[0]).toEqual(userMessage);
112
+ expect(combined[1]).toEqual(assistantMessage);
113
+ });
114
+
115
+ it("combines multiple tool calls across pages", () => {
116
+ const message1 = {
117
+ id: "msg1",
118
+ key: "msg1-key",
119
+ _creationTime: Date.now(),
120
+ order: 1,
121
+ stepOrder: 1,
122
+ status: "success" as const,
123
+ role: "assistant" as const,
124
+ text: "",
125
+ parts: [
126
+ {
127
+ type: "dynamic-tool" as const,
128
+ state: "input-available" as const,
129
+ toolCallId: "call_1",
130
+ toolName: "calculator",
131
+ input: { operation: "add", a: 2, b: 3 },
132
+ },
133
+ {
134
+ type: "dynamic-tool" as const,
135
+ state: "input-available" as const,
136
+ toolCallId: "call_2",
137
+ toolName: "formatter",
138
+ input: { text: "result" },
139
+ },
140
+ ],
141
+ };
142
+
143
+ const message2 = {
144
+ id: "msg2",
145
+ key: "msg2-key",
146
+ _creationTime: Date.now() + 1,
147
+ order: 1,
148
+ stepOrder: 2,
149
+ status: "success" as const,
150
+ role: "assistant" as const,
151
+ text: "The formatted result is: 5",
152
+ parts: [
153
+ {
154
+ type: "tool-calculator" as const,
155
+ state: "output-available" as const,
156
+ toolCallId: "call_1",
157
+ input: { operation: "add", a: 2, b: 3 },
158
+ output: { result: 5 },
159
+ },
160
+ {
161
+ type: "tool-formatter" as const,
162
+ state: "output-available" as const,
163
+ toolCallId: "call_2",
164
+ input: { text: "result" },
165
+ output: { formatted: "The formatted result is: 5" },
166
+ },
167
+ {
168
+ type: "text" as const,
169
+ text: "The formatted result is: 5",
170
+ state: "done" as const,
171
+ },
172
+ ],
173
+ };
174
+
175
+ const combined = combineUIMessages([message1, message2]);
176
+
177
+ expect(combined).toHaveLength(1);
178
+ expect(combined[0].role).toBe("assistant");
179
+ expect(combined[0].text).toBe("The formatted result is: 5");
180
+ expect(combined[0].parts).toHaveLength(3);
181
+
182
+ const calculatorPart = combined[0].parts.find(
183
+ (p) =>
184
+ p.type === "tool-calculator" &&
185
+ "toolCallId" in p &&
186
+ p.toolCallId === "call_1",
187
+ );
188
+ expect(calculatorPart).toMatchObject({
189
+ type: "tool-calculator",
190
+ state: "output-available",
191
+ toolCallId: "call_1",
192
+ input: { operation: "add", a: 2, b: 3 },
193
+ output: { result: 5 },
194
+ });
195
+
196
+ const formatterPart = combined[0].parts.find(
197
+ (p) =>
198
+ p.type === "tool-formatter" &&
199
+ "toolCallId" in p &&
200
+ p.toolCallId === "call_2",
201
+ );
202
+ expect(formatterPart).toMatchObject({
203
+ type: "tool-formatter",
204
+ state: "output-available",
205
+ toolCallId: "call_2",
206
+ input: { text: "result" },
207
+ output: { formatted: "The formatted result is: 5" },
208
+ });
209
+ });
210
+
211
+ it("handles tool call without corresponding output", () => {
212
+ const message1 = {
213
+ id: "msg1",
214
+ key: "msg1-key",
215
+ _creationTime: Date.now(),
216
+ order: 1,
217
+ stepOrder: 1,
218
+ status: "success" as const,
219
+ role: "assistant" as const,
220
+ text: "",
221
+ parts: [
222
+ {
223
+ type: "dynamic-tool" as const,
224
+ state: "input-available" as const,
225
+ toolCallId: "call_orphan",
226
+ toolName: "calculator",
227
+ input: { operation: "add", a: 2, b: 3 },
228
+ },
229
+ ],
230
+ };
231
+
232
+ const message2 = {
233
+ id: "msg2",
234
+ key: "msg2-key",
235
+ _creationTime: Date.now() + 1,
236
+ order: 1,
237
+ stepOrder: 2,
238
+ status: "success" as const,
239
+ role: "assistant" as const,
240
+ text: "Still processing...",
241
+ parts: [
242
+ {
243
+ type: "text" as const,
244
+ text: "Still processing...",
245
+ state: "done" as const,
246
+ },
247
+ ],
248
+ };
249
+
250
+ const combined = combineUIMessages([message1, message2]);
251
+
252
+ expect(combined).toHaveLength(1);
253
+ expect(combined[0].role).toBe("assistant");
254
+ expect(combined[0].text).toBe("Still processing...");
255
+ expect(combined[0].parts).toHaveLength(2);
256
+
257
+ const toolPart = combined[0].parts.find((p) => p.type === "dynamic-tool");
258
+ expect(toolPart).toMatchObject({
259
+ type: "dynamic-tool",
260
+ state: "input-available",
261
+ toolCallId: "call_orphan",
262
+ toolName: "calculator",
263
+ input: { operation: "add", a: 2, b: 3 },
264
+ });
265
+
266
+ const textPart = combined[0].parts.find((p) => p.type === "text");
267
+ expect(textPart).toMatchObject({
268
+ type: "text",
269
+ text: "Still processing...",
270
+ state: "done",
271
+ });
272
+ });
273
+ });
package/src/UIMessages.ts CHANGED
@@ -2,6 +2,7 @@ import {
2
2
  convertToModelMessages,
3
3
  type UIMessage as AIUIMessage,
4
4
  type DeepPartial,
5
+ type DynamicToolUIPart,
5
6
  type ReasoningUIPart,
6
7
  type SourceDocumentUIPart,
7
8
  type SourceUrlUIPart,
@@ -555,3 +556,66 @@ function toSourcePart(
555
556
  providerMetadata: part.providerMetadata,
556
557
  } satisfies SourceDocumentUIPart;
557
558
  }
559
+
560
+ export function combineUIMessages(messages: UIMessage[]): UIMessage[] {
561
+ const combined = messages.reduce((acc, message) => {
562
+ if (!acc.length) {
563
+ return [message];
564
+ }
565
+ const previous = acc.at(-1)!;
566
+ if (
567
+ message.order !== previous.order ||
568
+ previous.role !== message.role ||
569
+ message.role !== "assistant"
570
+ ) {
571
+ acc.push(message);
572
+ return acc;
573
+ }
574
+ // We will replace it with a combined message
575
+ acc.pop();
576
+ const newParts = [...previous.parts];
577
+ for (const part of message.parts) {
578
+ const toolCallId = getToolCallId(part);
579
+ if (!toolCallId) {
580
+ newParts.push(part);
581
+ continue;
582
+ }
583
+ const previousPartIndex = newParts.findIndex(
584
+ (p) => getToolCallId(p) === toolCallId,
585
+ );
586
+ const previousPart = newParts.splice(previousPartIndex, 1)[0];
587
+ if (!previousPart) {
588
+ newParts.push(part);
589
+ continue;
590
+ }
591
+ newParts.push(mergeParts(previousPart, part));
592
+ }
593
+ acc.push({
594
+ ...previous,
595
+ ...pick(message, ["status", "metadata", "agentName"]),
596
+ parts: newParts,
597
+ text: joinText(newParts),
598
+ });
599
+ return acc;
600
+ }, [] as UIMessage[]);
601
+ return combined;
602
+ }
603
+
604
+ function getToolCallId(
605
+ part: UIMessage["parts"][number] & { toolCallId?: string },
606
+ ) {
607
+ return part.toolCallId;
608
+ }
609
+
610
+ function mergeParts(
611
+ previousPart: UIMessage["parts"][number],
612
+ part: UIMessage["parts"][number],
613
+ ): UIMessage["parts"][number] {
614
+ const merged: Record<string, unknown> = { ...previousPart };
615
+ for (const [key, value] of Object.entries(part)) {
616
+ if (value !== undefined) {
617
+ merged[key] = value;
618
+ }
619
+ }
620
+ return merged as ToolUIPart | DynamicToolUIPart;
621
+ }
@@ -1,3 +1,4 @@
1
+ import type { JSONValue } from "@ai-sdk/provider";
1
2
  import type {
2
3
  FlexibleSchema,
3
4
  IdGenerator,
@@ -81,12 +82,10 @@ import type {
81
82
  AgentComponent,
82
83
  Config,
83
84
  ContextOptions,
84
- DefaultObjectSchema,
85
85
  GenerateObjectArgs,
86
86
  GenerationOutputMetadata,
87
87
  MaybeCustomCtx,
88
88
  ObjectMode,
89
- ObjectSchema,
90
89
  Options,
91
90
  RawRequestResponseHandler,
92
91
  MutationCtx,
@@ -99,6 +98,7 @@ import type {
99
98
  UsageHandler,
100
99
  UserActionCtx,
101
100
  QueryCtx,
101
+ AgentPrompt,
102
102
  } from "./types.js";
103
103
 
104
104
  export { stepCountIs } from "ai";
@@ -249,11 +249,9 @@ export class Agent<
249
249
  * When generating or streaming text with tools available, this
250
250
  * determines when to stop. Defaults to the AI SDK default.
251
251
  */
252
- stopWhen?: StopCondition<AgentTools> | Array<StopCondition<AgentTools>>;
253
- /**
254
- * @deprecated Use `languageEmbeddingModel` instead.
255
- */
256
- chat?: LanguageModel;
252
+ stopWhen?:
253
+ | StopCondition<NoInfer<AgentTools>>
254
+ | Array<StopCondition<NoInfer<AgentTools>>>;
257
255
  },
258
256
  ) {}
259
257
 
@@ -382,54 +380,23 @@ export class Agent<
382
380
  * The type of the arguments returned infers from the type of the arguments
383
381
  * you pass here.
384
382
  */
385
- args: T & {
386
- /**
387
- * If provided, this message will be used as the "prompt" for the LLM call,
388
- * instead of the prompt or messages.
389
- * This is useful if you want to first save a user message, then use it as
390
- * the prompt for the LLM call in another call.
391
- */
392
- promptMessageId?: string;
393
- /**
394
- * The model to use for the LLM calls. This will override the model specified
395
- * in the Agent constructor.
396
- */
397
- model?: LanguageModel;
398
- /**
399
- * The tools to use for the tool calls. This will override tools specified
400
- * in the Agent constructor or createThread / continueThread.
401
- */
402
- tools?: TOOLS;
403
- /**
404
- * The single prompt message to use for the LLM call. This will be the
405
- * last message in the context. If it's a string, it will be a user role.
406
- */
407
- prompt?: string | (ModelMessage | Message)[];
408
- /**
409
- * If provided alongside prompt, the ordering will be:
410
- * 1. system prompt
411
- * 2. search context
412
- * 3. recent messages
413
- * 4. these messages
414
- * 5. prompt messages, including those already on the same `order` as
415
- * the promptMessageId message, if provided.
416
- */
417
- messages?: (ModelMessage | Message)[];
418
- /**
419
- * This will be the first message in the context, and overrides the
420
- * agent's instructions.
421
- */
422
- system?: string;
423
- /**
424
- * The abort signal to be passed to the LLM call. If triggered, it will
425
- * mark the pending message as failed. If the generation is asynchronously
426
- * aborted, it will trigger this signal when detected.
427
- */
428
- abortSignal?: AbortSignal;
429
- stopWhen?:
430
- | StopCondition<TOOLS extends undefined ? AgentTools : TOOLS>
431
- | Array<StopCondition<TOOLS extends undefined ? AgentTools : TOOLS>>;
432
- },
383
+ args: T &
384
+ AgentPrompt & {
385
+ /**
386
+ * The tools to use for the tool calls. This will override tools specified
387
+ * in the Agent constructor or createThread / continueThread.
388
+ */
389
+ tools?: TOOLS;
390
+ /**
391
+ * The abort signal to be passed to the LLM call. If triggered, it will
392
+ * mark the pending message as failed. If the generation is asynchronously
393
+ * aborted, it will trigger this signal when detected.
394
+ */
395
+ abortSignal?: AbortSignal;
396
+ stopWhen?:
397
+ | StopCondition<TOOLS extends undefined ? AgentTools : TOOLS>
398
+ | Array<StopCondition<TOOLS extends undefined ? AgentTools : TOOLS>>;
399
+ },
433
400
  options?: Options & { userId?: string | null; threadId?: string },
434
401
  ): Promise<{
435
402
  args: T & {
@@ -481,9 +448,10 @@ export class Agent<
481
448
  * Use {@link continueThread} to get a version of this function already scoped
482
449
  * to a thread (and optionally userId).
483
450
  * @param ctx The context passed from the action function calling this.
484
- * @param { userId, threadId }: The user and thread to associate the message with
485
- * @param generateTextArgs The arguments to the generateText function, along with extra controls
486
- * for the {@link ContextOptions} and {@link StorageOptions}.
451
+ * @param scope: The user and thread to associate the message with
452
+ * @param generateTextArgs The arguments to the generateText function, along
453
+ * with {@link AgentPrompt} options, such as promptMessageId.
454
+ * @param options Extra controls for the {@link ContextOptions} and {@link StorageOptions}.
487
455
  * @returns The result of the generateText function.
488
456
  */
489
457
  async generateText<
@@ -493,15 +461,12 @@ export class Agent<
493
461
  >(
494
462
  ctx: ActionCtx & CustomCtx,
495
463
  threadOpts: { userId?: string | null; threadId?: string },
496
- generateTextArgs: TextArgs<AgentTools, TOOLS, OUTPUT, OUTPUT_PARTIAL> & {
497
- /**
498
- * If provided, this message will be used as the "prompt" for the LLM call,
499
- * instead of the prompt or messages.
500
- * This is useful if you want to first save a user message, then use it as
501
- * the prompt for the LLM call in another call.
502
- */
503
- promptMessageId?: string;
504
- },
464
+ /**
465
+ * The arguments to the generateText function, similar to the ai sdk's
466
+ * {@link generateText} function, along with Agent prompt options.
467
+ */
468
+ generateTextArgs: AgentPrompt &
469
+ TextArgs<AgentTools, TOOLS, OUTPUT, OUTPUT_PARTIAL>,
505
470
  options?: Options,
506
471
  ): Promise<
507
472
  GenerateTextResult<TOOLS extends undefined ? AgentTools : TOOLS, OUTPUT> &
@@ -557,22 +522,11 @@ export class Agent<
557
522
  ctx: ActionCtx & CustomCtx,
558
523
  threadOpts: { userId?: string | null; threadId?: string },
559
524
  /**
560
- * The arguments to the streamText function, similar to the ai `streamText` function.
525
+ * The arguments to the streamText function, similar to the ai sdk's
526
+ * {@link streamText} function, along with Agent prompt options.
561
527
  */
562
- streamTextArgs: StreamingTextArgs<
563
- AgentTools,
564
- TOOLS,
565
- OUTPUT,
566
- PARTIAL_OUTPUT
567
- > & {
568
- /**
569
- * If provided, this message will be used as the "prompt" for the LLM call,
570
- * instead of the prompt or messages.
571
- * This is useful if you want to first save a user message, then use it as
572
- * the prompt for the LLM call in another call.
573
- */
574
- promptMessageId?: string;
575
- },
528
+ streamTextArgs: AgentPrompt &
529
+ StreamingTextArgs<AgentTools, TOOLS, OUTPUT, PARTIAL_OUTPUT>,
576
530
  /**
577
531
  * The {@link ContextOptions} and {@link StorageOptions}
578
532
  * options to use for fetching contextual messages and saving input/output messages.
@@ -698,7 +652,7 @@ export class Agent<
698
652
  * to a thread (and optionally userId).
699
653
  */
700
654
  async generateObject<
701
- SCHEMA extends ObjectSchema = DefaultObjectSchema,
655
+ SCHEMA extends FlexibleSchema<unknown> = FlexibleSchema<JSONValue>,
702
656
  OUTPUT extends ObjectMode = InferSchema<SCHEMA> extends string
703
657
  ? "enum"
704
658
  : "object",
@@ -709,17 +663,11 @@ export class Agent<
709
663
  ctx: ActionCtx & CustomCtx,
710
664
  threadOpts: { userId?: string | null; threadId?: string },
711
665
  /**
712
- * The arguments to the generateObject function, similar to the ai.generateObject function.
666
+ * The arguments to the generateObject function, similar to the ai sdk's
667
+ * {@link generateObject} function, along with Agent prompt options.
713
668
  */
714
- generateObjectArgs: GenerateObjectArgs<SCHEMA, OUTPUT, RESULT> & {
715
- /**
716
- * If provided, this message will be used as the "prompt" for the LLM call,
717
- * instead of the prompt or messages.
718
- * This is useful if you want to first save a user message, then use it as
719
- * the prompt for the LLM call in another call.
720
- */
721
- promptMessageId?: string;
722
- },
669
+ generateObjectArgs: AgentPrompt &
670
+ GenerateObjectArgs<SCHEMA, OUTPUT, RESULT>,
723
671
  /**
724
672
  * The {@link ContextOptions} and {@link StorageOptions}
725
673
  * options to use for fetching contextual messages and saving input/output messages.
@@ -756,7 +704,7 @@ export class Agent<
756
704
  * to a thread (and optionally userId).
757
705
  */
758
706
  async streamObject<
759
- SCHEMA extends ObjectSchema = DefaultObjectSchema,
707
+ SCHEMA extends FlexibleSchema<unknown> = FlexibleSchema<JSONValue>,
760
708
  OUTPUT extends ObjectMode = InferSchema<SCHEMA> extends string
761
709
  ? "enum"
762
710
  : "object",
@@ -767,17 +715,10 @@ export class Agent<
767
715
  ctx: ActionCtx & CustomCtx,
768
716
  threadOpts: { userId?: string | null; threadId?: string },
769
717
  /**
770
- * The arguments to the streamObject function, similar to the ai `streamObject` function.
718
+ * The arguments to the streamObject function, similar to the ai sdk's
719
+ * {@link streamObject} function, along with Agent prompt options.
771
720
  */
772
- streamObjectArgs: StreamObjectArgs<SCHEMA, OUTPUT, RESULT> & {
773
- /**
774
- * If provided, this message will be used as the "prompt" for the LLM call,
775
- * instead of the prompt or messages.
776
- * This is useful if you want to first save a user message, then use it as
777
- * the prompt for the LLM call in another call.
778
- */
779
- promptMessageId?: string;
780
- },
721
+ streamObjectArgs: AgentPrompt & StreamObjectArgs<SCHEMA, OUTPUT, RESULT>,
781
722
  /**
782
723
  * The {@link ContextOptions} and {@link StorageOptions}
783
724
  * options to use for fetching contextual messages and saving input/output messages.
@@ -1563,7 +1504,7 @@ export class Agent<
1563
1504
  * and stopWhen.
1564
1505
  */
1565
1506
  asObjectAction<T, DataModel extends GenericDataModel>(
1566
- objectArgs: GenerateObjectArgs<FlexibleSchema<T>>,
1507
+ objectArgs: GenerateObjectArgs<FlexibleSchema<T>> & Partial<AgentPrompt>,
1567
1508
  options?: Options & MaybeCustomCtx<CustomCtx, DataModel, AgentTools>,
1568
1509
  ) {
1569
1510
  return internalActionGeneric({
@@ -1604,24 +1545,7 @@ export class Agent<
1604
1545
  }
1605
1546
 
1606
1547
  /**
1607
- * Save messages to the thread.
1608
- * Useful as a step in Workflows, e.g.
1609
- * ```ts
1610
- * const saveMessages = agent.asSaveMessagesMutation();
1611
- *
1612
- * const myWorkflow = workflow.define({
1613
- * args: {...},
1614
- * handler: async (step, args) => {
1615
- * // do things to create (but not save)messages
1616
- * const { messageIds } = await step.runMutation(internal.foo.saveMessages, {
1617
- * threadId: args.threadId,
1618
- * messages: args.messages,
1619
- * });
1620
- * // ...
1621
- * },
1622
- * })
1623
- * ```
1624
- * @returns A mutation that can be used to save messages to the thread.
1548
+ * @deprecated Use {@link saveMessages} directly instead.
1625
1549
  */
1626
1550
  asSaveMessagesMutation() {
1627
1551
  return internalMutationGeneric({