@convex-dev/agent 0.3.2 → 0.6.0-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/dist/UIMessages.d.ts +3 -2
- package/dist/UIMessages.d.ts.map +1 -1
- package/dist/UIMessages.js +100 -19
- package/dist/UIMessages.js.map +1 -1
- package/dist/client/createTool.d.ts +129 -25
- package/dist/client/createTool.d.ts.map +1 -1
- package/dist/client/createTool.js +65 -8
- package/dist/client/createTool.js.map +1 -1
- package/dist/client/definePlaygroundAPI.d.ts +560 -35
- package/dist/client/definePlaygroundAPI.d.ts.map +1 -1
- package/dist/client/files.d.ts.map +1 -1
- package/dist/client/files.js +4 -2
- package/dist/client/files.js.map +1 -1
- package/dist/client/index.d.ts +462 -37
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +26 -7
- package/dist/client/index.js.map +1 -1
- package/dist/client/messages.d.ts +114 -9
- package/dist/client/messages.d.ts.map +1 -1
- package/dist/client/mockModel.d.ts +17 -17
- package/dist/client/mockModel.d.ts.map +1 -1
- package/dist/client/mockModel.js +8 -6
- package/dist/client/mockModel.js.map +1 -1
- package/dist/client/saveInputMessages.d.ts +1 -1
- package/dist/client/saveInputMessages.d.ts.map +1 -1
- package/dist/client/saveInputMessages.js +1 -1
- package/dist/client/saveInputMessages.js.map +1 -1
- package/dist/client/search.d.ts +132 -14
- package/dist/client/search.d.ts.map +1 -1
- package/dist/client/search.js +66 -19
- package/dist/client/search.js.map +1 -1
- package/dist/client/streamText.d.ts +4 -4
- package/dist/client/streamText.d.ts.map +1 -1
- package/dist/client/streamText.js.map +1 -1
- package/dist/client/streaming.d.ts +1491 -87
- package/dist/client/streaming.d.ts.map +1 -1
- package/dist/client/types.d.ts +26 -6
- package/dist/client/types.d.ts.map +1 -1
- package/dist/component/_generated/component.d.ts +862 -19
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/files.d.ts +12 -6
- package/dist/component/files.d.ts.map +1 -1
- package/dist/component/files.js +10 -2
- package/dist/component/files.js.map +1 -1
- package/dist/component/messages.d.ts +1247 -92
- package/dist/component/messages.d.ts.map +1 -1
- package/dist/component/schema.d.ts +2823 -217
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +3 -1
- package/dist/component/schema.js.map +1 -1
- package/dist/component/streams.js +1 -1
- package/dist/component/streams.js.map +1 -1
- package/dist/component/threads.d.ts +10 -10
- package/dist/component/vector/index.d.ts +1 -1
- package/dist/deltas.d.ts.map +1 -1
- package/dist/deltas.js +40 -5
- package/dist/deltas.js.map +1 -1
- package/dist/mapping.d.ts.map +1 -1
- package/dist/mapping.js +117 -25
- package/dist/mapping.js.map +1 -1
- package/dist/react/useThreadMessages.d.ts.map +1 -1
- package/dist/react/useThreadMessages.js +17 -9
- package/dist/react/useThreadMessages.js.map +1 -1
- package/dist/shared.d.ts +2 -2
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js.map +1 -1
- package/dist/validators.d.ts +12196 -624
- package/dist/validators.d.ts.map +1 -1
- package/dist/validators.js +152 -9
- package/dist/validators.js.map +1 -1
- package/package.json +24 -22
- package/src/UIMessages.combineUIMessages.test.ts +239 -0
- package/src/UIMessages.ts +184 -66
- package/src/client/createTool.ts +291 -67
- package/src/client/files.ts +4 -2
- package/src/client/index.test.ts +1 -0
- package/src/client/index.ts +46 -25
- package/src/client/mockModel.ts +36 -34
- package/src/client/saveInputMessages.ts +2 -2
- package/src/client/search.test.ts +166 -0
- package/src/client/search.ts +121 -38
- package/src/client/streamText.ts +5 -5
- package/src/client/types.ts +31 -18
- package/src/component/_generated/component.ts +2329 -338
- package/src/component/files.ts +11 -2
- package/src/component/messages.test.ts +7 -7
- package/src/component/schema.ts +3 -1
- package/src/component/setup.test.ts +7 -0
- package/src/component/streams.ts +1 -1
- package/src/deltas.test.ts +90 -0
- package/src/deltas.ts +47 -8
- package/src/fromUIMessages.test.ts +32 -27
- package/src/mapping.test.ts +48 -0
- package/src/mapping.ts +234 -142
- package/src/react/useThreadMessages.ts +21 -9
- package/src/shared.ts +2 -0
- package/src/toUIMessages.test.ts +539 -1
- package/src/validators.ts +179 -20
- package/src/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
package/src/client/createTool.ts
CHANGED
|
@@ -1,9 +1,24 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { ToolResultOutput } from "@ai-sdk/provider-utils";
|
|
2
|
+
import type {
|
|
3
|
+
FlexibleSchema,
|
|
4
|
+
ModelMessage,
|
|
5
|
+
Tool,
|
|
6
|
+
ToolExecutionOptions,
|
|
7
|
+
ToolSet,
|
|
8
|
+
} from "ai";
|
|
3
9
|
import { tool } from "ai";
|
|
4
|
-
import type { Agent } from "./index.js";
|
|
5
10
|
import type { GenericActionCtx, GenericDataModel } from "convex/server";
|
|
6
11
|
import type { ProviderOptions } from "../validators.js";
|
|
12
|
+
import type { Agent } from "./index.js";
|
|
13
|
+
|
|
14
|
+
const MIGRATION_URL = "https://github.com/get-convex/agent/blob/main/MIGRATION.md";
|
|
15
|
+
const warnedDeprecations = new Set<string>();
|
|
16
|
+
function warnDeprecation(key: string, message: string) {
|
|
17
|
+
if (!warnedDeprecations.has(key)) {
|
|
18
|
+
warnedDeprecations.add(key);
|
|
19
|
+
console.warn(`[@convex-dev/agent] ${message}\n See: ${MIGRATION_URL}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
7
22
|
|
|
8
23
|
export type ToolCtx<DataModel extends GenericDataModel = GenericDataModel> =
|
|
9
24
|
GenericActionCtx<DataModel> & {
|
|
@@ -13,79 +28,254 @@ export type ToolCtx<DataModel extends GenericDataModel = GenericDataModel> =
|
|
|
13
28
|
messageId?: string;
|
|
14
29
|
};
|
|
15
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Function that is called to determine if the tool needs approval before it can be executed.
|
|
33
|
+
*/
|
|
34
|
+
export type ToolNeedsApprovalFunctionCtx<
|
|
35
|
+
INPUT,
|
|
36
|
+
Ctx extends ToolCtx = ToolCtx,
|
|
37
|
+
> = (
|
|
38
|
+
ctx: Ctx,
|
|
39
|
+
input: INPUT,
|
|
40
|
+
options: {
|
|
41
|
+
/**
|
|
42
|
+
* The ID of the tool call. You can use it e.g. when sending tool-call related information with stream data.
|
|
43
|
+
*/
|
|
44
|
+
toolCallId: string;
|
|
45
|
+
/**
|
|
46
|
+
* Messages that were sent to the language model to initiate the response that contained the tool call.
|
|
47
|
+
* The messages **do not** include the system prompt nor the assistant response that contained the tool call.
|
|
48
|
+
*/
|
|
49
|
+
messages: ModelMessage[];
|
|
50
|
+
/**
|
|
51
|
+
* Additional context.
|
|
52
|
+
*
|
|
53
|
+
* Experimental (can break in patch releases).
|
|
54
|
+
*/
|
|
55
|
+
experimental_context?: unknown;
|
|
56
|
+
},
|
|
57
|
+
) => boolean | PromiseLike<boolean>;
|
|
58
|
+
|
|
59
|
+
export type ToolExecuteFunctionCtx<
|
|
60
|
+
INPUT,
|
|
61
|
+
OUTPUT,
|
|
62
|
+
Ctx extends ToolCtx = ToolCtx,
|
|
63
|
+
> = (
|
|
64
|
+
ctx: Ctx,
|
|
65
|
+
input: INPUT,
|
|
66
|
+
options: ToolExecutionOptions,
|
|
67
|
+
) => AsyncIterable<OUTPUT> | PromiseLike<OUTPUT>;
|
|
68
|
+
|
|
69
|
+
type NeverOptional<N, T> = 0 extends 1 & N
|
|
70
|
+
? Partial<T>
|
|
71
|
+
: [N] extends [never]
|
|
72
|
+
? Partial<Record<keyof T, undefined>>
|
|
73
|
+
: T;
|
|
74
|
+
|
|
75
|
+
export type ToolOutputPropertiesCtx<
|
|
76
|
+
INPUT,
|
|
77
|
+
OUTPUT,
|
|
78
|
+
Ctx extends ToolCtx = ToolCtx,
|
|
79
|
+
> = NeverOptional<
|
|
80
|
+
OUTPUT,
|
|
81
|
+
| {
|
|
82
|
+
/**
|
|
83
|
+
* An async function that is called with the arguments from the tool call and produces a result.
|
|
84
|
+
* If `execute` (or `handler`) is not provided, the tool will not be executed automatically.
|
|
85
|
+
*
|
|
86
|
+
* @param input - The input of the tool call.
|
|
87
|
+
* @param options.abortSignal - A signal that can be used to abort the tool call.
|
|
88
|
+
*/
|
|
89
|
+
execute: ToolExecuteFunctionCtx<INPUT, OUTPUT, Ctx>;
|
|
90
|
+
outputSchema?: FlexibleSchema<OUTPUT>;
|
|
91
|
+
handler?: never;
|
|
92
|
+
}
|
|
93
|
+
| {
|
|
94
|
+
/** @deprecated Use execute instead. */
|
|
95
|
+
handler: ToolExecuteFunctionCtx<INPUT, OUTPUT, Ctx>;
|
|
96
|
+
outputSchema?: FlexibleSchema<OUTPUT>;
|
|
97
|
+
execute?: never;
|
|
98
|
+
}
|
|
99
|
+
| {
|
|
100
|
+
outputSchema: FlexibleSchema<OUTPUT>;
|
|
101
|
+
execute?: never;
|
|
102
|
+
handler?: never;
|
|
103
|
+
}
|
|
104
|
+
>;
|
|
105
|
+
|
|
106
|
+
export type ToolInputProperties<INPUT> =
|
|
107
|
+
| {
|
|
108
|
+
/**
|
|
109
|
+
* The schema of the input that the tool expects.
|
|
110
|
+
* The language model will use this to generate the input.
|
|
111
|
+
* It is also used to validate the output of the language model.
|
|
112
|
+
*
|
|
113
|
+
* You can use descriptions on the schema properties to make the input understandable for the language model.
|
|
114
|
+
*/
|
|
115
|
+
inputSchema: FlexibleSchema<INPUT>;
|
|
116
|
+
args?: never;
|
|
117
|
+
}
|
|
118
|
+
| {
|
|
119
|
+
/**
|
|
120
|
+
* The schema of the input that the tool expects. The language model will use this to generate the input.
|
|
121
|
+
* It is also used to validate the output of the language model.
|
|
122
|
+
* Use descriptions to make the input understandable for the language model.
|
|
123
|
+
*
|
|
124
|
+
* @deprecated Use inputSchema instead.
|
|
125
|
+
*/
|
|
126
|
+
args: FlexibleSchema<INPUT>;
|
|
127
|
+
inputSchema?: never;
|
|
128
|
+
};
|
|
129
|
+
|
|
16
130
|
/**
|
|
17
131
|
* This is a wrapper around the ai.tool function that adds extra context to the
|
|
18
132
|
* tool call, including the action context, userId, threadId, and messageId.
|
|
19
133
|
* @param tool The tool. See https://sdk.vercel.ai/docs/ai-sdk-core/tools-and-tool-calling
|
|
20
|
-
*
|
|
134
|
+
* Currently contains deprecated parameters `args` and `handler` to maintain backwards compatibility
|
|
135
|
+
* but these will be removed in the future. Use `inputSchema` and `execute` instead, respectively.
|
|
136
|
+
*
|
|
21
137
|
* @returns A tool to be used with the AI SDK.
|
|
22
138
|
*/
|
|
23
|
-
export function createTool<INPUT, OUTPUT, Ctx extends ToolCtx = ToolCtx>(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
139
|
+
export function createTool<INPUT, OUTPUT, Ctx extends ToolCtx = ToolCtx>(
|
|
140
|
+
def: {
|
|
141
|
+
/**
|
|
142
|
+
* An optional description of what the tool does.
|
|
143
|
+
* Will be used by the language model to decide whether to use the tool.
|
|
144
|
+
* Not used for provider-defined tools.
|
|
28
145
|
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
It is also used to validate the output of the language model.
|
|
33
|
-
Use descriptions to make the input understandable for the language model.
|
|
146
|
+
description?: string;
|
|
147
|
+
/**
|
|
148
|
+
* An optional title of the tool.
|
|
34
149
|
*/
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
@args is the input of the tool call.
|
|
41
|
-
@options.abortSignal is a signal that can be used to abort the tool call.
|
|
150
|
+
title?: string;
|
|
151
|
+
/**
|
|
152
|
+
* Additional provider-specific metadata. They are passed through
|
|
153
|
+
* to the provider from the AI SDK and enable provider-specific
|
|
154
|
+
* functionality that can be fully encapsulated in the provider.
|
|
42
155
|
*/
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
156
|
+
providerOptions?: ProviderOptions;
|
|
157
|
+
} & ToolInputProperties<INPUT> & {
|
|
158
|
+
/**
|
|
159
|
+
* An optional list of input examples that show the language
|
|
160
|
+
* model what the input should look like.
|
|
161
|
+
*/
|
|
162
|
+
inputExamples?: Array<{
|
|
163
|
+
input: NoInfer<INPUT>;
|
|
164
|
+
}>;
|
|
165
|
+
/**
|
|
166
|
+
* Whether the tool needs approval before it can be executed.
|
|
167
|
+
*/
|
|
168
|
+
needsApproval?:
|
|
169
|
+
| boolean
|
|
170
|
+
| ToolNeedsApprovalFunctionCtx<
|
|
171
|
+
[INPUT] extends [never] ? unknown : INPUT,
|
|
172
|
+
Ctx
|
|
173
|
+
>;
|
|
174
|
+
/**
|
|
175
|
+
* Strict mode setting for the tool.
|
|
176
|
+
*
|
|
177
|
+
* Providers that support strict mode will use this setting to determine
|
|
178
|
+
* how the input should be generated. Strict mode will always produce
|
|
179
|
+
* valid inputs, but it might limit what input schemas are supported.
|
|
180
|
+
*/
|
|
181
|
+
strict?: boolean;
|
|
182
|
+
/**
|
|
183
|
+
* Provide the context to use, e.g. when defining the tool at runtime.
|
|
184
|
+
*/
|
|
185
|
+
ctx?: Ctx;
|
|
186
|
+
/**
|
|
187
|
+
* Optional function that is called when the argument streaming starts.
|
|
188
|
+
* Only called when the tool is used in a streaming context.
|
|
189
|
+
*/
|
|
190
|
+
onInputStart?: (
|
|
191
|
+
ctx: Ctx,
|
|
192
|
+
options: ToolExecutionOptions,
|
|
193
|
+
) => void | PromiseLike<void>;
|
|
194
|
+
/**
|
|
195
|
+
* Optional function that is called when an argument streaming delta is available.
|
|
196
|
+
* Only called when the tool is used in a streaming context.
|
|
197
|
+
*/
|
|
198
|
+
onInputDelta?: (
|
|
199
|
+
ctx: Ctx,
|
|
200
|
+
options: { inputTextDelta: string } & ToolExecutionOptions,
|
|
201
|
+
) => void | PromiseLike<void>;
|
|
202
|
+
/**
|
|
203
|
+
* Optional function that is called when a tool call can be started,
|
|
204
|
+
* even if the execute function is not provided.
|
|
205
|
+
*/
|
|
206
|
+
onInputAvailable?: (
|
|
207
|
+
ctx: Ctx,
|
|
208
|
+
options: {
|
|
209
|
+
input: [INPUT] extends [never] ? unknown : INPUT;
|
|
210
|
+
} & ToolExecutionOptions,
|
|
211
|
+
) => void | PromiseLike<void>;
|
|
212
|
+
} & ToolOutputPropertiesCtx<INPUT, OUTPUT, Ctx> & {
|
|
213
|
+
/**
|
|
214
|
+
* Optional conversion function that maps the tool result to an output that can be used by the language model.
|
|
215
|
+
*
|
|
216
|
+
* If not provided, the tool result will be sent as a JSON object.
|
|
217
|
+
*/
|
|
218
|
+
toModelOutput?: (
|
|
219
|
+
ctx: Ctx,
|
|
220
|
+
options: {
|
|
221
|
+
/**
|
|
222
|
+
* The ID of the tool call. You can use it e.g. when sending tool-call related information with stream data.
|
|
223
|
+
*/
|
|
224
|
+
toolCallId: string;
|
|
225
|
+
/**
|
|
226
|
+
* The input of the tool call.
|
|
227
|
+
*/
|
|
228
|
+
input: [INPUT] extends [never] ? unknown : INPUT;
|
|
229
|
+
/**
|
|
230
|
+
* The output of the tool call.
|
|
231
|
+
*/
|
|
232
|
+
output: 0 extends 1 & OUTPUT
|
|
233
|
+
? any
|
|
234
|
+
: [OUTPUT] extends [never]
|
|
235
|
+
? any
|
|
236
|
+
: NoInfer<OUTPUT>;
|
|
237
|
+
},
|
|
238
|
+
) => ToolResultOutput | PromiseLike<ToolResultOutput>;
|
|
239
|
+
},
|
|
240
|
+
): Tool<INPUT, OUTPUT> {
|
|
241
|
+
const inputSchema = def.inputSchema ?? def.args;
|
|
242
|
+
if (!inputSchema)
|
|
243
|
+
throw new Error("To use a Convex tool, you must provide an `inputSchema` (or `args`)");
|
|
244
|
+
|
|
245
|
+
if (def.args && !def.inputSchema) {
|
|
246
|
+
warnDeprecation(
|
|
247
|
+
"createTool.args",
|
|
248
|
+
"createTool: 'args' is deprecated. Use 'inputSchema' instead.",
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
if (def.handler && !def.execute) {
|
|
252
|
+
warnDeprecation(
|
|
253
|
+
"createTool.handler",
|
|
254
|
+
"createTool: 'handler' is deprecated. Use 'execute' instead.",
|
|
255
|
+
);
|
|
256
|
+
}
|
|
78
257
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
258
|
+
const executeHandler = def.execute ?? def.handler;
|
|
259
|
+
if (!executeHandler && !def.outputSchema)
|
|
260
|
+
throw new Error(
|
|
261
|
+
"To use a Convex tool, you must either provide an execute" +
|
|
262
|
+
" handler function, define an outputSchema, or both",
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
const t = tool<INPUT, OUTPUT>({
|
|
83
266
|
type: "function",
|
|
84
267
|
__acceptsCtx: true,
|
|
85
268
|
ctx: def.ctx,
|
|
86
269
|
description: def.description,
|
|
87
|
-
|
|
88
|
-
|
|
270
|
+
title: def.title,
|
|
271
|
+
providerOptions: def.providerOptions,
|
|
272
|
+
inputSchema,
|
|
273
|
+
inputExamples: def.inputExamples,
|
|
274
|
+
needsApproval(this: Tool<INPUT, OUTPUT>, input, options) {
|
|
275
|
+
const needsApproval = def.needsApproval;
|
|
276
|
+
if (!needsApproval || typeof needsApproval === "boolean")
|
|
277
|
+
return Boolean(needsApproval);
|
|
278
|
+
|
|
89
279
|
if (!getCtx(this)) {
|
|
90
280
|
throw new Error(
|
|
91
281
|
"To use a Convex tool, you must either provide the ctx" +
|
|
@@ -93,18 +283,52 @@ export function createTool<INPUT, OUTPUT, Ctx extends ToolCtx = ToolCtx>(def: {
|
|
|
93
283
|
" call it (which injects the ctx, userId and threadId)",
|
|
94
284
|
);
|
|
95
285
|
}
|
|
96
|
-
return
|
|
286
|
+
return needsApproval(getCtx(this), input, options);
|
|
97
287
|
},
|
|
98
|
-
|
|
288
|
+
strict: def.strict,
|
|
289
|
+
...(executeHandler
|
|
290
|
+
? {
|
|
291
|
+
execute(
|
|
292
|
+
this: Tool<INPUT, OUTPUT>,
|
|
293
|
+
input: INPUT,
|
|
294
|
+
options: ToolExecutionOptions,
|
|
295
|
+
) {
|
|
296
|
+
if (!getCtx(this)) {
|
|
297
|
+
throw new Error(
|
|
298
|
+
"To use a Convex tool, you must either provide the ctx" +
|
|
299
|
+
" at definition time (dynamically in an action), or use the Agent to" +
|
|
300
|
+
" call it (which injects the ctx, userId and threadId)",
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
return executeHandler(getCtx(this), input, options);
|
|
304
|
+
},
|
|
305
|
+
}
|
|
306
|
+
: {}),
|
|
307
|
+
outputSchema: def.outputSchema,
|
|
99
308
|
});
|
|
100
309
|
if (def.onInputStart) {
|
|
101
|
-
|
|
310
|
+
const origOnInputStart = def.onInputStart;
|
|
311
|
+
t.onInputStart = function (this: Tool<INPUT, OUTPUT>, options) {
|
|
312
|
+
return origOnInputStart.call(this, getCtx(this), options);
|
|
313
|
+
};
|
|
102
314
|
}
|
|
103
315
|
if (def.onInputDelta) {
|
|
104
|
-
|
|
316
|
+
const origOnInputDelta = def.onInputDelta;
|
|
317
|
+
t.onInputDelta = function (this: Tool<INPUT, OUTPUT>, options) {
|
|
318
|
+
return origOnInputDelta.call(this, getCtx(this), options);
|
|
319
|
+
};
|
|
105
320
|
}
|
|
106
321
|
if (def.onInputAvailable) {
|
|
107
|
-
|
|
322
|
+
const origOnInputAvailable = def.onInputAvailable;
|
|
323
|
+
t.onInputAvailable = function (this: Tool<INPUT, OUTPUT>, options) {
|
|
324
|
+
return origOnInputAvailable.call(this, getCtx(this), options);
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
if (def.toModelOutput) {
|
|
328
|
+
const origToModelOutput = def.toModelOutput;
|
|
329
|
+
t.toModelOutput = function (this: Tool<INPUT, OUTPUT>, options) {
|
|
330
|
+
return origToModelOutput.call(this, getCtx(this), options);
|
|
331
|
+
};
|
|
108
332
|
}
|
|
109
333
|
return t;
|
|
110
334
|
}
|
package/src/client/files.ts
CHANGED
|
@@ -92,7 +92,7 @@ export async function storeFile(
|
|
|
92
92
|
storageId: newStorageId,
|
|
93
93
|
hash,
|
|
94
94
|
filename,
|
|
95
|
-
|
|
95
|
+
mediaType: blob.type,
|
|
96
96
|
});
|
|
97
97
|
const url = (await ctx.storage.getUrl(storageId as Id<"_storage">))!;
|
|
98
98
|
if (storageId !== newStorageId) {
|
|
@@ -142,8 +142,10 @@ export async function getFile(
|
|
|
142
142
|
if (!url) {
|
|
143
143
|
throw new Error(`File not found in storage: ${file.storageId}`);
|
|
144
144
|
}
|
|
145
|
+
// Support both mediaType (preferred) and mimeType (deprecated)
|
|
146
|
+
const mediaType = file.mediaType ?? file.mimeType ?? "";
|
|
145
147
|
return {
|
|
146
|
-
...getParts(url,
|
|
148
|
+
...getParts(url, mediaType, file.filename),
|
|
147
149
|
file: {
|
|
148
150
|
fileId,
|
|
149
151
|
url,
|
package/src/client/index.test.ts
CHANGED
package/src/client/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
} from "@ai-sdk/provider-utils";
|
|
7
7
|
import type {
|
|
8
8
|
CallSettings,
|
|
9
|
+
EmbeddingModel,
|
|
9
10
|
GenerateObjectResult,
|
|
10
11
|
GenerateTextResult,
|
|
11
12
|
LanguageModel,
|
|
@@ -17,6 +18,15 @@ import type {
|
|
|
17
18
|
ToolSet,
|
|
18
19
|
} from "ai";
|
|
19
20
|
import { generateObject, generateText, stepCountIs, streamObject } from "ai";
|
|
21
|
+
|
|
22
|
+
const MIGRATION_URL = "https://github.com/get-convex/agent/blob/main/MIGRATION.md";
|
|
23
|
+
const warnedDeprecations = new Set<string>();
|
|
24
|
+
function warnDeprecation(key: string, message: string) {
|
|
25
|
+
if (!warnedDeprecations.has(key)) {
|
|
26
|
+
warnedDeprecations.add(key);
|
|
27
|
+
console.warn(`[@convex-dev/agent] ${message}\n See: ${MIGRATION_URL}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
20
30
|
import { assert, omit, pick } from "convex-helpers";
|
|
21
31
|
import {
|
|
22
32
|
internalActionGeneric,
|
|
@@ -86,6 +96,7 @@ import type {
|
|
|
86
96
|
UsageHandler,
|
|
87
97
|
QueryCtx,
|
|
88
98
|
AgentPrompt,
|
|
99
|
+
Output,
|
|
89
100
|
} from "./types.js";
|
|
90
101
|
import { streamText } from "./streamText.js";
|
|
91
102
|
import { errorToString, willContinue } from "./utils.js";
|
|
@@ -241,7 +252,22 @@ export class Agent<
|
|
|
241
252
|
| StopCondition<NoInfer<AgentTools>>
|
|
242
253
|
| Array<StopCondition<NoInfer<AgentTools>>>;
|
|
243
254
|
},
|
|
244
|
-
) {
|
|
255
|
+
) {
|
|
256
|
+
if (this.options.textEmbeddingModel && !this.options.embeddingModel) {
|
|
257
|
+
warnDeprecation(
|
|
258
|
+
"textEmbeddingModel",
|
|
259
|
+
"textEmbeddingModel is deprecated. Use embeddingModel instead.",
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Get the embedding model, prioritizing embeddingModel over textEmbeddingModel.
|
|
266
|
+
* @private
|
|
267
|
+
*/
|
|
268
|
+
private getEmbeddingModel(): EmbeddingModel | undefined {
|
|
269
|
+
return this.options.embeddingModel ?? this.options.textEmbeddingModel;
|
|
270
|
+
}
|
|
245
271
|
|
|
246
272
|
/**
|
|
247
273
|
* Start a new thread with the agent. This will have a fresh history, though if
|
|
@@ -416,9 +442,7 @@ export class Agent<
|
|
|
416
442
|
...args,
|
|
417
443
|
tools: (args.tools ?? this.options.tools) as Tools,
|
|
418
444
|
system: args.system ?? this.options.instructions,
|
|
419
|
-
stopWhen: (args.stopWhen ?? this.options.stopWhen) as
|
|
420
|
-
| StopCondition<Tools>
|
|
421
|
-
| Array<StopCondition<Tools>>,
|
|
445
|
+
stopWhen: (args.stopWhen ?? this.options.stopWhen) as any,
|
|
422
446
|
},
|
|
423
447
|
{
|
|
424
448
|
...this.options,
|
|
@@ -444,8 +468,7 @@ export class Agent<
|
|
|
444
468
|
*/
|
|
445
469
|
async generateText<
|
|
446
470
|
TOOLS extends ToolSet | undefined = undefined,
|
|
447
|
-
OUTPUT = never,
|
|
448
|
-
OUTPUT_PARTIAL = never,
|
|
471
|
+
OUTPUT extends Output<any, any, any> = never,
|
|
449
472
|
>(
|
|
450
473
|
ctx: ActionCtx & CustomCtx,
|
|
451
474
|
threadOpts: { userId?: string | null; threadId?: string },
|
|
@@ -454,7 +477,7 @@ export class Agent<
|
|
|
454
477
|
* {@link generateText} function, along with Agent prompt options.
|
|
455
478
|
*/
|
|
456
479
|
generateTextArgs: AgentPrompt &
|
|
457
|
-
TextArgs<AgentTools, TOOLS, OUTPUT
|
|
480
|
+
TextArgs<AgentTools, TOOLS, OUTPUT>,
|
|
458
481
|
options?: Options,
|
|
459
482
|
): Promise<
|
|
460
483
|
GenerateTextResult<TOOLS extends undefined ? AgentTools : TOOLS, OUTPUT> &
|
|
@@ -469,7 +492,7 @@ export class Agent<
|
|
|
469
492
|
type Tools = TOOLS extends undefined ? AgentTools : TOOLS;
|
|
470
493
|
const steps: StepResult<Tools>[] = [];
|
|
471
494
|
try {
|
|
472
|
-
const result = (await generateText<Tools, OUTPUT
|
|
495
|
+
const result = (await generateText<Tools, OUTPUT>({
|
|
473
496
|
...args,
|
|
474
497
|
prepareStep: async (options) => {
|
|
475
498
|
const result = await generateTextArgs.prepareStep?.(options);
|
|
@@ -504,8 +527,7 @@ export class Agent<
|
|
|
504
527
|
*/
|
|
505
528
|
async streamText<
|
|
506
529
|
TOOLS extends ToolSet | undefined = undefined,
|
|
507
|
-
OUTPUT = never,
|
|
508
|
-
PARTIAL_OUTPUT = never,
|
|
530
|
+
OUTPUT extends Output<any, any, any> = never,
|
|
509
531
|
>(
|
|
510
532
|
ctx: ActionCtx & CustomCtx,
|
|
511
533
|
threadOpts: { userId?: string | null; threadId?: string },
|
|
@@ -514,7 +536,7 @@ export class Agent<
|
|
|
514
536
|
* {@link streamText} function, along with Agent prompt options.
|
|
515
537
|
*/
|
|
516
538
|
streamTextArgs: AgentPrompt &
|
|
517
|
-
StreamingTextArgs<AgentTools, TOOLS, OUTPUT
|
|
539
|
+
StreamingTextArgs<AgentTools, TOOLS, OUTPUT>,
|
|
518
540
|
/**
|
|
519
541
|
* The {@link ContextOptions} and {@link StorageOptions}
|
|
520
542
|
* options to use for fetching contextual messages and saving input/output messages.
|
|
@@ -535,12 +557,12 @@ export class Agent<
|
|
|
535
557
|
): Promise<
|
|
536
558
|
StreamTextResult<
|
|
537
559
|
TOOLS extends undefined ? AgentTools : TOOLS,
|
|
538
|
-
|
|
560
|
+
OUTPUT
|
|
539
561
|
> &
|
|
540
562
|
GenerationOutputMetadata
|
|
541
563
|
> {
|
|
542
564
|
type Tools = TOOLS extends undefined ? AgentTools : TOOLS;
|
|
543
|
-
return streamText<Tools, OUTPUT
|
|
565
|
+
return streamText<Tools, OUTPUT>(
|
|
544
566
|
ctx,
|
|
545
567
|
this.component,
|
|
546
568
|
{
|
|
@@ -548,9 +570,7 @@ export class Agent<
|
|
|
548
570
|
model: streamTextArgs.model ?? this.options.languageModel,
|
|
549
571
|
tools: (streamTextArgs.tools ?? this.options.tools) as Tools,
|
|
550
572
|
system: streamTextArgs.system ?? this.options.instructions,
|
|
551
|
-
stopWhen: (streamTextArgs.stopWhen ?? this.options.stopWhen) as
|
|
552
|
-
| StopCondition<Tools>
|
|
553
|
-
| Array<StopCondition<Tools>>,
|
|
573
|
+
stopWhen: (streamTextArgs.stopWhen ?? this.options.stopWhen) as any,
|
|
554
574
|
},
|
|
555
575
|
{
|
|
556
576
|
...threadOpts,
|
|
@@ -746,7 +766,7 @@ export class Agent<
|
|
|
746
766
|
const { skipEmbeddings, ...rest } = args;
|
|
747
767
|
if (args.embeddings) {
|
|
748
768
|
embeddings = args.embeddings;
|
|
749
|
-
} else if (!skipEmbeddings && this.
|
|
769
|
+
} else if (!skipEmbeddings && this.getEmbeddingModel()) {
|
|
750
770
|
if (!("runAction" in ctx)) {
|
|
751
771
|
console.warn(
|
|
752
772
|
"You're trying to save messages and generate embeddings, but you're in a mutation. " +
|
|
@@ -862,9 +882,10 @@ export class Agent<
|
|
|
862
882
|
contextOptions,
|
|
863
883
|
getEmbedding: async (text) => {
|
|
864
884
|
assert("runAction" in ctx);
|
|
885
|
+
const embeddingModel = this.getEmbeddingModel();
|
|
865
886
|
assert(
|
|
866
|
-
|
|
867
|
-
"
|
|
887
|
+
embeddingModel,
|
|
888
|
+
"An embeddingModel (or textEmbeddingModel) is required to be set on the Agent that you're doing vector search with",
|
|
868
889
|
);
|
|
869
890
|
return {
|
|
870
891
|
embedding: (
|
|
@@ -876,7 +897,7 @@ export class Agent<
|
|
|
876
897
|
values: [text],
|
|
877
898
|
})
|
|
878
899
|
).embeddings[0],
|
|
879
|
-
|
|
900
|
+
embeddingModel: embeddingModel,
|
|
880
901
|
};
|
|
881
902
|
},
|
|
882
903
|
});
|
|
@@ -975,10 +996,10 @@ export class Agent<
|
|
|
975
996
|
.join(", "),
|
|
976
997
|
);
|
|
977
998
|
}
|
|
978
|
-
const
|
|
979
|
-
if (!
|
|
999
|
+
const embeddingModel = this.getEmbeddingModel();
|
|
1000
|
+
if (!embeddingModel) {
|
|
980
1001
|
throw new Error(
|
|
981
|
-
"No embeddings were generated for the messages. You must pass
|
|
1002
|
+
"No embeddings were generated for the messages. You must pass an embeddingModel (or textEmbeddingModel) to the agent constructor.",
|
|
982
1003
|
);
|
|
983
1004
|
}
|
|
984
1005
|
await generateAndSaveEmbeddings(
|
|
@@ -989,7 +1010,7 @@ export class Agent<
|
|
|
989
1010
|
agentName: this.options.name,
|
|
990
1011
|
threadId: messages[0].threadId,
|
|
991
1012
|
userId: messages[0].userId,
|
|
992
|
-
|
|
1013
|
+
embeddingModel,
|
|
993
1014
|
},
|
|
994
1015
|
messages,
|
|
995
1016
|
);
|
|
@@ -1440,7 +1461,7 @@ export class Agent<
|
|
|
1440
1461
|
} as GenerateObjectArgs<FlexibleSchema<T>>;
|
|
1441
1462
|
const ctx = (
|
|
1442
1463
|
options?.customCtx
|
|
1443
|
-
? { ...ctx_, ...options.customCtx(ctx_, targetArgs, llmArgs) }
|
|
1464
|
+
? { ...ctx_, ...options.customCtx(ctx_, targetArgs, llmArgs as any) }
|
|
1444
1465
|
: ctx_
|
|
1445
1466
|
) as GenericActionCtx<GenericDataModel> & CustomCtx;
|
|
1446
1467
|
const value = await this.generateObject(ctx, targetArgs, llmArgs, {
|