@convex-dev/agent 0.0.17-alpha.2 → 0.1.0
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 +26 -8
- package/dist/commonjs/client/index.d.ts +229 -756
- package/dist/commonjs/client/index.d.ts.map +1 -1
- package/dist/commonjs/client/index.js +135 -140
- package/dist/commonjs/client/index.js.map +1 -1
- package/dist/commonjs/component/messages.d.ts +208 -896
- package/dist/commonjs/component/messages.d.ts.map +1 -1
- package/dist/commonjs/component/messages.js +117 -109
- package/dist/commonjs/component/messages.js.map +1 -1
- package/dist/commonjs/component/schema.d.ts +1278 -580
- package/dist/commonjs/component/schema.d.ts.map +1 -1
- package/dist/commonjs/component/schema.js +28 -21
- package/dist/commonjs/component/schema.js.map +1 -1
- package/dist/commonjs/component/users.d.ts +5 -2
- package/dist/commonjs/component/users.d.ts.map +1 -1
- package/dist/commonjs/component/users.js +57 -27
- package/dist/commonjs/component/users.js.map +1 -1
- package/dist/commonjs/validators.d.ts +44 -59
- package/dist/commonjs/validators.d.ts.map +1 -1
- package/dist/commonjs/validators.js +10 -12
- package/dist/commonjs/validators.js.map +1 -1
- package/dist/esm/client/index.d.ts +229 -756
- package/dist/esm/client/index.d.ts.map +1 -1
- package/dist/esm/client/index.js +135 -140
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/component/messages.d.ts +208 -896
- package/dist/esm/component/messages.d.ts.map +1 -1
- package/dist/esm/component/messages.js +117 -109
- package/dist/esm/component/messages.js.map +1 -1
- package/dist/esm/component/schema.d.ts +1278 -580
- package/dist/esm/component/schema.d.ts.map +1 -1
- package/dist/esm/component/schema.js +28 -21
- package/dist/esm/component/schema.js.map +1 -1
- package/dist/esm/component/users.d.ts +5 -2
- package/dist/esm/component/users.d.ts.map +1 -1
- package/dist/esm/component/users.js +57 -27
- package/dist/esm/component/users.js.map +1 -1
- package/dist/esm/validators.d.ts +44 -59
- package/dist/esm/validators.d.ts.map +1 -1
- package/dist/esm/validators.js +10 -12
- package/dist/esm/validators.js.map +1 -1
- package/package.json +4 -2
- package/src/client/index.ts +215 -199
- package/src/component/_generated/api.d.ts +19 -94
- package/src/component/messages.test.ts +110 -3
- package/src/component/messages.ts +176 -154
- package/src/component/schema.ts +34 -21
- package/src/component/users.ts +57 -32
- package/src/validators.ts +12 -15
package/src/client/index.ts
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
} from "ai";
|
|
28
28
|
import { assert } from "convex-helpers";
|
|
29
29
|
import { internalActionGeneric, internalMutationGeneric } from "convex/server";
|
|
30
|
-
import {
|
|
30
|
+
import { v } from "convex/values";
|
|
31
31
|
import { z } from "zod";
|
|
32
32
|
import { Mounts } from "../component/_generated/api.js";
|
|
33
33
|
import {
|
|
@@ -57,10 +57,9 @@ import {
|
|
|
57
57
|
type ProviderOptions,
|
|
58
58
|
type SearchOptions,
|
|
59
59
|
type Usage,
|
|
60
|
-
|
|
60
|
+
vMessageWithMetadata,
|
|
61
61
|
vSafeObjectArgs,
|
|
62
62
|
vTextArgs,
|
|
63
|
-
vThreadStatus,
|
|
64
63
|
} from "../validators.js";
|
|
65
64
|
import type {
|
|
66
65
|
OpaqueIds,
|
|
@@ -69,12 +68,16 @@ import type {
|
|
|
69
68
|
RunQueryCtx,
|
|
70
69
|
UseApi,
|
|
71
70
|
} from "./types.js";
|
|
72
|
-
import schema from "../component/schema.js";
|
|
73
71
|
|
|
72
|
+
import type { MessageDoc, ThreadDoc } from "../component/schema.js";
|
|
73
|
+
|
|
74
|
+
export { vMessageDoc, vThreadDoc } from "../component/schema.js";
|
|
74
75
|
export { extractText, isTool };
|
|
75
|
-
export type { Usage, ProviderMetadata };
|
|
76
|
+
export type { Usage, ProviderMetadata, MessageDoc, ThreadDoc };
|
|
76
77
|
export {
|
|
78
|
+
/** @deprecated Use vPaginationResult instead. */
|
|
77
79
|
paginationResultValidator,
|
|
80
|
+
paginationResultValidator as vPaginationResult,
|
|
78
81
|
vContextOptions,
|
|
79
82
|
vUsage,
|
|
80
83
|
vProviderMetadata,
|
|
@@ -261,11 +264,11 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
261
264
|
*/
|
|
262
265
|
userId?: string;
|
|
263
266
|
/**
|
|
264
|
-
* The title of the thread. Not currently used.
|
|
267
|
+
* The title of the thread. Not currently used for anything.
|
|
265
268
|
*/
|
|
266
269
|
title?: string;
|
|
267
270
|
/**
|
|
268
|
-
* The summary of the thread. Not currently used.
|
|
271
|
+
* The summary of the thread. Not currently used for anything.
|
|
269
272
|
*/
|
|
270
273
|
summary?: string;
|
|
271
274
|
/**
|
|
@@ -301,11 +304,11 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
301
304
|
*/
|
|
302
305
|
userId?: string;
|
|
303
306
|
/**
|
|
304
|
-
* The title of the thread. Not currently used.
|
|
307
|
+
* The title of the thread. Not currently used for anything.
|
|
305
308
|
*/
|
|
306
309
|
title?: string;
|
|
307
310
|
/**
|
|
308
|
-
* The summary of the thread. Not currently used.
|
|
311
|
+
* The summary of the thread. Not currently used for anything.
|
|
309
312
|
*/
|
|
310
313
|
summary?: string;
|
|
311
314
|
/**
|
|
@@ -418,37 +421,23 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
418
421
|
threadId: string | undefined;
|
|
419
422
|
messages: CoreMessage[];
|
|
420
423
|
/**
|
|
421
|
-
* If provided, it will search for messages
|
|
422
|
-
* Note: if this is far in the past,
|
|
424
|
+
* If provided, it will search for messages up to and including this message.
|
|
425
|
+
* Note: if this is far in the past, text and vector search results may be more
|
|
423
426
|
* limited, as it's post-filtering the results.
|
|
424
427
|
*/
|
|
425
|
-
|
|
428
|
+
upToAndIncludingMessageId?: string;
|
|
426
429
|
contextOptions: ContextOptions | undefined;
|
|
427
430
|
}
|
|
428
431
|
): Promise<MessageDoc[]> {
|
|
429
432
|
assert(args.userId || args.threadId, "Specify userId or threadId");
|
|
430
433
|
// Fetch the latest messages from the thread
|
|
431
|
-
const contextMessages: MessageDoc[] = [];
|
|
432
434
|
let included: Set<string> | undefined;
|
|
433
435
|
const opts = this.mergedContextOptions(args.contextOptions);
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
this.component.messages.searchMessages,
|
|
440
|
-
{
|
|
441
|
-
userId: opts?.searchOtherThreads ? args.userId : undefined,
|
|
442
|
-
threadId: args.threadId,
|
|
443
|
-
beforeMessageId: args.beforeMessageId,
|
|
444
|
-
...(await this.searchOptionsWithDefaults(opts, args.messages)),
|
|
445
|
-
}
|
|
446
|
-
);
|
|
447
|
-
// TODO: track what messages we used for context
|
|
448
|
-
included = new Set(searchMessages.map((m) => m._id));
|
|
449
|
-
contextMessages.push(...searchMessages);
|
|
450
|
-
}
|
|
451
|
-
if (args.threadId && opts.recentMessages !== 0) {
|
|
436
|
+
const contextMessages: MessageDoc[] = [];
|
|
437
|
+
if (
|
|
438
|
+
args.threadId &&
|
|
439
|
+
(opts.recentMessages !== 0 || args.upToAndIncludingMessageId)
|
|
440
|
+
) {
|
|
452
441
|
const { page } = await ctx.runQuery(
|
|
453
442
|
this.component.messages.listMessagesByThreadId,
|
|
454
443
|
{
|
|
@@ -459,14 +448,39 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
459
448
|
numItems: opts.recentMessages ?? DEFAULT_RECENT_MESSAGES,
|
|
460
449
|
cursor: null,
|
|
461
450
|
},
|
|
462
|
-
|
|
451
|
+
upToAndIncludingMessageId: args.upToAndIncludingMessageId,
|
|
463
452
|
order: "desc",
|
|
464
453
|
statuses: ["success"],
|
|
465
454
|
}
|
|
466
455
|
);
|
|
456
|
+
included = new Set(page.map((m) => m._id));
|
|
467
457
|
contextMessages.push(
|
|
468
458
|
// Reverse since we fetched in descending order
|
|
469
|
-
...page.
|
|
459
|
+
...page.reverse()
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
if (opts.searchOptions?.textSearch || opts.searchOptions?.vectorSearch) {
|
|
463
|
+
const targetMessage = contextMessages.find(
|
|
464
|
+
(m) => m._id === args.upToAndIncludingMessageId
|
|
465
|
+
)?.message;
|
|
466
|
+
const messagesToSearch = targetMessage
|
|
467
|
+
? [targetMessage, ...args.messages]
|
|
468
|
+
: args.messages;
|
|
469
|
+
if (!("runAction" in ctx)) {
|
|
470
|
+
throw new Error("searchUserMessages only works in an action");
|
|
471
|
+
}
|
|
472
|
+
const searchMessages = await ctx.runAction(
|
|
473
|
+
this.component.messages.searchMessages,
|
|
474
|
+
{
|
|
475
|
+
userId: opts?.searchOtherThreads ? args.userId : undefined,
|
|
476
|
+
threadId: args.threadId,
|
|
477
|
+
beforeMessageId: args.upToAndIncludingMessageId,
|
|
478
|
+
...(await this.searchOptionsWithDefaults(opts, messagesToSearch)),
|
|
479
|
+
}
|
|
480
|
+
);
|
|
481
|
+
// TODO: track what messages we used for context
|
|
482
|
+
contextMessages.unshift(
|
|
483
|
+
...searchMessages.filter((m) => !included?.has(m._id))
|
|
470
484
|
);
|
|
471
485
|
}
|
|
472
486
|
// Ensure we don't include tool messages without a corresponding tool call
|
|
@@ -534,6 +548,14 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
534
548
|
args: {
|
|
535
549
|
threadId: string;
|
|
536
550
|
userId?: string;
|
|
551
|
+
/**
|
|
552
|
+
* The message that these messages are in response to. They will be
|
|
553
|
+
* the same "order" as this message, at increasing stepOrder(s).
|
|
554
|
+
*/
|
|
555
|
+
promptMessageId?: string;
|
|
556
|
+
/**
|
|
557
|
+
* The messages to save.
|
|
558
|
+
*/
|
|
537
559
|
messages: CoreMessageMaybeWithId[];
|
|
538
560
|
/**
|
|
539
561
|
* Metadata to save with the messages. Each element corresponds to the
|
|
@@ -561,14 +583,11 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
561
583
|
threadId: args.threadId,
|
|
562
584
|
userId: args.userId,
|
|
563
585
|
agentName: this.options.name,
|
|
586
|
+
promptMessageId: args.promptMessageId,
|
|
587
|
+
embeddings,
|
|
564
588
|
messages: args.messages.map(
|
|
565
589
|
(m, i) =>
|
|
566
590
|
({
|
|
567
|
-
embedding: embeddings?.vectors[i] && {
|
|
568
|
-
model: embeddings.model,
|
|
569
|
-
dimension: embeddings.dimension,
|
|
570
|
-
vector: embeddings.vectors[i],
|
|
571
|
-
},
|
|
572
591
|
...args.metadata?.[i],
|
|
573
592
|
message: serializeMessage(m),
|
|
574
593
|
}) as MessageWithMetadata
|
|
@@ -582,10 +601,40 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
582
601
|
};
|
|
583
602
|
}
|
|
584
603
|
|
|
604
|
+
/**
|
|
605
|
+
* Save messages to the thread.
|
|
606
|
+
* Useful as a step in Workflows, e.g.
|
|
607
|
+
* ```ts
|
|
608
|
+
* const saveMessages = agent.asSaveMessagesMutation();
|
|
609
|
+
*
|
|
610
|
+
* const myWorkflow = workflow.define()
|
|
611
|
+
* ```
|
|
612
|
+
* @returns A mutation that can be used to save messages to the thread.
|
|
613
|
+
*/
|
|
614
|
+
asSaveMessagesMutation() {
|
|
615
|
+
return internalMutationGeneric({
|
|
616
|
+
args: {
|
|
617
|
+
threadId: v.string(),
|
|
618
|
+
userId: v.optional(v.string()),
|
|
619
|
+
promptMessageId: v.optional(v.string()),
|
|
620
|
+
messages: v.array(vMessageWithMetadata),
|
|
621
|
+
pending: v.optional(v.boolean()),
|
|
622
|
+
failPendingSteps: v.optional(v.boolean()),
|
|
623
|
+
},
|
|
624
|
+
handler: async (ctx, args) => {
|
|
625
|
+
return this.saveMessages(ctx, {
|
|
626
|
+
...args,
|
|
627
|
+
messages: args.messages.map((m) => m.message),
|
|
628
|
+
metadata: args.messages.map(({ message: _, ...m }) => m),
|
|
629
|
+
});
|
|
630
|
+
},
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
|
|
585
634
|
/**
|
|
586
635
|
* Explicitly save a "step" created by the AI SDK.
|
|
587
636
|
* @param ctx The ctx argument to a mutation or action.
|
|
588
|
-
* @param args
|
|
637
|
+
* @param args The Step generated by the AI SDK.
|
|
589
638
|
*/
|
|
590
639
|
async saveStep<TOOLS extends ToolSet>(
|
|
591
640
|
ctx: RunMutationCtx,
|
|
@@ -595,7 +644,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
595
644
|
/**
|
|
596
645
|
* The message this step is in response to.
|
|
597
646
|
*/
|
|
598
|
-
|
|
647
|
+
promptMessageId: string;
|
|
599
648
|
/**
|
|
600
649
|
* The step to save, possibly including multiple tool calls.
|
|
601
650
|
*/
|
|
@@ -620,20 +669,11 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
620
669
|
const embeddings = await this.generateEmbeddings(
|
|
621
670
|
messages.map((m) => m.message)
|
|
622
671
|
);
|
|
623
|
-
if (embeddings) {
|
|
624
|
-
const { model, dimension, vectors } = embeddings;
|
|
625
|
-
for (let i = 0; i < messages.length; i++) {
|
|
626
|
-
const vector = vectors[i];
|
|
627
|
-
if (vector) {
|
|
628
|
-
messages[i].embedding = { model, dimension, vector };
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
672
|
await ctx.runMutation(this.component.messages.addStep, {
|
|
633
673
|
userId: args.userId,
|
|
634
674
|
threadId: args.threadId,
|
|
635
|
-
|
|
636
|
-
step: { step, messages },
|
|
675
|
+
promptMessageId: args.promptMessageId,
|
|
676
|
+
step: { step, messages, embeddings },
|
|
637
677
|
failPendingSteps: false,
|
|
638
678
|
});
|
|
639
679
|
}
|
|
@@ -698,9 +738,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
698
738
|
* set in the agent constructor.
|
|
699
739
|
*/
|
|
700
740
|
usageHandler?: UsageHandler;
|
|
701
|
-
/**
|
|
702
|
-
* The tools to use for this thread. Overrides any tools passed in the agent constructor.
|
|
703
|
-
*/
|
|
741
|
+
/** @deprecated Pass `tools` in the next parameter instead. This is only intended to pass through thread-default tools. */
|
|
704
742
|
tools?: ToolSet;
|
|
705
743
|
},
|
|
706
744
|
args: TextArgs<AgentTools, TOOLS, OUTPUT, OUTPUT_PARTIAL>,
|
|
@@ -709,7 +747,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
709
747
|
GenerateTextResult<TOOLS extends undefined ? AgentTools : TOOLS, OUTPUT> &
|
|
710
748
|
GenerationOutputMetadata
|
|
711
749
|
> {
|
|
712
|
-
const { args: aiArgs, messageId } = await this.
|
|
750
|
+
const { args: aiArgs, messageId } = await this._saveMessagesAndFetchContext(
|
|
713
751
|
ctx,
|
|
714
752
|
args,
|
|
715
753
|
{ userId, threadId, ...options }
|
|
@@ -721,24 +759,20 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
721
759
|
) as TOOLS extends undefined ? AgentTools : TOOLS;
|
|
722
760
|
const saveOutputMessages =
|
|
723
761
|
options?.storageOptions?.saveOutputMessages ??
|
|
724
|
-
args.saveOutputMessages ??
|
|
725
762
|
this.options.storageOptions?.saveOutputMessages;
|
|
726
|
-
const model = aiArgs.model ?? this.options.chat;
|
|
727
763
|
const trackUsage = usageHandler ?? this.options.usageHandler;
|
|
728
764
|
try {
|
|
729
765
|
const result = (await generateText({
|
|
730
766
|
// Can be overridden
|
|
731
767
|
maxSteps: this.options.maxSteps,
|
|
732
|
-
maxRetries: this.options.maxRetries,
|
|
733
768
|
...aiArgs,
|
|
734
|
-
model,
|
|
735
769
|
tools,
|
|
736
770
|
onStepFinish: async (step) => {
|
|
737
771
|
if (threadId && messageId && saveOutputMessages !== false) {
|
|
738
772
|
await this.saveStep(ctx, {
|
|
739
773
|
userId,
|
|
740
774
|
threadId,
|
|
741
|
-
|
|
775
|
+
promptMessageId: messageId,
|
|
742
776
|
step,
|
|
743
777
|
});
|
|
744
778
|
}
|
|
@@ -747,8 +781,8 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
747
781
|
userId,
|
|
748
782
|
threadId,
|
|
749
783
|
agentName: this.options.name,
|
|
750
|
-
model: model.modelId,
|
|
751
|
-
provider: model.provider,
|
|
784
|
+
model: aiArgs.model.modelId,
|
|
785
|
+
provider: aiArgs.model.provider,
|
|
752
786
|
usage: step.usage,
|
|
753
787
|
providerMetadata: step.providerMetadata,
|
|
754
788
|
});
|
|
@@ -780,11 +814,6 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
780
814
|
* resulting messages to the thread, if specified.
|
|
781
815
|
* Use {@link continueThread} to get a version of this function already scoped
|
|
782
816
|
* to a thread (and optionally userId).
|
|
783
|
-
* @param ctx The context passed from the action function calling this.
|
|
784
|
-
* @param { userId, threadId }: The user and thread to associate the message with
|
|
785
|
-
* @param args The arguments to the streamText function, along with extra controls
|
|
786
|
-
* for the {@link ContextOptions} and {@link StorageOptions}.
|
|
787
|
-
* @returns The result of the streamText function.
|
|
788
817
|
*/
|
|
789
818
|
async streamText<
|
|
790
819
|
TOOLS extends ToolSet | undefined = undefined,
|
|
@@ -807,7 +836,14 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
807
836
|
usageHandler?: UsageHandler;
|
|
808
837
|
tools?: ToolSet;
|
|
809
838
|
},
|
|
839
|
+
/**
|
|
840
|
+
* The arguments to the streamText function, similar to the ai `streamText` function.
|
|
841
|
+
*/
|
|
810
842
|
args: StreamingTextArgs<AgentTools, TOOLS, OUTPUT, PARTIAL_OUTPUT>,
|
|
843
|
+
/**
|
|
844
|
+
* The {@link ContextOptions} and {@link StorageOptions}
|
|
845
|
+
* options to use for fetching contextual messages and saving input/output messages.
|
|
846
|
+
*/
|
|
811
847
|
options?: Options
|
|
812
848
|
): Promise<
|
|
813
849
|
StreamTextResult<
|
|
@@ -816,7 +852,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
816
852
|
> &
|
|
817
853
|
GenerationOutputMetadata
|
|
818
854
|
> {
|
|
819
|
-
const { args: aiArgs, messageId } = await this.
|
|
855
|
+
const { args: aiArgs, messageId } = await this._saveMessagesAndFetchContext(
|
|
820
856
|
ctx,
|
|
821
857
|
args,
|
|
822
858
|
{ userId, threadId, ...options }
|
|
@@ -828,16 +864,12 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
828
864
|
) as TOOLS extends undefined ? AgentTools : TOOLS;
|
|
829
865
|
const saveOutputMessages =
|
|
830
866
|
options?.storageOptions?.saveOutputMessages ??
|
|
831
|
-
args.saveOutputMessages ??
|
|
832
867
|
this.options.storageOptions?.saveOutputMessages;
|
|
833
|
-
const model = aiArgs.model ?? this.options.chat;
|
|
834
868
|
const trackUsage = usageHandler ?? this.options.usageHandler;
|
|
835
869
|
const result = streamText({
|
|
836
870
|
// Can be overridden
|
|
837
871
|
maxSteps: this.options.maxSteps,
|
|
838
|
-
maxRetries: this.options.maxRetries,
|
|
839
872
|
...aiArgs,
|
|
840
|
-
model,
|
|
841
873
|
tools,
|
|
842
874
|
onChunk: async (chunk) => {
|
|
843
875
|
// console.log("onChunk", chunk);
|
|
@@ -860,7 +892,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
860
892
|
await this.saveStep(ctx, {
|
|
861
893
|
userId,
|
|
862
894
|
threadId,
|
|
863
|
-
|
|
895
|
+
promptMessageId: messageId,
|
|
864
896
|
step,
|
|
865
897
|
});
|
|
866
898
|
}
|
|
@@ -869,8 +901,8 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
869
901
|
userId,
|
|
870
902
|
threadId,
|
|
871
903
|
agentName: this.options.name,
|
|
872
|
-
model: model.modelId,
|
|
873
|
-
provider: model.provider,
|
|
904
|
+
model: aiArgs.model.modelId,
|
|
905
|
+
provider: aiArgs.model.provider,
|
|
874
906
|
usage: step.usage,
|
|
875
907
|
providerMetadata: step.providerMetadata,
|
|
876
908
|
});
|
|
@@ -886,12 +918,15 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
886
918
|
return result;
|
|
887
919
|
}
|
|
888
920
|
|
|
889
|
-
async
|
|
921
|
+
async _saveMessagesAndFetchContext<
|
|
890
922
|
T extends {
|
|
891
923
|
id?: string;
|
|
892
924
|
prompt?: string;
|
|
893
925
|
messages?: CoreMessage[] | AIMessageWithoutId[];
|
|
894
926
|
system?: string;
|
|
927
|
+
promptMessageId?: string;
|
|
928
|
+
model?: LanguageModelV1;
|
|
929
|
+
maxRetries?: number;
|
|
895
930
|
},
|
|
896
931
|
>(
|
|
897
932
|
ctx: RunActionCtx | RunMutationCtx,
|
|
@@ -906,20 +941,33 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
906
941
|
threadId: string | undefined;
|
|
907
942
|
} & Options
|
|
908
943
|
): Promise<{
|
|
909
|
-
args: T;
|
|
944
|
+
args: T & { model: LanguageModelV1 };
|
|
910
945
|
messageId: string | undefined;
|
|
911
946
|
}> {
|
|
912
|
-
contextOptions ||= this.options.contextOptions
|
|
913
|
-
storageOptions ||= this.options.storageOptions
|
|
914
|
-
|
|
947
|
+
contextOptions ||= this.options.contextOptions;
|
|
948
|
+
storageOptions ||= this.options.storageOptions;
|
|
949
|
+
// If only a messageId is provided, this will be empty.
|
|
950
|
+
const messages = args.promptMessageId
|
|
951
|
+
? []
|
|
952
|
+
: promptOrMessagesToCoreMessages(args);
|
|
953
|
+
assert(
|
|
954
|
+
!args.promptMessageId || !(args.prompt || args.messages),
|
|
955
|
+
"you can't specify a prompt or message if you specify a promptMessageId"
|
|
956
|
+
);
|
|
957
|
+
// If only a messageId is provided, this will add that message to the end.
|
|
915
958
|
const contextMessages = await this.fetchContextMessages(ctx, {
|
|
916
959
|
userId,
|
|
917
960
|
threadId,
|
|
961
|
+
upToAndIncludingMessageId: args.promptMessageId,
|
|
918
962
|
messages,
|
|
919
963
|
contextOptions,
|
|
920
964
|
});
|
|
921
|
-
let messageId
|
|
922
|
-
if (
|
|
965
|
+
let messageId = args.promptMessageId;
|
|
966
|
+
if (
|
|
967
|
+
threadId &&
|
|
968
|
+
messages.length &&
|
|
969
|
+
storageOptions?.saveAnyInputMessages !== false
|
|
970
|
+
) {
|
|
923
971
|
const saveAll = storageOptions?.saveAllInputMessages;
|
|
924
972
|
const coreMessages = saveAll ? messages : messages.slice(-1);
|
|
925
973
|
const saved = await this.saveMessages(ctx, {
|
|
@@ -932,16 +980,18 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
932
980
|
});
|
|
933
981
|
messageId = saved.lastMessageId;
|
|
934
982
|
}
|
|
935
|
-
const { prompt: _, ...rest } = args;
|
|
983
|
+
const { prompt: _, model, ...rest } = args;
|
|
936
984
|
return {
|
|
937
985
|
args: {
|
|
938
986
|
...rest,
|
|
987
|
+
maxRetries: args.maxRetries ?? this.options.maxRetries,
|
|
988
|
+
model: model ?? this.options.chat,
|
|
939
989
|
system: args.system ?? this.options.instructions,
|
|
940
990
|
messages: [
|
|
941
991
|
...contextMessages.map((m) => deserializeMessage(m.message!)),
|
|
942
992
|
...messages,
|
|
943
993
|
],
|
|
944
|
-
} as T,
|
|
994
|
+
} as T & { model: LanguageModelV1 },
|
|
945
995
|
messageId,
|
|
946
996
|
};
|
|
947
997
|
}
|
|
@@ -952,11 +1002,6 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
952
1002
|
* resulting messages to the thread, if specified.
|
|
953
1003
|
* Use {@link continueThread} to get a version of this function already scoped
|
|
954
1004
|
* to a thread (and optionally userId).
|
|
955
|
-
* @param ctx The context passed from the action function calling this.
|
|
956
|
-
* @param { userId, threadId }: The user and thread to associate the message with
|
|
957
|
-
* @param args The arguments to the generateObject function, along with extra controls
|
|
958
|
-
* for the {@link ContextOptions} and {@link StorageOptions}.
|
|
959
|
-
* @returns The result of the generateObject function.
|
|
960
1005
|
*/
|
|
961
1006
|
async generateObject<T>(
|
|
962
1007
|
ctx: RunActionCtx,
|
|
@@ -965,33 +1010,35 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
965
1010
|
threadId,
|
|
966
1011
|
usageHandler,
|
|
967
1012
|
}: { userId?: string; threadId?: string; usageHandler?: UsageHandler },
|
|
1013
|
+
/**
|
|
1014
|
+
* The arguments to the generateObject function, similar to the ai.generateObject function.
|
|
1015
|
+
*/
|
|
968
1016
|
args: OurObjectArgs<T>,
|
|
1017
|
+
/**
|
|
1018
|
+
* The {@link ContextOptions} and {@link StorageOptions}
|
|
1019
|
+
* options to use for fetching contextual messages and saving input/output messages.
|
|
1020
|
+
*/
|
|
969
1021
|
options?: Options
|
|
970
1022
|
): Promise<GenerateObjectResult<T> & GenerationOutputMetadata> {
|
|
971
|
-
const { args: aiArgs, messageId } = await this.
|
|
1023
|
+
const { args: aiArgs, messageId } = await this._saveMessagesAndFetchContext(
|
|
972
1024
|
ctx,
|
|
973
1025
|
args,
|
|
974
1026
|
{ userId, threadId, ...options }
|
|
975
1027
|
);
|
|
976
|
-
const model = aiArgs.model ?? this.options.chat;
|
|
977
1028
|
const trackUsage = usageHandler ?? this.options.usageHandler;
|
|
978
1029
|
const saveOutputMessages =
|
|
979
1030
|
options?.storageOptions?.saveOutputMessages ??
|
|
980
|
-
args.saveOutputMessages ??
|
|
981
1031
|
this.options.storageOptions?.saveOutputMessages;
|
|
982
1032
|
try {
|
|
983
|
-
const result = (await generateObject(
|
|
984
|
-
// Can be overridden
|
|
985
|
-
maxRetries: this.options.maxRetries,
|
|
986
|
-
...aiArgs,
|
|
987
|
-
model,
|
|
1033
|
+
const result = (await generateObject(
|
|
988
1034
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
989
|
-
|
|
1035
|
+
aiArgs as any
|
|
1036
|
+
)) as GenerateObjectResult<T> & GenerationOutputMetadata;
|
|
990
1037
|
|
|
991
1038
|
if (threadId && messageId && saveOutputMessages !== false) {
|
|
992
1039
|
await this.saveObject(ctx, {
|
|
993
1040
|
threadId,
|
|
994
|
-
|
|
1041
|
+
promptMessageId: messageId,
|
|
995
1042
|
result,
|
|
996
1043
|
userId,
|
|
997
1044
|
});
|
|
@@ -1002,8 +1049,8 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
1002
1049
|
userId,
|
|
1003
1050
|
threadId,
|
|
1004
1051
|
agentName: this.options.name,
|
|
1005
|
-
model: model.modelId,
|
|
1006
|
-
provider: model.provider,
|
|
1052
|
+
model: aiArgs.model.modelId,
|
|
1053
|
+
provider: aiArgs.model.provider,
|
|
1007
1054
|
usage: result.usage,
|
|
1008
1055
|
providerMetadata: result.providerMetadata,
|
|
1009
1056
|
});
|
|
@@ -1021,16 +1068,11 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
1021
1068
|
}
|
|
1022
1069
|
|
|
1023
1070
|
/**
|
|
1024
|
-
* This behaves like
|
|
1071
|
+
* This behaves like `streamObject` from the "ai" package except that
|
|
1025
1072
|
* it add context based on the userId and threadId and saves the input and
|
|
1026
1073
|
* resulting messages to the thread, if specified.
|
|
1027
1074
|
* Use {@link continueThread} to get a version of this function already scoped
|
|
1028
1075
|
* to a thread (and optionally userId).
|
|
1029
|
-
* @param ctx The context passed from the action function calling this.
|
|
1030
|
-
* @param { userId, threadId }: The user and thread to associate the message with
|
|
1031
|
-
* @param args The arguments to the streamObject function, along with extra controls
|
|
1032
|
-
* for the {@link ContextOptions} and {@link StorageOptions}.
|
|
1033
|
-
* @returns The result of the streamObject function.
|
|
1034
1076
|
*/
|
|
1035
1077
|
async streamObject<T>(
|
|
1036
1078
|
ctx: RunActionCtx,
|
|
@@ -1039,29 +1081,31 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
1039
1081
|
threadId,
|
|
1040
1082
|
usageHandler,
|
|
1041
1083
|
}: { userId?: string; threadId?: string; usageHandler?: UsageHandler },
|
|
1084
|
+
/**
|
|
1085
|
+
* The arguments to the streamObject function, similar to the ai `streamObject` function.
|
|
1086
|
+
*/
|
|
1042
1087
|
args: OurStreamObjectArgs<T>,
|
|
1088
|
+
/**
|
|
1089
|
+
* The {@link ContextOptions} and {@link StorageOptions}
|
|
1090
|
+
* options to use for fetching contextual messages and saving input/output messages.
|
|
1091
|
+
*/
|
|
1043
1092
|
options?: Options
|
|
1044
1093
|
): Promise<
|
|
1045
1094
|
StreamObjectResult<DeepPartial<T>, T, never> & GenerationOutputMetadata
|
|
1046
1095
|
> {
|
|
1047
1096
|
// TODO: unify all this shared code between all the generate* and stream* functions
|
|
1048
|
-
const { args: aiArgs, messageId } = await this.
|
|
1097
|
+
const { args: aiArgs, messageId } = await this._saveMessagesAndFetchContext(
|
|
1049
1098
|
ctx,
|
|
1050
1099
|
args,
|
|
1051
1100
|
{ userId, threadId, ...options }
|
|
1052
1101
|
);
|
|
1053
|
-
const model = aiArgs.model ?? this.options.chat;
|
|
1054
1102
|
const trackUsage = usageHandler ?? this.options.usageHandler;
|
|
1055
1103
|
const saveOutputMessages =
|
|
1056
1104
|
options?.storageOptions?.saveOutputMessages ??
|
|
1057
|
-
args.saveOutputMessages ??
|
|
1058
1105
|
this.options.storageOptions?.saveOutputMessages;
|
|
1059
1106
|
const stream = streamObject<T>({
|
|
1060
|
-
// Can be overridden
|
|
1061
|
-
maxRetries: this.options.maxRetries,
|
|
1062
1107
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1063
1108
|
...(aiArgs as any),
|
|
1064
|
-
model,
|
|
1065
1109
|
onError: async (error) => {
|
|
1066
1110
|
console.error("onError", error);
|
|
1067
1111
|
return args.onError?.(error);
|
|
@@ -1071,7 +1115,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
1071
1115
|
await this.saveObject(ctx, {
|
|
1072
1116
|
userId,
|
|
1073
1117
|
threadId,
|
|
1074
|
-
|
|
1118
|
+
promptMessageId: messageId,
|
|
1075
1119
|
result: {
|
|
1076
1120
|
object: result.object,
|
|
1077
1121
|
finishReason: "stop",
|
|
@@ -1092,8 +1136,8 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
1092
1136
|
userId,
|
|
1093
1137
|
threadId,
|
|
1094
1138
|
agentName: this.options.name,
|
|
1095
|
-
model: model.modelId,
|
|
1096
|
-
provider: model.provider,
|
|
1139
|
+
model: aiArgs.model.modelId,
|
|
1140
|
+
provider: aiArgs.model.provider,
|
|
1097
1141
|
usage: result.usage,
|
|
1098
1142
|
providerMetadata: result.providerMetadata,
|
|
1099
1143
|
});
|
|
@@ -1119,38 +1163,25 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
1119
1163
|
args: {
|
|
1120
1164
|
userId: string | undefined;
|
|
1121
1165
|
threadId: string;
|
|
1122
|
-
|
|
1166
|
+
promptMessageId: string;
|
|
1123
1167
|
result: GenerateObjectResult<unknown>;
|
|
1124
1168
|
metadata?: Omit<MessageWithMetadata, "message">;
|
|
1125
1169
|
}
|
|
1126
1170
|
): Promise<void> {
|
|
1127
|
-
const { step, messages
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1171
|
+
const { step, messages } = serializeObjectResult(args.result, {
|
|
1172
|
+
model: this.options.chat.modelId,
|
|
1173
|
+
provider: this.options.chat.provider,
|
|
1174
|
+
});
|
|
1175
|
+
const embeddings = await this.generateEmbeddings(
|
|
1176
|
+
messages.map((m) => m.message)
|
|
1133
1177
|
);
|
|
1134
|
-
const embeddings = await this.generateEmbeddings([withoutEmbed[0].message]);
|
|
1135
|
-
const messages = embeddings?.vectors[0]
|
|
1136
|
-
? [
|
|
1137
|
-
{
|
|
1138
|
-
...withoutEmbed[0],
|
|
1139
|
-
embedding: {
|
|
1140
|
-
dimension: embeddings.dimension,
|
|
1141
|
-
model: embeddings.model,
|
|
1142
|
-
vector: embeddings.vectors[0],
|
|
1143
|
-
},
|
|
1144
|
-
},
|
|
1145
|
-
]
|
|
1146
|
-
: withoutEmbed;
|
|
1147
1178
|
|
|
1148
1179
|
await ctx.runMutation(this.component.messages.addStep, {
|
|
1149
1180
|
userId: args.userId,
|
|
1150
1181
|
threadId: args.threadId,
|
|
1151
|
-
|
|
1182
|
+
promptMessageId: args.promptMessageId,
|
|
1152
1183
|
failPendingSteps: false,
|
|
1153
|
-
step: { step, messages },
|
|
1184
|
+
step: { step, messages, embeddings },
|
|
1154
1185
|
});
|
|
1155
1186
|
}
|
|
1156
1187
|
|
|
@@ -1239,11 +1270,11 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
1239
1270
|
* Create an action out of this agent so you can call it from workflows or other actions
|
|
1240
1271
|
* without a wrapping function.
|
|
1241
1272
|
* @param spec Configuration for the agent acting as an action, including
|
|
1242
|
-
* {@link ContextOptions} and maxSteps.
|
|
1273
|
+
* {@link ContextOptions}, {@link StorageOptions}, and maxSteps.
|
|
1243
1274
|
*/
|
|
1244
1275
|
asTextAction(spec?: {
|
|
1245
|
-
contextOptions?: ContextOptions;
|
|
1246
1276
|
maxSteps?: number;
|
|
1277
|
+
contextOptions?: ContextOptions;
|
|
1247
1278
|
storageOptions?: StorageOptions;
|
|
1248
1279
|
}) {
|
|
1249
1280
|
const maxSteps = spec?.maxSteps ?? this.options.maxSteps;
|
|
@@ -1308,7 +1339,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
1308
1339
|
this.options.storageOptions,
|
|
1309
1340
|
}
|
|
1310
1341
|
);
|
|
1311
|
-
return value.object as T;
|
|
1342
|
+
return { object: value.object as T };
|
|
1312
1343
|
},
|
|
1313
1344
|
});
|
|
1314
1345
|
}
|
|
@@ -1341,7 +1372,6 @@ export function filterOutOrphanedToolMessages(docs: MessageDoc[]) {
|
|
|
1341
1372
|
return result;
|
|
1342
1373
|
}
|
|
1343
1374
|
|
|
1344
|
-
|
|
1345
1375
|
export type ToolCtx = RunActionCtx & {
|
|
1346
1376
|
userId?: string;
|
|
1347
1377
|
threadId?: string;
|
|
@@ -1468,6 +1498,13 @@ type TextArgs<
|
|
|
1468
1498
|
>[0],
|
|
1469
1499
|
"toolChoice" | "tools" | "model"
|
|
1470
1500
|
> & {
|
|
1501
|
+
/**
|
|
1502
|
+
* If provided, this message will be used as the "prompt" for the LLM call,
|
|
1503
|
+
* instead of the prompt or messages.
|
|
1504
|
+
* This is useful if you want to first save a user message, then use it as
|
|
1505
|
+
* the prompt for the LLM call in another call.
|
|
1506
|
+
*/
|
|
1507
|
+
promptMessageId?: string;
|
|
1471
1508
|
/**
|
|
1472
1509
|
* The model to use for the tool calls. This will override the model specified
|
|
1473
1510
|
* in the Agent constructor.
|
|
@@ -1483,8 +1520,7 @@ type TextArgs<
|
|
|
1483
1520
|
* specified in the tools array. e.g. {toolName: "getWeather", type: "tool"}
|
|
1484
1521
|
*/
|
|
1485
1522
|
toolChoice?: ToolChoice<TOOLS extends undefined ? AgentTools : TOOLS>;
|
|
1486
|
-
}
|
|
1487
|
-
StorageOptions;
|
|
1523
|
+
};
|
|
1488
1524
|
|
|
1489
1525
|
type StreamingTextArgs<
|
|
1490
1526
|
AgentTools extends ToolSet,
|
|
@@ -1516,38 +1552,42 @@ type StreamingTextArgs<
|
|
|
1516
1552
|
* specified in the tools array. e.g. {toolName: "getWeather", type: "tool"}
|
|
1517
1553
|
*/
|
|
1518
1554
|
toolChoice?: ToolChoice<TOOLS extends undefined ? AgentTools : TOOLS>;
|
|
1519
|
-
}
|
|
1520
|
-
StorageOptions;
|
|
1555
|
+
};
|
|
1521
1556
|
|
|
1522
|
-
type BaseGenerateObjectOptions =
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1557
|
+
type BaseGenerateObjectOptions = CallSettings & {
|
|
1558
|
+
/**
|
|
1559
|
+
* The model to use for the object generation. This will override the model
|
|
1560
|
+
* specified in the Agent constructor.
|
|
1561
|
+
*/
|
|
1562
|
+
model?: LanguageModelV1;
|
|
1563
|
+
/**
|
|
1564
|
+
* The system prompt to use for the object generation. This will override the
|
|
1565
|
+
* system prompt specified in the Agent constructor.
|
|
1566
|
+
*/
|
|
1567
|
+
system?: string;
|
|
1568
|
+
/**
|
|
1569
|
+
* The prompt to the LLM to use for the object generation.
|
|
1570
|
+
* Specify this or messages, but not both.
|
|
1571
|
+
*/
|
|
1572
|
+
prompt?: string;
|
|
1573
|
+
/**
|
|
1574
|
+
* The messages to use for the object generation.
|
|
1575
|
+
* Note: recent messages are automatically added based on the thread it's
|
|
1576
|
+
* associated with and your contextOptions.
|
|
1577
|
+
*/
|
|
1578
|
+
messages?: CoreMessage[];
|
|
1579
|
+
/**
|
|
1580
|
+
* The message to use as the "prompt" for the object generation.
|
|
1581
|
+
* If this is provided, it will be used instead of the prompt or messages.
|
|
1582
|
+
* This is useful if you want to first save a user message, then use it as
|
|
1583
|
+
* the prompt for the object generation in another call.
|
|
1584
|
+
*/
|
|
1585
|
+
promptMessageId?: string;
|
|
1586
|
+
experimental_repairText?: RepairTextFunction;
|
|
1587
|
+
experimental_telemetry?: TelemetrySettings;
|
|
1588
|
+
providerOptions?: ProviderOptions;
|
|
1589
|
+
experimental_providerMetadata?: ProviderMetadata;
|
|
1590
|
+
};
|
|
1551
1591
|
|
|
1552
1592
|
type GenerateObjectObjectOptions<T extends Record<string, unknown>> =
|
|
1553
1593
|
BaseGenerateObjectOptions & {
|
|
@@ -1724,30 +1764,6 @@ interface Thread<DefaultTools extends ToolSet> {
|
|
|
1724
1764
|
>;
|
|
1725
1765
|
}
|
|
1726
1766
|
|
|
1727
|
-
export const vThreadDoc = v.object({
|
|
1728
|
-
_id: v.string(),
|
|
1729
|
-
_creationTime: v.number(),
|
|
1730
|
-
userId: v.optional(v.string()), // Unset for anonymous
|
|
1731
|
-
title: v.optional(v.string()),
|
|
1732
|
-
summary: v.optional(v.string()),
|
|
1733
|
-
status: vThreadStatus,
|
|
1734
|
-
});
|
|
1735
|
-
export type ThreadDoc = Infer<typeof vThreadDoc>;
|
|
1736
|
-
|
|
1737
|
-
export const vMessageDoc = v.object({
|
|
1738
|
-
_id: v.string(),
|
|
1739
|
-
_creationTime: v.number(),
|
|
1740
|
-
...schema.tables.messages.validator.fields,
|
|
1741
|
-
// Overwrite all the types that have a v.id validator
|
|
1742
|
-
// Outside of the component, they are strings
|
|
1743
|
-
threadId: v.string(),
|
|
1744
|
-
parentMessageId: v.optional(v.string()),
|
|
1745
|
-
stepId: v.optional(v.string()),
|
|
1746
|
-
embeddingId: v.optional(v.string()),
|
|
1747
|
-
files: v.optional(v.array(vFileWithStringId)),
|
|
1748
|
-
});
|
|
1749
|
-
export type MessageDoc = Infer<typeof vMessageDoc>;
|
|
1750
|
-
|
|
1751
1767
|
type MessageWithMetadata = OpaqueIds<InnerMessageWithMetadata>;
|
|
1752
1768
|
|
|
1753
1769
|
export function toUIMessages(messages: MessageDoc[]): UIMessage[] {
|