@convex-dev/agent 0.0.8 → 0.0.9-alpha.1
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.
- package/README.md +7 -3
- package/dist/commonjs/client/index.d.ts +338 -14
- package/dist/commonjs/client/index.d.ts.map +1 -1
- package/dist/commonjs/client/index.js +163 -24
- package/dist/commonjs/client/index.js.map +1 -1
- package/dist/commonjs/mapping.d.ts +2 -1
- package/dist/commonjs/mapping.d.ts.map +1 -1
- package/dist/commonjs/mapping.js +22 -16
- package/dist/commonjs/mapping.js.map +1 -1
- package/dist/commonjs/react/index.d.ts +11 -0
- package/dist/commonjs/react/index.d.ts.map +1 -1
- package/dist/commonjs/react/index.js +11 -0
- package/dist/commonjs/react/index.js.map +1 -1
- package/dist/esm/client/index.d.ts +338 -14
- package/dist/esm/client/index.d.ts.map +1 -1
- package/dist/esm/client/index.js +163 -24
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/mapping.d.ts +2 -1
- package/dist/esm/mapping.d.ts.map +1 -1
- package/dist/esm/mapping.js +22 -16
- package/dist/esm/mapping.js.map +1 -1
- package/dist/esm/react/index.d.ts +11 -0
- package/dist/esm/react/index.d.ts.map +1 -1
- package/dist/esm/react/index.js +11 -0
- package/dist/esm/react/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client/index.ts +332 -37
- package/src/mapping.ts +23 -16
- package/src/react/index.ts +11 -0
package/src/client/index.ts
CHANGED
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
} from "../component/vector/tables";
|
|
39
39
|
import {
|
|
40
40
|
AIMessageWithoutId,
|
|
41
|
+
deserializeMessage,
|
|
41
42
|
promptOrMessagesToCoreMessages,
|
|
42
43
|
serializeMessageWithId,
|
|
43
44
|
serializeNewMessagesInStep,
|
|
@@ -64,6 +65,10 @@ import { RunActionCtx, RunMutationCtx, RunQueryCtx, UseApi } from "./types.js";
|
|
|
64
65
|
export { convexToZod, zodToConvex };
|
|
65
66
|
export type { ThreadDoc, MessageDoc } from "./types.js";
|
|
66
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Options to configure what messages are fetched as context,
|
|
70
|
+
* automatically with thread.generateText, or directly via search.
|
|
71
|
+
*/
|
|
67
72
|
export type ContextOptions = {
|
|
68
73
|
/**
|
|
69
74
|
* Whether to include tool messages in the context.
|
|
@@ -104,14 +109,20 @@ export type ContextOptions = {
|
|
|
104
109
|
searchOtherThreads?: boolean;
|
|
105
110
|
};
|
|
106
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Options to configure the automatic saving of messages
|
|
114
|
+
* when generating text / objects in a thread.
|
|
115
|
+
*/
|
|
107
116
|
export type StorageOptions = {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
117
|
+
/**
|
|
118
|
+
* Defaults to false, allowing you to pass in arbitrary context that will
|
|
119
|
+
* be in addition to automatically fetched content.
|
|
120
|
+
* Pass true to have all input messages saved to the thread history.
|
|
121
|
+
*/
|
|
111
122
|
saveAllInputMessages?: boolean;
|
|
112
|
-
|
|
123
|
+
/** Defaults to true, saving the prompt, or last message passed to generateText. */
|
|
113
124
|
saveAnyInputMessages?: boolean;
|
|
114
|
-
|
|
125
|
+
/** Defaults to true. Whether to save messages generated while chatting. */
|
|
115
126
|
saveOutputMessages?: boolean;
|
|
116
127
|
};
|
|
117
128
|
|
|
@@ -123,15 +134,65 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
123
134
|
constructor(
|
|
124
135
|
public component: UseApi<Mounts>,
|
|
125
136
|
public options: {
|
|
137
|
+
/**
|
|
138
|
+
* The name for the agent. This will be attributed on each message
|
|
139
|
+
* created by this agent.
|
|
140
|
+
*/
|
|
126
141
|
name?: string;
|
|
142
|
+
/**
|
|
143
|
+
* The LLM model to use for generating / streaming text and objects.
|
|
144
|
+
* e.g.
|
|
145
|
+
* import { openai } from "@ai-sdk/openai"
|
|
146
|
+
* const myAgent = new Agent(components.agent, {
|
|
147
|
+
* chat: openai.chat("gpt-4o-mini"),
|
|
148
|
+
*/
|
|
127
149
|
chat: LanguageModelV1;
|
|
150
|
+
/**
|
|
151
|
+
* The model to use for text embeddings. Optional.
|
|
152
|
+
* If specified, it will use this for generating vector embeddings
|
|
153
|
+
* of chats, and can opt-in to doing vector search for automatic context
|
|
154
|
+
* on generateText, etc.
|
|
155
|
+
* e.g.
|
|
156
|
+
* import { openai } from "@ai-sdk/openai"
|
|
157
|
+
* const myAgent = new Agent(components.agent, {
|
|
158
|
+
* textEmbedding: openai.embedding("text-embedding-3-small")
|
|
159
|
+
*/
|
|
128
160
|
textEmbedding?: EmbeddingModelV1<string>;
|
|
161
|
+
/**
|
|
162
|
+
* The default system prompt to put in each request.
|
|
163
|
+
* Override per-prompt by passing the "system" parameter.
|
|
164
|
+
*/
|
|
129
165
|
instructions?: string;
|
|
166
|
+
/**
|
|
167
|
+
* Tools that the agent can call out to and get responses from.
|
|
168
|
+
* They can be AI SDK tools (import {tool} from "ai")
|
|
169
|
+
* or tools that have Convex context
|
|
170
|
+
* (import { createTool } from "@convex-dev/agent")
|
|
171
|
+
* Note: Convex tools can't currently annotate the parameters
|
|
172
|
+
* with descriptions, so the names should be self-evident from naming.
|
|
173
|
+
*/
|
|
130
174
|
tools?: AgentTools;
|
|
175
|
+
/**
|
|
176
|
+
* Options to determine what messages are included as context in message
|
|
177
|
+
* generation. To disable any messages automatically being added, pass:
|
|
178
|
+
* { recentMessages: 0 }
|
|
179
|
+
*/
|
|
131
180
|
contextOptions?: ContextOptions;
|
|
132
|
-
|
|
181
|
+
/**
|
|
182
|
+
* Determines whether messages are automatically stored when passed as
|
|
183
|
+
* arguments or generated.
|
|
184
|
+
*/
|
|
185
|
+
storageOptions?: StorageOptions;
|
|
186
|
+
/**
|
|
187
|
+
* When generating or streaming text with tools available, this
|
|
188
|
+
* determines the default max number of iterations.
|
|
189
|
+
*/
|
|
133
190
|
maxSteps?: number;
|
|
134
|
-
|
|
191
|
+
/**
|
|
192
|
+
* The maximum number of calls to make to an LLM in case it fails.
|
|
193
|
+
* This can be overridden at each generate/stream callsite.
|
|
194
|
+
*/
|
|
195
|
+
maxRetries?: number;
|
|
135
196
|
}
|
|
136
197
|
) {}
|
|
137
198
|
|
|
@@ -227,12 +288,34 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
227
288
|
};
|
|
228
289
|
}
|
|
229
290
|
|
|
291
|
+
/**
|
|
292
|
+
* Continues a thread using this agent. Note: threads can be continued
|
|
293
|
+
* by different agents. This is a convenience around calling the various
|
|
294
|
+
* generate and stream functions with explicit userId and threadId parameters.
|
|
295
|
+
* @param ctx The ctx object passed to the action handler
|
|
296
|
+
* @param { threadId, userId }: the thread and user to associate the messages with.
|
|
297
|
+
* @returns Functions bound to the userId and threadId on a `{thread}` object.
|
|
298
|
+
*/
|
|
299
|
+
/**
|
|
300
|
+
* Continues a thread using this agent. Note: threads can be continued
|
|
301
|
+
* by different agents. This is a convenience around calling the various
|
|
302
|
+
* generate and stream functions with explicit userId and threadId parameters.
|
|
303
|
+
* @param ctx The ctx object passed to the action handler
|
|
304
|
+
* @param { threadId, userId }: the thread and user to associate the messages with.
|
|
305
|
+
* @returns Functions bound to the userId and threadId on a `{thread}` object.
|
|
306
|
+
*/
|
|
230
307
|
async continueThread(
|
|
231
308
|
ctx: RunActionCtx,
|
|
232
309
|
{
|
|
233
310
|
threadId,
|
|
234
311
|
userId,
|
|
235
312
|
}: {
|
|
313
|
+
/**
|
|
314
|
+
* The associated thread created by {@link createThread}
|
|
315
|
+
*/
|
|
316
|
+
/**
|
|
317
|
+
* The associated thread created by {@link createThread}
|
|
318
|
+
*/
|
|
236
319
|
threadId: string;
|
|
237
320
|
/**
|
|
238
321
|
* If supplied, the userId can be used to search across other threads for
|
|
@@ -243,7 +326,6 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
243
326
|
): Promise<{
|
|
244
327
|
thread: Thread<AgentTools>;
|
|
245
328
|
}> {
|
|
246
|
-
// return this.component.continueThread(ctx, args);
|
|
247
329
|
return {
|
|
248
330
|
thread: {
|
|
249
331
|
threadId,
|
|
@@ -258,6 +340,22 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
258
340
|
};
|
|
259
341
|
}
|
|
260
342
|
|
|
343
|
+
/**
|
|
344
|
+
*
|
|
345
|
+
* @param ctx Either a query, mutation, or action ctx.
|
|
346
|
+
* If it is not an action context, you can't do text or
|
|
347
|
+
* vector search.
|
|
348
|
+
* @param args The associated thread, user, message
|
|
349
|
+
* @returns
|
|
350
|
+
*/
|
|
351
|
+
/**
|
|
352
|
+
*
|
|
353
|
+
* @param ctx Either a query, mutation, or action ctx.
|
|
354
|
+
* If it is not an action context, you can't do text or
|
|
355
|
+
* vector search.
|
|
356
|
+
* @param args The associated thread, user, message
|
|
357
|
+
* @returns
|
|
358
|
+
*/
|
|
261
359
|
async fetchContextMessages(
|
|
262
360
|
ctx: RunQueryCtx | RunActionCtx,
|
|
263
361
|
args: {
|
|
@@ -287,7 +385,9 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
287
385
|
);
|
|
288
386
|
// TODO: track what messages we used for context
|
|
289
387
|
included = new Set(searchMessages.map((m) => m._id));
|
|
290
|
-
contextMessages.push(
|
|
388
|
+
contextMessages.push(
|
|
389
|
+
...searchMessages.map((m) => deserializeMessage(m.message!))
|
|
390
|
+
);
|
|
291
391
|
}
|
|
292
392
|
if (args.threadId && opts.recentMessages !== 0) {
|
|
293
393
|
const { page } = await ctx.runQuery(
|
|
@@ -305,7 +405,9 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
305
405
|
}
|
|
306
406
|
);
|
|
307
407
|
contextMessages.push(
|
|
308
|
-
...page
|
|
408
|
+
...page
|
|
409
|
+
.filter((m) => !included?.has(m._id))
|
|
410
|
+
.map((m) => deserializeMessage(m.message!))
|
|
309
411
|
);
|
|
310
412
|
}
|
|
311
413
|
return contextMessages;
|
|
@@ -350,14 +452,48 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
350
452
|
return embeddings;
|
|
351
453
|
}
|
|
352
454
|
|
|
455
|
+
/**
|
|
456
|
+
* Explicitly save messages associated with the thread (& user if provided)
|
|
457
|
+
* @param ctx The ctx parameter to a mutation or action.
|
|
458
|
+
* @param args The messages and context to save
|
|
459
|
+
* @returns
|
|
460
|
+
*/
|
|
461
|
+
/**
|
|
462
|
+
* Explicitly save messages associated with the thread (& user if provided)
|
|
463
|
+
* @param ctx The ctx parameter to a mutation or action.
|
|
464
|
+
* @param args The messages and context to save
|
|
465
|
+
* @returns
|
|
466
|
+
*/
|
|
353
467
|
async saveMessages(
|
|
354
468
|
ctx: RunMutationCtx,
|
|
355
469
|
args: {
|
|
356
470
|
threadId: string;
|
|
357
471
|
userId?: string;
|
|
358
472
|
messages: CoreMessageMaybeWithId[];
|
|
473
|
+
/**
|
|
474
|
+
* If false, it will "commit" the messages immediately.
|
|
475
|
+
* If true, it will mark them as pending until the final step has finished.
|
|
476
|
+
*/
|
|
477
|
+
/**
|
|
478
|
+
* If false, it will "commit" the messages immediately.
|
|
479
|
+
* If true, it will mark them as pending until the final step has finished.
|
|
480
|
+
*/
|
|
359
481
|
pending?: boolean;
|
|
482
|
+
/**
|
|
483
|
+
* The message that this is responding to.
|
|
484
|
+
*/
|
|
485
|
+
/**
|
|
486
|
+
* The message that this is responding to.
|
|
487
|
+
*/
|
|
360
488
|
parentMessageId?: string;
|
|
489
|
+
/**
|
|
490
|
+
* Whether to mark all pending messages in the thread as failed.
|
|
491
|
+
* This is used to recover from a failure via a retry that wipes the slate clean.
|
|
492
|
+
*/
|
|
493
|
+
/**
|
|
494
|
+
* Whether to mark all pending messages in the thread as failed.
|
|
495
|
+
* This is used to recover from a failure via a retry that wipes the slate clean.
|
|
496
|
+
*/
|
|
361
497
|
failPendingSteps?: boolean;
|
|
362
498
|
}
|
|
363
499
|
): Promise<{
|
|
@@ -381,9 +517,29 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
381
517
|
};
|
|
382
518
|
}
|
|
383
519
|
|
|
520
|
+
/**
|
|
521
|
+
* Explicitly save a "step" created by the AI SDK.
|
|
522
|
+
* @param ctx The ctx argument to a mutation or action.
|
|
523
|
+
* @param args What to save
|
|
524
|
+
*/
|
|
525
|
+
/**
|
|
526
|
+
* Explicitly save a "step" created by the AI SDK.
|
|
527
|
+
* @param ctx The ctx argument to a mutation or action.
|
|
528
|
+
* @param args What to save
|
|
529
|
+
*/
|
|
384
530
|
async saveStep<TOOLS extends ToolSet>(
|
|
385
531
|
ctx: RunMutationCtx,
|
|
386
|
-
args: {
|
|
532
|
+
args: {
|
|
533
|
+
threadId: string;
|
|
534
|
+
/**
|
|
535
|
+
* The message this step is in response to.
|
|
536
|
+
*/
|
|
537
|
+
messageId: string;
|
|
538
|
+
/**
|
|
539
|
+
* The step to save, possibly including multiple tool calls.
|
|
540
|
+
*/
|
|
541
|
+
step: StepResult<TOOLS>;
|
|
542
|
+
}
|
|
387
543
|
): Promise<void> {
|
|
388
544
|
const step = serializeStep(args.step as StepResult<ToolSet>);
|
|
389
545
|
const messages = serializeNewMessagesInStep(args.step);
|
|
@@ -396,15 +552,28 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
396
552
|
});
|
|
397
553
|
}
|
|
398
554
|
|
|
399
|
-
|
|
400
|
-
|
|
555
|
+
/**
|
|
556
|
+
* Commit or rollback a message that was pending.
|
|
557
|
+
* This is done automatically when saving messages by default.
|
|
558
|
+
* If creating pending messages, you can call this when the full "transaction" is done.
|
|
559
|
+
* @param ctx The ctx argument to your mutation or action.
|
|
560
|
+
* @param args What message to save. Generally the parent message sent into
|
|
561
|
+
* the generateText call.
|
|
562
|
+
*/
|
|
563
|
+
/**
|
|
564
|
+
* Commit or rollback a message that was pending.
|
|
565
|
+
* This is done automatically when saving messages by default.
|
|
566
|
+
* If creating pending messages, you can call this when the full "transaction" is done.
|
|
567
|
+
* @param ctx The ctx argument to your mutation or action.
|
|
568
|
+
* @param args What message to save. Generally the parent message sent into
|
|
569
|
+
* the generateText call.
|
|
570
|
+
*/
|
|
571
|
+
async completeMessage(
|
|
401
572
|
ctx: RunMutationCtx,
|
|
402
573
|
args: {
|
|
403
574
|
threadId: string;
|
|
404
575
|
messageId: string;
|
|
405
|
-
result:
|
|
406
|
-
| { kind: "error"; error: string }
|
|
407
|
-
| { kind: "success"; value: { steps: StepResult<TOOLS>[] } };
|
|
576
|
+
result: { kind: "error"; error: string } | { kind: "success" };
|
|
408
577
|
}
|
|
409
578
|
): Promise<void> {
|
|
410
579
|
const result = args.result;
|
|
@@ -421,12 +590,15 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
421
590
|
}
|
|
422
591
|
|
|
423
592
|
/**
|
|
424
|
-
* This behaves like {@link generateText}
|
|
425
|
-
* the userId and threadId
|
|
426
|
-
* thread, if specified.
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
* @param
|
|
593
|
+
* This behaves like {@link generateText} from the "ai" package except that
|
|
594
|
+
* it add context based on the userId and threadId and saves the input and
|
|
595
|
+
* resulting messages to the thread, if specified.
|
|
596
|
+
* Use {@link continueThread} to get a version of this function already scoped
|
|
597
|
+
* to a thread (and optionally userId).
|
|
598
|
+
* @param ctx The context passed from the action function calling this.
|
|
599
|
+
* @param { userId, threadId }: The user and thread to associate the message with
|
|
600
|
+
* @param args The arguments to the generateText function, along with extra controls
|
|
601
|
+
* for the {@link ContextOptions} and {@link StorageOptions}.
|
|
430
602
|
* @returns The result of the generateText function.
|
|
431
603
|
*/
|
|
432
604
|
async generateText<
|
|
@@ -456,17 +628,21 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
456
628
|
);
|
|
457
629
|
const toolCtx = { ...ctx, userId, threadId, messageId };
|
|
458
630
|
const tools = wrapTools(toolCtx, this.options.tools, args.tools) as TOOLS;
|
|
459
|
-
const
|
|
631
|
+
const saveOutputMessages =
|
|
632
|
+
args.saveOutputMessages ??
|
|
633
|
+
this.options.storageOptions?.saveOutputMessages;
|
|
460
634
|
try {
|
|
461
635
|
const result = (await generateText({
|
|
636
|
+
// Can be overridden
|
|
462
637
|
model: this.options.chat,
|
|
638
|
+
maxSteps: this.options.maxSteps,
|
|
639
|
+
maxRetries: this.options.maxRetries,
|
|
463
640
|
...aiArgs,
|
|
464
|
-
maxSteps,
|
|
465
641
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
466
642
|
toolChoice: args.toolChoice as any,
|
|
467
643
|
tools,
|
|
468
644
|
onStepFinish: async (step) => {
|
|
469
|
-
if (threadId && messageId &&
|
|
645
|
+
if (threadId && messageId && saveOutputMessages !== false) {
|
|
470
646
|
await this.saveStep(ctx, {
|
|
471
647
|
threadId,
|
|
472
648
|
messageId,
|
|
@@ -490,6 +666,18 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
490
666
|
}
|
|
491
667
|
}
|
|
492
668
|
|
|
669
|
+
/**
|
|
670
|
+
* This behaves like {@link streamText} from the "ai" package except that
|
|
671
|
+
* it add context based on the userId and threadId and saves the input and
|
|
672
|
+
* resulting messages to the thread, if specified.
|
|
673
|
+
* Use {@link continueThread} to get a version of this function already scoped
|
|
674
|
+
* to a thread (and optionally userId).
|
|
675
|
+
* @param ctx The context passed from the action function calling this.
|
|
676
|
+
* @param { userId, threadId }: The user and thread to associate the message with
|
|
677
|
+
* @param args The arguments to the streamText function, along with extra controls
|
|
678
|
+
* for the {@link ContextOptions} and {@link StorageOptions}.
|
|
679
|
+
* @returns The result of the streamText function.
|
|
680
|
+
*/
|
|
493
681
|
async streamText<
|
|
494
682
|
TOOLS extends ToolSet,
|
|
495
683
|
OUTPUT = never,
|
|
@@ -511,11 +699,15 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
511
699
|
);
|
|
512
700
|
const toolCtx = { ...ctx, userId, threadId, messageId };
|
|
513
701
|
const tools = wrapTools(toolCtx, this.options.tools, args.tools) as TOOLS;
|
|
514
|
-
const
|
|
702
|
+
const saveOutputMessages =
|
|
703
|
+
args.saveOutputMessages ??
|
|
704
|
+
this.options.storageOptions?.saveOutputMessages;
|
|
515
705
|
const result = streamText({
|
|
706
|
+
// Can be overridden
|
|
516
707
|
model: this.options.chat,
|
|
708
|
+
maxSteps: this.options.maxSteps,
|
|
709
|
+
maxRetries: this.options.maxRetries,
|
|
517
710
|
...aiArgs,
|
|
518
|
-
maxSteps,
|
|
519
711
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
520
712
|
toolChoice: args.toolChoice as any,
|
|
521
713
|
tools,
|
|
@@ -525,7 +717,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
525
717
|
},
|
|
526
718
|
onError: async (error) => {
|
|
527
719
|
console.error("onError", error);
|
|
528
|
-
if (threadId && messageId &&
|
|
720
|
+
if (threadId && messageId && saveOutputMessages !== false) {
|
|
529
721
|
await ctx.runMutation(this.component.messages.rollbackMessage, {
|
|
530
722
|
messageId,
|
|
531
723
|
error: (error.error as Error).message,
|
|
@@ -562,7 +754,6 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
562
754
|
userId,
|
|
563
755
|
threadId,
|
|
564
756
|
parentMessageId,
|
|
565
|
-
saveAllInputMessages,
|
|
566
757
|
system,
|
|
567
758
|
...args
|
|
568
759
|
}: {
|
|
@@ -577,6 +768,12 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
577
768
|
args: T;
|
|
578
769
|
messageId: string | undefined;
|
|
579
770
|
}> {
|
|
771
|
+
const saveAny =
|
|
772
|
+
args.saveAnyInputMessages ??
|
|
773
|
+
this.options.storageOptions?.saveAnyInputMessages;
|
|
774
|
+
const saveAll =
|
|
775
|
+
args.saveAllInputMessages ??
|
|
776
|
+
this.options.storageOptions?.saveAllInputMessages;
|
|
580
777
|
const messages = promptOrMessagesToCoreMessages(args);
|
|
581
778
|
const contextMessages = await this.fetchContextMessages(ctx, {
|
|
582
779
|
messages,
|
|
@@ -586,11 +783,11 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
586
783
|
...args,
|
|
587
784
|
});
|
|
588
785
|
let messageId: string | undefined;
|
|
589
|
-
if (threadId) {
|
|
786
|
+
if (threadId && saveAny !== false) {
|
|
590
787
|
const saved = await this.saveMessages(ctx, {
|
|
591
788
|
threadId,
|
|
592
789
|
userId,
|
|
593
|
-
messages:
|
|
790
|
+
messages: saveAll ? messages : messages.slice(-1),
|
|
594
791
|
pending: true,
|
|
595
792
|
// We should just fail if you pass in an ID for the message, fail those children
|
|
596
793
|
// failPendingSteps: true,
|
|
@@ -609,6 +806,18 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
609
806
|
};
|
|
610
807
|
}
|
|
611
808
|
|
|
809
|
+
/**
|
|
810
|
+
* This behaves like {@link generateObject} from the "ai" package except that
|
|
811
|
+
* it add context based on the userId and threadId and saves the input and
|
|
812
|
+
* resulting messages to the thread, if specified.
|
|
813
|
+
* Use {@link continueThread} to get a version of this function already scoped
|
|
814
|
+
* to a thread (and optionally userId).
|
|
815
|
+
* @param ctx The context passed from the action function calling this.
|
|
816
|
+
* @param { userId, threadId }: The user and thread to associate the message with
|
|
817
|
+
* @param args The arguments to the generateObject function, along with extra controls
|
|
818
|
+
* for the {@link ContextOptions} and {@link StorageOptions}.
|
|
819
|
+
* @returns The result of the generateObject function.
|
|
820
|
+
*/
|
|
612
821
|
async generateObject<T>(
|
|
613
822
|
ctx: RunActionCtx,
|
|
614
823
|
{ userId, threadId }: { userId?: string; threadId?: string },
|
|
@@ -619,14 +828,19 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
619
828
|
{ ...args, userId, threadId }
|
|
620
829
|
);
|
|
621
830
|
|
|
831
|
+
const saveOutputMessages =
|
|
832
|
+
args.saveOutputMessages ??
|
|
833
|
+
this.options.storageOptions?.saveOutputMessages;
|
|
622
834
|
try {
|
|
623
835
|
const result = (await generateObject({
|
|
836
|
+
// Can be overridden
|
|
624
837
|
model: this.options.chat,
|
|
838
|
+
maxRetries: this.options.maxRetries,
|
|
625
839
|
...aiArgs,
|
|
626
840
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
627
841
|
} as any)) as GenerateObjectResult<T> & GenerationOutputMetadata;
|
|
628
842
|
|
|
629
|
-
if (threadId && messageId &&
|
|
843
|
+
if (threadId && messageId && saveOutputMessages !== false) {
|
|
630
844
|
await this.saveObject(ctx, { threadId, messageId, result });
|
|
631
845
|
}
|
|
632
846
|
result.messageId = messageId;
|
|
@@ -642,6 +856,18 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
642
856
|
}
|
|
643
857
|
}
|
|
644
858
|
|
|
859
|
+
/**
|
|
860
|
+
* This behaves like {@link streamObject} from the "ai" package except that
|
|
861
|
+
* it add context based on the userId and threadId and saves the input and
|
|
862
|
+
* resulting messages to the thread, if specified.
|
|
863
|
+
* Use {@link continueThread} to get a version of this function already scoped
|
|
864
|
+
* to a thread (and optionally userId).
|
|
865
|
+
* @param ctx The context passed from the action function calling this.
|
|
866
|
+
* @param { userId, threadId }: The user and thread to associate the message with
|
|
867
|
+
* @param args The arguments to the streamObject function, along with extra controls
|
|
868
|
+
* for the {@link ContextOptions} and {@link StorageOptions}.
|
|
869
|
+
* @returns The result of the streamObject function.
|
|
870
|
+
*/
|
|
645
871
|
async streamObject<T>(
|
|
646
872
|
ctx: RunMutationCtx,
|
|
647
873
|
{ userId, threadId }: { userId?: string; threadId?: string },
|
|
@@ -654,8 +880,13 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
654
880
|
ctx,
|
|
655
881
|
{ ...args, userId, threadId }
|
|
656
882
|
);
|
|
883
|
+
const saveOutputMessages =
|
|
884
|
+
args.saveOutputMessages ??
|
|
885
|
+
this.options.storageOptions?.saveOutputMessages;
|
|
657
886
|
const stream = streamObject<T>({
|
|
887
|
+
// Can be overridden
|
|
658
888
|
model: this.options.chat,
|
|
889
|
+
maxRetries: this.options.maxRetries,
|
|
659
890
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
660
891
|
...(aiArgs as any),
|
|
661
892
|
onError: async (error) => {
|
|
@@ -663,7 +894,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
663
894
|
return args.onError?.(error);
|
|
664
895
|
},
|
|
665
896
|
onFinish: async (result) => {
|
|
666
|
-
if (threadId && messageId &&
|
|
897
|
+
if (threadId && messageId && saveOutputMessages !== false) {
|
|
667
898
|
await this.saveObject(ctx, {
|
|
668
899
|
threadId,
|
|
669
900
|
messageId,
|
|
@@ -691,6 +922,13 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
691
922
|
return stream;
|
|
692
923
|
}
|
|
693
924
|
|
|
925
|
+
/**
|
|
926
|
+
* Manually save the result of a generateObject call to the thread.
|
|
927
|
+
* This happens automatically when using {@link generateObject} or {@link streamObject}
|
|
928
|
+
* from the `thread` object created by {@link continueThread} or {@link createThread}.
|
|
929
|
+
* @param ctx The context passed from the mutation or action function calling this.
|
|
930
|
+
* @param args The arguments to the saveObject function.
|
|
931
|
+
*/
|
|
694
932
|
async saveObject(
|
|
695
933
|
ctx: RunMutationCtx,
|
|
696
934
|
args: {
|
|
@@ -758,7 +996,11 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
758
996
|
}
|
|
759
997
|
|
|
760
998
|
/**
|
|
761
|
-
*
|
|
999
|
+
* Create an action out of this agent so you can call it from workflows or other actions
|
|
1000
|
+
* without a wrapping function.
|
|
1001
|
+
* Note: currently this is not well typed. The return type of the action is always `any`.
|
|
1002
|
+
* @param spec Configuration for the agent acting as an action, including
|
|
1003
|
+
* {@link ContextOptions} and maxSteps.
|
|
762
1004
|
*/
|
|
763
1005
|
asAction(spec?: { contextOptions?: ContextOptions; maxSteps?: number }) {
|
|
764
1006
|
return internalActionGeneric({
|
|
@@ -847,7 +1089,8 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
847
1089
|
}
|
|
848
1090
|
|
|
849
1091
|
/**
|
|
850
|
-
* Create a tool
|
|
1092
|
+
* Create a tool out of this agent so other agents can call this one.
|
|
1093
|
+
* Create a tool out of this agent so other agents can call this one.
|
|
851
1094
|
* @param spec The specification for the arguments to this agent.
|
|
852
1095
|
* They will be encoded as JSON and passed to the agent.
|
|
853
1096
|
* @returns The agent as a tool that can be passed to other agents.
|
|
@@ -985,7 +1228,7 @@ type BaseGenerateObjectOptions = StorageOptions &
|
|
|
985
1228
|
|
|
986
1229
|
type GenerateObjectObjectOptions<T extends Record<string, unknown>> =
|
|
987
1230
|
BaseGenerateObjectOptions & {
|
|
988
|
-
output
|
|
1231
|
+
output?: "object";
|
|
989
1232
|
mode?: "auto" | "json" | "tool";
|
|
990
1233
|
schema: z.Schema<T>;
|
|
991
1234
|
schemaName?: string;
|
|
@@ -1042,7 +1285,20 @@ type OurStreamObjectArgs<T> = StreamObjectArgs<T> &
|
|
|
1042
1285
|
>;
|
|
1043
1286
|
|
|
1044
1287
|
interface Thread<AgentTools extends ToolSet> {
|
|
1288
|
+
/**
|
|
1289
|
+
* The target threadId, from the startThread or continueThread initializers.
|
|
1290
|
+
*/
|
|
1045
1291
|
threadId: string;
|
|
1292
|
+
/**
|
|
1293
|
+
* This behaves like {@link generateText} from the "ai" package except that
|
|
1294
|
+
* it add context based on the userId and threadId and saves the input and
|
|
1295
|
+
* resulting messages to the thread, if specified.
|
|
1296
|
+
* Use {@link continueThread} to get a version of this function already scoped
|
|
1297
|
+
* to a thread (and optionally userId).
|
|
1298
|
+
* @param args The arguments to the generateText function, along with extra controls
|
|
1299
|
+
* for the {@link ContextOptions} and {@link StorageOptions}.
|
|
1300
|
+
* @returns The result of the generateText function.
|
|
1301
|
+
*/
|
|
1046
1302
|
generateText<TOOLS extends ToolSet, OUTPUT = never, OUTPUT_PARTIAL = never>(
|
|
1047
1303
|
args: TextArgs<
|
|
1048
1304
|
AgentTools,
|
|
@@ -1053,6 +1309,16 @@ interface Thread<AgentTools extends ToolSet> {
|
|
|
1053
1309
|
GenerateTextResult<TOOLS & AgentTools, OUTPUT> & GenerationOutputMetadata
|
|
1054
1310
|
>;
|
|
1055
1311
|
|
|
1312
|
+
/**
|
|
1313
|
+
* This behaves like {@link streamText} from the "ai" package except that
|
|
1314
|
+
* it add context based on the userId and threadId and saves the input and
|
|
1315
|
+
* resulting messages to the thread, if specified.
|
|
1316
|
+
* Use {@link continueThread} to get a version of this function already scoped
|
|
1317
|
+
* to a thread (and optionally userId).
|
|
1318
|
+
* @param args The arguments to the streamText function, along with extra controls
|
|
1319
|
+
* for the {@link ContextOptions} and {@link StorageOptions}.
|
|
1320
|
+
* @returns The result of the streamText function.
|
|
1321
|
+
*/
|
|
1056
1322
|
streamText<TOOLS extends ToolSet, OUTPUT = never, PARTIAL_OUTPUT = never>(
|
|
1057
1323
|
args: TextArgs<
|
|
1058
1324
|
AgentTools,
|
|
@@ -1063,13 +1329,42 @@ interface Thread<AgentTools extends ToolSet> {
|
|
|
1063
1329
|
StreamTextResult<TOOLS & AgentTools, PARTIAL_OUTPUT> &
|
|
1064
1330
|
GenerationOutputMetadata
|
|
1065
1331
|
>;
|
|
1066
|
-
|
|
1332
|
+
/**
|
|
1333
|
+
* This behaves like {@link generateObject} from the "ai" package except that
|
|
1334
|
+
* it add context based on the userId and threadId and saves the input and
|
|
1335
|
+
* resulting messages to the thread, if specified. This overload is for objects, arrays, and enums.
|
|
1336
|
+
* Use {@link continueThread} to get a version of this function already scoped
|
|
1337
|
+
* to a thread (and optionally userId).
|
|
1338
|
+
* @param args The arguments to the generateObject function, along with extra controls
|
|
1339
|
+
* for the {@link ContextOptions} and {@link StorageOptions}.
|
|
1340
|
+
* @returns The result of the generateObject function.
|
|
1341
|
+
*/
|
|
1067
1342
|
generateObject<T>(
|
|
1068
1343
|
args: OurObjectArgs<T>
|
|
1069
1344
|
): Promise<GenerateObjectResult<T> & GenerationOutputMetadata>;
|
|
1345
|
+
/**
|
|
1346
|
+
* This behaves like {@link generateObject} from the "ai" package except that
|
|
1347
|
+
* it add context based on the userId and threadId and saves the input and
|
|
1348
|
+
* resulting messages to the thread, if specified. This overload is for when there's no schema.
|
|
1349
|
+
* Use {@link continueThread} to get a version of this function already scoped
|
|
1350
|
+
* to a thread (and optionally userId).
|
|
1351
|
+
* @param args The arguments to the generateObject function, along with extra controls
|
|
1352
|
+
* for the {@link ContextOptions} and {@link StorageOptions}.
|
|
1353
|
+
* @returns The result of the generateObject function.
|
|
1354
|
+
*/
|
|
1070
1355
|
generateObject(
|
|
1071
1356
|
args: GenerateObjectNoSchemaOptions
|
|
1072
1357
|
): Promise<GenerateObjectResult<JSONValue> & GenerationOutputMetadata>;
|
|
1358
|
+
/**
|
|
1359
|
+
* This behaves like {@link streamObject} from the "ai" package except that
|
|
1360
|
+
* it add context based on the userId and threadId and saves the input and
|
|
1361
|
+
* resulting messages to the thread, if specified.
|
|
1362
|
+
* Use {@link continueThread} to get a version of this function already scoped
|
|
1363
|
+
* to a thread (and optionally userId).
|
|
1364
|
+
* @param args The arguments to the streamObject function, along with extra controls
|
|
1365
|
+
* for the {@link ContextOptions} and {@link StorageOptions}.
|
|
1366
|
+
* @returns The result of the streamObject function.
|
|
1367
|
+
*/
|
|
1073
1368
|
streamObject<T>(
|
|
1074
1369
|
args: OurStreamObjectArgs<T>
|
|
1075
1370
|
): Promise<
|