@convex-dev/agent 0.1.1 → 0.1.2-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/dist/commonjs/client/createTool.d.ts +49 -0
- package/dist/commonjs/client/createTool.d.ts.map +1 -0
- package/dist/commonjs/client/createTool.js +45 -0
- package/dist/commonjs/client/createTool.js.map +1 -0
- package/dist/commonjs/client/index.d.ts +101 -322
- package/dist/commonjs/client/index.d.ts.map +1 -1
- package/dist/commonjs/client/index.js +142 -194
- package/dist/commonjs/client/index.js.map +1 -1
- package/dist/commonjs/client/streaming.d.ts +54 -0
- package/dist/commonjs/client/streaming.d.ts.map +1 -0
- package/dist/commonjs/client/streaming.js +121 -0
- package/dist/commonjs/client/streaming.js.map +1 -0
- package/dist/commonjs/client/types.d.ts +290 -2
- package/dist/commonjs/client/types.d.ts.map +1 -1
- package/dist/commonjs/component/messages.d.ts +104 -138
- package/dist/commonjs/component/messages.d.ts.map +1 -1
- package/dist/commonjs/component/messages.js +15 -14
- package/dist/commonjs/component/messages.js.map +1 -1
- package/dist/commonjs/component/schema.d.ts +873 -3
- package/dist/commonjs/component/schema.d.ts.map +1 -1
- package/dist/commonjs/component/schema.js +39 -1
- package/dist/commonjs/component/schema.js.map +1 -1
- package/dist/commonjs/component/streams.d.ts +191 -0
- package/dist/commonjs/component/streams.d.ts.map +1 -0
- package/dist/commonjs/component/streams.js +169 -0
- package/dist/commonjs/component/streams.js.map +1 -0
- package/dist/commonjs/component/threads.d.ts +1 -1
- package/dist/commonjs/component/threads.js +3 -3
- package/dist/commonjs/component/threads.js.map +1 -1
- package/dist/commonjs/component/users.js +2 -2
- package/dist/commonjs/component/users.js.map +1 -1
- package/dist/commonjs/mapping.d.ts.map +1 -1
- package/dist/commonjs/mapping.js +3 -1
- package/dist/commonjs/mapping.js.map +1 -1
- package/dist/commonjs/react/index.d.ts +99 -0
- package/dist/commonjs/react/index.d.ts.map +1 -1
- package/dist/commonjs/react/index.js +505 -1
- package/dist/commonjs/react/index.js.map +1 -1
- package/dist/commonjs/react/toUIMessages.d.ts +8 -0
- package/dist/commonjs/react/toUIMessages.d.ts.map +1 -0
- package/dist/commonjs/react/toUIMessages.js +134 -0
- package/dist/commonjs/react/toUIMessages.js.map +1 -0
- package/dist/commonjs/validators.d.ts +506 -4
- package/dist/commonjs/validators.d.ts.map +1 -1
- package/dist/commonjs/validators.js +49 -2
- package/dist/commonjs/validators.js.map +1 -1
- package/dist/esm/client/createTool.d.ts +49 -0
- package/dist/esm/client/createTool.d.ts.map +1 -0
- package/dist/esm/client/createTool.js +45 -0
- package/dist/esm/client/createTool.js.map +1 -0
- package/dist/esm/client/index.d.ts +101 -322
- package/dist/esm/client/index.d.ts.map +1 -1
- package/dist/esm/client/index.js +142 -194
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/client/streaming.d.ts +54 -0
- package/dist/esm/client/streaming.d.ts.map +1 -0
- package/dist/esm/client/streaming.js +121 -0
- package/dist/esm/client/streaming.js.map +1 -0
- package/dist/esm/client/types.d.ts +290 -2
- package/dist/esm/client/types.d.ts.map +1 -1
- package/dist/esm/component/messages.d.ts +104 -138
- package/dist/esm/component/messages.d.ts.map +1 -1
- package/dist/esm/component/messages.js +15 -14
- package/dist/esm/component/messages.js.map +1 -1
- package/dist/esm/component/schema.d.ts +873 -3
- package/dist/esm/component/schema.d.ts.map +1 -1
- package/dist/esm/component/schema.js +39 -1
- package/dist/esm/component/schema.js.map +1 -1
- package/dist/esm/component/streams.d.ts +191 -0
- package/dist/esm/component/streams.d.ts.map +1 -0
- package/dist/esm/component/streams.js +169 -0
- package/dist/esm/component/streams.js.map +1 -0
- package/dist/esm/component/threads.d.ts +1 -1
- package/dist/esm/component/threads.js +3 -3
- package/dist/esm/component/threads.js.map +1 -1
- package/dist/esm/component/users.js +2 -2
- package/dist/esm/component/users.js.map +1 -1
- package/dist/esm/mapping.d.ts.map +1 -1
- package/dist/esm/mapping.js +3 -1
- package/dist/esm/mapping.js.map +1 -1
- package/dist/esm/react/index.d.ts +99 -0
- package/dist/esm/react/index.d.ts.map +1 -1
- package/dist/esm/react/index.js +505 -1
- package/dist/esm/react/index.js.map +1 -1
- package/dist/esm/react/toUIMessages.d.ts +8 -0
- package/dist/esm/react/toUIMessages.d.ts.map +1 -0
- package/dist/esm/react/toUIMessages.js +134 -0
- package/dist/esm/react/toUIMessages.js.map +1 -0
- package/dist/esm/validators.d.ts +506 -4
- package/dist/esm/validators.d.ts.map +1 -1
- package/dist/esm/validators.js +49 -2
- package/dist/esm/validators.js.map +1 -1
- package/package.json +5 -1
- package/src/client/createTool.ts +108 -0
- package/src/client/index.ts +270 -689
- package/src/client/streaming.ts +166 -0
- package/src/client/types.ts +430 -5
- package/src/component/_generated/api.d.ts +339 -188
- package/src/component/messages.ts +15 -14
- package/src/component/schema.ts +46 -0
- package/src/component/streams.ts +206 -0
- package/src/component/threads.ts +3 -3
- package/src/component/users.ts +2 -2
- package/src/mapping.ts +3 -1
- package/src/react/index.ts +687 -1
- package/src/react/toUIMessages.ts +153 -0
- package/src/validators.test.ts +18 -0
- package/src/validators.ts +72 -2
package/src/client/index.ts
CHANGED
|
@@ -4,32 +4,20 @@ import type {
|
|
|
4
4
|
DeepPartial,
|
|
5
5
|
GenerateObjectResult,
|
|
6
6
|
GenerateTextResult,
|
|
7
|
-
JSONValue,
|
|
8
|
-
RepairTextFunction,
|
|
9
|
-
Schema,
|
|
10
7
|
StepResult,
|
|
11
8
|
StreamObjectResult,
|
|
12
9
|
StreamTextResult,
|
|
13
|
-
TelemetrySettings,
|
|
14
|
-
Tool,
|
|
15
|
-
ToolChoice,
|
|
16
|
-
ToolExecutionOptions,
|
|
17
10
|
ToolSet,
|
|
18
|
-
UIMessage,
|
|
19
|
-
} from "ai";
|
|
20
|
-
import type { ToolInvocationUIPart } from "@ai-sdk/ui-utils";
|
|
21
|
-
import {
|
|
22
|
-
generateObject,
|
|
23
|
-
generateText,
|
|
24
|
-
streamObject,
|
|
25
|
-
streamText,
|
|
26
|
-
tool,
|
|
27
11
|
} from "ai";
|
|
12
|
+
import { generateObject, generateText, streamObject, streamText } from "ai";
|
|
28
13
|
import { assert } from "convex-helpers";
|
|
29
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
internalActionGeneric,
|
|
16
|
+
internalMutationGeneric,
|
|
17
|
+
PaginationOptions,
|
|
18
|
+
PaginationResult,
|
|
19
|
+
} from "convex/server";
|
|
30
20
|
import { v } from "convex/values";
|
|
31
|
-
import { z } from "zod";
|
|
32
|
-
import { Mounts } from "../component/_generated/api.js";
|
|
33
21
|
import {
|
|
34
22
|
validateVectorDimension,
|
|
35
23
|
type VectorDimension,
|
|
@@ -42,7 +30,6 @@ import {
|
|
|
42
30
|
serializeNewMessagesInStep,
|
|
43
31
|
serializeObjectResult,
|
|
44
32
|
serializeStep,
|
|
45
|
-
toUIFilePart,
|
|
46
33
|
} from "../mapping.js";
|
|
47
34
|
import {
|
|
48
35
|
DEFAULT_MESSAGE_RANGE,
|
|
@@ -51,132 +38,71 @@ import {
|
|
|
51
38
|
isTool,
|
|
52
39
|
} from "../shared.js";
|
|
53
40
|
import {
|
|
54
|
-
type CallSettings,
|
|
55
41
|
type MessageWithMetadata as InnerMessageWithMetadata,
|
|
42
|
+
type MessageStatus,
|
|
56
43
|
type ProviderMetadata,
|
|
57
|
-
type ProviderOptions,
|
|
58
44
|
type SearchOptions,
|
|
45
|
+
type StreamArgs,
|
|
59
46
|
type Usage,
|
|
60
47
|
vMessageWithMetadata,
|
|
61
48
|
vSafeObjectArgs,
|
|
62
49
|
vTextArgs,
|
|
63
50
|
} from "../validators.js";
|
|
64
51
|
import type {
|
|
52
|
+
AgentComponent,
|
|
53
|
+
ContextOptions,
|
|
54
|
+
GenerationOutputMetadata,
|
|
65
55
|
OpaqueIds,
|
|
56
|
+
Options,
|
|
57
|
+
OurObjectArgs,
|
|
58
|
+
OurStreamObjectArgs,
|
|
66
59
|
RunActionCtx,
|
|
67
60
|
RunMutationCtx,
|
|
68
61
|
RunQueryCtx,
|
|
69
|
-
|
|
62
|
+
StorageOptions,
|
|
63
|
+
StreamingTextArgs,
|
|
64
|
+
SyncStreamsReturnValue,
|
|
65
|
+
TextArgs,
|
|
66
|
+
Thread,
|
|
67
|
+
UsageHandler,
|
|
70
68
|
} from "./types.js";
|
|
71
69
|
|
|
72
70
|
import type { MessageDoc, ThreadDoc } from "../component/schema.js";
|
|
71
|
+
import { createTool, wrapTools } from "./createTool.js";
|
|
72
|
+
import {
|
|
73
|
+
DeltaStreamer,
|
|
74
|
+
mergeTransforms,
|
|
75
|
+
StreamingOptions,
|
|
76
|
+
} from "./streaming.js";
|
|
73
77
|
|
|
74
78
|
export { vMessageDoc, vThreadDoc } from "../component/schema.js";
|
|
75
|
-
export { extractText, isTool };
|
|
76
|
-
export type { Usage, ProviderMetadata, MessageDoc, ThreadDoc };
|
|
77
79
|
export {
|
|
78
|
-
|
|
79
|
-
paginationResultValidator,
|
|
80
|
-
paginationResultValidator as vPaginationResult,
|
|
80
|
+
vAssistantMessage,
|
|
81
81
|
vContextOptions,
|
|
82
|
-
|
|
82
|
+
vMessage,
|
|
83
|
+
vPaginationResult,
|
|
83
84
|
vProviderMetadata,
|
|
84
|
-
vUserMessage,
|
|
85
|
-
vAssistantMessage,
|
|
86
|
-
vToolMessage,
|
|
87
85
|
vStorageOptions,
|
|
86
|
+
vStreamArgs,
|
|
88
87
|
vSystemMessage,
|
|
89
|
-
|
|
88
|
+
vToolMessage,
|
|
89
|
+
vUsage,
|
|
90
|
+
vUserMessage,
|
|
90
91
|
} from "../validators.js";
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
excludeToolMessages?: boolean;
|
|
104
|
-
/**
|
|
105
|
-
* How many recent messages to include. These are added after the search
|
|
106
|
-
* messages, and do not count against the search limit.
|
|
107
|
-
* Default: 100
|
|
108
|
-
*/
|
|
109
|
-
recentMessages?: number;
|
|
110
|
-
/**
|
|
111
|
-
* Options for searching messages.
|
|
112
|
-
*/
|
|
113
|
-
searchOptions?: {
|
|
114
|
-
/**
|
|
115
|
-
* The maximum number of messages to fetch. Default is 10.
|
|
116
|
-
*/
|
|
117
|
-
limit: number;
|
|
118
|
-
/**
|
|
119
|
-
* Whether to use text search to find messages. Default is false.
|
|
120
|
-
*/
|
|
121
|
-
textSearch?: boolean;
|
|
122
|
-
/**
|
|
123
|
-
* Whether to use vector search to find messages. Default is false.
|
|
124
|
-
* At least one of textSearch or vectorSearch must be true.
|
|
125
|
-
*/
|
|
126
|
-
vectorSearch?: boolean;
|
|
127
|
-
/**
|
|
128
|
-
* What messages around the search results to include.
|
|
129
|
-
* Default: { before: 2, after: 1 }
|
|
130
|
-
* (two before, and one after each message found in the search)
|
|
131
|
-
* Note, this is after the limit is applied.
|
|
132
|
-
* By default this will quadruple the number of messages fetched.
|
|
133
|
-
*/
|
|
134
|
-
messageRange?: { before: number; after: number };
|
|
135
|
-
};
|
|
136
|
-
/**
|
|
137
|
-
* Whether to search across other threads for relevant messages.
|
|
138
|
-
* By default, only the current thread is searched.
|
|
139
|
-
*/
|
|
140
|
-
searchOtherThreads?: boolean;
|
|
92
|
+
export { createTool, extractText, isTool };
|
|
93
|
+
export type {
|
|
94
|
+
AgentComponent,
|
|
95
|
+
ContextOptions,
|
|
96
|
+
MessageDoc,
|
|
97
|
+
ProviderMetadata,
|
|
98
|
+
StorageOptions,
|
|
99
|
+
SyncStreamsReturnValue,
|
|
100
|
+
Thread,
|
|
101
|
+
ThreadDoc,
|
|
102
|
+
Usage,
|
|
103
|
+
UsageHandler,
|
|
141
104
|
};
|
|
142
105
|
|
|
143
|
-
/**
|
|
144
|
-
* Options to configure the automatic saving of messages
|
|
145
|
-
* when generating text / objects in a thread.
|
|
146
|
-
*/
|
|
147
|
-
export type StorageOptions = {
|
|
148
|
-
/**
|
|
149
|
-
* Defaults to false, allowing you to pass in arbitrary context that will
|
|
150
|
-
* be in addition to automatically fetched content.
|
|
151
|
-
* Pass true to have all input messages saved to the thread history.
|
|
152
|
-
*/
|
|
153
|
-
saveAllInputMessages?: boolean;
|
|
154
|
-
/** Defaults to true, saving the prompt, or last message passed to generateText. */
|
|
155
|
-
saveAnyInputMessages?: boolean;
|
|
156
|
-
/** Defaults to true. Whether to save messages generated while chatting. */
|
|
157
|
-
saveOutputMessages?: boolean;
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
export type GenerationOutputMetadata = { messageId?: string };
|
|
161
|
-
|
|
162
|
-
type CoreMessageMaybeWithId = CoreMessage & { id?: string | undefined };
|
|
163
|
-
|
|
164
|
-
export type UsageHandler = (
|
|
165
|
-
ctx: RunActionCtx,
|
|
166
|
-
args: {
|
|
167
|
-
userId: string | undefined;
|
|
168
|
-
threadId: string | undefined;
|
|
169
|
-
agentName: string | undefined;
|
|
170
|
-
usage: Usage;
|
|
171
|
-
// Often has more information, like cached token usage in the case of openai.
|
|
172
|
-
providerMetadata: ProviderMetadata | undefined;
|
|
173
|
-
model: string;
|
|
174
|
-
provider: string;
|
|
175
|
-
}
|
|
176
|
-
) => void | Promise<void>;
|
|
177
|
-
|
|
178
|
-
export type AgentComponent = UseApi<Mounts>;
|
|
179
|
-
|
|
180
106
|
export class Agent<AgentTools extends ToolSet> {
|
|
181
107
|
constructor(
|
|
182
108
|
public component: AgentComponent,
|
|
@@ -406,6 +332,72 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
406
332
|
};
|
|
407
333
|
}
|
|
408
334
|
|
|
335
|
+
/**
|
|
336
|
+
* List messages from a thread.
|
|
337
|
+
* @param ctx A ctx object from a query, mutation, or action.
|
|
338
|
+
* @param args.threadId The thread to list messages from.
|
|
339
|
+
* @param args.paginationOpts Pagination options (e.g. via usePaginatedQuery).
|
|
340
|
+
* @param args.excludeToolMessages Whether to exclude tool messages.
|
|
341
|
+
* False by default.
|
|
342
|
+
* @param args.statuses What statuses to include. All by default.
|
|
343
|
+
* @returns The MessageDoc's in a format compatible with usePaginatedQuery.
|
|
344
|
+
*/
|
|
345
|
+
async listMessages(
|
|
346
|
+
ctx: RunQueryCtx,
|
|
347
|
+
args: {
|
|
348
|
+
threadId: string;
|
|
349
|
+
paginationOpts: PaginationOptions;
|
|
350
|
+
excludeToolMessages?: boolean;
|
|
351
|
+
statuses?: MessageStatus[];
|
|
352
|
+
}
|
|
353
|
+
): Promise<PaginationResult<MessageDoc>> {
|
|
354
|
+
if (args.paginationOpts.numItems === 0) {
|
|
355
|
+
return {
|
|
356
|
+
page: [],
|
|
357
|
+
isDone: true,
|
|
358
|
+
continueCursor: args.paginationOpts.cursor ?? "",
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
return ctx.runQuery(this.component.messages.listMessagesByThreadId, {
|
|
362
|
+
order: "desc",
|
|
363
|
+
...args,
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* A function that handles fetching stream deltas, used with the React hooks
|
|
369
|
+
* `useThreadMessages` or `useStreamingThreadMessages`.
|
|
370
|
+
* @param ctx A ctx object from a query, mutation, or action.
|
|
371
|
+
* @param args.threadId The thread to sync streams for.
|
|
372
|
+
* @param args.streamArgs The stream arguments with per-stream cursors.
|
|
373
|
+
* @returns The deltas for each stream from their existing cursor.
|
|
374
|
+
*/
|
|
375
|
+
async syncStreams(
|
|
376
|
+
ctx: RunQueryCtx,
|
|
377
|
+
args: {
|
|
378
|
+
threadId: string;
|
|
379
|
+
streamArgs: StreamArgs | undefined;
|
|
380
|
+
}
|
|
381
|
+
): Promise<SyncStreamsReturnValue | undefined> {
|
|
382
|
+
if (!args.streamArgs) return undefined;
|
|
383
|
+
if (args.streamArgs.kind === "list") {
|
|
384
|
+
return {
|
|
385
|
+
kind: "list",
|
|
386
|
+
messages: await ctx.runQuery(this.component.streams.list, {
|
|
387
|
+
threadId: args.threadId,
|
|
388
|
+
}),
|
|
389
|
+
};
|
|
390
|
+
} else {
|
|
391
|
+
return {
|
|
392
|
+
kind: "deltas",
|
|
393
|
+
deltas: await ctx.runQuery(this.component.streams.listDeltas, {
|
|
394
|
+
threadId: args.threadId,
|
|
395
|
+
cursors: args.streamArgs.cursors,
|
|
396
|
+
}),
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
409
401
|
/**
|
|
410
402
|
* Fetch the context messages for a thread.
|
|
411
403
|
* @param ctx Either a query, mutation, or action ctx.
|
|
@@ -432,7 +424,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
432
424
|
assert(args.userId || args.threadId, "Specify userId or threadId");
|
|
433
425
|
// Fetch the latest messages from the thread
|
|
434
426
|
let included: Set<string> | undefined;
|
|
435
|
-
const opts = this.
|
|
427
|
+
const opts = this._mergedContextOptions(args.contextOptions);
|
|
436
428
|
const contextMessages: MessageDoc[] = [];
|
|
437
429
|
if (
|
|
438
430
|
args.threadId &&
|
|
@@ -475,7 +467,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
475
467
|
userId: opts?.searchOtherThreads ? args.userId : undefined,
|
|
476
468
|
threadId: args.threadId,
|
|
477
469
|
beforeMessageId: args.upToAndIncludingMessageId,
|
|
478
|
-
...(await this.
|
|
470
|
+
...(await this._searchOptionsWithDefaults(opts, messagesToSearch)),
|
|
479
471
|
}
|
|
480
472
|
);
|
|
481
473
|
// TODO: track what messages we used for context
|
|
@@ -537,6 +529,35 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
537
529
|
return embeddings;
|
|
538
530
|
}
|
|
539
531
|
|
|
532
|
+
async saveMessage(
|
|
533
|
+
ctx: RunMutationCtx,
|
|
534
|
+
args: {
|
|
535
|
+
threadId: string;
|
|
536
|
+
userId?: string;
|
|
537
|
+
metadata?: Omit<MessageWithMetadata, "message">;
|
|
538
|
+
} & (
|
|
539
|
+
| {
|
|
540
|
+
prompt?: undefined;
|
|
541
|
+
message: CoreMessage;
|
|
542
|
+
}
|
|
543
|
+
| {
|
|
544
|
+
prompt: string;
|
|
545
|
+
message?: undefined;
|
|
546
|
+
}
|
|
547
|
+
)
|
|
548
|
+
) {
|
|
549
|
+
const { lastMessageId } = await this.saveMessages(ctx, {
|
|
550
|
+
threadId: args.threadId,
|
|
551
|
+
userId: args.userId,
|
|
552
|
+
messages:
|
|
553
|
+
args.prompt !== undefined
|
|
554
|
+
? [{ role: "user", content: args.prompt }]
|
|
555
|
+
: [args.message],
|
|
556
|
+
metadata: args.metadata ? [args.metadata] : undefined,
|
|
557
|
+
});
|
|
558
|
+
return { messageId: lastMessageId };
|
|
559
|
+
}
|
|
560
|
+
|
|
540
561
|
/**
|
|
541
562
|
* Explicitly save messages associated with the thread (& user if provided)
|
|
542
563
|
* @param ctx The ctx parameter to a mutation or action.
|
|
@@ -576,7 +597,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
576
597
|
}
|
|
577
598
|
): Promise<{
|
|
578
599
|
lastMessageId: string;
|
|
579
|
-
|
|
600
|
+
messages: MessageDoc[];
|
|
580
601
|
}> {
|
|
581
602
|
const embeddings = await this.generateEmbeddings(args.messages);
|
|
582
603
|
const result = await ctx.runMutation(this.component.messages.addMessages, {
|
|
@@ -597,7 +618,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
597
618
|
});
|
|
598
619
|
return {
|
|
599
620
|
lastMessageId: result.messages.at(-1)!._id,
|
|
600
|
-
|
|
621
|
+
messages: result.messages,
|
|
601
622
|
};
|
|
602
623
|
}
|
|
603
624
|
|
|
@@ -622,11 +643,15 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
622
643
|
failPendingSteps: v.optional(v.boolean()),
|
|
623
644
|
},
|
|
624
645
|
handler: async (ctx, args) => {
|
|
625
|
-
|
|
646
|
+
const { lastMessageId, messages } = await this.saveMessages(ctx, {
|
|
626
647
|
...args,
|
|
627
648
|
messages: args.messages.map((m) => m.message),
|
|
628
649
|
metadata: args.messages.map(({ message: _, ...m }) => m),
|
|
629
650
|
});
|
|
651
|
+
return {
|
|
652
|
+
lastMessageId,
|
|
653
|
+
messageIds: messages.map((m) => m._id),
|
|
654
|
+
};
|
|
630
655
|
},
|
|
631
656
|
});
|
|
632
657
|
}
|
|
@@ -660,7 +685,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
660
685
|
*/
|
|
661
686
|
provider?: string;
|
|
662
687
|
}
|
|
663
|
-
): Promise<
|
|
688
|
+
): Promise<MessageDoc[]> {
|
|
664
689
|
const step = serializeStep(args.step as StepResult<ToolSet>);
|
|
665
690
|
const messages = serializeNewMessagesInStep(args.step, {
|
|
666
691
|
provider: args.provider ?? this.options.chat.provider,
|
|
@@ -669,13 +694,14 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
669
694
|
const embeddings = await this.generateEmbeddings(
|
|
670
695
|
messages.map((m) => m.message)
|
|
671
696
|
);
|
|
672
|
-
await ctx.runMutation(this.component.messages.addStep, {
|
|
697
|
+
const saved = await ctx.runMutation(this.component.messages.addStep, {
|
|
673
698
|
userId: args.userId,
|
|
674
699
|
threadId: args.threadId,
|
|
675
700
|
promptMessageId: args.promptMessageId,
|
|
676
701
|
step: { step, messages, embeddings },
|
|
677
702
|
failPendingSteps: false,
|
|
678
703
|
});
|
|
704
|
+
return saved;
|
|
679
705
|
}
|
|
680
706
|
|
|
681
707
|
/**
|
|
@@ -752,7 +778,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
752
778
|
args,
|
|
753
779
|
{ userId, threadId, ...options }
|
|
754
780
|
);
|
|
755
|
-
const toolCtx = { ...ctx, userId, threadId, messageId };
|
|
781
|
+
const toolCtx = { ...ctx, userId, threadId, messageId, agent: this };
|
|
756
782
|
const tools = wrapTools(
|
|
757
783
|
toolCtx,
|
|
758
784
|
args.tools ?? threadTools ?? this.options.tools
|
|
@@ -844,7 +870,19 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
844
870
|
* The {@link ContextOptions} and {@link StorageOptions}
|
|
845
871
|
* options to use for fetching contextual messages and saving input/output messages.
|
|
846
872
|
*/
|
|
847
|
-
options?: Options
|
|
873
|
+
options?: Options & {
|
|
874
|
+
/**
|
|
875
|
+
* Whether to save incremental data (deltas) from streaming responses.
|
|
876
|
+
* Defaults to false.
|
|
877
|
+
* If false, it will not save any deltas to the database.
|
|
878
|
+
* If true, it will save deltas with {@link DEFAULT_STREAMING_OPTIONS}.
|
|
879
|
+
*
|
|
880
|
+
* Regardless of this option, when streaming you are able to use this
|
|
881
|
+
* `streamText` function as you would with the "ai" package's version:
|
|
882
|
+
* iterating over the text, streaming it over HTTP, etc.
|
|
883
|
+
*/
|
|
884
|
+
saveStreamDeltas?: boolean | StreamingOptions;
|
|
885
|
+
}
|
|
848
886
|
): Promise<
|
|
849
887
|
StreamTextResult<
|
|
850
888
|
TOOLS extends undefined ? AgentTools : TOOLS,
|
|
@@ -852,28 +890,50 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
852
890
|
> &
|
|
853
891
|
GenerationOutputMetadata
|
|
854
892
|
> {
|
|
855
|
-
const
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
);
|
|
860
|
-
const
|
|
893
|
+
const context = await this._saveMessagesAndFetchContext(ctx, args, {
|
|
894
|
+
userId,
|
|
895
|
+
threadId,
|
|
896
|
+
...options,
|
|
897
|
+
});
|
|
898
|
+
const { args: aiArgs, messageId, order, stepOrder } = context;
|
|
899
|
+
const toolCtx = { ...ctx, userId, threadId, messageId, agent: this };
|
|
861
900
|
const tools = wrapTools(
|
|
862
901
|
toolCtx,
|
|
863
902
|
args.tools ?? threadTools ?? this.options.tools
|
|
864
903
|
) as TOOLS extends undefined ? AgentTools : TOOLS;
|
|
865
|
-
const
|
|
866
|
-
options
|
|
867
|
-
|
|
904
|
+
const storageOptions = {
|
|
905
|
+
...this.options.storageOptions,
|
|
906
|
+
...options?.storageOptions,
|
|
907
|
+
};
|
|
908
|
+
const saveOutputMessages = storageOptions.saveOutputMessages;
|
|
868
909
|
const trackUsage = usageHandler ?? this.options.usageHandler;
|
|
910
|
+
const streamer =
|
|
911
|
+
threadId && options?.saveStreamDeltas
|
|
912
|
+
? new DeltaStreamer(this.component, ctx, options.saveStreamDeltas, {
|
|
913
|
+
threadId,
|
|
914
|
+
userId,
|
|
915
|
+
agentName: this.options.name,
|
|
916
|
+
model: aiArgs.model.modelId,
|
|
917
|
+
provider: aiArgs.model.provider,
|
|
918
|
+
providerOptions: aiArgs.providerOptions,
|
|
919
|
+
order,
|
|
920
|
+
stepOrder,
|
|
921
|
+
})
|
|
922
|
+
: undefined;
|
|
923
|
+
|
|
869
924
|
const result = streamText({
|
|
870
925
|
// Can be overridden
|
|
871
926
|
maxSteps: this.options.maxSteps,
|
|
872
927
|
...aiArgs,
|
|
873
928
|
tools,
|
|
874
|
-
|
|
929
|
+
experimental_transform: mergeTransforms(
|
|
930
|
+
options?.saveStreamDeltas,
|
|
931
|
+
args.experimental_transform
|
|
932
|
+
),
|
|
933
|
+
onChunk: async (event) => {
|
|
934
|
+
await streamer?.addParts([event.chunk]);
|
|
875
935
|
// console.log("onChunk", chunk);
|
|
876
|
-
return args.onChunk?.(
|
|
936
|
+
return args.onChunk?.(event);
|
|
877
937
|
},
|
|
878
938
|
onError: async (error) => {
|
|
879
939
|
console.error("onError", error);
|
|
@@ -889,12 +949,13 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
889
949
|
// console.log("onStepFinish", step);
|
|
890
950
|
// TODO: compare delta to the output. internally drop the deltas when committing
|
|
891
951
|
if (threadId && messageId) {
|
|
892
|
-
await this.saveStep(ctx, {
|
|
952
|
+
const saved = await this.saveStep(ctx, {
|
|
893
953
|
userId,
|
|
894
954
|
threadId,
|
|
895
955
|
promptMessageId: messageId,
|
|
896
956
|
step,
|
|
897
957
|
});
|
|
958
|
+
await streamer?.finish(saved);
|
|
898
959
|
}
|
|
899
960
|
if (trackUsage && step.usage) {
|
|
900
961
|
await trackUsage(ctx, {
|
|
@@ -943,6 +1004,8 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
943
1004
|
): Promise<{
|
|
944
1005
|
args: T & { model: LanguageModelV1 };
|
|
945
1006
|
messageId: string | undefined;
|
|
1007
|
+
order: number | undefined;
|
|
1008
|
+
stepOrder: number | undefined;
|
|
946
1009
|
}> {
|
|
947
1010
|
contextOptions ||= this.options.contextOptions;
|
|
948
1011
|
storageOptions ||= this.options.storageOptions;
|
|
@@ -963,6 +1026,12 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
963
1026
|
contextOptions,
|
|
964
1027
|
});
|
|
965
1028
|
let messageId = args.promptMessageId;
|
|
1029
|
+
let order = args.promptMessageId
|
|
1030
|
+
? contextMessages.at(-1)?.order
|
|
1031
|
+
: undefined;
|
|
1032
|
+
let stepOrder = args.promptMessageId
|
|
1033
|
+
? contextMessages.at(-1)?.stepOrder
|
|
1034
|
+
: undefined;
|
|
966
1035
|
if (
|
|
967
1036
|
threadId &&
|
|
968
1037
|
messages.length &&
|
|
@@ -979,6 +1048,8 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
979
1048
|
failPendingSteps: true,
|
|
980
1049
|
});
|
|
981
1050
|
messageId = saved.lastMessageId;
|
|
1051
|
+
order = saved.messages.at(-1)?.order;
|
|
1052
|
+
stepOrder = saved.messages.at(-1)?.stepOrder;
|
|
982
1053
|
}
|
|
983
1054
|
const { prompt: _, model, ...rest } = args;
|
|
984
1055
|
return {
|
|
@@ -993,6 +1064,8 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
993
1064
|
],
|
|
994
1065
|
} as T & { model: LanguageModelV1 },
|
|
995
1066
|
messageId,
|
|
1067
|
+
order,
|
|
1068
|
+
stepOrder,
|
|
996
1069
|
};
|
|
997
1070
|
}
|
|
998
1071
|
|
|
@@ -1185,7 +1258,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
1185
1258
|
});
|
|
1186
1259
|
}
|
|
1187
1260
|
|
|
1188
|
-
|
|
1261
|
+
_mergedContextOptions(opts: ContextOptions | undefined): ContextOptions {
|
|
1189
1262
|
const searchOptions = {
|
|
1190
1263
|
...this.options.contextOptions?.searchOptions,
|
|
1191
1264
|
...opts?.searchOptions,
|
|
@@ -1199,7 +1272,7 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
1199
1272
|
};
|
|
1200
1273
|
}
|
|
1201
1274
|
|
|
1202
|
-
async
|
|
1275
|
+
async _searchOptionsWithDefaults(
|
|
1203
1276
|
contextOptions: ContextOptions,
|
|
1204
1277
|
messages: CoreMessage[]
|
|
1205
1278
|
): Promise<SearchOptions> {
|
|
@@ -1273,31 +1346,68 @@ export class Agent<AgentTools extends ToolSet> {
|
|
|
1273
1346
|
* {@link ContextOptions}, {@link StorageOptions}, and maxSteps.
|
|
1274
1347
|
*/
|
|
1275
1348
|
asTextAction(spec?: {
|
|
1349
|
+
/**
|
|
1350
|
+
* The maximum number of steps to take in this action.
|
|
1351
|
+
* Defaults to the {@link Agent.maxSteps} option.
|
|
1352
|
+
*/
|
|
1276
1353
|
maxSteps?: number;
|
|
1354
|
+
/**
|
|
1355
|
+
* The {@link ContextOptions} to use for fetching contextual messages and
|
|
1356
|
+
* saving input/output messages.
|
|
1357
|
+
* Defaults to the {@link Agent.contextOptions} option.
|
|
1358
|
+
*/
|
|
1277
1359
|
contextOptions?: ContextOptions;
|
|
1360
|
+
/**
|
|
1361
|
+
* The {@link StorageOptions} to use for saving input/output messages.
|
|
1362
|
+
* Defaults to the {@link Agent.storageOptions} option.
|
|
1363
|
+
*/
|
|
1278
1364
|
storageOptions?: StorageOptions;
|
|
1365
|
+
/**
|
|
1366
|
+
* Whether to stream the text.
|
|
1367
|
+
* If false, it will generate the text in a single call. (default)
|
|
1368
|
+
* If true or {@link StreamingOptions}, it will stream the text from the LLM
|
|
1369
|
+
* and save the chunks to the database with the options you specify, or the
|
|
1370
|
+
* defaults if you pass true.
|
|
1371
|
+
*/
|
|
1372
|
+
stream?: boolean | StreamingOptions;
|
|
1279
1373
|
}) {
|
|
1280
1374
|
const maxSteps = spec?.maxSteps ?? this.options.maxSteps;
|
|
1281
1375
|
return internalActionGeneric({
|
|
1282
1376
|
args: vTextArgs,
|
|
1283
1377
|
handler: async (ctx, args) => {
|
|
1284
1378
|
const { contextOptions, storageOptions, ...rest } = args;
|
|
1285
|
-
const
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1379
|
+
const stream =
|
|
1380
|
+
args.stream === true ? spec?.stream || true : spec?.stream ?? false;
|
|
1381
|
+
const targetArgs = { userId: args.userId, threadId: args.threadId };
|
|
1382
|
+
const llmArgs = { maxSteps, ...rest };
|
|
1383
|
+
const opts = {
|
|
1384
|
+
contextOptions:
|
|
1385
|
+
contextOptions ??
|
|
1386
|
+
spec?.contextOptions ??
|
|
1387
|
+
this.options.contextOptions,
|
|
1388
|
+
storageOptions:
|
|
1389
|
+
storageOptions ??
|
|
1390
|
+
spec?.storageOptions ??
|
|
1391
|
+
this.options.storageOptions,
|
|
1392
|
+
saveStreamDeltas: stream,
|
|
1393
|
+
};
|
|
1394
|
+
if (stream) {
|
|
1395
|
+
const result = await this.streamText(ctx, targetArgs, llmArgs, opts);
|
|
1396
|
+
await result.consumeStream();
|
|
1397
|
+
return {
|
|
1398
|
+
text: await result.text,
|
|
1399
|
+
finishReason: await result.finishReason,
|
|
1400
|
+
messageId: result.messageId,
|
|
1401
|
+
};
|
|
1402
|
+
} else {
|
|
1403
|
+
const { text, messageId, finishReason } = await this.generateText(
|
|
1404
|
+
ctx,
|
|
1405
|
+
targetArgs,
|
|
1406
|
+
llmArgs,
|
|
1407
|
+
opts
|
|
1408
|
+
);
|
|
1409
|
+
return { text, messageId, finishReason };
|
|
1410
|
+
}
|
|
1301
1411
|
},
|
|
1302
1412
|
});
|
|
1303
1413
|
}
|
|
@@ -1372,534 +1482,5 @@ export function filterOutOrphanedToolMessages(docs: MessageDoc[]) {
|
|
|
1372
1482
|
return result;
|
|
1373
1483
|
}
|
|
1374
1484
|
|
|
1375
|
-
export type ToolCtx = RunActionCtx & {
|
|
1376
|
-
userId?: string;
|
|
1377
|
-
threadId?: string;
|
|
1378
|
-
messageId?: string;
|
|
1379
|
-
};
|
|
1380
|
-
|
|
1381
|
-
// Vendoring in from "ai" package since it wasn't exported
|
|
1382
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1383
|
-
type ToolParameters = z.ZodTypeAny | Schema<any>;
|
|
1384
|
-
type inferParameters<PARAMETERS extends ToolParameters> =
|
|
1385
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1386
|
-
PARAMETERS extends Schema<any>
|
|
1387
|
-
? PARAMETERS["_type"]
|
|
1388
|
-
: PARAMETERS extends z.ZodTypeAny
|
|
1389
|
-
? z.infer<PARAMETERS>
|
|
1390
|
-
: never;
|
|
1391
|
-
|
|
1392
|
-
/**
|
|
1393
|
-
* This is a wrapper around the ai.tool function that adds extra context to the
|
|
1394
|
-
* tool call, including the action context, userId, threadId, and messageId.
|
|
1395
|
-
* @param tool The tool. See https://sdk.vercel.ai/docs/ai-sdk-core/tools-and-tool-calling
|
|
1396
|
-
* but swap parameters for args and handler for execute.
|
|
1397
|
-
* @returns A tool to be used with the AI SDK.
|
|
1398
|
-
*/
|
|
1399
|
-
export function createTool<PARAMETERS extends ToolParameters, RESULT>(t: {
|
|
1400
|
-
/**
|
|
1401
|
-
An optional description of what the tool does.
|
|
1402
|
-
Will be used by the language model to decide whether to use the tool.
|
|
1403
|
-
Not used for provider-defined tools.
|
|
1404
|
-
*/
|
|
1405
|
-
description?: string;
|
|
1406
|
-
/**
|
|
1407
|
-
The schema of the input that the tool expects. The language model will use this to generate the input.
|
|
1408
|
-
It is also used to validate the output of the language model.
|
|
1409
|
-
Use descriptions to make the input understandable for the language model.
|
|
1410
|
-
*/
|
|
1411
|
-
args: PARAMETERS;
|
|
1412
|
-
/**
|
|
1413
|
-
An async function that is called with the arguments from the tool call and produces a result.
|
|
1414
|
-
If not provided, the tool will not be executed automatically.
|
|
1415
|
-
|
|
1416
|
-
@args is the input of the tool call.
|
|
1417
|
-
@options.abortSignal is a signal that can be used to abort the tool call.
|
|
1418
|
-
*/
|
|
1419
|
-
handler: (
|
|
1420
|
-
ctx: ToolCtx,
|
|
1421
|
-
args: inferParameters<PARAMETERS>,
|
|
1422
|
-
options: ToolExecutionOptions
|
|
1423
|
-
) => PromiseLike<RESULT>;
|
|
1424
|
-
ctx?: ToolCtx;
|
|
1425
|
-
}): Tool<PARAMETERS, RESULT> & {
|
|
1426
|
-
execute: (
|
|
1427
|
-
args: inferParameters<PARAMETERS>,
|
|
1428
|
-
options: ToolExecutionOptions
|
|
1429
|
-
) => PromiseLike<RESULT>;
|
|
1430
|
-
} {
|
|
1431
|
-
const args = {
|
|
1432
|
-
__acceptsCtx: true,
|
|
1433
|
-
ctx: t.ctx,
|
|
1434
|
-
description: t.description,
|
|
1435
|
-
parameters: t.args,
|
|
1436
|
-
async execute(
|
|
1437
|
-
args: inferParameters<PARAMETERS>,
|
|
1438
|
-
options: ToolExecutionOptions
|
|
1439
|
-
) {
|
|
1440
|
-
if (!this.ctx) {
|
|
1441
|
-
throw new Error(
|
|
1442
|
-
"To use a Convex tool, you must either provide the ctx" +
|
|
1443
|
-
" at definition time (dynamically in an action), or use the Agent to" +
|
|
1444
|
-
" call it (which injects the ctx, userId and threadId)"
|
|
1445
|
-
);
|
|
1446
|
-
}
|
|
1447
|
-
return t.handler(this.ctx, args, options);
|
|
1448
|
-
},
|
|
1449
|
-
};
|
|
1450
|
-
return tool(args);
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
|
-
function wrapTools(
|
|
1454
|
-
ctx: ToolCtx,
|
|
1455
|
-
...toolSets: (ToolSet | undefined)[]
|
|
1456
|
-
): ToolSet {
|
|
1457
|
-
const output = {} as ToolSet;
|
|
1458
|
-
for (const toolSet of toolSets) {
|
|
1459
|
-
if (!toolSet) {
|
|
1460
|
-
continue;
|
|
1461
|
-
}
|
|
1462
|
-
for (const [name, tool] of Object.entries(toolSet)) {
|
|
1463
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1464
|
-
if (!(tool as any).__acceptsCtx) {
|
|
1465
|
-
output[name] = tool;
|
|
1466
|
-
} else {
|
|
1467
|
-
const out = { ...tool, ctx };
|
|
1468
|
-
output[name] = out;
|
|
1469
|
-
}
|
|
1470
|
-
}
|
|
1471
|
-
}
|
|
1472
|
-
return output;
|
|
1473
|
-
}
|
|
1474
|
-
|
|
1475
|
-
type Options = {
|
|
1476
|
-
/**
|
|
1477
|
-
* The context options to use for passing in message history to the LLM.
|
|
1478
|
-
*/
|
|
1479
|
-
contextOptions?: ContextOptions;
|
|
1480
|
-
/**
|
|
1481
|
-
* The storage options to use for saving the input and output messages to the thread.
|
|
1482
|
-
*/
|
|
1483
|
-
storageOptions?: StorageOptions;
|
|
1484
|
-
};
|
|
1485
|
-
|
|
1486
|
-
type TextArgs<
|
|
1487
|
-
AgentTools extends ToolSet,
|
|
1488
|
-
TOOLS extends ToolSet | undefined = undefined,
|
|
1489
|
-
OUTPUT = never,
|
|
1490
|
-
OUTPUT_PARTIAL = never,
|
|
1491
|
-
> = Omit<
|
|
1492
|
-
Parameters<
|
|
1493
|
-
typeof generateText<
|
|
1494
|
-
TOOLS extends undefined ? AgentTools : TOOLS,
|
|
1495
|
-
OUTPUT,
|
|
1496
|
-
OUTPUT_PARTIAL
|
|
1497
|
-
>
|
|
1498
|
-
>[0],
|
|
1499
|
-
"toolChoice" | "tools" | "model"
|
|
1500
|
-
> & {
|
|
1501
|
-
/**
|
|
1502
|
-
* If provided, this message will be used as the "prompt" for the LLM call,
|
|
1503
|
-
* instead of the prompt or messages.
|
|
1504
|
-
* This is useful if you want to first save a user message, then use it as
|
|
1505
|
-
* the prompt for the LLM call in another call.
|
|
1506
|
-
*/
|
|
1507
|
-
promptMessageId?: string;
|
|
1508
|
-
/**
|
|
1509
|
-
* The model to use for the tool calls. This will override the model specified
|
|
1510
|
-
* in the Agent constructor.
|
|
1511
|
-
*/
|
|
1512
|
-
model?: LanguageModelV1;
|
|
1513
|
-
/**
|
|
1514
|
-
* The tools to use for the tool calls. This will override tools specified
|
|
1515
|
-
* in the Agent constructor or createThread / continueThread.
|
|
1516
|
-
*/
|
|
1517
|
-
tools?: TOOLS;
|
|
1518
|
-
/**
|
|
1519
|
-
* The tool choice to use for the tool calls. This must be one of the tools
|
|
1520
|
-
* specified in the tools array. e.g. {toolName: "getWeather", type: "tool"}
|
|
1521
|
-
*/
|
|
1522
|
-
toolChoice?: ToolChoice<TOOLS extends undefined ? AgentTools : TOOLS>;
|
|
1523
|
-
};
|
|
1524
|
-
|
|
1525
|
-
type StreamingTextArgs<
|
|
1526
|
-
AgentTools extends ToolSet,
|
|
1527
|
-
TOOLS extends ToolSet | undefined = undefined,
|
|
1528
|
-
OUTPUT = never,
|
|
1529
|
-
OUTPUT_PARTIAL = never,
|
|
1530
|
-
> = Omit<
|
|
1531
|
-
Parameters<
|
|
1532
|
-
typeof streamText<
|
|
1533
|
-
TOOLS extends undefined ? AgentTools : TOOLS,
|
|
1534
|
-
OUTPUT,
|
|
1535
|
-
OUTPUT_PARTIAL
|
|
1536
|
-
>
|
|
1537
|
-
>[0],
|
|
1538
|
-
"toolChoice" | "tools" | "model"
|
|
1539
|
-
> & {
|
|
1540
|
-
/**
|
|
1541
|
-
* The model to use for the tool calls. This will override the model specified
|
|
1542
|
-
* in the Agent constructor.
|
|
1543
|
-
*/
|
|
1544
|
-
model?: LanguageModelV1;
|
|
1545
|
-
/**
|
|
1546
|
-
* The tools to use for the tool calls. This will override tools specified
|
|
1547
|
-
* in the Agent constructor or createThread / continueThread.
|
|
1548
|
-
*/
|
|
1549
|
-
tools?: TOOLS;
|
|
1550
|
-
/**
|
|
1551
|
-
* The tool choice to use for the tool calls. This must be one of the tools
|
|
1552
|
-
* specified in the tools array. e.g. {toolName: "getWeather", type: "tool"}
|
|
1553
|
-
*/
|
|
1554
|
-
toolChoice?: ToolChoice<TOOLS extends undefined ? AgentTools : TOOLS>;
|
|
1555
|
-
};
|
|
1556
|
-
|
|
1557
|
-
type BaseGenerateObjectOptions = CallSettings & {
|
|
1558
|
-
/**
|
|
1559
|
-
* The model to use for the object generation. This will override the model
|
|
1560
|
-
* specified in the Agent constructor.
|
|
1561
|
-
*/
|
|
1562
|
-
model?: LanguageModelV1;
|
|
1563
|
-
/**
|
|
1564
|
-
* The system prompt to use for the object generation. This will override the
|
|
1565
|
-
* system prompt specified in the Agent constructor.
|
|
1566
|
-
*/
|
|
1567
|
-
system?: string;
|
|
1568
|
-
/**
|
|
1569
|
-
* The prompt to the LLM to use for the object generation.
|
|
1570
|
-
* Specify this or messages, but not both.
|
|
1571
|
-
*/
|
|
1572
|
-
prompt?: string;
|
|
1573
|
-
/**
|
|
1574
|
-
* The messages to use for the object generation.
|
|
1575
|
-
* Note: recent messages are automatically added based on the thread it's
|
|
1576
|
-
* associated with and your contextOptions.
|
|
1577
|
-
*/
|
|
1578
|
-
messages?: CoreMessage[];
|
|
1579
|
-
/**
|
|
1580
|
-
* The message to use as the "prompt" for the object generation.
|
|
1581
|
-
* If this is provided, it will be used instead of the prompt or messages.
|
|
1582
|
-
* This is useful if you want to first save a user message, then use it as
|
|
1583
|
-
* the prompt for the object generation in another call.
|
|
1584
|
-
*/
|
|
1585
|
-
promptMessageId?: string;
|
|
1586
|
-
experimental_repairText?: RepairTextFunction;
|
|
1587
|
-
experimental_telemetry?: TelemetrySettings;
|
|
1588
|
-
providerOptions?: ProviderOptions;
|
|
1589
|
-
experimental_providerMetadata?: ProviderMetadata;
|
|
1590
|
-
};
|
|
1591
|
-
|
|
1592
|
-
type GenerateObjectObjectOptions<T extends Record<string, unknown>> =
|
|
1593
|
-
BaseGenerateObjectOptions & {
|
|
1594
|
-
output?: "object";
|
|
1595
|
-
mode?: "auto" | "json" | "tool";
|
|
1596
|
-
schema: z.Schema<T>;
|
|
1597
|
-
schemaName?: string;
|
|
1598
|
-
schemaDescription?: string;
|
|
1599
|
-
};
|
|
1600
|
-
|
|
1601
|
-
type GenerateObjectArrayOptions<T> = BaseGenerateObjectOptions & {
|
|
1602
|
-
output: "array";
|
|
1603
|
-
mode?: "auto" | "json" | "tool";
|
|
1604
|
-
schema: z.Schema<T>;
|
|
1605
|
-
schemaName?: string;
|
|
1606
|
-
schemaDescription?: string;
|
|
1607
|
-
};
|
|
1608
|
-
|
|
1609
|
-
type GenerateObjectWithEnumOptions<T extends string> =
|
|
1610
|
-
BaseGenerateObjectOptions & {
|
|
1611
|
-
output: "enum";
|
|
1612
|
-
enum: Array<T>;
|
|
1613
|
-
mode?: "auto" | "json" | "tool";
|
|
1614
|
-
};
|
|
1615
|
-
|
|
1616
|
-
type GenerateObjectNoSchemaOptions = BaseGenerateObjectOptions & {
|
|
1617
|
-
schema?: undefined;
|
|
1618
|
-
mode?: "json";
|
|
1619
|
-
};
|
|
1620
|
-
|
|
1621
|
-
// TODO: simplify this to just use the generateObject args, with an optional
|
|
1622
|
-
// model and tool/toolChoice types
|
|
1623
|
-
type GenerateObjectArgs<T> =
|
|
1624
|
-
T extends Record<string, unknown>
|
|
1625
|
-
? GenerateObjectObjectOptions<T>
|
|
1626
|
-
: T extends Array<unknown>
|
|
1627
|
-
? GenerateObjectArrayOptions<T>
|
|
1628
|
-
: T extends string
|
|
1629
|
-
? GenerateObjectWithEnumOptions<T>
|
|
1630
|
-
: GenerateObjectNoSchemaOptions;
|
|
1631
|
-
|
|
1632
|
-
type StreamObjectArgs<T> =
|
|
1633
|
-
T extends Record<string, unknown>
|
|
1634
|
-
? GenerateObjectObjectOptions<T>
|
|
1635
|
-
: T extends Array<unknown>
|
|
1636
|
-
? GenerateObjectArrayOptions<T>
|
|
1637
|
-
: GenerateObjectNoSchemaOptions;
|
|
1638
|
-
|
|
1639
|
-
type OurObjectArgs<T> = GenerateObjectArgs<T> &
|
|
1640
|
-
Pick<
|
|
1641
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1642
|
-
Parameters<typeof generateObject<any>>[0],
|
|
1643
|
-
"experimental_repairText" | "abortSignal"
|
|
1644
|
-
>;
|
|
1645
|
-
|
|
1646
|
-
type OurStreamObjectArgs<T> = StreamObjectArgs<T> &
|
|
1647
|
-
Pick<
|
|
1648
|
-
Parameters<typeof streamObject<T>>[0],
|
|
1649
|
-
"onError" | "onFinish" | "abortSignal"
|
|
1650
|
-
>;
|
|
1651
|
-
|
|
1652
|
-
type ThreadOutputMetadata = GenerationOutputMetadata & {
|
|
1653
|
-
messageId: string;
|
|
1654
|
-
};
|
|
1655
|
-
|
|
1656
|
-
/**
|
|
1657
|
-
* The interface for a thread returned from {@link createThread} or {@link continueThread}.
|
|
1658
|
-
* This is contextual to a thread and/or user.
|
|
1659
|
-
*/
|
|
1660
|
-
interface Thread<DefaultTools extends ToolSet> {
|
|
1661
|
-
/**
|
|
1662
|
-
* The target threadId, from the startThread or continueThread initializers.
|
|
1663
|
-
*/
|
|
1664
|
-
threadId: string;
|
|
1665
|
-
/**
|
|
1666
|
-
* This behaves like {@link generateText} from the "ai" package except that
|
|
1667
|
-
* it add context based on the userId and threadId and saves the input and
|
|
1668
|
-
* resulting messages to the thread, if specified.
|
|
1669
|
-
* Use {@link continueThread} to get a version of this function already scoped
|
|
1670
|
-
* to a thread (and optionally userId).
|
|
1671
|
-
* @param args The arguments to the generateText function, along with extra controls
|
|
1672
|
-
* for the {@link ContextOptions} and {@link StorageOptions}.
|
|
1673
|
-
* @returns The result of the generateText function.
|
|
1674
|
-
*/
|
|
1675
|
-
generateText<
|
|
1676
|
-
TOOLS extends ToolSet | undefined = undefined,
|
|
1677
|
-
OUTPUT = never,
|
|
1678
|
-
OUTPUT_PARTIAL = never,
|
|
1679
|
-
>(
|
|
1680
|
-
args: TextArgs<
|
|
1681
|
-
TOOLS extends undefined ? DefaultTools : TOOLS,
|
|
1682
|
-
TOOLS,
|
|
1683
|
-
OUTPUT,
|
|
1684
|
-
OUTPUT_PARTIAL
|
|
1685
|
-
>,
|
|
1686
|
-
options?: Options
|
|
1687
|
-
): Promise<
|
|
1688
|
-
GenerateTextResult<TOOLS extends undefined ? DefaultTools : TOOLS, OUTPUT> &
|
|
1689
|
-
ThreadOutputMetadata
|
|
1690
|
-
>;
|
|
1691
|
-
|
|
1692
|
-
/**
|
|
1693
|
-
* This behaves like {@link streamText} from the "ai" package except that
|
|
1694
|
-
* it add context based on the userId and threadId and saves the input and
|
|
1695
|
-
* resulting messages to the thread, if specified.
|
|
1696
|
-
* Use {@link continueThread} to get a version of this function already scoped
|
|
1697
|
-
* to a thread (and optionally userId).
|
|
1698
|
-
* @param args The arguments to the streamText function, along with extra controls
|
|
1699
|
-
* for the {@link ContextOptions} and {@link StorageOptions}.
|
|
1700
|
-
* @returns The result of the streamText function.
|
|
1701
|
-
*/
|
|
1702
|
-
streamText<
|
|
1703
|
-
TOOLS extends ToolSet | undefined = undefined,
|
|
1704
|
-
OUTPUT = never,
|
|
1705
|
-
PARTIAL_OUTPUT = never,
|
|
1706
|
-
>(
|
|
1707
|
-
args: StreamingTextArgs<
|
|
1708
|
-
TOOLS extends undefined ? DefaultTools : TOOLS,
|
|
1709
|
-
TOOLS,
|
|
1710
|
-
OUTPUT,
|
|
1711
|
-
PARTIAL_OUTPUT
|
|
1712
|
-
>,
|
|
1713
|
-
options?: Options
|
|
1714
|
-
): Promise<
|
|
1715
|
-
StreamTextResult<
|
|
1716
|
-
TOOLS extends undefined ? DefaultTools : TOOLS,
|
|
1717
|
-
PARTIAL_OUTPUT
|
|
1718
|
-
> &
|
|
1719
|
-
ThreadOutputMetadata
|
|
1720
|
-
>;
|
|
1721
|
-
/**
|
|
1722
|
-
* This behaves like {@link generateObject} from the "ai" package except that
|
|
1723
|
-
* it add context based on the userId and threadId and saves the input and
|
|
1724
|
-
* resulting messages to the thread, if specified. This overload is for objects, arrays, and enums.
|
|
1725
|
-
* Use {@link continueThread} to get a version of this function already scoped
|
|
1726
|
-
* to a thread (and optionally userId).
|
|
1727
|
-
* @param args The arguments to the generateObject function, along with extra controls
|
|
1728
|
-
* for the {@link ContextOptions} and {@link StorageOptions}.
|
|
1729
|
-
* @returns The result of the generateObject function.
|
|
1730
|
-
*/
|
|
1731
|
-
generateObject<T>(
|
|
1732
|
-
args: OurObjectArgs<T>,
|
|
1733
|
-
options?: Options
|
|
1734
|
-
): Promise<GenerateObjectResult<T> & ThreadOutputMetadata>;
|
|
1735
|
-
/**
|
|
1736
|
-
* This behaves like {@link generateObject} from the "ai" package except that
|
|
1737
|
-
* it add context based on the userId and threadId and saves the input and
|
|
1738
|
-
* resulting messages to the thread, if specified. This overload is for when there's no schema.
|
|
1739
|
-
* Use {@link continueThread} to get a version of this function already scoped
|
|
1740
|
-
* to a thread (and optionally userId).
|
|
1741
|
-
* @param args The arguments to the generateObject function, along with extra controls
|
|
1742
|
-
* for the {@link ContextOptions} and {@link StorageOptions}.
|
|
1743
|
-
* @returns The result of the generateObject function.
|
|
1744
|
-
*/
|
|
1745
|
-
generateObject(
|
|
1746
|
-
args: GenerateObjectNoSchemaOptions,
|
|
1747
|
-
options?: Options
|
|
1748
|
-
): Promise<GenerateObjectResult<JSONValue> & ThreadOutputMetadata>;
|
|
1749
|
-
/**
|
|
1750
|
-
* This behaves like {@link streamObject} from the "ai" package except that
|
|
1751
|
-
* it add context based on the userId and threadId and saves the input and
|
|
1752
|
-
* resulting messages to the thread, if specified.
|
|
1753
|
-
* Use {@link continueThread} to get a version of this function already scoped
|
|
1754
|
-
* to a thread (and optionally userId).
|
|
1755
|
-
* @param args The arguments to the streamObject function, along with extra controls
|
|
1756
|
-
* for the {@link ContextOptions} and {@link StorageOptions}.
|
|
1757
|
-
* @returns The result of the streamObject function.
|
|
1758
|
-
*/
|
|
1759
|
-
streamObject<T>(
|
|
1760
|
-
args: OurStreamObjectArgs<T>,
|
|
1761
|
-
options?: Options
|
|
1762
|
-
): Promise<
|
|
1763
|
-
StreamObjectResult<DeepPartial<T>, T, never> & ThreadOutputMetadata
|
|
1764
|
-
>;
|
|
1765
|
-
}
|
|
1766
|
-
|
|
1767
1485
|
type MessageWithMetadata = OpaqueIds<InnerMessageWithMetadata>;
|
|
1768
|
-
|
|
1769
|
-
export function toUIMessages(messages: MessageDoc[]): UIMessage[] {
|
|
1770
|
-
const uiMessages: UIMessage[] = [];
|
|
1771
|
-
let assistantMessage: UIMessage | undefined;
|
|
1772
|
-
for (const message of messages) {
|
|
1773
|
-
const coreMessage = message.message && deserializeMessage(message.message);
|
|
1774
|
-
const text = message.text ?? "";
|
|
1775
|
-
const content = coreMessage?.content;
|
|
1776
|
-
const nonStringContent =
|
|
1777
|
-
content && typeof content !== "string" ? content : [];
|
|
1778
|
-
if (!coreMessage) continue;
|
|
1779
|
-
if (coreMessage.role === "system") {
|
|
1780
|
-
uiMessages.push({
|
|
1781
|
-
id: message.id ?? message._id,
|
|
1782
|
-
createdAt: new Date(message._creationTime),
|
|
1783
|
-
role: "system",
|
|
1784
|
-
content: text,
|
|
1785
|
-
parts: [{ type: "text", text }],
|
|
1786
|
-
});
|
|
1787
|
-
} else if (coreMessage.role === "user") {
|
|
1788
|
-
const parts: UIMessage["parts"] = [];
|
|
1789
|
-
if (text) {
|
|
1790
|
-
parts.push({ type: "text", text });
|
|
1791
|
-
}
|
|
1792
|
-
if (message.files) {
|
|
1793
|
-
parts.push(...message.files.map(toUIFilePart));
|
|
1794
|
-
}
|
|
1795
|
-
uiMessages.push({
|
|
1796
|
-
id: message.id ?? message._id,
|
|
1797
|
-
createdAt: new Date(message._creationTime),
|
|
1798
|
-
role: "user",
|
|
1799
|
-
content: message.text ?? "",
|
|
1800
|
-
parts,
|
|
1801
|
-
});
|
|
1802
|
-
} else {
|
|
1803
|
-
if (coreMessage.role === "tool" && !assistantMessage) {
|
|
1804
|
-
console.warn(
|
|
1805
|
-
"Tool message without preceding assistant message.. skipping",
|
|
1806
|
-
message
|
|
1807
|
-
);
|
|
1808
|
-
continue;
|
|
1809
|
-
}
|
|
1810
|
-
if (!assistantMessage) {
|
|
1811
|
-
assistantMessage = {
|
|
1812
|
-
id: message.id ?? message._id,
|
|
1813
|
-
createdAt: new Date(message._creationTime),
|
|
1814
|
-
role: "assistant",
|
|
1815
|
-
content: message.text ?? "",
|
|
1816
|
-
parts: [],
|
|
1817
|
-
};
|
|
1818
|
-
uiMessages.push(assistantMessage);
|
|
1819
|
-
}
|
|
1820
|
-
// update it to the last message's id
|
|
1821
|
-
assistantMessage.id = message.id ?? message._id;
|
|
1822
|
-
if (message.text) {
|
|
1823
|
-
assistantMessage.parts.push({
|
|
1824
|
-
type: "text",
|
|
1825
|
-
text: message.text,
|
|
1826
|
-
});
|
|
1827
|
-
assistantMessage.content += message.text;
|
|
1828
|
-
}
|
|
1829
|
-
if (message.reasoning) {
|
|
1830
|
-
assistantMessage.parts.push({
|
|
1831
|
-
type: "reasoning",
|
|
1832
|
-
reasoning: message.reasoning,
|
|
1833
|
-
details: message.reasoningDetails ?? [],
|
|
1834
|
-
});
|
|
1835
|
-
}
|
|
1836
|
-
for (const source of message.sources ?? []) {
|
|
1837
|
-
assistantMessage.parts.push({
|
|
1838
|
-
type: "source",
|
|
1839
|
-
source,
|
|
1840
|
-
});
|
|
1841
|
-
}
|
|
1842
|
-
for (const file of message.files ?? []) {
|
|
1843
|
-
assistantMessage.parts.push(toUIFilePart(file));
|
|
1844
|
-
}
|
|
1845
|
-
for (const contentPart of nonStringContent) {
|
|
1846
|
-
switch (contentPart.type) {
|
|
1847
|
-
case "tool-call":
|
|
1848
|
-
assistantMessage.parts.push({
|
|
1849
|
-
type: "step-start",
|
|
1850
|
-
});
|
|
1851
|
-
assistantMessage.parts.push({
|
|
1852
|
-
type: "tool-invocation",
|
|
1853
|
-
toolInvocation: {
|
|
1854
|
-
state: "call",
|
|
1855
|
-
step: assistantMessage.parts.filter(
|
|
1856
|
-
(part) => part.type === "tool-invocation"
|
|
1857
|
-
).length,
|
|
1858
|
-
toolCallId: contentPart.toolCallId,
|
|
1859
|
-
toolName: contentPart.toolName,
|
|
1860
|
-
args: contentPart.args,
|
|
1861
|
-
},
|
|
1862
|
-
});
|
|
1863
|
-
break;
|
|
1864
|
-
case "tool-result": {
|
|
1865
|
-
const call = assistantMessage.parts.find(
|
|
1866
|
-
(part) =>
|
|
1867
|
-
part.type === "tool-invocation" &&
|
|
1868
|
-
part.toolInvocation.toolCallId === contentPart.toolCallId
|
|
1869
|
-
) as ToolInvocationUIPart | undefined;
|
|
1870
|
-
const toolInvocation: ToolInvocationUIPart["toolInvocation"] = {
|
|
1871
|
-
state: "result",
|
|
1872
|
-
toolCallId: contentPart.toolCallId,
|
|
1873
|
-
toolName: contentPart.toolName,
|
|
1874
|
-
args: call?.toolInvocation.args,
|
|
1875
|
-
result: contentPart.result,
|
|
1876
|
-
step:
|
|
1877
|
-
call?.toolInvocation.step ??
|
|
1878
|
-
assistantMessage.parts.filter(
|
|
1879
|
-
(part) => part.type === "tool-invocation"
|
|
1880
|
-
).length,
|
|
1881
|
-
};
|
|
1882
|
-
if (call) {
|
|
1883
|
-
(call as ToolInvocationUIPart).toolInvocation = toolInvocation;
|
|
1884
|
-
} else {
|
|
1885
|
-
console.warn(
|
|
1886
|
-
"Tool result without preceding tool call.. adding anyways",
|
|
1887
|
-
contentPart
|
|
1888
|
-
);
|
|
1889
|
-
assistantMessage.parts.push({
|
|
1890
|
-
type: "tool-invocation",
|
|
1891
|
-
toolInvocation,
|
|
1892
|
-
});
|
|
1893
|
-
}
|
|
1894
|
-
break;
|
|
1895
|
-
}
|
|
1896
|
-
}
|
|
1897
|
-
}
|
|
1898
|
-
if (!message.tool) {
|
|
1899
|
-
// Reset it so the next set of tool calls will create a new assistant message
|
|
1900
|
-
assistantMessage = undefined;
|
|
1901
|
-
}
|
|
1902
|
-
}
|
|
1903
|
-
}
|
|
1904
|
-
return uiMessages;
|
|
1905
|
-
}
|
|
1486
|
+
type CoreMessageMaybeWithId = CoreMessage & { id?: string | undefined };
|