@convex-dev/agent 0.1.18-alpha.1 → 0.2.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/createTool.d.ts +31 -10
- package/dist/client/createTool.d.ts.map +1 -1
- package/dist/client/createTool.js +25 -10
- package/dist/client/createTool.js.map +1 -1
- package/dist/client/defaultComponent.d.ts +11 -0
- package/dist/client/defaultComponent.d.ts.map +1 -0
- package/dist/client/defaultComponent.js +7 -0
- package/dist/client/defaultComponent.js.map +1 -0
- package/dist/client/definePlaygroundAPI.d.ts +174 -199
- package/dist/client/definePlaygroundAPI.d.ts.map +1 -1
- package/dist/client/definePlaygroundAPI.js +17 -35
- package/dist/client/definePlaygroundAPI.js.map +1 -1
- package/dist/client/files.d.ts +6 -3
- package/dist/client/files.d.ts.map +1 -1
- package/dist/client/files.js +7 -7
- package/dist/client/files.js.map +1 -1
- package/dist/client/index.d.ts +152 -589
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +138 -222
- package/dist/client/index.js.map +1 -1
- package/dist/client/messages.d.ts +538 -0
- package/dist/client/messages.d.ts.map +1 -0
- package/dist/client/messages.js +91 -0
- package/dist/client/messages.js.map +1 -0
- package/dist/client/search.d.ts +30 -7
- package/dist/client/search.d.ts.map +1 -1
- package/dist/client/search.js +20 -3
- package/dist/client/search.js.map +1 -1
- package/dist/client/streaming.d.ts +3 -2
- package/dist/client/streaming.d.ts.map +1 -1
- package/dist/client/streaming.js.map +1 -1
- package/dist/client/threads.d.ts +46 -0
- package/dist/client/threads.d.ts.map +1 -0
- package/dist/client/threads.js +49 -0
- package/dist/client/threads.js.map +1 -0
- package/dist/client/types.d.ts +39 -42
- package/dist/client/types.d.ts.map +1 -1
- package/dist/component/_generated/api.d.ts +437 -75
- package/dist/component/messages.d.ts +254 -55
- package/dist/component/messages.d.ts.map +1 -1
- package/dist/component/messages.js +29 -25
- package/dist/component/messages.js.map +1 -1
- package/dist/component/schema.d.ts +1459 -158
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +8 -14
- package/dist/component/schema.js.map +1 -1
- package/dist/component/streams.d.ts +180 -6
- package/dist/component/streams.d.ts.map +1 -1
- package/dist/mapping.d.ts +11 -15
- package/dist/mapping.d.ts.map +1 -1
- package/dist/mapping.js +191 -61
- package/dist/mapping.js.map +1 -1
- package/dist/react/deltas.d.ts +0 -3
- package/dist/react/deltas.d.ts.map +1 -1
- package/dist/react/deltas.js +140 -44
- package/dist/react/deltas.js.map +1 -1
- package/dist/react/optimisticallySendMessage.d.ts.map +1 -1
- package/dist/react/optimisticallySendMessage.js +2 -1
- package/dist/react/optimisticallySendMessage.js.map +1 -1
- package/dist/react/toUIMessages.d.ts +5 -4
- package/dist/react/toUIMessages.d.ts.map +1 -1
- package/dist/react/toUIMessages.js +103 -40
- package/dist/react/toUIMessages.js.map +1 -1
- package/dist/validators.d.ts +1978 -1210
- package/dist/validators.d.ts.map +1 -1
- package/dist/validators.js +90 -54
- package/dist/validators.js.map +1 -1
- package/package.json +32 -28
- package/src/client/createTool.ts +69 -38
- package/src/client/defaultComponent.ts +17 -0
- package/src/client/definePlaygroundAPI.ts +29 -43
- package/src/client/files.ts +7 -8
- package/src/client/index.test.ts +20 -18
- package/src/client/index.ts +228 -434
- package/src/client/messages.ts +191 -0
- package/src/client/search.ts +30 -6
- package/src/client/streaming.ts +4 -3
- package/src/client/threads.ts +78 -0
- package/src/client/types.ts +50 -72
- package/src/component/_generated/api.d.ts +437 -75
- package/src/component/messages.test.ts +182 -40
- package/src/component/messages.ts +30 -32
- package/src/component/schema.ts +8 -14
- package/src/mapping.ts +230 -94
- package/src/react/deltas.ts +165 -52
- package/src/react/optimisticallySendMessage.ts +4 -1
- package/src/react/toUIMessages.test.ts +154 -36
- package/src/react/toUIMessages.ts +136 -57
- package/src/validators.test.ts +2 -101
- package/src/validators.ts +111 -68
- package/dist/client/listMessages.d.ts +0 -22
- package/dist/client/listMessages.d.ts.map +0 -1
- package/dist/client/listMessages.js +0 -25
- package/dist/client/listMessages.js.map +0 -1
- package/src/client/listMessages.ts +0 -38
- package/src/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
package/src/client/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LanguageModelV2 } from "@ai-sdk/provider";
|
|
2
2
|
import type {
|
|
3
3
|
AssistantContent,
|
|
4
|
-
|
|
4
|
+
ModelMessage,
|
|
5
5
|
DeepPartial,
|
|
6
6
|
FilePart,
|
|
7
7
|
GenerateObjectResult,
|
|
@@ -12,11 +12,18 @@ import type {
|
|
|
12
12
|
StreamTextResult,
|
|
13
13
|
ToolSet,
|
|
14
14
|
UserContent,
|
|
15
|
+
StopCondition,
|
|
16
|
+
Schema,
|
|
17
|
+
ToolChoice,
|
|
18
|
+
LanguageModel,
|
|
19
|
+
EmbeddingModel,
|
|
20
|
+
CallSettings,
|
|
15
21
|
} from "ai";
|
|
16
22
|
import {
|
|
17
23
|
embedMany,
|
|
18
24
|
generateObject,
|
|
19
25
|
generateText,
|
|
26
|
+
stepCountIs,
|
|
20
27
|
streamObject,
|
|
21
28
|
streamText,
|
|
22
29
|
} from "ai";
|
|
@@ -38,28 +45,37 @@ import {
|
|
|
38
45
|
type VectorDimension,
|
|
39
46
|
} from "../component/vector/tables.js";
|
|
40
47
|
import {
|
|
41
|
-
type AIMessageWithoutId,
|
|
42
48
|
deserializeMessage,
|
|
43
|
-
promptOrMessagesToCoreMessages,
|
|
44
49
|
serializeMessage,
|
|
45
50
|
serializeNewMessagesInStep,
|
|
46
51
|
serializeObjectResult,
|
|
47
52
|
} from "../mapping.js";
|
|
48
53
|
import { extractText, isTool } from "../shared.js";
|
|
49
54
|
import {
|
|
50
|
-
type
|
|
55
|
+
type Message,
|
|
51
56
|
type MessageStatus,
|
|
52
57
|
type MessageWithMetadata,
|
|
53
58
|
type ProviderMetadata,
|
|
54
59
|
type StreamArgs,
|
|
55
60
|
type Usage,
|
|
61
|
+
vMessageEmbeddings,
|
|
56
62
|
vMessageWithMetadata,
|
|
57
63
|
vSafeObjectArgs,
|
|
58
64
|
vTextArgs,
|
|
59
65
|
} from "../validators.js";
|
|
60
|
-
import { createTool, wrapTools } from "./createTool.js";
|
|
61
|
-
import {
|
|
62
|
-
|
|
66
|
+
import { createTool, wrapTools, type ToolCtx } from "./createTool.js";
|
|
67
|
+
import {
|
|
68
|
+
listMessages,
|
|
69
|
+
saveMessages,
|
|
70
|
+
type SaveMessageArgs,
|
|
71
|
+
type SaveMessagesArgs,
|
|
72
|
+
} from "./messages.js";
|
|
73
|
+
import { createThread, getThreadMetadata } from "./threads.js";
|
|
74
|
+
import {
|
|
75
|
+
fetchContextMessages,
|
|
76
|
+
getModelName,
|
|
77
|
+
getProviderName,
|
|
78
|
+
} from "./search.js";
|
|
63
79
|
import {
|
|
64
80
|
DeltaStreamer,
|
|
65
81
|
mergeTransforms,
|
|
@@ -86,9 +102,15 @@ import type {
|
|
|
86
102
|
UsageHandler,
|
|
87
103
|
UserActionCtx,
|
|
88
104
|
} from "./types.js";
|
|
105
|
+
import type z from "zod/v3";
|
|
89
106
|
|
|
107
|
+
export { stepCountIs } from "ai";
|
|
90
108
|
export { vMessageDoc, vThreadDoc } from "../component/schema.js";
|
|
91
|
-
export {
|
|
109
|
+
export {
|
|
110
|
+
serializeDataOrUrl,
|
|
111
|
+
deserializeMessage,
|
|
112
|
+
serializeMessage,
|
|
113
|
+
} from "../mapping.js";
|
|
92
114
|
// NOTE: these are also exported via @convex-dev/agent/validators
|
|
93
115
|
// a future version may put them all here or move these over there
|
|
94
116
|
export {
|
|
@@ -106,16 +128,20 @@ export {
|
|
|
106
128
|
} from "../validators.js";
|
|
107
129
|
export type { ToolCtx } from "./createTool.js";
|
|
108
130
|
export { getFile, storeFile } from "./files.js";
|
|
109
|
-
export { filterOutOrphanedToolMessages } from "./search.js";
|
|
110
|
-
export { abortStream, listStreams } from "./streaming.js";
|
|
111
131
|
export {
|
|
112
|
-
|
|
113
|
-
extractText,
|
|
132
|
+
filterOutOrphanedToolMessages,
|
|
114
133
|
fetchContextMessages,
|
|
115
|
-
|
|
134
|
+
} from "./search.js";
|
|
135
|
+
export { abortStream, listStreams, syncStreams } from "./streaming.js";
|
|
136
|
+
export {
|
|
116
137
|
listMessages,
|
|
117
|
-
|
|
118
|
-
|
|
138
|
+
saveMessage,
|
|
139
|
+
saveMessages,
|
|
140
|
+
type SaveMessageArgs,
|
|
141
|
+
type SaveMessagesArgs,
|
|
142
|
+
} from "./messages.js";
|
|
143
|
+
export { createThread, getThreadMetadata } from "./threads.js";
|
|
144
|
+
export { createTool, extractText, isTool };
|
|
119
145
|
export {
|
|
120
146
|
definePlaygroundAPI,
|
|
121
147
|
type PlaygroundAPI,
|
|
@@ -175,7 +201,7 @@ export class Agent<
|
|
|
175
201
|
* const myAgent = new Agent(components.agent, {
|
|
176
202
|
* chat: openai.chat("gpt-4o-mini"),
|
|
177
203
|
*/
|
|
178
|
-
chat:
|
|
204
|
+
chat: LanguageModel;
|
|
179
205
|
/**
|
|
180
206
|
* The model to use for text embeddings. Optional.
|
|
181
207
|
* If specified, it will use this for generating vector embeddings
|
|
@@ -186,7 +212,7 @@ export class Agent<
|
|
|
186
212
|
* const myAgent = new Agent(components.agent, {
|
|
187
213
|
* textEmbedding: openai.embedding("text-embedding-3-small")
|
|
188
214
|
*/
|
|
189
|
-
textEmbedding?:
|
|
215
|
+
textEmbedding?: EmbeddingModel<string>;
|
|
190
216
|
/**
|
|
191
217
|
* The default system prompt to put in each request.
|
|
192
218
|
* Override per-prompt by passing the "system" parameter.
|
|
@@ -212,14 +238,15 @@ export class Agent<
|
|
|
212
238
|
storageOptions?: StorageOptions;
|
|
213
239
|
/**
|
|
214
240
|
* When generating or streaming text with tools available, this
|
|
215
|
-
* determines
|
|
241
|
+
* determines when to stop. Defaults to stepCountIs(1).
|
|
216
242
|
*/
|
|
217
|
-
|
|
243
|
+
stopWhen?: StopCondition<AgentTools> | Array<StopCondition<AgentTools>>;
|
|
218
244
|
/**
|
|
219
|
-
* The
|
|
220
|
-
* This can be overridden at each generate/stream callsite
|
|
245
|
+
* The default settings to use for the LLM calls.
|
|
246
|
+
* This can be overridden at each generate/stream callsite on a per-field
|
|
247
|
+
* basis. To clear a default setting, you'll need to pass `undefined`.
|
|
221
248
|
*/
|
|
222
|
-
|
|
249
|
+
callSettings?: CallSettings;
|
|
223
250
|
/**
|
|
224
251
|
* The usage handler to use for this agent.
|
|
225
252
|
*/
|
|
@@ -309,9 +336,7 @@ export class Agent<
|
|
|
309
336
|
*/
|
|
310
337
|
tools?: ThreadTools;
|
|
311
338
|
},
|
|
312
|
-
): Promise<{
|
|
313
|
-
threadId: string;
|
|
314
|
-
}>;
|
|
339
|
+
): Promise<{ threadId: string }>;
|
|
315
340
|
async createThread<ThreadTools extends ToolSet | undefined = undefined>(
|
|
316
341
|
ctx: (ActionCtx & CustomCtx) | RunMutationCtx,
|
|
317
342
|
args?: {
|
|
@@ -335,10 +360,7 @@ export class Agent<
|
|
|
335
360
|
usageHandler: args?.usageHandler,
|
|
336
361
|
tools: args?.tools,
|
|
337
362
|
});
|
|
338
|
-
return {
|
|
339
|
-
threadId,
|
|
340
|
-
thread,
|
|
341
|
-
};
|
|
363
|
+
return { threadId, thread };
|
|
342
364
|
}
|
|
343
365
|
|
|
344
366
|
/**
|
|
@@ -394,30 +416,6 @@ export class Agent<
|
|
|
394
416
|
};
|
|
395
417
|
}
|
|
396
418
|
|
|
397
|
-
/**
|
|
398
|
-
* Search for threads by title, paginated.
|
|
399
|
-
* @param ctx The context passed from the query/mutation/action.
|
|
400
|
-
* @returns The threads matching the search, paginated.
|
|
401
|
-
*/
|
|
402
|
-
async searchThreadTitles(
|
|
403
|
-
ctx: RunQueryCtx,
|
|
404
|
-
{
|
|
405
|
-
userId,
|
|
406
|
-
query,
|
|
407
|
-
limit,
|
|
408
|
-
}: {
|
|
409
|
-
userId?: string | undefined;
|
|
410
|
-
query: string;
|
|
411
|
-
limit?: number;
|
|
412
|
-
},
|
|
413
|
-
): Promise<ThreadDoc[]> {
|
|
414
|
-
return ctx.runQuery(this.component.threads.searchThreadTitles, {
|
|
415
|
-
userId,
|
|
416
|
-
query,
|
|
417
|
-
limit: limit ?? 10,
|
|
418
|
-
});
|
|
419
|
-
}
|
|
420
|
-
|
|
421
419
|
/**
|
|
422
420
|
* This behaves like {@link generateText} from the "ai" package except that
|
|
423
421
|
* it add context based on the userId and threadId and saves the input and
|
|
@@ -439,8 +437,8 @@ export class Agent<
|
|
|
439
437
|
{
|
|
440
438
|
userId: argsUserId,
|
|
441
439
|
threadId,
|
|
442
|
-
usageHandler,
|
|
443
440
|
tools: threadTools,
|
|
441
|
+
...usageHandler
|
|
444
442
|
}: {
|
|
445
443
|
userId?: string | null;
|
|
446
444
|
threadId?: string;
|
|
@@ -458,34 +456,36 @@ export class Agent<
|
|
|
458
456
|
GenerateTextResult<TOOLS extends undefined ? AgentTools : TOOLS, OUTPUT> &
|
|
459
457
|
GenerationOutputMetadata
|
|
460
458
|
> {
|
|
461
|
-
const opts = { ...this.options, ...options, usageHandler };
|
|
459
|
+
const opts = { ...this.options, ...options, ...usageHandler };
|
|
462
460
|
const context = await this._saveMessagesAndFetchContext(ctx, args, {
|
|
463
461
|
userId: argsUserId ?? undefined,
|
|
464
462
|
threadId,
|
|
465
463
|
...opts,
|
|
466
464
|
});
|
|
467
465
|
const { args: aiArgs, messageId, order, userId } = context;
|
|
466
|
+
const messages = context.savedMessages ?? [];
|
|
468
467
|
const toolCtx = {
|
|
469
468
|
...(ctx as UserActionCtx & CustomCtx),
|
|
470
469
|
userId,
|
|
471
470
|
threadId,
|
|
472
471
|
messageId,
|
|
473
472
|
agent: this,
|
|
474
|
-
};
|
|
473
|
+
} satisfies ToolCtx;
|
|
474
|
+
type Tools = TOOLS extends undefined ? AgentTools : TOOLS;
|
|
475
475
|
const tools = wrapTools(
|
|
476
476
|
toolCtx,
|
|
477
477
|
args.tools ?? threadTools ?? this.options.tools,
|
|
478
|
-
) as
|
|
478
|
+
) as Tools;
|
|
479
479
|
const saveOutput = opts.storageOptions?.saveMessages !== "none";
|
|
480
480
|
try {
|
|
481
|
-
const result = (await generateText({
|
|
481
|
+
const result = (await generateText<Tools, OUTPUT, OUTPUT_PARTIAL>({
|
|
482
482
|
// Can be overridden
|
|
483
|
-
|
|
483
|
+
stopWhen: this.options.stopWhen as StopCondition<Tools> | undefined,
|
|
484
484
|
...aiArgs,
|
|
485
485
|
tools,
|
|
486
486
|
onStepFinish: async (step) => {
|
|
487
487
|
if (threadId && messageId && saveOutput) {
|
|
488
|
-
await this.saveStep(ctx, {
|
|
488
|
+
const saved = await this.saveStep(ctx, {
|
|
489
489
|
userId,
|
|
490
490
|
threadId,
|
|
491
491
|
promptMessageId: messageId,
|
|
@@ -493,6 +493,7 @@ export class Agent<
|
|
|
493
493
|
provider: aiArgs.model.provider,
|
|
494
494
|
step,
|
|
495
495
|
});
|
|
496
|
+
messages.push(...saved.messages);
|
|
496
497
|
}
|
|
497
498
|
if (this.options.rawRequestResponseHandler) {
|
|
498
499
|
await this.options.rawRequestResponseHandler(ctx, {
|
|
@@ -516,13 +517,10 @@ export class Agent<
|
|
|
516
517
|
}
|
|
517
518
|
return args.onStepFinish?.(step);
|
|
518
519
|
},
|
|
519
|
-
})) as GenerateTextResult<
|
|
520
|
-
TOOLS extends undefined ? AgentTools : TOOLS,
|
|
521
|
-
OUTPUT
|
|
522
|
-
> &
|
|
523
|
-
GenerationOutputMetadata;
|
|
520
|
+
})) as GenerateTextResult<Tools, OUTPUT> & GenerationOutputMetadata;
|
|
524
521
|
result.messageId = messageId;
|
|
525
522
|
result.order = order;
|
|
523
|
+
result.messages = messages;
|
|
526
524
|
return result;
|
|
527
525
|
} catch (error) {
|
|
528
526
|
if (threadId && messageId) {
|
|
@@ -552,9 +550,9 @@ export class Agent<
|
|
|
552
550
|
{
|
|
553
551
|
userId: argsUserId,
|
|
554
552
|
threadId,
|
|
555
|
-
usageHandler,
|
|
556
553
|
/** Note: to get better type inference, pass tools in the next arg */
|
|
557
554
|
tools: threadTools,
|
|
555
|
+
...usageHandler
|
|
558
556
|
}: {
|
|
559
557
|
userId?: string | null;
|
|
560
558
|
threadId?: string;
|
|
@@ -589,13 +587,14 @@ export class Agent<
|
|
|
589
587
|
> &
|
|
590
588
|
GenerationOutputMetadata
|
|
591
589
|
> {
|
|
592
|
-
const opts = { ...this.options, ...options, usageHandler };
|
|
590
|
+
const opts = { ...this.options, ...options, ...usageHandler };
|
|
593
591
|
const context = await this._saveMessagesAndFetchContext(ctx, args, {
|
|
594
592
|
userId: argsUserId ?? undefined,
|
|
595
593
|
threadId,
|
|
596
594
|
...opts,
|
|
597
595
|
});
|
|
598
596
|
const { args: aiArgs, messageId, order, stepOrder, userId } = context;
|
|
597
|
+
const messages = context.savedMessages ?? [];
|
|
599
598
|
const toolCtx = {
|
|
600
599
|
...(ctx as UserActionCtx & CustomCtx),
|
|
601
600
|
userId,
|
|
@@ -624,8 +623,8 @@ export class Agent<
|
|
|
624
623
|
: undefined;
|
|
625
624
|
|
|
626
625
|
const result = streamText({
|
|
627
|
-
//
|
|
628
|
-
|
|
626
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
627
|
+
stopWhen: this.options.stopWhen as any, // Can be overridden
|
|
629
628
|
...aiArgs,
|
|
630
629
|
tools,
|
|
631
630
|
abortSignal: streamer?.abortController.signal ?? aiArgs.abortSignal,
|
|
@@ -661,6 +660,7 @@ export class Agent<
|
|
|
661
660
|
step,
|
|
662
661
|
});
|
|
663
662
|
await streamer?.finish(saved.messages);
|
|
663
|
+
messages.push(...saved.messages);
|
|
664
664
|
}
|
|
665
665
|
if (this.options.rawRequestResponseHandler) {
|
|
666
666
|
await this.options.rawRequestResponseHandler(ctx, {
|
|
@@ -691,6 +691,7 @@ export class Agent<
|
|
|
691
691
|
GenerationOutputMetadata;
|
|
692
692
|
result.messageId = messageId;
|
|
693
693
|
result.order = order;
|
|
694
|
+
result.messages = messages;
|
|
694
695
|
return result;
|
|
695
696
|
}
|
|
696
697
|
|
|
@@ -706,7 +707,7 @@ export class Agent<
|
|
|
706
707
|
{
|
|
707
708
|
userId: argsUserId,
|
|
708
709
|
threadId,
|
|
709
|
-
usageHandler
|
|
710
|
+
...usageHandler
|
|
710
711
|
}: {
|
|
711
712
|
userId?: string | null;
|
|
712
713
|
threadId?: string;
|
|
@@ -722,13 +723,14 @@ export class Agent<
|
|
|
722
723
|
*/
|
|
723
724
|
options?: Options,
|
|
724
725
|
): Promise<GenerateObjectResult<T> & GenerationOutputMetadata> {
|
|
725
|
-
const opts = { ...this.options, ...options, usageHandler };
|
|
726
|
+
const opts = { ...this.options, ...options, ...usageHandler };
|
|
726
727
|
const context = await this._saveMessagesAndFetchContext(ctx, args, {
|
|
727
728
|
userId: argsUserId ?? undefined,
|
|
728
729
|
threadId,
|
|
729
730
|
...opts,
|
|
730
731
|
});
|
|
731
732
|
const { args: aiArgs, messageId, order, userId } = context;
|
|
733
|
+
const messages = context.savedMessages ?? [];
|
|
732
734
|
const saveOutput = opts.storageOptions?.saveMessages !== "none";
|
|
733
735
|
try {
|
|
734
736
|
const result = (await generateObject(
|
|
@@ -737,7 +739,7 @@ export class Agent<
|
|
|
737
739
|
)) as GenerateObjectResult<T> & GenerationOutputMetadata;
|
|
738
740
|
|
|
739
741
|
if (threadId && messageId && saveOutput) {
|
|
740
|
-
await this.saveObject(ctx, {
|
|
742
|
+
const saved = await this.saveObject(ctx, {
|
|
741
743
|
threadId,
|
|
742
744
|
promptMessageId: messageId,
|
|
743
745
|
result,
|
|
@@ -745,9 +747,11 @@ export class Agent<
|
|
|
745
747
|
model: aiArgs.model.modelId,
|
|
746
748
|
provider: aiArgs.model.provider,
|
|
747
749
|
});
|
|
750
|
+
messages.push(...saved.messages);
|
|
748
751
|
}
|
|
749
752
|
result.messageId = messageId;
|
|
750
753
|
result.order = order;
|
|
754
|
+
result.messages = messages;
|
|
751
755
|
if (this.options.rawRequestResponseHandler) {
|
|
752
756
|
await this.options.rawRequestResponseHandler(ctx, {
|
|
753
757
|
userId,
|
|
@@ -787,12 +791,12 @@ export class Agent<
|
|
|
787
791
|
* Use {@link continueThread} to get a version of this function already scoped
|
|
788
792
|
* to a thread (and optionally userId).
|
|
789
793
|
*/
|
|
790
|
-
async streamObject<T>(
|
|
794
|
+
async streamObject<T extends z.Schema | Schema>(
|
|
791
795
|
ctx: ActionCtx,
|
|
792
796
|
{
|
|
793
797
|
userId: argsUserId,
|
|
794
798
|
threadId,
|
|
795
|
-
usageHandler
|
|
799
|
+
...usageHandler
|
|
796
800
|
}: {
|
|
797
801
|
userId?: string | null;
|
|
798
802
|
threadId?: string;
|
|
@@ -811,15 +815,17 @@ export class Agent<
|
|
|
811
815
|
StreamObjectResult<DeepPartial<T>, T, never> & GenerationOutputMetadata
|
|
812
816
|
> {
|
|
813
817
|
// TODO: unify all this shared code between all the generate* and stream* functions
|
|
814
|
-
const opts = { ...this.options, ...options, usageHandler };
|
|
818
|
+
const opts = { ...this.options, ...options, ...usageHandler };
|
|
815
819
|
const context = await this._saveMessagesAndFetchContext(ctx, args, {
|
|
816
820
|
userId: argsUserId ?? undefined,
|
|
817
821
|
threadId,
|
|
818
822
|
...opts,
|
|
819
823
|
});
|
|
820
824
|
const { args: aiArgs, messageId, order, userId } = context;
|
|
825
|
+
const messages = context.savedMessages ?? [];
|
|
821
826
|
const saveOutput = opts.storageOptions?.saveMessages !== "none";
|
|
822
|
-
|
|
827
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
828
|
+
const stream = streamObject<any>({
|
|
823
829
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
824
830
|
...(aiArgs as any),
|
|
825
831
|
onError: async (error) => {
|
|
@@ -828,7 +834,7 @@ export class Agent<
|
|
|
828
834
|
},
|
|
829
835
|
onFinish: async (result) => {
|
|
830
836
|
if (threadId && messageId && saveOutput) {
|
|
831
|
-
await this.saveObject(ctx, {
|
|
837
|
+
const saved = await this.saveObject(ctx, {
|
|
832
838
|
userId,
|
|
833
839
|
threadId,
|
|
834
840
|
promptMessageId: messageId,
|
|
@@ -840,14 +846,12 @@ export class Agent<
|
|
|
840
846
|
request: await stream.request,
|
|
841
847
|
response: result.response,
|
|
842
848
|
providerMetadata: result.providerMetadata,
|
|
843
|
-
experimental_providerMetadata:
|
|
844
|
-
result.experimental_providerMetadata,
|
|
845
|
-
logprobs: undefined,
|
|
846
849
|
toJsonResponse: stream.toTextStreamResponse,
|
|
847
850
|
},
|
|
848
851
|
model: aiArgs.model.modelId,
|
|
849
852
|
provider: aiArgs.model.provider,
|
|
850
853
|
});
|
|
854
|
+
messages.push(...saved.messages);
|
|
851
855
|
}
|
|
852
856
|
if (opts.usageHandler && result.usage) {
|
|
853
857
|
await opts.usageHandler(ctx, {
|
|
@@ -876,6 +880,7 @@ export class Agent<
|
|
|
876
880
|
GenerationOutputMetadata;
|
|
877
881
|
stream.messageId = messageId;
|
|
878
882
|
stream.order = order;
|
|
883
|
+
stream.messages = messages;
|
|
879
884
|
return stream;
|
|
880
885
|
}
|
|
881
886
|
|
|
@@ -898,14 +903,11 @@ export class Agent<
|
|
|
898
903
|
skipEmbeddings?: boolean;
|
|
899
904
|
},
|
|
900
905
|
) {
|
|
901
|
-
const {
|
|
906
|
+
const { messages } = await this.saveMessages(ctx, {
|
|
902
907
|
threadId: args.threadId,
|
|
903
908
|
userId: args.userId,
|
|
904
909
|
embeddings: args.embedding
|
|
905
|
-
? {
|
|
906
|
-
model: args.embedding.model,
|
|
907
|
-
vectors: [args.embedding.vector],
|
|
908
|
-
}
|
|
910
|
+
? { model: args.embedding.model, vectors: [args.embedding.vector] }
|
|
909
911
|
: undefined,
|
|
910
912
|
messages:
|
|
911
913
|
args.prompt !== undefined
|
|
@@ -914,7 +916,8 @@ export class Agent<
|
|
|
914
916
|
metadata: args.metadata ? [args.metadata] : undefined,
|
|
915
917
|
skipEmbeddings: args.skipEmbeddings,
|
|
916
918
|
});
|
|
917
|
-
|
|
919
|
+
const message = messages.at(-1)!;
|
|
920
|
+
return { messageId: message._id, message };
|
|
918
921
|
}
|
|
919
922
|
|
|
920
923
|
/**
|
|
@@ -936,16 +939,8 @@ export class Agent<
|
|
|
936
939
|
*/
|
|
937
940
|
skipEmbeddings?: boolean;
|
|
938
941
|
},
|
|
939
|
-
): Promise<{
|
|
940
|
-
|
|
941
|
-
messages: MessageDoc[];
|
|
942
|
-
}> {
|
|
943
|
-
let embeddings:
|
|
944
|
-
| {
|
|
945
|
-
vectors: (number[] | null)[];
|
|
946
|
-
model: string;
|
|
947
|
-
}
|
|
948
|
-
| undefined;
|
|
942
|
+
): Promise<{ messages: MessageDoc[] }> {
|
|
943
|
+
let embeddings: { vectors: (number[] | null)[]; model: string } | undefined;
|
|
949
944
|
const { skipEmbeddings, ...rest } = args;
|
|
950
945
|
if (args.embeddings) {
|
|
951
946
|
embeddings = args.embeddings;
|
|
@@ -967,10 +962,7 @@ export class Agent<
|
|
|
967
962
|
} else {
|
|
968
963
|
embeddings = await this.generateEmbeddings(
|
|
969
964
|
ctx,
|
|
970
|
-
{
|
|
971
|
-
userId: args.userId ?? undefined,
|
|
972
|
-
threadId: args.threadId,
|
|
973
|
-
},
|
|
965
|
+
{ userId: args.userId ?? undefined, threadId: args.threadId },
|
|
974
966
|
args.messages,
|
|
975
967
|
);
|
|
976
968
|
}
|
|
@@ -1037,7 +1029,7 @@ export class Agent<
|
|
|
1037
1029
|
args: {
|
|
1038
1030
|
userId: string | undefined;
|
|
1039
1031
|
threadId: string | undefined;
|
|
1040
|
-
messages:
|
|
1032
|
+
messages: (ModelMessage | Message)[];
|
|
1041
1033
|
/**
|
|
1042
1034
|
* If provided, it will search for messages up to and including this message.
|
|
1043
1035
|
* Note: if this is far in the past, text and vector search results may be more
|
|
@@ -1069,7 +1061,7 @@ export class Agent<
|
|
|
1069
1061
|
values: [text],
|
|
1070
1062
|
})
|
|
1071
1063
|
).embeddings[0],
|
|
1072
|
-
embeddingModel: this.options.textEmbedding
|
|
1064
|
+
embeddingModel: this.options.textEmbedding,
|
|
1073
1065
|
};
|
|
1074
1066
|
},
|
|
1075
1067
|
});
|
|
@@ -1121,11 +1113,8 @@ export class Agent<
|
|
|
1121
1113
|
{
|
|
1122
1114
|
userId,
|
|
1123
1115
|
threadId,
|
|
1124
|
-
}: {
|
|
1125
|
-
|
|
1126
|
-
threadId: string | undefined;
|
|
1127
|
-
},
|
|
1128
|
-
messages: CoreMessage[],
|
|
1116
|
+
}: { userId: string | undefined; threadId: string | undefined },
|
|
1117
|
+
messages: (ModelMessage | Message)[],
|
|
1129
1118
|
) {
|
|
1130
1119
|
if (!this.options.textEmbedding) {
|
|
1131
1120
|
return undefined;
|
|
@@ -1151,7 +1140,6 @@ export class Agent<
|
|
|
1151
1140
|
threadId,
|
|
1152
1141
|
values: messageTexts as string[],
|
|
1153
1142
|
});
|
|
1154
|
-
// TODO: record usage of embeddings
|
|
1155
1143
|
// Then assemble the embeddings into a single array with nulls for the messages without text.
|
|
1156
1144
|
const embeddingsOrNull = Array(messages.length).fill(null);
|
|
1157
1145
|
textIndexes.forEach((i, j) => {
|
|
@@ -1160,11 +1148,8 @@ export class Agent<
|
|
|
1160
1148
|
if (textEmbeddings.embeddings.length > 0) {
|
|
1161
1149
|
const dimension = textEmbeddings.embeddings[0].length;
|
|
1162
1150
|
validateVectorDimension(dimension);
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
dimension,
|
|
1166
|
-
model: this.options.textEmbedding.modelId,
|
|
1167
|
-
};
|
|
1151
|
+
const model = getModelName(this.options.textEmbedding);
|
|
1152
|
+
embeddings = { vectors: embeddingsOrNull, dimension, model };
|
|
1168
1153
|
}
|
|
1169
1154
|
return embeddings;
|
|
1170
1155
|
}
|
|
@@ -1178,9 +1163,7 @@ export class Agent<
|
|
|
1178
1163
|
*/
|
|
1179
1164
|
async generateAndSaveEmbeddings(
|
|
1180
1165
|
ctx: RunActionCtx,
|
|
1181
|
-
args: {
|
|
1182
|
-
messageIds: string[];
|
|
1183
|
-
},
|
|
1166
|
+
args: { messageIds: string[] },
|
|
1184
1167
|
) {
|
|
1185
1168
|
const messages = (
|
|
1186
1169
|
await ctx.runQuery(this.component.messages.getMessagesByIds, {
|
|
@@ -1218,7 +1201,7 @@ export class Agent<
|
|
|
1218
1201
|
userId: messagesMissingEmbeddings[0]!.userId,
|
|
1219
1202
|
threadId: messagesMissingEmbeddings[0]!.threadId,
|
|
1220
1203
|
},
|
|
1221
|
-
messagesMissingEmbeddings.map((m) => m!.message!),
|
|
1204
|
+
messagesMissingEmbeddings.map((m) => deserializeMessage(m!.message!)),
|
|
1222
1205
|
);
|
|
1223
1206
|
if (!embeddings) {
|
|
1224
1207
|
if (!this.options.textEmbedding) {
|
|
@@ -1278,14 +1261,14 @@ export class Agent<
|
|
|
1278
1261
|
*/
|
|
1279
1262
|
provider?: string;
|
|
1280
1263
|
},
|
|
1281
|
-
): Promise<{ messages: MessageDoc[]
|
|
1264
|
+
): Promise<{ messages: MessageDoc[] }> {
|
|
1282
1265
|
const messages = await serializeNewMessagesInStep(
|
|
1283
1266
|
ctx,
|
|
1284
1267
|
this.component,
|
|
1285
1268
|
args.step,
|
|
1286
1269
|
{
|
|
1287
|
-
provider: args.provider ?? this.options.chat
|
|
1288
|
-
model: args.model ?? this.options.chat
|
|
1270
|
+
provider: args.provider ?? getProviderName(this.options.chat),
|
|
1271
|
+
model: args.model ?? getModelName(this.options.chat),
|
|
1289
1272
|
},
|
|
1290
1273
|
);
|
|
1291
1274
|
const embeddings = await this.generateEmbeddings(
|
|
@@ -1293,7 +1276,7 @@ export class Agent<
|
|
|
1293
1276
|
{ userId: args.userId, threadId: args.threadId },
|
|
1294
1277
|
messages.map((m) => m.message),
|
|
1295
1278
|
);
|
|
1296
|
-
|
|
1279
|
+
return ctx.runMutation(this.component.messages.addMessages, {
|
|
1297
1280
|
userId: args.userId,
|
|
1298
1281
|
threadId: args.threadId,
|
|
1299
1282
|
agentName: this.options.name,
|
|
@@ -1302,7 +1285,6 @@ export class Agent<
|
|
|
1302
1285
|
embeddings,
|
|
1303
1286
|
failPendingSteps: false,
|
|
1304
1287
|
});
|
|
1305
|
-
return saved;
|
|
1306
1288
|
}
|
|
1307
1289
|
|
|
1308
1290
|
/**
|
|
@@ -1323,23 +1305,23 @@ export class Agent<
|
|
|
1323
1305
|
result: GenerateObjectResult<unknown>;
|
|
1324
1306
|
metadata?: Omit<MessageWithMetadata, "message">;
|
|
1325
1307
|
},
|
|
1326
|
-
): Promise<
|
|
1308
|
+
): Promise<{ messages: MessageDoc[] }> {
|
|
1327
1309
|
const { messages } = await serializeObjectResult(
|
|
1328
1310
|
ctx,
|
|
1329
1311
|
this.component,
|
|
1330
1312
|
args.result,
|
|
1331
1313
|
{
|
|
1332
|
-
model: args.model ?? this.options.chat
|
|
1333
|
-
provider: args.provider ?? this.options.chat
|
|
1314
|
+
model: args.model ?? getModelName(this.options.chat),
|
|
1315
|
+
provider: args.provider ?? getProviderName(this.options.chat),
|
|
1334
1316
|
},
|
|
1335
1317
|
);
|
|
1336
1318
|
const embeddings = await this.generateEmbeddings(
|
|
1337
1319
|
ctx,
|
|
1338
1320
|
{ userId: args.userId, threadId: args.threadId },
|
|
1339
|
-
messages.map((m) => m.message),
|
|
1321
|
+
messages.map((m) => deserializeMessage(m.message)),
|
|
1340
1322
|
);
|
|
1341
1323
|
|
|
1342
|
-
|
|
1324
|
+
return ctx.runMutation(this.component.messages.addMessages, {
|
|
1343
1325
|
userId: args.userId,
|
|
1344
1326
|
threadId: args.threadId,
|
|
1345
1327
|
promptMessageId: args.promptMessageId,
|
|
@@ -1347,7 +1329,6 @@ export class Agent<
|
|
|
1347
1329
|
messages,
|
|
1348
1330
|
embeddings,
|
|
1349
1331
|
agentName: this.options.name,
|
|
1350
|
-
pending: false,
|
|
1351
1332
|
});
|
|
1352
1333
|
}
|
|
1353
1334
|
|
|
@@ -1392,7 +1373,7 @@ export class Agent<
|
|
|
1392
1373
|
messageId: string;
|
|
1393
1374
|
patch: {
|
|
1394
1375
|
/** The message to replace the existing message. */
|
|
1395
|
-
message:
|
|
1376
|
+
message: ModelMessage | Message;
|
|
1396
1377
|
/** The status to set on the message. */
|
|
1397
1378
|
status: "success" | "error";
|
|
1398
1379
|
/** The error message to set on the message. */
|
|
@@ -1437,9 +1418,7 @@ export class Agent<
|
|
|
1437
1418
|
*/
|
|
1438
1419
|
async deleteMessages(
|
|
1439
1420
|
ctx: RunMutationCtx,
|
|
1440
|
-
args: {
|
|
1441
|
-
messageIds: string[];
|
|
1442
|
-
},
|
|
1421
|
+
args: { messageIds: string[] },
|
|
1443
1422
|
): Promise<void> {
|
|
1444
1423
|
await ctx.runMutation(this.component.messages.deleteByIds, args);
|
|
1445
1424
|
}
|
|
@@ -1452,9 +1431,7 @@ export class Agent<
|
|
|
1452
1431
|
*/
|
|
1453
1432
|
async deleteMessage(
|
|
1454
1433
|
ctx: RunMutationCtx,
|
|
1455
|
-
args: {
|
|
1456
|
-
messageId: string;
|
|
1457
|
-
},
|
|
1434
|
+
args: { messageId: string },
|
|
1458
1435
|
): Promise<void> {
|
|
1459
1436
|
await ctx.runMutation(this.component.messages.deleteByIds, {
|
|
1460
1437
|
messageIds: [args.messageId],
|
|
@@ -1507,8 +1484,8 @@ export class Agent<
|
|
|
1507
1484
|
endOrder: number;
|
|
1508
1485
|
endStepOrder?: number;
|
|
1509
1486
|
},
|
|
1510
|
-
): Promise<
|
|
1511
|
-
|
|
1487
|
+
): Promise<{ isDone: boolean; lastOrder?: number; lastStepOrder?: number }> {
|
|
1488
|
+
return ctx.runMutation(this.component.messages.deleteByOrder, {
|
|
1512
1489
|
threadId: args.threadId,
|
|
1513
1490
|
startOrder: args.startOrder,
|
|
1514
1491
|
startStepOrder: args.startStepOrder,
|
|
@@ -1526,10 +1503,7 @@ export class Agent<
|
|
|
1526
1503
|
*/
|
|
1527
1504
|
async deleteThreadAsync(
|
|
1528
1505
|
ctx: RunMutationCtx,
|
|
1529
|
-
args: {
|
|
1530
|
-
threadId: string;
|
|
1531
|
-
pageSize?: number;
|
|
1532
|
-
},
|
|
1506
|
+
args: { threadId: string; pageSize?: number },
|
|
1533
1507
|
): Promise<void> {
|
|
1534
1508
|
await ctx.runMutation(this.component.threads.deleteAllForThreadIdAsync, {
|
|
1535
1509
|
threadId: args.threadId,
|
|
@@ -1546,10 +1520,7 @@ export class Agent<
|
|
|
1546
1520
|
*/
|
|
1547
1521
|
async deleteThreadSync(
|
|
1548
1522
|
ctx: RunActionCtx,
|
|
1549
|
-
args: {
|
|
1550
|
-
threadId: string;
|
|
1551
|
-
pageSize?: number;
|
|
1552
|
-
},
|
|
1523
|
+
args: { threadId: string; pageSize?: number },
|
|
1553
1524
|
): Promise<void> {
|
|
1554
1525
|
await ctx.runAction(this.component.threads.deleteAllForThreadIdSync, {
|
|
1555
1526
|
threadId: args.threadId,
|
|
@@ -1560,12 +1531,11 @@ export class Agent<
|
|
|
1560
1531
|
async _saveMessagesAndFetchContext<
|
|
1561
1532
|
T extends {
|
|
1562
1533
|
id?: string;
|
|
1563
|
-
prompt?: string;
|
|
1564
|
-
messages?:
|
|
1534
|
+
prompt?: string | (ModelMessage | Message)[];
|
|
1535
|
+
messages?: (ModelMessage | Message)[];
|
|
1565
1536
|
system?: string;
|
|
1566
1537
|
promptMessageId?: string;
|
|
1567
|
-
model?:
|
|
1568
|
-
maxRetries?: number;
|
|
1538
|
+
model?: LanguageModelV2;
|
|
1569
1539
|
},
|
|
1570
1540
|
>(
|
|
1571
1541
|
ctx: RunActionCtx,
|
|
@@ -1575,19 +1545,22 @@ export class Agent<
|
|
|
1575
1545
|
threadId,
|
|
1576
1546
|
contextOptions,
|
|
1577
1547
|
storageOptions,
|
|
1578
|
-
}: {
|
|
1579
|
-
userId: string | undefined;
|
|
1580
|
-
threadId: string | undefined;
|
|
1581
|
-
} & Options,
|
|
1548
|
+
}: { userId: string | undefined; threadId: string | undefined } & Options,
|
|
1582
1549
|
): Promise<{
|
|
1583
|
-
args: T & { model:
|
|
1550
|
+
args: T & { model: LanguageModelV2 };
|
|
1584
1551
|
userId: string | undefined;
|
|
1585
1552
|
messageId: string | undefined;
|
|
1586
1553
|
order: number | undefined;
|
|
1587
1554
|
stepOrder: number | undefined;
|
|
1555
|
+
savedMessages: MessageDoc[] | undefined;
|
|
1588
1556
|
}> {
|
|
1589
1557
|
// If only a promptMessageId is provided, this will be empty.
|
|
1590
|
-
const messages =
|
|
1558
|
+
const messages = args.messages ?? [];
|
|
1559
|
+
const prompt: (ModelMessage | Message)[] = !args.prompt
|
|
1560
|
+
? []
|
|
1561
|
+
: Array.isArray(args.prompt)
|
|
1562
|
+
? args.prompt
|
|
1563
|
+
: [{ role: "user", content: args.prompt }];
|
|
1591
1564
|
const userId =
|
|
1592
1565
|
argsUserId ??
|
|
1593
1566
|
(threadId &&
|
|
@@ -1603,45 +1576,47 @@ export class Agent<
|
|
|
1603
1576
|
});
|
|
1604
1577
|
// If it was a promptMessageId, pop it off context messages
|
|
1605
1578
|
// and add to the end of messages.
|
|
1606
|
-
|
|
1579
|
+
const promptMessageIndex = args.promptMessageId
|
|
1580
|
+
? contextMessages.findIndex((m) => m._id === args.promptMessageId)
|
|
1581
|
+
: -1;
|
|
1607
1582
|
const promptMessage =
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
? contextMessages.pop()
|
|
1583
|
+
promptMessageIndex !== -1
|
|
1584
|
+
? contextMessages.splice(promptMessageIndex, 1)[0]
|
|
1611
1585
|
: undefined;
|
|
1612
|
-
|
|
1613
|
-
// If they specify both a promptMessageId and a prompt, we prefer
|
|
1614
|
-
// the prompt to stand in for the promptMessageId message.
|
|
1615
|
-
promptMessage.message = { role: "user", content: args.prompt };
|
|
1616
|
-
}
|
|
1586
|
+
|
|
1617
1587
|
let messageId = promptMessage?._id;
|
|
1618
1588
|
let order = promptMessage?.order;
|
|
1619
1589
|
let stepOrder = promptMessage?.stepOrder;
|
|
1590
|
+
let savedMessages = undefined;
|
|
1620
1591
|
if (
|
|
1621
1592
|
threadId &&
|
|
1622
|
-
messages.length &&
|
|
1593
|
+
messages.length + prompt.length &&
|
|
1623
1594
|
storageOptions?.saveMessages !== "none" &&
|
|
1624
1595
|
// If it was a promptMessageId, we don't want to save it again.
|
|
1625
1596
|
(!args.promptMessageId || storageOptions?.saveMessages === "all")
|
|
1626
1597
|
) {
|
|
1627
1598
|
const saveAll = storageOptions?.saveMessages === "all";
|
|
1628
|
-
const coreMessages =
|
|
1599
|
+
const coreMessages = [...messages, ...prompt];
|
|
1600
|
+
const toSave = saveAll ? coreMessages : coreMessages.slice(-1);
|
|
1601
|
+
const metadata = Array.from({ length: toSave.length }, () => ({}));
|
|
1629
1602
|
const saved = await this.saveMessages(ctx, {
|
|
1630
1603
|
threadId,
|
|
1631
1604
|
userId,
|
|
1632
|
-
messages:
|
|
1633
|
-
metadata
|
|
1634
|
-
i === coreMessages.length - 1 ? { id: args.id } : {},
|
|
1635
|
-
),
|
|
1605
|
+
messages: toSave,
|
|
1606
|
+
metadata,
|
|
1636
1607
|
failPendingSteps: true,
|
|
1637
1608
|
});
|
|
1638
|
-
messageId = saved.
|
|
1639
|
-
order = saved.messages.at(-1)
|
|
1640
|
-
stepOrder = saved.messages.at(-1)
|
|
1609
|
+
messageId = saved.messages.at(-1)!._id;
|
|
1610
|
+
order = saved.messages.at(-1)!.order;
|
|
1611
|
+
stepOrder = saved.messages.at(-1)!.stepOrder;
|
|
1612
|
+
savedMessages = saved.messages;
|
|
1641
1613
|
}
|
|
1614
|
+
|
|
1642
1615
|
if (promptMessage?.message) {
|
|
1643
|
-
|
|
1644
|
-
|
|
1616
|
+
if (!args.prompt) {
|
|
1617
|
+
// If they override the prompt, we skip the existing prompt message.
|
|
1618
|
+
messages.push(deserializeMessage(promptMessage.message));
|
|
1619
|
+
}
|
|
1645
1620
|
// Lazily generate embeddings for the prompt message, if it doesn't have
|
|
1646
1621
|
// embeddings yet. This can happen if the message was saved in a mutation
|
|
1647
1622
|
// where the LLM is not available.
|
|
@@ -1650,10 +1625,28 @@ export class Agent<
|
|
|
1650
1625
|
}
|
|
1651
1626
|
}
|
|
1652
1627
|
|
|
1628
|
+
const prePrompt = contextMessages.map((m) =>
|
|
1629
|
+
deserializeMessage(m.message!),
|
|
1630
|
+
);
|
|
1631
|
+
let existingResponses: ModelMessage[] = [];
|
|
1632
|
+
if (promptMessageIndex !== -1) {
|
|
1633
|
+
// pull any messages that already responded to the prompt off
|
|
1634
|
+
// and add them after the prompt
|
|
1635
|
+
existingResponses = prePrompt.splice(promptMessageIndex);
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1653
1638
|
let processedMessages = [
|
|
1654
|
-
...
|
|
1639
|
+
...prePrompt,
|
|
1655
1640
|
...messages,
|
|
1641
|
+
...prompt,
|
|
1642
|
+
...existingResponses,
|
|
1656
1643
|
];
|
|
1644
|
+
if (promptMessageIndex === -1) {
|
|
1645
|
+
processedMessages.push(...prompt);
|
|
1646
|
+
} else {
|
|
1647
|
+
// We add the prompt where the prompt message was
|
|
1648
|
+
processedMessages.splice(promptMessageIndex, 0, ...prompt);
|
|
1649
|
+
}
|
|
1657
1650
|
|
|
1658
1651
|
// Process messages to inline localhost files (if not, file urls pointing to localhost will be sent to LLM providers)
|
|
1659
1652
|
if (process.env.CONVEX_CLOUD_URL?.startsWith("http://127.0.0.1")) {
|
|
@@ -1663,14 +1656,15 @@ export class Agent<
|
|
|
1663
1656
|
const { prompt: _, model, ...rest } = args;
|
|
1664
1657
|
return {
|
|
1665
1658
|
args: {
|
|
1659
|
+
...this.options.callSettings,
|
|
1666
1660
|
...rest,
|
|
1667
|
-
maxRetries: args.maxRetries ?? this.options.maxRetries,
|
|
1668
1661
|
model: model ?? this.options.chat,
|
|
1669
1662
|
system: args.system ?? this.options.instructions,
|
|
1670
1663
|
messages: processedMessages,
|
|
1671
|
-
} as T & { model:
|
|
1664
|
+
} as T & { model: LanguageModelV2 },
|
|
1672
1665
|
userId,
|
|
1673
1666
|
messageId,
|
|
1667
|
+
savedMessages,
|
|
1674
1668
|
order,
|
|
1675
1669
|
stepOrder,
|
|
1676
1670
|
};
|
|
@@ -1692,23 +1686,23 @@ export class Agent<
|
|
|
1692
1686
|
"a textEmbedding model is required to be set on the Agent that you're doing vector search with",
|
|
1693
1687
|
);
|
|
1694
1688
|
const result = await embedMany({
|
|
1689
|
+
...this.options.callSettings,
|
|
1695
1690
|
model: embeddingModel,
|
|
1696
1691
|
values: options.values,
|
|
1697
1692
|
abortSignal: options.abortSignal,
|
|
1698
1693
|
headers: options.headers,
|
|
1699
|
-
maxRetries: this.options.maxRetries,
|
|
1700
1694
|
});
|
|
1701
1695
|
if (this.options.usageHandler && result.usage) {
|
|
1702
1696
|
await this.options.usageHandler(ctx, {
|
|
1703
1697
|
userId: options.userId,
|
|
1704
1698
|
threadId: options.threadId,
|
|
1705
1699
|
agentName: this.options.name,
|
|
1706
|
-
model: embeddingModel
|
|
1707
|
-
provider: embeddingModel
|
|
1700
|
+
model: getModelName(embeddingModel),
|
|
1701
|
+
provider: getProviderName(embeddingModel),
|
|
1708
1702
|
providerMetadata: undefined,
|
|
1709
1703
|
usage: {
|
|
1710
|
-
|
|
1711
|
-
|
|
1704
|
+
inputTokens: result.usage.tokens,
|
|
1705
|
+
outputTokens: 0,
|
|
1712
1706
|
totalTokens: result.usage.tokens,
|
|
1713
1707
|
},
|
|
1714
1708
|
});
|
|
@@ -1722,11 +1716,11 @@ export class Agent<
|
|
|
1722
1716
|
* able to access localhost URLs.
|
|
1723
1717
|
*/
|
|
1724
1718
|
private async _inlineMessagesFiles(
|
|
1725
|
-
messages:
|
|
1726
|
-
): Promise<
|
|
1719
|
+
messages: (ModelMessage | Message)[],
|
|
1720
|
+
): Promise<(ModelMessage | Message)[]> {
|
|
1727
1721
|
// Process each message to convert localhost URLs to base64
|
|
1728
1722
|
return Promise.all(
|
|
1729
|
-
messages.map(async (message): Promise<
|
|
1723
|
+
messages.map(async (message): Promise<ModelMessage | Message> => {
|
|
1730
1724
|
if (
|
|
1731
1725
|
(message.role !== "user" && message.role !== "assistant") ||
|
|
1732
1726
|
typeof message.content === "string" ||
|
|
@@ -1744,10 +1738,7 @@ export class Agent<
|
|
|
1744
1738
|
);
|
|
1745
1739
|
if (this._isLocalhostUrl(part.image)) {
|
|
1746
1740
|
const imageData = await this._downloadFile(part.image);
|
|
1747
|
-
return {
|
|
1748
|
-
...part,
|
|
1749
|
-
image: imageData,
|
|
1750
|
-
} as ImagePart;
|
|
1741
|
+
return { ...part, image: imageData } as ImagePart;
|
|
1751
1742
|
}
|
|
1752
1743
|
}
|
|
1753
1744
|
|
|
@@ -1755,10 +1746,7 @@ export class Agent<
|
|
|
1755
1746
|
if (part.type === "file" && part.data instanceof URL) {
|
|
1756
1747
|
if (this._isLocalhostUrl(part.data)) {
|
|
1757
1748
|
const fileData = await this._downloadFile(part.data);
|
|
1758
|
-
return {
|
|
1759
|
-
...part,
|
|
1760
|
-
data: fileData,
|
|
1761
|
-
} as FilePart;
|
|
1749
|
+
return { ...part, data: fileData } as FilePart;
|
|
1762
1750
|
}
|
|
1763
1751
|
}
|
|
1764
1752
|
|
|
@@ -1766,15 +1754,9 @@ export class Agent<
|
|
|
1766
1754
|
}),
|
|
1767
1755
|
);
|
|
1768
1756
|
if (message.role === "user") {
|
|
1769
|
-
return {
|
|
1770
|
-
...message,
|
|
1771
|
-
content: processedContent as UserContent,
|
|
1772
|
-
};
|
|
1757
|
+
return { ...message, content: processedContent as UserContent };
|
|
1773
1758
|
} else {
|
|
1774
|
-
return {
|
|
1775
|
-
...message,
|
|
1776
|
-
content: processedContent as AssistantContent,
|
|
1777
|
-
};
|
|
1759
|
+
return { ...message, content: processedContent as AssistantContent };
|
|
1778
1760
|
}
|
|
1779
1761
|
}),
|
|
1780
1762
|
);
|
|
@@ -1845,15 +1827,15 @@ export class Agent<
|
|
|
1845
1827
|
* Create an action out of this agent so you can call it from workflows or other actions
|
|
1846
1828
|
* without a wrapping function.
|
|
1847
1829
|
* @param spec Configuration for the agent acting as an action, including
|
|
1848
|
-
* {@link ContextOptions}, {@link StorageOptions}, and
|
|
1830
|
+
* {@link ContextOptions}, {@link StorageOptions}, and {@link stopWhen}.
|
|
1849
1831
|
*/
|
|
1850
1832
|
asTextAction<DataModel extends GenericDataModel>(
|
|
1851
1833
|
spec?: {
|
|
1852
1834
|
/**
|
|
1853
|
-
*
|
|
1854
|
-
* Defaults to the {@link Agent.
|
|
1835
|
+
* When to stop generating text.
|
|
1836
|
+
* Defaults to the {@link Agent["options"].stopWhen} option.
|
|
1855
1837
|
*/
|
|
1856
|
-
|
|
1838
|
+
stopWhen?: StopCondition<AgentTools> | Array<StopCondition<AgentTools>>;
|
|
1857
1839
|
/**
|
|
1858
1840
|
* The {@link ContextOptions} to use for fetching contextual messages and
|
|
1859
1841
|
* saving input/output messages.
|
|
@@ -1902,17 +1884,25 @@ export class Agent<
|
|
|
1902
1884
|
}
|
|
1903
1885
|
: { customCtx?: never }),
|
|
1904
1886
|
) {
|
|
1905
|
-
const
|
|
1887
|
+
const stopWhen = spec?.stopWhen ?? this.options.stopWhen;
|
|
1906
1888
|
return internalActionGeneric({
|
|
1907
1889
|
args: vTextArgs,
|
|
1908
1890
|
handler: async (ctx_, args) => {
|
|
1909
1891
|
const stream =
|
|
1910
|
-
args.stream === true ? spec?.stream || true : spec?.stream ?? false;
|
|
1892
|
+
args.stream === true ? spec?.stream || true : (spec?.stream ?? false);
|
|
1911
1893
|
const targetArgs = { userId: args.userId, threadId: args.threadId };
|
|
1912
1894
|
const llmArgs = {
|
|
1913
|
-
|
|
1895
|
+
stopWhen,
|
|
1914
1896
|
...omit(args, ["storageOptions", "contextOptions"]),
|
|
1915
|
-
|
|
1897
|
+
messages: args.messages?.map(deserializeMessage),
|
|
1898
|
+
prompt: Array.isArray(args.prompt)
|
|
1899
|
+
? args.prompt.map(deserializeMessage)
|
|
1900
|
+
: args.prompt,
|
|
1901
|
+
toolChoice: args.toolChoice as ToolChoice<AgentTools>,
|
|
1902
|
+
} satisfies StreamingTextArgs<AgentTools>;
|
|
1903
|
+
if (args.maxSteps) {
|
|
1904
|
+
llmArgs.stopWhen = stepCountIs(args.maxSteps);
|
|
1905
|
+
}
|
|
1916
1906
|
const opts = {
|
|
1917
1907
|
...this.options,
|
|
1918
1908
|
...(spec && pick(spec, ["contextOptions", "storageOptions"])),
|
|
@@ -1925,7 +1915,13 @@ export class Agent<
|
|
|
1925
1915
|
: ctx_
|
|
1926
1916
|
) as UserActionCtx & CustomCtx;
|
|
1927
1917
|
if (stream) {
|
|
1928
|
-
|
|
1918
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1919
|
+
const result = await this.streamText<any>(
|
|
1920
|
+
ctx,
|
|
1921
|
+
targetArgs,
|
|
1922
|
+
llmArgs,
|
|
1923
|
+
opts,
|
|
1924
|
+
);
|
|
1929
1925
|
await result.consumeStream();
|
|
1930
1926
|
return {
|
|
1931
1927
|
text: await result.text,
|
|
@@ -1935,7 +1931,13 @@ export class Agent<
|
|
|
1935
1931
|
warnings: result.warnings,
|
|
1936
1932
|
};
|
|
1937
1933
|
} else {
|
|
1938
|
-
|
|
1934
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1935
|
+
const res = await this.generateText<any>(
|
|
1936
|
+
ctx,
|
|
1937
|
+
targetArgs,
|
|
1938
|
+
llmArgs,
|
|
1939
|
+
opts,
|
|
1940
|
+
);
|
|
1939
1941
|
return {
|
|
1940
1942
|
text: res.text,
|
|
1941
1943
|
messageId: res.messageId,
|
|
@@ -1952,28 +1954,27 @@ export class Agent<
|
|
|
1952
1954
|
* it from workflows or other actions without a wrapping function.
|
|
1953
1955
|
* @param spec Configuration for the agent acting as an action, including
|
|
1954
1956
|
* the normal parameters to {@link generateObject}, plus {@link ContextOptions}
|
|
1955
|
-
* and
|
|
1957
|
+
* and stopWhen.
|
|
1956
1958
|
*/
|
|
1957
1959
|
asObjectAction<T>(
|
|
1958
|
-
spec: OurObjectArgs<T
|
|
1960
|
+
spec: OurObjectArgs<T>,
|
|
1959
1961
|
options?: {
|
|
1960
1962
|
contextOptions?: ContextOptions;
|
|
1961
1963
|
storageOptions?: StorageOptions;
|
|
1962
1964
|
},
|
|
1963
1965
|
) {
|
|
1964
|
-
const maxSteps = spec?.maxSteps ?? this.options.maxSteps;
|
|
1965
1966
|
return internalActionGeneric({
|
|
1966
1967
|
args: vSafeObjectArgs,
|
|
1967
1968
|
handler: async (ctx, args) => {
|
|
1968
|
-
const
|
|
1969
|
+
const { userId, threadId, ...rest } = args;
|
|
1970
|
+
const overrides = pick(rest, ["contextOptions", "storageOptions"]);
|
|
1969
1971
|
const value = await this.generateObject(
|
|
1970
1972
|
ctx,
|
|
1971
|
-
{ userId
|
|
1973
|
+
{ userId, threadId },
|
|
1972
1974
|
{
|
|
1973
1975
|
...spec,
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
} as unknown as OurObjectArgs<unknown>,
|
|
1976
|
+
...omit(rest, ["contextOptions", "storageOptions"]),
|
|
1977
|
+
} as OurObjectArgs<unknown>,
|
|
1977
1978
|
{ ...this.options, ...options, ...overrides },
|
|
1978
1979
|
);
|
|
1979
1980
|
return {
|
|
@@ -2014,228 +2015,21 @@ export class Agent<
|
|
|
2014
2015
|
userId: v.optional(v.string()),
|
|
2015
2016
|
promptMessageId: v.optional(v.string()),
|
|
2016
2017
|
messages: v.array(vMessageWithMetadata),
|
|
2017
|
-
pending: v.optional(v.boolean()),
|
|
2018
2018
|
failPendingSteps: v.optional(v.boolean()),
|
|
2019
|
+
embeddings: v.optional(vMessageEmbeddings),
|
|
2019
2020
|
},
|
|
2020
2021
|
handler: async (ctx, args) => {
|
|
2021
|
-
const {
|
|
2022
|
+
const { messages } = await this.saveMessages(ctx, {
|
|
2022
2023
|
...args,
|
|
2023
|
-
messages: args.messages.map((m) => m.message),
|
|
2024
|
+
messages: args.messages.map((m) => deserializeMessage(m.message)),
|
|
2024
2025
|
metadata: args.messages.map(({ message: _, ...m }) => m),
|
|
2026
|
+
skipEmbeddings: true,
|
|
2025
2027
|
});
|
|
2026
2028
|
return {
|
|
2027
|
-
lastMessageId,
|
|
2028
|
-
|
|
2029
|
+
lastMessageId: messages.at(-1)!._id,
|
|
2030
|
+
messages: messages.map((m) => pick(m, ["_id", "order", "stepOrder"])),
|
|
2029
2031
|
};
|
|
2030
2032
|
},
|
|
2031
2033
|
});
|
|
2032
2034
|
}
|
|
2033
2035
|
}
|
|
2034
|
-
|
|
2035
|
-
type CoreMessageMaybeWithId = CoreMessage & { id?: string | undefined };
|
|
2036
|
-
|
|
2037
|
-
/**
|
|
2038
|
-
* Create a thread to store messages with an Agent.
|
|
2039
|
-
* @param ctx The context from a mutation or action.
|
|
2040
|
-
* @param component The Agent component, usually `components.agent`.
|
|
2041
|
-
* @param args The associated thread metadata.
|
|
2042
|
-
* @returns The id of the created thread.
|
|
2043
|
-
*/
|
|
2044
|
-
export async function createThread(
|
|
2045
|
-
ctx: RunMutationCtx,
|
|
2046
|
-
component: AgentComponent,
|
|
2047
|
-
args?: {
|
|
2048
|
-
userId?: string | null;
|
|
2049
|
-
title?: string;
|
|
2050
|
-
summary?: string;
|
|
2051
|
-
},
|
|
2052
|
-
) {
|
|
2053
|
-
const { _id: threadId } = await ctx.runMutation(
|
|
2054
|
-
component.threads.createThread,
|
|
2055
|
-
{
|
|
2056
|
-
userId: args?.userId ?? undefined,
|
|
2057
|
-
title: args?.title,
|
|
2058
|
-
summary: args?.summary,
|
|
2059
|
-
},
|
|
2060
|
-
);
|
|
2061
|
-
return threadId;
|
|
2062
|
-
}
|
|
2063
|
-
|
|
2064
|
-
/**
|
|
2065
|
-
* Get the metadata for a thread.
|
|
2066
|
-
* @param ctx A ctx object from a query, mutation, or action.
|
|
2067
|
-
* @param args.threadId The thread to get the metadata for.
|
|
2068
|
-
* @returns The metadata for the thread.
|
|
2069
|
-
*/
|
|
2070
|
-
export async function getThreadMetadata(
|
|
2071
|
-
ctx: RunQueryCtx,
|
|
2072
|
-
component: AgentComponent,
|
|
2073
|
-
args: { threadId: string },
|
|
2074
|
-
): Promise<ThreadDoc> {
|
|
2075
|
-
const thread = await ctx.runQuery(component.threads.getThread, {
|
|
2076
|
-
threadId: args.threadId,
|
|
2077
|
-
});
|
|
2078
|
-
if (!thread) {
|
|
2079
|
-
throw new Error("Thread not found");
|
|
2080
|
-
}
|
|
2081
|
-
return thread;
|
|
2082
|
-
}
|
|
2083
|
-
|
|
2084
|
-
type SaveMessagesArgs = {
|
|
2085
|
-
threadId: string;
|
|
2086
|
-
userId?: string | null;
|
|
2087
|
-
/**
|
|
2088
|
-
* The message that these messages are in response to. They will be
|
|
2089
|
-
* the same "order" as this message, at increasing stepOrder(s).
|
|
2090
|
-
*/
|
|
2091
|
-
promptMessageId?: string;
|
|
2092
|
-
/**
|
|
2093
|
-
* The messages to save.
|
|
2094
|
-
*/
|
|
2095
|
-
messages: CoreMessageMaybeWithId[];
|
|
2096
|
-
/**
|
|
2097
|
-
* Metadata to save with the messages. Each element corresponds to the
|
|
2098
|
-
* message at the same index.
|
|
2099
|
-
*/
|
|
2100
|
-
metadata?: Omit<MessageWithMetadata, "message">[];
|
|
2101
|
-
/**
|
|
2102
|
-
* If false, it will "commit" the messages immediately.
|
|
2103
|
-
* If true, it will mark them as pending until the final step has finished.
|
|
2104
|
-
* Defaults to false.
|
|
2105
|
-
*/
|
|
2106
|
-
pending?: boolean;
|
|
2107
|
-
/**
|
|
2108
|
-
* If true, it will fail any pending steps.
|
|
2109
|
-
* Defaults to false.
|
|
2110
|
-
*/
|
|
2111
|
-
failPendingSteps?: boolean;
|
|
2112
|
-
/**
|
|
2113
|
-
* The embeddings to save with the messages.
|
|
2114
|
-
*/
|
|
2115
|
-
embeddings?: Omit<MessageEmbeddings, "dimension">;
|
|
2116
|
-
};
|
|
2117
|
-
|
|
2118
|
-
/**
|
|
2119
|
-
* Explicitly save messages associated with the thread (& user if provided)
|
|
2120
|
-
*/
|
|
2121
|
-
export async function saveMessages(
|
|
2122
|
-
ctx: RunMutationCtx,
|
|
2123
|
-
component: AgentComponent,
|
|
2124
|
-
args: SaveMessagesArgs & {
|
|
2125
|
-
/**
|
|
2126
|
-
* The agent name to associate with the messages.
|
|
2127
|
-
*/
|
|
2128
|
-
agentName?: string;
|
|
2129
|
-
},
|
|
2130
|
-
) {
|
|
2131
|
-
let embeddings: MessageEmbeddings | undefined;
|
|
2132
|
-
if (args.embeddings) {
|
|
2133
|
-
const dimension = args.embeddings.vectors.find((v) => v !== null)?.length;
|
|
2134
|
-
if (dimension) {
|
|
2135
|
-
validateVectorDimension(dimension);
|
|
2136
|
-
embeddings = {
|
|
2137
|
-
model: args.embeddings.model,
|
|
2138
|
-
dimension,
|
|
2139
|
-
vectors: args.embeddings.vectors,
|
|
2140
|
-
};
|
|
2141
|
-
}
|
|
2142
|
-
}
|
|
2143
|
-
const result = await ctx.runMutation(component.messages.addMessages, {
|
|
2144
|
-
threadId: args.threadId,
|
|
2145
|
-
userId: args.userId ?? undefined,
|
|
2146
|
-
agentName: args.agentName,
|
|
2147
|
-
promptMessageId: args.promptMessageId,
|
|
2148
|
-
embeddings,
|
|
2149
|
-
messages: await Promise.all(
|
|
2150
|
-
args.messages.map(async (m, i) => {
|
|
2151
|
-
const { message, fileIds } = await serializeMessage(ctx, component, m);
|
|
2152
|
-
return {
|
|
2153
|
-
...args.metadata?.[i],
|
|
2154
|
-
message,
|
|
2155
|
-
fileIds,
|
|
2156
|
-
} as MessageWithMetadata;
|
|
2157
|
-
}),
|
|
2158
|
-
),
|
|
2159
|
-
failPendingSteps: args.failPendingSteps ?? false,
|
|
2160
|
-
pending: args.pending ?? false,
|
|
2161
|
-
});
|
|
2162
|
-
return {
|
|
2163
|
-
lastMessageId: result.messages.at(-1)!._id,
|
|
2164
|
-
messages: result.messages,
|
|
2165
|
-
};
|
|
2166
|
-
}
|
|
2167
|
-
|
|
2168
|
-
type SaveMessageArgs = {
|
|
2169
|
-
threadId: string;
|
|
2170
|
-
userId?: string | null;
|
|
2171
|
-
/**
|
|
2172
|
-
* Metadata to save with the messages. Each element corresponds to the
|
|
2173
|
-
* message at the same index.
|
|
2174
|
-
*/
|
|
2175
|
-
metadata?: Omit<MessageWithMetadata, "message">;
|
|
2176
|
-
/**
|
|
2177
|
-
* The embedding to save with the message.
|
|
2178
|
-
*/
|
|
2179
|
-
embedding?: {
|
|
2180
|
-
vector: number[];
|
|
2181
|
-
model: string;
|
|
2182
|
-
};
|
|
2183
|
-
} & (
|
|
2184
|
-
| {
|
|
2185
|
-
prompt?: undefined;
|
|
2186
|
-
/**
|
|
2187
|
-
* The message to save.
|
|
2188
|
-
*/
|
|
2189
|
-
message: CoreMessage;
|
|
2190
|
-
}
|
|
2191
|
-
| {
|
|
2192
|
-
/*
|
|
2193
|
-
* The prompt to save with the message.
|
|
2194
|
-
*/
|
|
2195
|
-
prompt: string;
|
|
2196
|
-
message?: undefined;
|
|
2197
|
-
}
|
|
2198
|
-
);
|
|
2199
|
-
|
|
2200
|
-
/**
|
|
2201
|
-
* Save a message to the thread.
|
|
2202
|
-
* @param ctx A ctx object from a mutation or action.
|
|
2203
|
-
* @param args The message and what to associate it with (user / thread)
|
|
2204
|
-
* You can pass extra metadata alongside the message, e.g. associated fileIds.
|
|
2205
|
-
* @returns The messageId of the saved message.
|
|
2206
|
-
*/
|
|
2207
|
-
export async function saveMessage(
|
|
2208
|
-
ctx: RunMutationCtx,
|
|
2209
|
-
component: AgentComponent,
|
|
2210
|
-
args: SaveMessageArgs & {
|
|
2211
|
-
/**
|
|
2212
|
-
* The agent name to associate with the message.
|
|
2213
|
-
*/
|
|
2214
|
-
agentName?: string;
|
|
2215
|
-
},
|
|
2216
|
-
) {
|
|
2217
|
-
let embeddings:
|
|
2218
|
-
| {
|
|
2219
|
-
vectors: number[][];
|
|
2220
|
-
model: string;
|
|
2221
|
-
}
|
|
2222
|
-
| undefined;
|
|
2223
|
-
if (args.embedding && args.embedding.vector) {
|
|
2224
|
-
embeddings = {
|
|
2225
|
-
model: args.embedding.model,
|
|
2226
|
-
vectors: [args.embedding.vector],
|
|
2227
|
-
};
|
|
2228
|
-
}
|
|
2229
|
-
const { lastMessageId, messages } = await saveMessages(ctx, component, {
|
|
2230
|
-
threadId: args.threadId,
|
|
2231
|
-
userId: args.userId ?? undefined,
|
|
2232
|
-
agentName: args.agentName,
|
|
2233
|
-
messages:
|
|
2234
|
-
args.prompt !== undefined
|
|
2235
|
-
? [{ role: "user", content: args.prompt }]
|
|
2236
|
-
: [args.message],
|
|
2237
|
-
metadata: args.metadata ? [args.metadata] : undefined,
|
|
2238
|
-
embeddings,
|
|
2239
|
-
});
|
|
2240
|
-
return { messageId: lastMessageId, message: messages.at(-1)! };
|
|
2241
|
-
}
|