@convex-dev/agent 0.2.6-alpha.1 → 0.2.7
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/dist/client/createTool.js +1 -1
- package/dist/client/createTool.js.map +1 -1
- package/dist/client/definePlaygroundAPI.d.ts +6 -4
- package/dist/client/definePlaygroundAPI.d.ts.map +1 -1
- package/dist/client/definePlaygroundAPI.js +15 -6
- package/dist/client/definePlaygroundAPI.js.map +1 -1
- package/dist/client/index.d.ts +55 -122
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +47 -371
- package/dist/client/index.js.map +1 -1
- package/dist/client/messages.d.ts +1 -1
- package/dist/client/messages.d.ts.map +1 -1
- package/dist/client/mockModel.d.ts +5 -3
- package/dist/client/mockModel.d.ts.map +1 -1
- package/dist/client/mockModel.js +33 -24
- package/dist/client/mockModel.js.map +1 -1
- package/dist/client/saveInputMessages.d.ts +20 -0
- package/dist/client/saveInputMessages.d.ts.map +1 -0
- package/dist/client/saveInputMessages.js +57 -0
- package/dist/client/saveInputMessages.js.map +1 -0
- package/dist/client/search.d.ts +110 -9
- package/dist/client/search.d.ts.map +1 -1
- package/dist/client/search.js +271 -39
- package/dist/client/search.js.map +1 -1
- package/dist/client/start.d.ts +84 -0
- package/dist/client/start.d.ts.map +1 -0
- package/dist/client/start.js +171 -0
- package/dist/client/start.js.map +1 -0
- package/dist/client/streaming.d.ts +8 -8
- package/dist/client/streaming.d.ts.map +1 -1
- package/dist/client/streaming.js +2 -1
- package/dist/client/streaming.js.map +1 -1
- package/dist/client/textStreamParts.d.ts.map +1 -1
- package/dist/client/textStreamParts.js +2 -9
- package/dist/client/textStreamParts.js.map +1 -1
- package/dist/client/threads.d.ts +1 -1
- package/dist/client/threads.d.ts.map +1 -1
- package/dist/client/types.d.ts +147 -17
- package/dist/client/types.d.ts.map +1 -1
- package/dist/component/_generated/api.d.ts +11 -3
- package/dist/component/messages.d.ts +13 -4
- package/dist/component/messages.d.ts.map +1 -1
- package/dist/component/messages.js +67 -25
- package/dist/component/messages.js.map +1 -1
- package/dist/component/schema.d.ts +2 -1643
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +0 -24
- package/dist/component/schema.js.map +1 -1
- package/dist/mapping.d.ts +5 -8
- package/dist/mapping.d.ts.map +1 -1
- package/dist/mapping.js +72 -6
- package/dist/mapping.js.map +1 -1
- package/dist/react/deltas.d.ts.map +1 -1
- package/dist/react/deltas.js +1 -0
- package/dist/react/deltas.js.map +1 -1
- package/dist/react/fromUIMessages.d.ts +13 -0
- package/dist/react/fromUIMessages.d.ts.map +1 -0
- package/dist/react/fromUIMessages.js +75 -0
- package/dist/react/fromUIMessages.js.map +1 -0
- package/dist/react/toUIMessages.d.ts +5 -2
- package/dist/react/toUIMessages.d.ts.map +1 -1
- package/dist/react/toUIMessages.js +3 -0
- package/dist/react/toUIMessages.js.map +1 -1
- package/dist/shared.d.ts +10 -0
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +26 -0
- package/dist/shared.js.map +1 -1
- package/dist/validators.d.ts +1640 -0
- package/dist/validators.d.ts.map +1 -1
- package/dist/validators.js +41 -0
- package/dist/validators.js.map +1 -1
- package/package.json +4 -4
- package/src/client/createTool.ts +1 -1
- package/src/client/definePlaygroundAPI.ts +16 -7
- package/src/client/index.test.ts +11 -46
- package/src/client/index.ts +128 -573
- package/src/client/messages.ts +1 -1
- package/src/client/mock.json +68 -0
- package/src/client/mockModel.ts +47 -31
- package/src/client/saveInputMessages.test.ts +576 -0
- package/src/client/saveInputMessages.ts +100 -0
- package/src/client/search.test.ts +1017 -0
- package/src/client/search.ts +446 -68
- package/src/client/start.ts +315 -0
- package/src/client/stream.json +48 -0
- package/src/client/streaming.ts +3 -3
- package/src/client/textStreamParts.ts +2 -11
- package/src/client/threads.ts +1 -1
- package/src/client/types.ts +153 -22
- package/src/component/_generated/api.d.ts +11 -3
- package/src/component/messages.ts +73 -27
- package/src/component/schema.ts +1 -29
- package/src/mapping.ts +83 -6
- package/src/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/src/react/deltas.ts +1 -0
- package/src/react/fromUIMessages.test.ts +467 -0
- package/src/react/fromUIMessages.ts +90 -0
- package/src/react/toUIMessages.ts +21 -13
- package/src/shared.ts +33 -0
- package/src/validators.test.ts +13 -2
- package/src/validators.ts +48 -0
package/src/client/index.ts
CHANGED
|
@@ -2,11 +2,9 @@ import type {
|
|
|
2
2
|
FlexibleSchema,
|
|
3
3
|
IdGenerator,
|
|
4
4
|
InferSchema,
|
|
5
|
-
ProviderOptions,
|
|
6
5
|
} from "@ai-sdk/provider-utils";
|
|
7
6
|
import type {
|
|
8
7
|
CallSettings,
|
|
9
|
-
EmbeddingModel,
|
|
10
8
|
GenerateObjectResult,
|
|
11
9
|
GenerateTextResult,
|
|
12
10
|
LanguageModel,
|
|
@@ -18,7 +16,6 @@ import type {
|
|
|
18
16
|
ToolSet,
|
|
19
17
|
} from "ai";
|
|
20
18
|
import {
|
|
21
|
-
embedMany,
|
|
22
19
|
generateObject,
|
|
23
20
|
generateText,
|
|
24
21
|
stepCountIs,
|
|
@@ -35,31 +32,28 @@ import {
|
|
|
35
32
|
type WithoutSystemFields,
|
|
36
33
|
} from "convex/server";
|
|
37
34
|
import { convexToJson, v, type Value } from "convex/values";
|
|
38
|
-
import type { MessageDoc, ThreadDoc } from "../component/schema.js";
|
|
39
35
|
import type { threadFieldsSupportingPatch } from "../component/threads.js";
|
|
40
|
-
import {
|
|
41
|
-
validateVectorDimension,
|
|
42
|
-
type VectorDimension,
|
|
43
|
-
} from "../component/vector/tables.js";
|
|
36
|
+
import { type VectorDimension } from "../component/vector/tables.js";
|
|
44
37
|
import {
|
|
45
38
|
deserializeMessage,
|
|
46
39
|
serializeMessage,
|
|
47
40
|
serializeNewMessagesInStep,
|
|
48
41
|
serializeObjectResult,
|
|
49
42
|
} from "../mapping.js";
|
|
50
|
-
import {
|
|
43
|
+
import { getModelName, getProviderName } from "../shared.js";
|
|
51
44
|
import {
|
|
52
45
|
vMessageEmbeddings,
|
|
53
46
|
vMessageWithMetadata,
|
|
54
47
|
vSafeObjectArgs,
|
|
55
48
|
vTextArgs,
|
|
56
49
|
type Message,
|
|
50
|
+
type MessageDoc,
|
|
57
51
|
type MessageStatus,
|
|
58
52
|
type MessageWithMetadata,
|
|
59
53
|
type ProviderMetadata,
|
|
60
54
|
type StreamArgs,
|
|
55
|
+
type ThreadDoc,
|
|
61
56
|
} from "../validators.js";
|
|
62
|
-
import { wrapTools, type ToolCtx } from "./createTool.js";
|
|
63
57
|
import {
|
|
64
58
|
listMessages,
|
|
65
59
|
saveMessages,
|
|
@@ -67,10 +61,12 @@ import {
|
|
|
67
61
|
type SaveMessagesArgs,
|
|
68
62
|
} from "./messages.js";
|
|
69
63
|
import {
|
|
64
|
+
embedMany,
|
|
65
|
+
embedMessages,
|
|
70
66
|
fetchContextMessages,
|
|
71
|
-
|
|
72
|
-
getProviderName,
|
|
67
|
+
generateAndSaveEmbeddings,
|
|
73
68
|
} from "./search.js";
|
|
69
|
+
import { start } from "./start.js";
|
|
74
70
|
import {
|
|
75
71
|
DeltaStreamer,
|
|
76
72
|
syncStreams,
|
|
@@ -104,12 +100,10 @@ import type {
|
|
|
104
100
|
Thread,
|
|
105
101
|
UsageHandler,
|
|
106
102
|
UserActionCtx,
|
|
103
|
+
Config,
|
|
107
104
|
} from "./types.js";
|
|
108
|
-
import { inlineMessagesFiles } from "./files.js";
|
|
109
|
-
import type { DataModel } from "../component/_generated/dataModel.js";
|
|
110
105
|
|
|
111
106
|
export { stepCountIs } from "ai";
|
|
112
|
-
export { vMessageDoc, vThreadDoc } from "../component/schema.js";
|
|
113
107
|
export {
|
|
114
108
|
deserializeMessage,
|
|
115
109
|
serializeDataOrUrl,
|
|
@@ -123,18 +117,22 @@ export {
|
|
|
123
117
|
vAssistantMessage,
|
|
124
118
|
vContextOptions,
|
|
125
119
|
vMessage,
|
|
120
|
+
vMessageDoc,
|
|
126
121
|
vPaginationResult,
|
|
127
122
|
vProviderMetadata,
|
|
128
123
|
vStorageOptions,
|
|
129
124
|
vStreamArgs,
|
|
130
125
|
vSystemMessage,
|
|
126
|
+
vThreadDoc,
|
|
131
127
|
vToolMessage,
|
|
132
128
|
vUsage,
|
|
133
129
|
vUserMessage,
|
|
134
130
|
vSource,
|
|
135
131
|
vContent,
|
|
136
|
-
type SourcePart,
|
|
137
132
|
type Message,
|
|
133
|
+
type MessageDoc,
|
|
134
|
+
type SourcePart,
|
|
135
|
+
type ThreadDoc,
|
|
138
136
|
type Usage,
|
|
139
137
|
} from "../validators.js";
|
|
140
138
|
export type { ToolCtx } from "./createTool.js";
|
|
@@ -154,6 +152,10 @@ export {
|
|
|
154
152
|
export {
|
|
155
153
|
fetchContextMessages,
|
|
156
154
|
filterOutOrphanedToolMessages,
|
|
155
|
+
fetchContextWithPrompt,
|
|
156
|
+
generateAndSaveEmbeddings,
|
|
157
|
+
embedMessages,
|
|
158
|
+
embedMany,
|
|
157
159
|
} from "./search.js";
|
|
158
160
|
export {
|
|
159
161
|
abortStream,
|
|
@@ -171,94 +173,18 @@ export { extractText, isTool, sorted } from "../shared.js";
|
|
|
171
173
|
export { createTool } from "./createTool.js";
|
|
172
174
|
export type {
|
|
173
175
|
AgentComponent,
|
|
176
|
+
Config,
|
|
174
177
|
ContextOptions,
|
|
175
|
-
MessageDoc,
|
|
176
178
|
ProviderMetadata,
|
|
177
179
|
RawRequestResponseHandler,
|
|
178
180
|
StorageOptions,
|
|
179
181
|
StreamArgs,
|
|
180
182
|
SyncStreamsReturnValue,
|
|
181
183
|
Thread,
|
|
182
|
-
ThreadDoc,
|
|
183
184
|
UsageHandler,
|
|
184
185
|
};
|
|
185
186
|
export { mockModel } from "./mockModel.js";
|
|
186
187
|
|
|
187
|
-
// 10k characters should be more than enough for most cases, and stays under
|
|
188
|
-
// the 8k token limit for some models.
|
|
189
|
-
const MAX_EMBEDDING_TEXT_LENGTH = 10_000;
|
|
190
|
-
|
|
191
|
-
export type Config = {
|
|
192
|
-
/**
|
|
193
|
-
* The LLM model to use for generating / streaming text and objects.
|
|
194
|
-
* e.g.
|
|
195
|
-
* import { openai } from "@ai-sdk/openai"
|
|
196
|
-
* const myAgent = new Agent(components.agent, {
|
|
197
|
-
* languageModel: openai.chat("gpt-4o-mini"),
|
|
198
|
-
*/
|
|
199
|
-
languageModel?: LanguageModel;
|
|
200
|
-
/**
|
|
201
|
-
* The model to use for text embeddings. Optional.
|
|
202
|
-
* If specified, it will use this for generating vector embeddings
|
|
203
|
-
* of chats, and can opt-in to doing vector search for automatic context
|
|
204
|
-
* on generateText, etc.
|
|
205
|
-
* e.g.
|
|
206
|
-
* import { openai } from "@ai-sdk/openai"
|
|
207
|
-
* const myAgent = new Agent(components.agent, {
|
|
208
|
-
* ...
|
|
209
|
-
* textEmbeddingModel: openai.embedding("text-embedding-3-small")
|
|
210
|
-
*/
|
|
211
|
-
textEmbeddingModel?: EmbeddingModel<string>;
|
|
212
|
-
/**
|
|
213
|
-
* Options to determine what messages are included as context in message
|
|
214
|
-
* generation. To disable any messages automatically being added, pass:
|
|
215
|
-
* { recentMessages: 0 }
|
|
216
|
-
*/
|
|
217
|
-
contextOptions?: ContextOptions;
|
|
218
|
-
/**
|
|
219
|
-
* Determines whether messages are automatically stored when passed as
|
|
220
|
-
* arguments or generated.
|
|
221
|
-
*/
|
|
222
|
-
storageOptions?: StorageOptions;
|
|
223
|
-
/**
|
|
224
|
-
* The usage handler to use for this agent.
|
|
225
|
-
*/
|
|
226
|
-
usageHandler?: UsageHandler;
|
|
227
|
-
/**
|
|
228
|
-
* Called for each LLM request/response, so you can do things like
|
|
229
|
-
* log the raw request body or response headers to a table, or logs.
|
|
230
|
-
*/
|
|
231
|
-
rawRequestResponseHandler?: RawRequestResponseHandler;
|
|
232
|
-
/**
|
|
233
|
-
* Default provider options to pass for the LLM calls.
|
|
234
|
-
* This can be overridden at each generate/stream callsite on a per-field
|
|
235
|
-
* basis. To clear a default setting, you'll need to pass `undefined`.
|
|
236
|
-
*/
|
|
237
|
-
providerOptions?: ProviderOptions;
|
|
238
|
-
/**
|
|
239
|
-
* The default settings to use for the LLM calls.
|
|
240
|
-
* This can be overridden at each generate/stream callsite on a per-field
|
|
241
|
-
* basis. To clear a default setting, you'll need to pass `undefined`.
|
|
242
|
-
*/
|
|
243
|
-
callSettings?: CallSettings;
|
|
244
|
-
/**
|
|
245
|
-
* The maximum number of steps to allow for a single generation.
|
|
246
|
-
*
|
|
247
|
-
* For example, if an agent wants to call a tool, that call and tool response
|
|
248
|
-
* will be one step. Generating a response based on the tool call & response
|
|
249
|
-
* will be a second step.
|
|
250
|
-
* If it runs out of steps, it will return the last step result, which may
|
|
251
|
-
* not be an assistant message.
|
|
252
|
-
|
|
253
|
-
* This becomes the default value when `stopWhen` is not specified in the
|
|
254
|
-
* Agent or generation callsite.
|
|
255
|
-
* AI SDK v5 removed the `maxSteps` argument, but this is kept here for
|
|
256
|
-
* convenience and backwards compatibility.
|
|
257
|
-
* Defaults to 1.
|
|
258
|
-
*/
|
|
259
|
-
maxSteps?: number;
|
|
260
|
-
};
|
|
261
|
-
|
|
262
188
|
export class Agent<
|
|
263
189
|
/**
|
|
264
190
|
* You can require that all `ctx` args to generateText & streamText
|
|
@@ -313,7 +239,7 @@ export class Agent<
|
|
|
313
239
|
tools?: AgentTools;
|
|
314
240
|
/**
|
|
315
241
|
* When generating or streaming text with tools available, this
|
|
316
|
-
* determines when to stop. Defaults to
|
|
242
|
+
* determines when to stop. Defaults to the AI SDK default.
|
|
317
243
|
*/
|
|
318
244
|
stopWhen?: StopCondition<AgentTools> | Array<StopCondition<AgentTools>>;
|
|
319
245
|
/**
|
|
@@ -501,6 +427,7 @@ export class Agent<
|
|
|
501
427
|
args: T & {
|
|
502
428
|
system?: string;
|
|
503
429
|
model: LanguageModel;
|
|
430
|
+
prompt?: never;
|
|
504
431
|
messages: ModelMessage[];
|
|
505
432
|
tools?: TOOLS extends undefined ? AgentTools : TOOLS;
|
|
506
433
|
} & CallSettings;
|
|
@@ -518,182 +445,25 @@ export class Agent<
|
|
|
518
445
|
fail: (reason: string) => Promise<void>;
|
|
519
446
|
getSavedMessages: () => MessageDoc[];
|
|
520
447
|
}> {
|
|
521
|
-
const { threadId, ...opts } = { ...this.options, ...options };
|
|
522
|
-
const context = await this._saveMessagesAndFetchContext(ctx, {
|
|
523
|
-
userId: options?.userId,
|
|
524
|
-
threadId: options?.threadId,
|
|
525
|
-
messages: args.messages,
|
|
526
|
-
prompt: args.prompt,
|
|
527
|
-
promptMessageId: args.promptMessageId,
|
|
528
|
-
...opts,
|
|
529
|
-
});
|
|
530
|
-
let pendingMessageId = context.pendingMessageId;
|
|
531
|
-
const { messages, promptMessageId, order, stepOrder, userId } = context;
|
|
532
|
-
const savedMessages = context.savedMessages ?? [];
|
|
533
|
-
const toolCtx = {
|
|
534
|
-
...(ctx as UserActionCtx & CustomCtx),
|
|
535
|
-
userId,
|
|
536
|
-
threadId,
|
|
537
|
-
promptMessageId,
|
|
538
|
-
agent: this,
|
|
539
|
-
} satisfies ToolCtx;
|
|
540
448
|
type Tools = TOOLS extends undefined ? AgentTools : TOOLS;
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
messageId: pendingMessageId,
|
|
552
|
-
result: { status: "failed", error: reason },
|
|
553
|
-
});
|
|
554
|
-
}
|
|
555
|
-
};
|
|
556
|
-
if (args.abortSignal) {
|
|
557
|
-
const abortSignal = args.abortSignal;
|
|
558
|
-
abortSignal.addEventListener(
|
|
559
|
-
"abort",
|
|
560
|
-
async () => {
|
|
561
|
-
await fail(abortSignal.reason ?? "Aborted");
|
|
562
|
-
},
|
|
563
|
-
{ once: true },
|
|
564
|
-
);
|
|
565
|
-
}
|
|
566
|
-
const aiArgs = {
|
|
567
|
-
...this.options.callSettings,
|
|
568
|
-
providerOptions: this.options.providerOptions,
|
|
569
|
-
...omit(args, ["messages", "prompt", "promptMessageId"]),
|
|
570
|
-
model: args.model ?? this.options.languageModel,
|
|
571
|
-
system: args.system ?? this.options.instructions,
|
|
572
|
-
messages,
|
|
573
|
-
stopWhen:
|
|
574
|
-
args.stopWhen ??
|
|
575
|
-
this.options.stopWhen ??
|
|
576
|
-
stepCountIs(this.options.maxSteps ?? 1),
|
|
577
|
-
tools,
|
|
578
|
-
} as T & {
|
|
579
|
-
model: LanguageModel;
|
|
580
|
-
messages: ModelMessage[];
|
|
581
|
-
tools?: TOOLS extends undefined ? AgentTools : TOOLS;
|
|
582
|
-
} & CallSettings;
|
|
583
|
-
if (pendingMessageId) {
|
|
584
|
-
if (!aiArgs._internal?.generateId) {
|
|
585
|
-
aiArgs._internal = {
|
|
586
|
-
...aiArgs._internal,
|
|
587
|
-
generateId: () => pendingMessageId ?? crypto.randomUUID(),
|
|
588
|
-
};
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
let activeModel = aiArgs.model;
|
|
592
|
-
return {
|
|
593
|
-
args: aiArgs,
|
|
594
|
-
order: order ?? 0,
|
|
595
|
-
stepOrder: stepOrder ?? 0,
|
|
596
|
-
userId,
|
|
597
|
-
promptMessageId,
|
|
598
|
-
getSavedMessages: () => savedMessages,
|
|
599
|
-
updateModel: (model: LanguageModel | undefined) => {
|
|
600
|
-
if (model) {
|
|
601
|
-
activeModel = model;
|
|
602
|
-
}
|
|
449
|
+
return start<T, Tools, CustomCtx>(
|
|
450
|
+
ctx,
|
|
451
|
+
this.component,
|
|
452
|
+
{
|
|
453
|
+
...args,
|
|
454
|
+
tools: (args.tools ?? this.options.tools) as Tools,
|
|
455
|
+
system: args.system ?? this.options.instructions,
|
|
456
|
+
stopWhen: (args.stopWhen ?? this.options.stopWhen) as
|
|
457
|
+
| StopCondition<Tools>
|
|
458
|
+
| Array<StopCondition<Tools>>,
|
|
603
459
|
},
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
createPendingMessage?: boolean,
|
|
610
|
-
) => {
|
|
611
|
-
if (threadId && promptMessageId && saveOutput) {
|
|
612
|
-
const metadata = {
|
|
613
|
-
// TODO: get up to date one when user selects mid-generation
|
|
614
|
-
model: getModelName(activeModel),
|
|
615
|
-
provider: getProviderName(activeModel),
|
|
616
|
-
};
|
|
617
|
-
const serialized =
|
|
618
|
-
"object" in toSave
|
|
619
|
-
? await serializeObjectResult(
|
|
620
|
-
ctx,
|
|
621
|
-
this.component,
|
|
622
|
-
toSave.object,
|
|
623
|
-
metadata,
|
|
624
|
-
)
|
|
625
|
-
: await serializeNewMessagesInStep(
|
|
626
|
-
ctx,
|
|
627
|
-
this.component,
|
|
628
|
-
toSave.step,
|
|
629
|
-
metadata,
|
|
630
|
-
);
|
|
631
|
-
const embeddings = await this.generateEmbeddings(
|
|
632
|
-
ctx,
|
|
633
|
-
{ userId, threadId },
|
|
634
|
-
serialized.messages.map((m) => m.message),
|
|
635
|
-
);
|
|
636
|
-
if (createPendingMessage) {
|
|
637
|
-
serialized.messages.push({
|
|
638
|
-
message: { role: "assistant", content: [] },
|
|
639
|
-
status: "pending",
|
|
640
|
-
});
|
|
641
|
-
embeddings?.vectors.push(null);
|
|
642
|
-
}
|
|
643
|
-
const saved = await ctx.runMutation(
|
|
644
|
-
this.component.messages.addMessages,
|
|
645
|
-
{
|
|
646
|
-
userId,
|
|
647
|
-
threadId,
|
|
648
|
-
agentName: this.options.name,
|
|
649
|
-
promptMessageId,
|
|
650
|
-
pendingMessageId,
|
|
651
|
-
messages: serialized.messages,
|
|
652
|
-
embeddings,
|
|
653
|
-
failPendingSteps: false,
|
|
654
|
-
},
|
|
655
|
-
);
|
|
656
|
-
const lastMessage = saved.messages.at(-1)!;
|
|
657
|
-
if (createPendingMessage) {
|
|
658
|
-
if (lastMessage.status === "failed") {
|
|
659
|
-
pendingMessageId = undefined;
|
|
660
|
-
savedMessages.push(...saved.messages);
|
|
661
|
-
await fail(
|
|
662
|
-
lastMessage.error ??
|
|
663
|
-
"Aborting - the pending message was marked as failed",
|
|
664
|
-
);
|
|
665
|
-
} else {
|
|
666
|
-
pendingMessageId = lastMessage._id;
|
|
667
|
-
savedMessages.push(...saved.messages.slice(0, -1));
|
|
668
|
-
}
|
|
669
|
-
} else {
|
|
670
|
-
pendingMessageId = undefined;
|
|
671
|
-
savedMessages.push(...saved.messages);
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
const output = "object" in toSave ? toSave.object : toSave.step;
|
|
675
|
-
if (this.options.rawRequestResponseHandler) {
|
|
676
|
-
await this.options.rawRequestResponseHandler(ctx, {
|
|
677
|
-
userId,
|
|
678
|
-
threadId,
|
|
679
|
-
agentName: this.options.name,
|
|
680
|
-
request: output.request,
|
|
681
|
-
response: output.response,
|
|
682
|
-
});
|
|
683
|
-
}
|
|
684
|
-
if (opts.usageHandler && output.usage) {
|
|
685
|
-
await opts.usageHandler(ctx, {
|
|
686
|
-
userId,
|
|
687
|
-
threadId,
|
|
688
|
-
agentName: this.options.name,
|
|
689
|
-
model: getModelName(activeModel),
|
|
690
|
-
provider: getProviderName(activeModel),
|
|
691
|
-
usage: output.usage,
|
|
692
|
-
providerMetadata: output.providerMetadata,
|
|
693
|
-
});
|
|
694
|
-
}
|
|
460
|
+
{
|
|
461
|
+
...this.options,
|
|
462
|
+
...options,
|
|
463
|
+
agentName: this.options.name,
|
|
464
|
+
agentForToolCtx: this,
|
|
695
465
|
},
|
|
696
|
-
|
|
466
|
+
);
|
|
697
467
|
}
|
|
698
468
|
|
|
699
469
|
/**
|
|
@@ -715,7 +485,15 @@ export class Agent<
|
|
|
715
485
|
>(
|
|
716
486
|
ctx: ActionCtx & CustomCtx,
|
|
717
487
|
threadOpts: { userId?: string | null; threadId?: string },
|
|
718
|
-
generateTextArgs: TextArgs<AgentTools, TOOLS, OUTPUT, OUTPUT_PARTIAL
|
|
488
|
+
generateTextArgs: TextArgs<AgentTools, TOOLS, OUTPUT, OUTPUT_PARTIAL> & {
|
|
489
|
+
/**
|
|
490
|
+
* If provided, this message will be used as the "prompt" for the LLM call,
|
|
491
|
+
* instead of the prompt or messages.
|
|
492
|
+
* This is useful if you want to first save a user message, then use it as
|
|
493
|
+
* the prompt for the LLM call in another call.
|
|
494
|
+
*/
|
|
495
|
+
promptMessageId?: string;
|
|
496
|
+
},
|
|
719
497
|
options?: Options,
|
|
720
498
|
): Promise<
|
|
721
499
|
GenerateTextResult<TOOLS extends undefined ? AgentTools : TOOLS, OUTPUT> &
|
|
@@ -778,7 +556,15 @@ export class Agent<
|
|
|
778
556
|
TOOLS,
|
|
779
557
|
OUTPUT,
|
|
780
558
|
PARTIAL_OUTPUT
|
|
781
|
-
|
|
559
|
+
> & {
|
|
560
|
+
/**
|
|
561
|
+
* If provided, this message will be used as the "prompt" for the LLM call,
|
|
562
|
+
* instead of the prompt or messages.
|
|
563
|
+
* This is useful if you want to first save a user message, then use it as
|
|
564
|
+
* the prompt for the LLM call in another call.
|
|
565
|
+
*/
|
|
566
|
+
promptMessageId?: string;
|
|
567
|
+
},
|
|
782
568
|
/**
|
|
783
569
|
* The {@link ContextOptions} and {@link StorageOptions}
|
|
784
570
|
* options to use for fetching contextual messages and saving input/output messages.
|
|
@@ -853,9 +639,6 @@ export class Agent<
|
|
|
853
639
|
await streamer?.fail(errorToString(error.error));
|
|
854
640
|
return streamTextArgs.onError?.(error);
|
|
855
641
|
},
|
|
856
|
-
// onFinish: async (event) => {
|
|
857
|
-
// return streamTextArgs.onFinish?.(event);
|
|
858
|
-
// },
|
|
859
642
|
prepareStep: async (options) => {
|
|
860
643
|
const result = await streamTextArgs.prepareStep?.(options);
|
|
861
644
|
if (result) {
|
|
@@ -878,12 +661,6 @@ export class Agent<
|
|
|
878
661
|
TOOLS extends undefined ? AgentTools : TOOLS,
|
|
879
662
|
PARTIAL_OUTPUT
|
|
880
663
|
>;
|
|
881
|
-
const metadata: GenerationOutputMetadata = {
|
|
882
|
-
promptMessageId,
|
|
883
|
-
order,
|
|
884
|
-
savedMessages: call.getSavedMessages(),
|
|
885
|
-
messageId: promptMessageId,
|
|
886
|
-
};
|
|
887
664
|
if (
|
|
888
665
|
(typeof options?.saveStreamDeltas === "object" &&
|
|
889
666
|
!options.saveStreamDeltas.returnImmediately) ||
|
|
@@ -891,6 +668,12 @@ export class Agent<
|
|
|
891
668
|
) {
|
|
892
669
|
await result.consumeStream();
|
|
893
670
|
}
|
|
671
|
+
const metadata: GenerationOutputMetadata = {
|
|
672
|
+
promptMessageId,
|
|
673
|
+
order,
|
|
674
|
+
savedMessages: call.getSavedMessages(),
|
|
675
|
+
messageId: promptMessageId,
|
|
676
|
+
};
|
|
894
677
|
return Object.assign(result, metadata);
|
|
895
678
|
}
|
|
896
679
|
|
|
@@ -915,7 +698,15 @@ export class Agent<
|
|
|
915
698
|
/**
|
|
916
699
|
* The arguments to the generateObject function, similar to the ai.generateObject function.
|
|
917
700
|
*/
|
|
918
|
-
generateObjectArgs: GenerateObjectArgs<SCHEMA, OUTPUT, RESULT
|
|
701
|
+
generateObjectArgs: GenerateObjectArgs<SCHEMA, OUTPUT, RESULT> & {
|
|
702
|
+
/**
|
|
703
|
+
* If provided, this message will be used as the "prompt" for the LLM call,
|
|
704
|
+
* instead of the prompt or messages.
|
|
705
|
+
* This is useful if you want to first save a user message, then use it as
|
|
706
|
+
* the prompt for the LLM call in another call.
|
|
707
|
+
*/
|
|
708
|
+
promptMessageId?: string;
|
|
709
|
+
},
|
|
919
710
|
/**
|
|
920
711
|
* The {@link ContextOptions} and {@link StorageOptions}
|
|
921
712
|
* options to use for fetching contextual messages and saving input/output messages.
|
|
@@ -973,15 +764,6 @@ export class Agent<
|
|
|
973
764
|
* the prompt for the LLM call in another call.
|
|
974
765
|
*/
|
|
975
766
|
promptMessageId?: string;
|
|
976
|
-
/**
|
|
977
|
-
* The model to use for the LLM calls. This will override the model specified
|
|
978
|
-
* in the Agent constructor.
|
|
979
|
-
*/
|
|
980
|
-
model?: LanguageModel;
|
|
981
|
-
/**
|
|
982
|
-
* The tools to use for the tool calls. This will override tools specified
|
|
983
|
-
* in the Agent constructor or createThread / continueThread.
|
|
984
|
-
*/
|
|
985
767
|
},
|
|
986
768
|
/**
|
|
987
769
|
* The {@link ContextOptions} and {@link StorageOptions}
|
|
@@ -1177,11 +959,22 @@ export class Agent<
|
|
|
1177
959
|
args: {
|
|
1178
960
|
userId: string | undefined;
|
|
1179
961
|
threadId: string | undefined;
|
|
1180
|
-
messages: (ModelMessage | Message)[];
|
|
1181
962
|
/**
|
|
1182
|
-
* If
|
|
1183
|
-
*
|
|
1184
|
-
|
|
963
|
+
* If targetMessageId is not provided, this text will be used
|
|
964
|
+
* for text and vector search
|
|
965
|
+
*/
|
|
966
|
+
searchText?: string;
|
|
967
|
+
/**
|
|
968
|
+
* If provided, it will use this message for text/vector search (if enabled)
|
|
969
|
+
* and will only fetch messages up to (and including) this message's "order"
|
|
970
|
+
*/
|
|
971
|
+
targetMessageId?: string;
|
|
972
|
+
/**
|
|
973
|
+
* @deprecated use searchText and targetMessageId instead
|
|
974
|
+
*/
|
|
975
|
+
messages?: (ModelMessage | Message)[];
|
|
976
|
+
/**
|
|
977
|
+
* @deprecated use targetMessageId instead
|
|
1185
978
|
*/
|
|
1186
979
|
upToAndIncludingMessageId?: string;
|
|
1187
980
|
contextOptions: ContextOptions | undefined;
|
|
@@ -1203,7 +996,9 @@ export class Agent<
|
|
|
1203
996
|
);
|
|
1204
997
|
return {
|
|
1205
998
|
embedding: (
|
|
1206
|
-
await
|
|
999
|
+
await embedMany(ctx, {
|
|
1000
|
+
...this.options,
|
|
1001
|
+
agentName: this.options.name,
|
|
1207
1002
|
userId: args.userId,
|
|
1208
1003
|
threadId: args.threadId,
|
|
1209
1004
|
values: [text],
|
|
@@ -1258,51 +1053,21 @@ export class Agent<
|
|
|
1258
1053
|
*/
|
|
1259
1054
|
async generateEmbeddings(
|
|
1260
1055
|
ctx: RunActionCtx,
|
|
1261
|
-
{
|
|
1262
|
-
userId,
|
|
1263
|
-
threadId,
|
|
1264
|
-
}: { userId: string | undefined; threadId: string | undefined },
|
|
1056
|
+
args: { userId: string | undefined; threadId: string | undefined },
|
|
1265
1057
|
messages: (ModelMessage | Message)[],
|
|
1266
|
-
)
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
const textIndexes = messageTexts
|
|
1280
|
-
.map((t, i) => (t ? i : undefined))
|
|
1281
|
-
.filter((i) => i !== undefined);
|
|
1282
|
-
if (textIndexes.length === 0) {
|
|
1283
|
-
return undefined;
|
|
1284
|
-
}
|
|
1285
|
-
const values = messageTexts
|
|
1286
|
-
.map((t) => t && t.trim().slice(0, MAX_EMBEDDING_TEXT_LENGTH))
|
|
1287
|
-
.filter((t): t is string => !!t);
|
|
1288
|
-
// Then embed those messages.
|
|
1289
|
-
const textEmbeddings = await this.doEmbed(ctx, {
|
|
1290
|
-
userId,
|
|
1291
|
-
threadId,
|
|
1292
|
-
values,
|
|
1293
|
-
});
|
|
1294
|
-
// Then assemble the embeddings into a single array with nulls for the messages without text.
|
|
1295
|
-
const embeddingsOrNull = Array(messages.length).fill(null);
|
|
1296
|
-
textIndexes.forEach((i, j) => {
|
|
1297
|
-
embeddingsOrNull[i] = textEmbeddings.embeddings[j];
|
|
1298
|
-
});
|
|
1299
|
-
if (textEmbeddings.embeddings.length > 0) {
|
|
1300
|
-
const dimension = textEmbeddings.embeddings[0].length;
|
|
1301
|
-
validateVectorDimension(dimension);
|
|
1302
|
-
const model = getModelName(this.options.textEmbeddingModel);
|
|
1303
|
-
embeddings = { vectors: embeddingsOrNull, dimension, model };
|
|
1304
|
-
}
|
|
1305
|
-
return embeddings;
|
|
1058
|
+
): Promise<
|
|
1059
|
+
| {
|
|
1060
|
+
vectors: (number[] | null)[];
|
|
1061
|
+
dimension: VectorDimension;
|
|
1062
|
+
model: string;
|
|
1063
|
+
}
|
|
1064
|
+
| undefined
|
|
1065
|
+
> {
|
|
1066
|
+
return embedMessages(
|
|
1067
|
+
ctx,
|
|
1068
|
+
{ ...args, ...this.options, agentName: this.options.name },
|
|
1069
|
+
messages,
|
|
1070
|
+
);
|
|
1306
1071
|
}
|
|
1307
1072
|
|
|
1308
1073
|
/**
|
|
@@ -1329,10 +1094,6 @@ export class Agent<
|
|
|
1329
1094
|
.join(", "),
|
|
1330
1095
|
);
|
|
1331
1096
|
}
|
|
1332
|
-
await this._generateAndSaveEmbeddings(ctx, messages);
|
|
1333
|
-
}
|
|
1334
|
-
|
|
1335
|
-
async _generateAndSaveEmbeddings(ctx: RunActionCtx, messages: MessageDoc[]) {
|
|
1336
1097
|
if (messages.some((m) => !m.message)) {
|
|
1337
1098
|
throw new Error(
|
|
1338
1099
|
"Some messages don't have a message: " +
|
|
@@ -1342,45 +1103,24 @@ export class Agent<
|
|
|
1342
1103
|
.join(", "),
|
|
1343
1104
|
);
|
|
1344
1105
|
}
|
|
1345
|
-
const
|
|
1346
|
-
if (
|
|
1347
|
-
|
|
1106
|
+
const { textEmbeddingModel } = this.options;
|
|
1107
|
+
if (!textEmbeddingModel) {
|
|
1108
|
+
throw new Error(
|
|
1109
|
+
"No embeddings were generated for the messages. You must pass a textEmbeddingModel to the agent constructor.",
|
|
1110
|
+
);
|
|
1348
1111
|
}
|
|
1349
|
-
|
|
1112
|
+
await generateAndSaveEmbeddings(
|
|
1350
1113
|
ctx,
|
|
1114
|
+
this.component,
|
|
1351
1115
|
{
|
|
1352
|
-
|
|
1353
|
-
|
|
1116
|
+
...this.options,
|
|
1117
|
+
agentName: this.options.name,
|
|
1118
|
+
threadId: messages[0].threadId,
|
|
1119
|
+
userId: messages[0].userId,
|
|
1120
|
+
textEmbeddingModel,
|
|
1354
1121
|
},
|
|
1355
|
-
|
|
1122
|
+
messages,
|
|
1356
1123
|
);
|
|
1357
|
-
if (!embeddings) {
|
|
1358
|
-
if (!this.options.textEmbeddingModel) {
|
|
1359
|
-
throw new Error(
|
|
1360
|
-
"No embeddings were generated for the messages. You must pass a textEmbeddingModel to the agent constructor.",
|
|
1361
|
-
);
|
|
1362
|
-
}
|
|
1363
|
-
throw new Error(
|
|
1364
|
-
"No embeddings were generated for these messages: " +
|
|
1365
|
-
messagesMissingEmbeddings.map((m) => m!._id).join(", "),
|
|
1366
|
-
);
|
|
1367
|
-
}
|
|
1368
|
-
await ctx.runMutation(this.component.vector.index.insertBatch, {
|
|
1369
|
-
vectorDimension: embeddings.dimension,
|
|
1370
|
-
vectors: messagesMissingEmbeddings
|
|
1371
|
-
.map((m, i) => ({
|
|
1372
|
-
messageId: m!._id,
|
|
1373
|
-
model: embeddings.model,
|
|
1374
|
-
table: "messages",
|
|
1375
|
-
userId: m.userId,
|
|
1376
|
-
threadId: m.threadId,
|
|
1377
|
-
vector: embeddings.vectors[i],
|
|
1378
|
-
}))
|
|
1379
|
-
.filter(
|
|
1380
|
-
(v): v is Extract<typeof v, { vector: number[] }> =>
|
|
1381
|
-
v.vector !== null,
|
|
1382
|
-
),
|
|
1383
|
-
});
|
|
1384
1124
|
}
|
|
1385
1125
|
|
|
1386
1126
|
/**
|
|
@@ -1677,189 +1417,6 @@ export class Agent<
|
|
|
1677
1417
|
});
|
|
1678
1418
|
}
|
|
1679
1419
|
|
|
1680
|
-
async _saveMessagesAndFetchContext(
|
|
1681
|
-
ctx: RunActionCtx,
|
|
1682
|
-
{
|
|
1683
|
-
userId: argsUserId,
|
|
1684
|
-
threadId,
|
|
1685
|
-
contextOptions,
|
|
1686
|
-
storageOptions,
|
|
1687
|
-
...args
|
|
1688
|
-
}: {
|
|
1689
|
-
prompt: string | (ModelMessage | Message)[] | undefined;
|
|
1690
|
-
messages: (ModelMessage | Message)[] | undefined;
|
|
1691
|
-
promptMessageId: string | undefined;
|
|
1692
|
-
userId: string | null | undefined;
|
|
1693
|
-
threadId: string | undefined;
|
|
1694
|
-
} & Options,
|
|
1695
|
-
): Promise<{
|
|
1696
|
-
messages: ModelMessage[];
|
|
1697
|
-
userId: string | undefined;
|
|
1698
|
-
promptMessageId: string | undefined;
|
|
1699
|
-
pendingMessageId: string | undefined;
|
|
1700
|
-
order: number | undefined;
|
|
1701
|
-
stepOrder: number | undefined;
|
|
1702
|
-
savedMessages: MessageDoc[] | undefined;
|
|
1703
|
-
}> {
|
|
1704
|
-
// If only a promptMessageId is provided, this will be empty.
|
|
1705
|
-
const messages: (ModelMessage | Message)[] = args.messages ?? [];
|
|
1706
|
-
const promptArray: ModelMessage[] = !args.prompt
|
|
1707
|
-
? []
|
|
1708
|
-
: Array.isArray(args.prompt)
|
|
1709
|
-
? args.prompt.map((p) => deserializeMessage(p))
|
|
1710
|
-
: [{ role: "user", content: args.prompt }];
|
|
1711
|
-
const userId =
|
|
1712
|
-
argsUserId ??
|
|
1713
|
-
(threadId &&
|
|
1714
|
-
(await ctx.runQuery(this.component.threads.getThread, { threadId }))
|
|
1715
|
-
?.userId) ??
|
|
1716
|
-
undefined;
|
|
1717
|
-
// If only a messageId is provided, this will add that message to the end.
|
|
1718
|
-
const contextMessages: MessageDoc[] = await this.fetchContextMessages(ctx, {
|
|
1719
|
-
userId,
|
|
1720
|
-
threadId,
|
|
1721
|
-
upToAndIncludingMessageId: args.promptMessageId,
|
|
1722
|
-
messages,
|
|
1723
|
-
contextOptions,
|
|
1724
|
-
});
|
|
1725
|
-
// If it was a promptMessageId, pop it off context messages
|
|
1726
|
-
// and add to the end of messages.
|
|
1727
|
-
const promptMessageIndex = args.promptMessageId
|
|
1728
|
-
? contextMessages.findIndex((m) => m._id === args.promptMessageId)
|
|
1729
|
-
: -1;
|
|
1730
|
-
const promptMessage: MessageDoc | undefined =
|
|
1731
|
-
promptMessageIndex !== -1
|
|
1732
|
-
? contextMessages.splice(promptMessageIndex, 1)[0]
|
|
1733
|
-
: undefined;
|
|
1734
|
-
|
|
1735
|
-
let promptMessageId = promptMessage?._id;
|
|
1736
|
-
let order = promptMessage?.order;
|
|
1737
|
-
let stepOrder = promptMessage?.stepOrder;
|
|
1738
|
-
let savedMessages = undefined;
|
|
1739
|
-
let pendingMessageId = undefined;
|
|
1740
|
-
if (threadId && storageOptions?.saveMessages !== "none") {
|
|
1741
|
-
let saved: { messages: MessageDoc[] };
|
|
1742
|
-
if (
|
|
1743
|
-
messages.length + promptArray.length &&
|
|
1744
|
-
// If it was a promptMessageId, we don't want to save it again.
|
|
1745
|
-
(!args.promptMessageId || storageOptions?.saveMessages === "all")
|
|
1746
|
-
) {
|
|
1747
|
-
const saveAll = storageOptions?.saveMessages === "all";
|
|
1748
|
-
const coreMessages: (ModelMessage | Message)[] = [
|
|
1749
|
-
...messages,
|
|
1750
|
-
...promptArray,
|
|
1751
|
-
];
|
|
1752
|
-
const toSave = saveAll ? coreMessages : coreMessages.slice(-1);
|
|
1753
|
-
const metadata = Array.from({ length: toSave.length }, () => ({}));
|
|
1754
|
-
saved = await this.saveMessages(ctx, {
|
|
1755
|
-
threadId,
|
|
1756
|
-
userId,
|
|
1757
|
-
messages: [...toSave, { role: "assistant", content: [] }],
|
|
1758
|
-
metadata: [...metadata, { status: "pending" }],
|
|
1759
|
-
// TODO: sanity check
|
|
1760
|
-
failPendingSteps: !!args.promptMessageId,
|
|
1761
|
-
});
|
|
1762
|
-
promptMessageId = saved.messages.at(-2)!._id;
|
|
1763
|
-
} else {
|
|
1764
|
-
saved = await this.saveMessages(ctx, {
|
|
1765
|
-
threadId,
|
|
1766
|
-
userId,
|
|
1767
|
-
messages: [{ role: "assistant", content: [] }],
|
|
1768
|
-
metadata: [{ status: "pending" }],
|
|
1769
|
-
failPendingSteps: !!args.promptMessageId,
|
|
1770
|
-
});
|
|
1771
|
-
}
|
|
1772
|
-
pendingMessageId = saved.messages.at(-1)!._id;
|
|
1773
|
-
order = saved.messages.at(-1)!.order;
|
|
1774
|
-
stepOrder = saved.messages.at(-1)!.stepOrder;
|
|
1775
|
-
// Don't return the pending message
|
|
1776
|
-
savedMessages = saved.messages.slice(0, -1);
|
|
1777
|
-
}
|
|
1778
|
-
|
|
1779
|
-
if (promptMessage?.message) {
|
|
1780
|
-
if (!args.prompt) {
|
|
1781
|
-
// If they override the prompt, we skip the existing prompt message.
|
|
1782
|
-
messages.push(promptMessage.message);
|
|
1783
|
-
}
|
|
1784
|
-
// Lazily generate embeddings for the prompt message, if it doesn't have
|
|
1785
|
-
// embeddings yet. This can happen if the message was saved in a mutation
|
|
1786
|
-
// where the LLM is not available.
|
|
1787
|
-
if (!promptMessage.embeddingId && this.options.textEmbeddingModel) {
|
|
1788
|
-
await this._generateAndSaveEmbeddings(ctx, [promptMessage]);
|
|
1789
|
-
}
|
|
1790
|
-
}
|
|
1791
|
-
|
|
1792
|
-
const prePrompt = contextMessages.map((m) => m.message).filter((m) => !!m);
|
|
1793
|
-
let existingResponses: (ModelMessage | Message)[] = [];
|
|
1794
|
-
if (promptMessageIndex !== -1) {
|
|
1795
|
-
// pull any messages that already responded to the prompt off
|
|
1796
|
-
// and add them after the prompt
|
|
1797
|
-
existingResponses = prePrompt.splice(promptMessageIndex);
|
|
1798
|
-
}
|
|
1799
|
-
|
|
1800
|
-
let processedMessages: ModelMessage[] = [
|
|
1801
|
-
...prePrompt,
|
|
1802
|
-
...messages,
|
|
1803
|
-
...promptArray,
|
|
1804
|
-
...existingResponses,
|
|
1805
|
-
].map((m) => deserializeMessage(m));
|
|
1806
|
-
|
|
1807
|
-
// Process messages to inline localhost files (if not, file urls pointing to localhost will be sent to LLM providers)
|
|
1808
|
-
if (process.env.CONVEX_CLOUD_URL?.startsWith("http://127.0.0.1")) {
|
|
1809
|
-
processedMessages = await inlineMessagesFiles(processedMessages);
|
|
1810
|
-
}
|
|
1811
|
-
|
|
1812
|
-
return {
|
|
1813
|
-
messages: processedMessages,
|
|
1814
|
-
userId,
|
|
1815
|
-
promptMessageId,
|
|
1816
|
-
pendingMessageId,
|
|
1817
|
-
savedMessages,
|
|
1818
|
-
order,
|
|
1819
|
-
stepOrder,
|
|
1820
|
-
};
|
|
1821
|
-
}
|
|
1822
|
-
|
|
1823
|
-
async doEmbed(
|
|
1824
|
-
ctx: RunActionCtx,
|
|
1825
|
-
options: {
|
|
1826
|
-
userId: string | undefined;
|
|
1827
|
-
threadId: string | undefined;
|
|
1828
|
-
values: string[];
|
|
1829
|
-
abortSignal?: AbortSignal;
|
|
1830
|
-
headers?: Record<string, string>;
|
|
1831
|
-
},
|
|
1832
|
-
): Promise<{ embeddings: number[][] }> {
|
|
1833
|
-
const embeddingModel = this.options.textEmbeddingModel;
|
|
1834
|
-
assert(
|
|
1835
|
-
embeddingModel,
|
|
1836
|
-
"a textEmbeddingModel is required to be set on the Agent that you're doing vector search with",
|
|
1837
|
-
);
|
|
1838
|
-
const result = await embedMany({
|
|
1839
|
-
...this.options.callSettings,
|
|
1840
|
-
model: embeddingModel,
|
|
1841
|
-
values: options.values,
|
|
1842
|
-
abortSignal: options.abortSignal,
|
|
1843
|
-
headers: options.headers,
|
|
1844
|
-
});
|
|
1845
|
-
if (this.options.usageHandler && result.usage) {
|
|
1846
|
-
await this.options.usageHandler(ctx, {
|
|
1847
|
-
userId: options.userId,
|
|
1848
|
-
threadId: options.threadId,
|
|
1849
|
-
agentName: this.options.name,
|
|
1850
|
-
model: getModelName(embeddingModel),
|
|
1851
|
-
provider: getProviderName(embeddingModel),
|
|
1852
|
-
providerMetadata: undefined,
|
|
1853
|
-
usage: {
|
|
1854
|
-
inputTokens: result.usage.tokens,
|
|
1855
|
-
outputTokens: 0,
|
|
1856
|
-
totalTokens: result.usage.tokens,
|
|
1857
|
-
},
|
|
1858
|
-
});
|
|
1859
|
-
}
|
|
1860
|
-
return { embeddings: result.embeddings };
|
|
1861
|
-
}
|
|
1862
|
-
|
|
1863
1420
|
/**
|
|
1864
1421
|
* WORKFLOW UTILITIES
|
|
1865
1422
|
*/
|
|
@@ -1925,19 +1482,20 @@ export class Agent<
|
|
|
1925
1482
|
handler: async (ctx_, args) => {
|
|
1926
1483
|
const stream =
|
|
1927
1484
|
args.stream === true ? spec?.stream || true : (spec?.stream ?? false);
|
|
1928
|
-
const
|
|
1485
|
+
const { userId, threadId, prompt, messages, maxSteps, ...rest } = args;
|
|
1486
|
+
const targetArgs = { userId, threadId };
|
|
1929
1487
|
const llmArgs = {
|
|
1930
|
-
stopWhen: spec?.stopWhen
|
|
1488
|
+
stopWhen: spec?.stopWhen,
|
|
1931
1489
|
...overrides,
|
|
1932
|
-
...omit(
|
|
1933
|
-
messages:
|
|
1934
|
-
prompt: Array.isArray(
|
|
1935
|
-
?
|
|
1936
|
-
:
|
|
1490
|
+
...omit(rest, ["storageOptions", "contextOptions", "stream"]),
|
|
1491
|
+
messages: messages?.map(deserializeMessage),
|
|
1492
|
+
prompt: Array.isArray(prompt)
|
|
1493
|
+
? prompt.map(deserializeMessage)
|
|
1494
|
+
: prompt,
|
|
1937
1495
|
toolChoice: args.toolChoice as ToolChoice<AgentTools>,
|
|
1938
1496
|
} satisfies StreamingTextArgs<AgentTools>;
|
|
1939
|
-
if (
|
|
1940
|
-
llmArgs.stopWhen = stepCountIs(
|
|
1497
|
+
if (maxSteps) {
|
|
1498
|
+
llmArgs.stopWhen = stepCountIs(maxSteps);
|
|
1941
1499
|
}
|
|
1942
1500
|
const opts = {
|
|
1943
1501
|
...pick(spec, ["contextOptions", "storageOptions"]),
|
|
@@ -1993,11 +1551,8 @@ export class Agent<
|
|
|
1993
1551
|
* the normal parameters to {@link generateObject}, plus {@link ContextOptions}
|
|
1994
1552
|
* and stopWhen.
|
|
1995
1553
|
*/
|
|
1996
|
-
asObjectAction<T>(
|
|
1997
|
-
objectArgs:
|
|
1998
|
-
Parameters<typeof generateObject<FlexibleSchema<T>>>[0],
|
|
1999
|
-
"model"
|
|
2000
|
-
>,
|
|
1554
|
+
asObjectAction<T, DataModel extends GenericDataModel>(
|
|
1555
|
+
objectArgs: GenerateObjectArgs<FlexibleSchema<T>>,
|
|
2001
1556
|
options?: Options & MaybeCustomCtx<CustomCtx, DataModel, AgentTools>,
|
|
2002
1557
|
) {
|
|
2003
1558
|
return internalActionGeneric({
|
|
@@ -2014,7 +1569,7 @@ export class Agent<
|
|
|
2014
1569
|
prompt: Array.isArray(args.prompt)
|
|
2015
1570
|
? args.prompt.map(deserializeMessage)
|
|
2016
1571
|
: args.prompt,
|
|
2017
|
-
} as
|
|
1572
|
+
} as GenerateObjectArgs<FlexibleSchema<T>>;
|
|
2018
1573
|
const ctx = (
|
|
2019
1574
|
options?.customCtx
|
|
2020
1575
|
? { ...ctx_, ...options.customCtx(ctx_, targetArgs, llmArgs) }
|