@convex-dev/agent 0.6.4 → 0.7.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/MIGRATION.md +60 -116
- package/dist/client/messages.d.ts +1 -398
- package/dist/client/messages.d.ts.map +1 -1
- package/dist/client/messages.js +3 -47
- package/dist/client/messages.js.map +1 -1
- package/dist/client/types.d.ts +1 -455
- package/dist/client/types.d.ts.map +1 -1
- package/dist/component/_generated/component.d.ts +805 -45
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/messages.d.ts +1252 -201
- package/dist/component/messages.d.ts.map +1 -1
- package/dist/component/messages.js +49 -23
- package/dist/component/messages.js.map +1 -1
- package/dist/component/schema.d.ts +2593 -332
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/streams.d.ts +7 -1
- package/dist/component/streams.d.ts.map +1 -1
- package/dist/component/streams.js +24 -30
- package/dist/component/streams.js.map +1 -1
- package/dist/component/threads.d.ts.map +1 -1
- package/dist/component/threads.js +1 -2
- package/dist/component/threads.js.map +1 -1
- package/dist/react/index.d.ts +5 -5
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +5 -5
- package/dist/react/index.js.map +1 -1
- package/dist/shared.d.ts +19 -7
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +4 -4
- package/dist/shared.js.map +1 -1
- package/dist/streaming/materializePersistedUIMessageChunks.d.ts +16 -0
- package/dist/streaming/materializePersistedUIMessageChunks.d.ts.map +1 -0
- package/dist/streaming/materializePersistedUIMessageChunks.js +302 -0
- package/dist/streaming/materializePersistedUIMessageChunks.js.map +1 -0
- package/dist/streaming/persistedUIMessageChunks.d.ts +106 -0
- package/dist/streaming/persistedUIMessageChunks.d.ts.map +1 -0
- package/dist/streaming/persistedUIMessageChunks.js +475 -0
- package/dist/streaming/persistedUIMessageChunks.js.map +1 -0
- package/dist/validators.d.ts +10026 -1055
- package/dist/validators.d.ts.map +1 -1
- package/dist/validators.js +71 -9
- package/dist/validators.js.map +1 -1
- package/dist/{UIMessages.d.ts → vercel/UIMessages.d.ts} +1 -1
- package/dist/vercel/UIMessages.d.ts.map +1 -0
- package/dist/{UIMessages.js → vercel/UIMessages.js} +63 -1
- package/dist/vercel/UIMessages.js.map +1 -0
- package/dist/{client → vercel/client}/createTool.d.ts +23 -16
- package/dist/vercel/client/createTool.d.ts.map +1 -0
- package/dist/{client → vercel/client}/createTool.js +2 -0
- package/dist/vercel/client/createTool.js.map +1 -0
- package/dist/{client → vercel/client}/definePlaygroundAPI.d.ts +533 -79
- package/dist/{client → vercel/client}/definePlaygroundAPI.d.ts.map +1 -1
- package/dist/{client → vercel/client}/definePlaygroundAPI.js +8 -7
- package/dist/vercel/client/definePlaygroundAPI.js.map +1 -0
- package/dist/{client → vercel/client}/files.d.ts +2 -2
- package/dist/vercel/client/files.d.ts.map +1 -0
- package/dist/vercel/client/files.js.map +1 -0
- package/dist/vercel/client/messages.d.ts +542 -0
- package/dist/vercel/client/messages.d.ts.map +1 -0
- package/dist/vercel/client/messages.js +66 -0
- package/dist/vercel/client/messages.js.map +1 -0
- package/dist/{client → vercel/client}/mockModel.d.ts +17 -17
- package/dist/vercel/client/mockModel.d.ts.map +1 -0
- package/dist/{client → vercel/client}/mockModel.js +12 -13
- package/dist/vercel/client/mockModel.js.map +1 -0
- package/dist/{client → vercel/client}/saveInputMessages.d.ts +2 -2
- package/dist/vercel/client/saveInputMessages.d.ts.map +1 -0
- package/dist/vercel/client/saveInputMessages.js.map +1 -0
- package/dist/{client → vercel/client}/search.d.ts +119 -22
- package/dist/vercel/client/search.d.ts.map +1 -0
- package/dist/{client → vercel/client}/search.js +2 -2
- package/dist/vercel/client/search.js.map +1 -0
- package/dist/{client → vercel/client}/start.d.ts +26 -11
- package/dist/vercel/client/start.d.ts.map +1 -0
- package/dist/{client → vercel/client}/start.js +64 -22
- package/dist/vercel/client/start.js.map +1 -0
- package/dist/{client → vercel/client}/streamText.d.ts +13 -12
- package/dist/vercel/client/streamText.d.ts.map +1 -0
- package/dist/{client → vercel/client}/streamText.js +43 -9
- package/dist/vercel/client/streamText.js.map +1 -0
- package/dist/{client → vercel/client}/streaming.d.ts +1410 -183
- package/dist/vercel/client/streaming.d.ts.map +1 -0
- package/dist/{client → vercel/client}/streaming.js +120 -52
- package/dist/vercel/client/streaming.js.map +1 -0
- package/dist/vercel/client/types.d.ts +456 -0
- package/dist/vercel/client/types.d.ts.map +1 -0
- package/dist/vercel/client/types.js +3 -0
- package/dist/vercel/client/types.js.map +1 -0
- package/dist/{client → vercel/client}/utils.d.ts +3 -2
- package/dist/vercel/client/utils.d.ts.map +1 -0
- package/dist/{client → vercel/client}/utils.js +2 -2
- package/dist/vercel/client/utils.js.map +1 -0
- package/dist/{deltas.d.ts → vercel/deltas.d.ts} +3 -4
- package/dist/vercel/deltas.d.ts.map +1 -0
- package/dist/{deltas.js → vercel/deltas.js} +195 -99
- package/dist/vercel/deltas.js.map +1 -0
- package/dist/{client → vercel}/index.d.ts +482 -106
- package/dist/vercel/index.d.ts.map +1 -0
- package/dist/{client → vercel}/index.js +64 -46
- package/dist/vercel/index.js.map +1 -0
- package/dist/{mapping.d.ts → vercel/mapping.d.ts} +5 -19
- package/dist/vercel/mapping.d.ts.map +1 -0
- package/dist/{mapping.js → vercel/mapping.js} +411 -114
- package/dist/vercel/mapping.js.map +1 -0
- package/dist/{react → vercel/react}/optimisticallySendMessage.d.ts +2 -2
- package/dist/vercel/react/optimisticallySendMessage.d.ts.map +1 -0
- package/dist/vercel/react/optimisticallySendMessage.js.map +1 -0
- package/dist/{react → vercel/react}/types.d.ts +1 -1
- package/dist/vercel/react/types.d.ts.map +1 -0
- package/dist/{react → vercel/react}/types.js.map +1 -1
- package/dist/{react → vercel/react}/useDeltaStreams.d.ts +1 -1
- package/dist/vercel/react/useDeltaStreams.d.ts.map +1 -0
- package/dist/{react → vercel/react}/useDeltaStreams.js +1 -1
- package/dist/vercel/react/useDeltaStreams.js.map +1 -0
- package/dist/{react → vercel/react}/useStreamingUIMessages.d.ts +1 -1
- package/dist/vercel/react/useStreamingUIMessages.d.ts.map +1 -0
- package/dist/{react → vercel/react}/useStreamingUIMessages.js +7 -3
- package/dist/vercel/react/useStreamingUIMessages.js.map +1 -0
- package/dist/{react → vercel/react}/useThreadMessages.d.ts +1 -1
- package/dist/vercel/react/useThreadMessages.d.ts.map +1 -0
- package/dist/{react → vercel/react}/useThreadMessages.js +1 -1
- package/dist/vercel/react/useThreadMessages.js.map +1 -0
- package/dist/{react → vercel/react}/useUIMessages.d.ts +1 -1
- package/dist/vercel/react/useUIMessages.d.ts.map +1 -0
- package/dist/{react → vercel/react}/useUIMessages.js +1 -1
- package/dist/vercel/react/useUIMessages.js.map +1 -0
- package/package.json +31 -24
- package/src/client/messages.ts +5 -107
- package/src/client/types.ts +0 -608
- package/src/component/_generated/component.ts +1089 -48
- package/src/component/messages.test.ts +273 -1
- package/src/component/messages.ts +62 -32
- package/src/component/streams.ts +47 -47
- package/src/component/threads.ts +5 -2
- package/src/eslintConfig.test.ts +44 -0
- package/src/react/index.ts +8 -5
- package/src/shared.ts +26 -36
- package/src/streaming/materializePersistedUIMessageChunks.test.ts +513 -0
- package/src/streaming/materializePersistedUIMessageChunks.ts +398 -0
- package/src/streaming/persistedUIMessageChunks.test.ts +205 -0
- package/src/streaming/persistedUIMessageChunks.ts +658 -0
- package/src/validators.test.ts +4 -1
- package/src/validators.ts +89 -8
- package/src/{UIMessages.combineUIMessages.test.ts → vercel/UIMessages.combineUIMessages.test.ts} +4 -1
- package/src/{UIMessages.ts → vercel/UIMessages.ts} +95 -3
- package/src/{client → vercel/client}/approval.test.ts +23 -13
- package/src/{client → vercel/client}/createTool.ts +62 -22
- package/src/{client → vercel/client}/definePlaygroundAPI.ts +15 -16
- package/src/{client → vercel/client}/files.ts +2 -2
- package/src/{client → vercel/client}/index.test.ts +99 -31
- package/src/vercel/client/messages.ts +182 -0
- package/src/{client → vercel/client}/mockModel.ts +38 -39
- package/src/{client → vercel/client}/saveInputMessages.test.ts +1 -1
- package/src/{client → vercel/client}/saveInputMessages.ts +3 -3
- package/src/{client → vercel/client}/search.test.ts +3 -3
- package/src/{client → vercel/client}/search.ts +4 -4
- package/src/{client → vercel/client}/setup.test.ts +6 -3
- package/src/vercel/client/start.test.ts +14 -0
- package/src/{client → vercel/client}/start.ts +147 -36
- package/src/vercel/client/streamText.test.ts +223 -0
- package/src/{client → vercel/client}/streamText.ts +102 -31
- package/src/{client → vercel/client}/streaming.integration.test.ts +6 -3
- package/src/{client → vercel/client}/streaming.test.ts +178 -4
- package/src/{client → vercel/client}/streaming.ts +114 -52
- package/src/vercel/client/types.test.ts +13 -0
- package/src/vercel/client/types.ts +679 -0
- package/src/{client → vercel/client}/utils.ts +13 -7
- package/src/{deltas.test.ts → vercel/deltas.test.ts} +384 -93
- package/src/{deltas.ts → vercel/deltas.ts} +218 -115
- package/src/{fromUIMessages.test.ts → vercel/fromUIMessages.test.ts} +17 -1
- package/src/{client → vercel}/index.ts +167 -84
- package/src/{mapping.test.ts → vercel/mapping.test.ts} +377 -92
- package/src/{mapping.ts → vercel/mapping.ts} +501 -137
- package/src/{react → vercel/react}/optimisticallySendMessage.ts +2 -2
- package/src/{react → vercel/react}/types.ts +1 -1
- package/src/{react → vercel/react}/useDeltaStreams.ts +6 -2
- package/src/{react → vercel/react}/useStreamingUIMessages.ts +7 -3
- package/src/{react → vercel/react}/useThreadMessages.ts +2 -2
- package/src/{react → vercel/react}/useUIMessages.ts +2 -2
- package/src/{toUIMessages.test.ts → vercel/toUIMessages.test.ts} +49 -2
- package/dist/UIMessages.d.ts.map +0 -1
- package/dist/UIMessages.js.map +0 -1
- package/dist/client/createTool.d.ts.map +0 -1
- package/dist/client/createTool.js.map +0 -1
- package/dist/client/definePlaygroundAPI.js.map +0 -1
- package/dist/client/files.d.ts.map +0 -1
- package/dist/client/files.js.map +0 -1
- package/dist/client/index.d.ts.map +0 -1
- package/dist/client/index.js.map +0 -1
- package/dist/client/mockModel.d.ts.map +0 -1
- package/dist/client/mockModel.js.map +0 -1
- package/dist/client/saveInputMessages.d.ts.map +0 -1
- package/dist/client/saveInputMessages.js.map +0 -1
- package/dist/client/search.d.ts.map +0 -1
- package/dist/client/search.js.map +0 -1
- package/dist/client/start.d.ts.map +0 -1
- package/dist/client/start.js.map +0 -1
- package/dist/client/streamText.d.ts.map +0 -1
- package/dist/client/streamText.js.map +0 -1
- package/dist/client/streaming.d.ts.map +0 -1
- package/dist/client/streaming.js.map +0 -1
- package/dist/client/utils.d.ts.map +0 -1
- package/dist/client/utils.js.map +0 -1
- package/dist/deltas.d.ts.map +0 -1
- package/dist/deltas.js.map +0 -1
- package/dist/mapping.d.ts.map +0 -1
- package/dist/mapping.js.map +0 -1
- package/dist/react/optimisticallySendMessage.d.ts.map +0 -1
- package/dist/react/optimisticallySendMessage.js.map +0 -1
- package/dist/react/types.d.ts.map +0 -1
- package/dist/react/useDeltaStreams.d.ts.map +0 -1
- package/dist/react/useDeltaStreams.js.map +0 -1
- package/dist/react/useStreamingUIMessages.d.ts.map +0 -1
- package/dist/react/useStreamingUIMessages.js.map +0 -1
- package/dist/react/useThreadMessages.d.ts.map +0 -1
- package/dist/react/useThreadMessages.js.map +0 -1
- package/dist/react/useUIMessages.d.ts.map +0 -1
- package/dist/react/useUIMessages.js.map +0 -1
- package/src/client/streamText.test.ts +0 -102
- /package/dist/{client → vercel/client}/files.js +0 -0
- /package/dist/{client → vercel/client}/saveInputMessages.js +0 -0
- /package/dist/{react → vercel/react}/optimisticallySendMessage.js +0 -0
- /package/dist/{react → vercel/react}/types.js +0 -0
- /package/src/{UIMessages.test.ts → vercel/UIMessages.test.ts} +0 -0
- /package/src/{react → vercel/react}/useUIMessages.test.ts +0 -0
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { JSONObject } from "@ai-sdk/provider";
|
|
2
|
+
import type {
|
|
3
|
+
Context,
|
|
4
|
+
Experimental_SandboxSession,
|
|
5
|
+
ToolResultOutput,
|
|
6
|
+
} from "@ai-sdk/provider-utils";
|
|
2
7
|
import type {
|
|
3
8
|
FlexibleSchema,
|
|
4
9
|
ModelMessage,
|
|
@@ -8,8 +13,8 @@ import type {
|
|
|
8
13
|
} from "ai";
|
|
9
14
|
import { tool } from "ai";
|
|
10
15
|
import type { GenericActionCtx, GenericDataModel } from "convex/server";
|
|
11
|
-
import type { ProviderOptions } from "
|
|
12
|
-
import type { Agent } from "
|
|
16
|
+
import type { ProviderOptions } from "../../validators.js";
|
|
17
|
+
import type { Agent } from "../index.js";
|
|
13
18
|
|
|
14
19
|
const MIGRATION_URL = "node_modules/@convex-dev/agent/MIGRATION.md";
|
|
15
20
|
const warnedDeprecations = new Set<string>();
|
|
@@ -28,12 +33,16 @@ export type ToolCtx<DataModel extends GenericDataModel = GenericDataModel> =
|
|
|
28
33
|
messageId?: string;
|
|
29
34
|
};
|
|
30
35
|
|
|
36
|
+
export type AgentToolExecutionOptions<TOOL_CONTEXT extends Context = Context> =
|
|
37
|
+
ToolExecutionOptions<TOOL_CONTEXT>;
|
|
38
|
+
|
|
31
39
|
/**
|
|
32
40
|
* Function that is called to determine if the tool needs approval before it can be executed.
|
|
33
41
|
*/
|
|
34
42
|
export type ToolNeedsApprovalFunctionCtx<
|
|
35
43
|
INPUT,
|
|
36
44
|
Ctx extends ToolCtx = ToolCtx,
|
|
45
|
+
TOOL_CONTEXT extends Context = Context,
|
|
37
46
|
> = (
|
|
38
47
|
ctx: Ctx,
|
|
39
48
|
input: INPUT,
|
|
@@ -52,7 +61,7 @@ export type ToolNeedsApprovalFunctionCtx<
|
|
|
52
61
|
*
|
|
53
62
|
* Experimental (can break in patch releases).
|
|
54
63
|
*/
|
|
55
|
-
|
|
64
|
+
context: TOOL_CONTEXT;
|
|
56
65
|
},
|
|
57
66
|
) => boolean | PromiseLike<boolean>;
|
|
58
67
|
|
|
@@ -60,10 +69,11 @@ export type ToolExecuteFunctionCtx<
|
|
|
60
69
|
INPUT,
|
|
61
70
|
OUTPUT,
|
|
62
71
|
Ctx extends ToolCtx = ToolCtx,
|
|
72
|
+
TOOL_CONTEXT extends Context = Context,
|
|
63
73
|
> = (
|
|
64
74
|
ctx: Ctx,
|
|
65
75
|
input: INPUT,
|
|
66
|
-
options:
|
|
76
|
+
options: AgentToolExecutionOptions<TOOL_CONTEXT>,
|
|
67
77
|
) => AsyncIterable<OUTPUT> | PromiseLike<OUTPUT>;
|
|
68
78
|
|
|
69
79
|
type NeverOptional<N, T> = 0 extends 1 & N
|
|
@@ -83,6 +93,7 @@ export type ToolOutputPropertiesCtx<
|
|
|
83
93
|
INPUT,
|
|
84
94
|
OUTPUT,
|
|
85
95
|
Ctx extends ToolCtx = ToolCtx,
|
|
96
|
+
TOOL_CONTEXT extends Context = Context,
|
|
86
97
|
> = NeverOptional<
|
|
87
98
|
OUTPUT,
|
|
88
99
|
{
|
|
@@ -93,7 +104,7 @@ export type ToolOutputPropertiesCtx<
|
|
|
93
104
|
* @param input - The input of the tool call.
|
|
94
105
|
* @param options.abortSignal - A signal that can be used to abort the tool call.
|
|
95
106
|
*/
|
|
96
|
-
execute?: ToolExecuteFunctionCtx<INPUT, OUTPUT, Ctx>;
|
|
107
|
+
execute?: ToolExecuteFunctionCtx<INPUT, OUTPUT, Ctx, TOOL_CONTEXT>;
|
|
97
108
|
outputSchema?: FlexibleSchema<OUTPUT>;
|
|
98
109
|
/**
|
|
99
110
|
* @deprecated Removed in v0.6.0. Use `execute` instead.
|
|
@@ -133,14 +144,24 @@ export type ToolInputProperties<INPUT> = {
|
|
|
133
144
|
*
|
|
134
145
|
* @returns A tool to be used with the AI SDK.
|
|
135
146
|
*/
|
|
136
|
-
export function createTool<
|
|
147
|
+
export function createTool<
|
|
148
|
+
INPUT,
|
|
149
|
+
OUTPUT,
|
|
150
|
+
Ctx extends ToolCtx = ToolCtx,
|
|
151
|
+
TOOL_CONTEXT extends Context = Context,
|
|
152
|
+
>(
|
|
137
153
|
def: {
|
|
138
154
|
/**
|
|
139
155
|
* An optional description of what the tool does.
|
|
140
156
|
* Will be used by the language model to decide whether to use the tool.
|
|
141
157
|
* Not used for provider-defined tools.
|
|
142
158
|
*/
|
|
143
|
-
description?:
|
|
159
|
+
description?:
|
|
160
|
+
| string
|
|
161
|
+
| ((options: {
|
|
162
|
+
context: NoInfer<TOOL_CONTEXT>;
|
|
163
|
+
experimental_sandbox?: Experimental_SandboxSession;
|
|
164
|
+
}) => string);
|
|
144
165
|
/**
|
|
145
166
|
* An optional title of the tool.
|
|
146
167
|
*/
|
|
@@ -151,6 +172,8 @@ export function createTool<INPUT, OUTPUT, Ctx extends ToolCtx = ToolCtx>(
|
|
|
151
172
|
* functionality that can be fully encapsulated in the provider.
|
|
152
173
|
*/
|
|
153
174
|
providerOptions?: ProviderOptions;
|
|
175
|
+
metadata?: JSONObject;
|
|
176
|
+
contextSchema?: FlexibleSchema<TOOL_CONTEXT>;
|
|
154
177
|
} & ToolInputProperties<INPUT> & {
|
|
155
178
|
/**
|
|
156
179
|
* An optional list of input examples that show the language
|
|
@@ -166,7 +189,8 @@ export function createTool<INPUT, OUTPUT, Ctx extends ToolCtx = ToolCtx>(
|
|
|
166
189
|
| boolean
|
|
167
190
|
| ToolNeedsApprovalFunctionCtx<
|
|
168
191
|
[INPUT] extends [never] ? unknown : INPUT,
|
|
169
|
-
Ctx
|
|
192
|
+
Ctx,
|
|
193
|
+
TOOL_CONTEXT
|
|
170
194
|
>;
|
|
171
195
|
/**
|
|
172
196
|
* Strict mode setting for the tool.
|
|
@@ -186,7 +210,7 @@ export function createTool<INPUT, OUTPUT, Ctx extends ToolCtx = ToolCtx>(
|
|
|
186
210
|
*/
|
|
187
211
|
onInputStart?: (
|
|
188
212
|
ctx: Ctx,
|
|
189
|
-
options:
|
|
213
|
+
options: AgentToolExecutionOptions<TOOL_CONTEXT>,
|
|
190
214
|
) => void | PromiseLike<void>;
|
|
191
215
|
/**
|
|
192
216
|
* Optional function that is called when an argument streaming delta is available.
|
|
@@ -194,7 +218,9 @@ export function createTool<INPUT, OUTPUT, Ctx extends ToolCtx = ToolCtx>(
|
|
|
194
218
|
*/
|
|
195
219
|
onInputDelta?: (
|
|
196
220
|
ctx: Ctx,
|
|
197
|
-
options: {
|
|
221
|
+
options: {
|
|
222
|
+
inputTextDelta: string;
|
|
223
|
+
} & AgentToolExecutionOptions<TOOL_CONTEXT>,
|
|
198
224
|
) => void | PromiseLike<void>;
|
|
199
225
|
/**
|
|
200
226
|
* Optional function that is called when a tool call can be started,
|
|
@@ -204,9 +230,9 @@ export function createTool<INPUT, OUTPUT, Ctx extends ToolCtx = ToolCtx>(
|
|
|
204
230
|
ctx: Ctx,
|
|
205
231
|
options: {
|
|
206
232
|
input: [INPUT] extends [never] ? unknown : INPUT;
|
|
207
|
-
} &
|
|
233
|
+
} & AgentToolExecutionOptions<TOOL_CONTEXT>,
|
|
208
234
|
) => void | PromiseLike<void>;
|
|
209
|
-
} & ToolOutputPropertiesCtx<INPUT, OUTPUT, Ctx> & {
|
|
235
|
+
} & ToolOutputPropertiesCtx<INPUT, OUTPUT, Ctx, TOOL_CONTEXT> & {
|
|
210
236
|
/**
|
|
211
237
|
* Optional conversion function that maps the tool result to an output that can be used by the language model.
|
|
212
238
|
*
|
|
@@ -234,7 +260,7 @@ export function createTool<INPUT, OUTPUT, Ctx extends ToolCtx = ToolCtx>(
|
|
|
234
260
|
},
|
|
235
261
|
) => ToolResultOutput | PromiseLike<ToolResultOutput>;
|
|
236
262
|
},
|
|
237
|
-
): Tool<INPUT, OUTPUT> {
|
|
263
|
+
): Tool<INPUT, OUTPUT, TOOL_CONTEXT> {
|
|
238
264
|
// Runtime backwards compat - types will show errors but runtime still works
|
|
239
265
|
const inputSchema = def.inputSchema ?? (def as any).args;
|
|
240
266
|
if (!inputSchema)
|
|
@@ -260,16 +286,18 @@ export function createTool<INPUT, OUTPUT, Ctx extends ToolCtx = ToolCtx>(
|
|
|
260
286
|
" handler function, define an outputSchema, or both",
|
|
261
287
|
);
|
|
262
288
|
|
|
263
|
-
const t = tool<INPUT, OUTPUT>({
|
|
289
|
+
const t = tool<INPUT, OUTPUT, TOOL_CONTEXT>({
|
|
264
290
|
type: "function",
|
|
265
291
|
__acceptsCtx: true,
|
|
266
292
|
ctx: def.ctx,
|
|
267
293
|
description: def.description,
|
|
268
294
|
title: def.title,
|
|
269
295
|
providerOptions: def.providerOptions,
|
|
296
|
+
metadata: def.metadata,
|
|
270
297
|
inputSchema,
|
|
298
|
+
contextSchema: def.contextSchema,
|
|
271
299
|
inputExamples: def.inputExamples,
|
|
272
|
-
needsApproval(this: Tool<INPUT, OUTPUT>, input, options) {
|
|
300
|
+
needsApproval(this: Tool<INPUT, OUTPUT, TOOL_CONTEXT>, input, options) {
|
|
273
301
|
const needsApproval = def.needsApproval;
|
|
274
302
|
if (!needsApproval || typeof needsApproval === "boolean")
|
|
275
303
|
return Boolean(needsApproval);
|
|
@@ -287,9 +315,9 @@ export function createTool<INPUT, OUTPUT, Ctx extends ToolCtx = ToolCtx>(
|
|
|
287
315
|
...(executeHandler
|
|
288
316
|
? {
|
|
289
317
|
execute(
|
|
290
|
-
this: Tool<INPUT, OUTPUT>,
|
|
318
|
+
this: Tool<INPUT, OUTPUT, TOOL_CONTEXT>,
|
|
291
319
|
input: INPUT,
|
|
292
|
-
options: ToolExecutionOptions
|
|
320
|
+
options: ToolExecutionOptions<TOOL_CONTEXT>,
|
|
293
321
|
) {
|
|
294
322
|
if (!getCtx(this)) {
|
|
295
323
|
throw new Error(
|
|
@@ -306,25 +334,37 @@ export function createTool<INPUT, OUTPUT, Ctx extends ToolCtx = ToolCtx>(
|
|
|
306
334
|
});
|
|
307
335
|
if (def.onInputStart) {
|
|
308
336
|
const origOnInputStart = def.onInputStart;
|
|
309
|
-
t.onInputStart = function (
|
|
337
|
+
t.onInputStart = function (
|
|
338
|
+
this: Tool<INPUT, OUTPUT, TOOL_CONTEXT>,
|
|
339
|
+
options,
|
|
340
|
+
) {
|
|
310
341
|
return origOnInputStart.call(this, getCtx(this), options);
|
|
311
342
|
};
|
|
312
343
|
}
|
|
313
344
|
if (def.onInputDelta) {
|
|
314
345
|
const origOnInputDelta = def.onInputDelta;
|
|
315
|
-
t.onInputDelta = function (
|
|
346
|
+
t.onInputDelta = function (
|
|
347
|
+
this: Tool<INPUT, OUTPUT, TOOL_CONTEXT>,
|
|
348
|
+
options,
|
|
349
|
+
) {
|
|
316
350
|
return origOnInputDelta.call(this, getCtx(this), options);
|
|
317
351
|
};
|
|
318
352
|
}
|
|
319
353
|
if (def.onInputAvailable) {
|
|
320
354
|
const origOnInputAvailable = def.onInputAvailable;
|
|
321
|
-
t.onInputAvailable = function (
|
|
355
|
+
t.onInputAvailable = function (
|
|
356
|
+
this: Tool<INPUT, OUTPUT, TOOL_CONTEXT>,
|
|
357
|
+
options,
|
|
358
|
+
) {
|
|
322
359
|
return origOnInputAvailable.call(this, getCtx(this), options);
|
|
323
360
|
};
|
|
324
361
|
}
|
|
325
362
|
if (def.toModelOutput) {
|
|
326
363
|
const origToModelOutput = def.toModelOutput;
|
|
327
|
-
t.toModelOutput = function (
|
|
364
|
+
t.toModelOutput = function (
|
|
365
|
+
this: Tool<INPUT, OUTPUT, TOOL_CONTEXT>,
|
|
366
|
+
options,
|
|
367
|
+
) {
|
|
328
368
|
return origToModelOutput.call(this, getCtx(this), options);
|
|
329
369
|
};
|
|
330
370
|
}
|
|
@@ -11,26 +11,27 @@ import {
|
|
|
11
11
|
} from "convex/server";
|
|
12
12
|
import { v } from "convex/values";
|
|
13
13
|
import {
|
|
14
|
-
createThread as createThread_,
|
|
15
|
-
listMessages as listMessages_,
|
|
16
|
-
toModelMessage,
|
|
17
14
|
vContextOptions,
|
|
18
15
|
vMessage,
|
|
19
16
|
vMessageDoc,
|
|
20
17
|
vPaginationResult,
|
|
21
18
|
vStorageOptions,
|
|
22
19
|
vThreadDoc,
|
|
23
|
-
type Agent,
|
|
24
|
-
type AgentComponent,
|
|
25
20
|
vStreamArgs,
|
|
26
|
-
syncStreams,
|
|
27
|
-
vStreamMessagesReturnValue,
|
|
28
|
-
isTool,
|
|
29
|
-
extractText,
|
|
30
21
|
type MessageDoc,
|
|
31
|
-
} from "
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
22
|
+
} from "../../validators.js";
|
|
23
|
+
import { createThread as createThread_ } from "../../client/threads.js";
|
|
24
|
+
import {
|
|
25
|
+
extractText,
|
|
26
|
+
getModelName,
|
|
27
|
+
getProviderName,
|
|
28
|
+
isTool,
|
|
29
|
+
} from "../../shared.js";
|
|
30
|
+
import { serializeResponseMessages, toModelMessage } from "../mapping.js";
|
|
31
|
+
import type { Agent } from "../index.js";
|
|
32
|
+
import { listMessages as listMessages_ } from "./messages.js";
|
|
33
|
+
import { syncStreams, vStreamMessagesReturnValue } from "./streaming.js";
|
|
34
|
+
import type { AgentComponent } from "./types.js";
|
|
34
35
|
|
|
35
36
|
export type PlaygroundAPI = ApiFromModules<{
|
|
36
37
|
playground: ReturnType<typeof definePlaygroundAPI>;
|
|
@@ -281,9 +282,8 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
281
282
|
{ contextOptions, storageOptions, saveStreamDeltas: true },
|
|
282
283
|
);
|
|
283
284
|
const outputMessages: MessageDoc[][] = [];
|
|
284
|
-
let previousResponseMessageCount = 0;
|
|
285
285
|
for (const step of await steps) {
|
|
286
|
-
const { messages } = await
|
|
286
|
+
const { messages } = await serializeResponseMessages(
|
|
287
287
|
ctx,
|
|
288
288
|
component,
|
|
289
289
|
step,
|
|
@@ -291,9 +291,8 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
291
291
|
model: getModelName(agent.options.languageModel),
|
|
292
292
|
provider: getProviderName(agent.options.languageModel),
|
|
293
293
|
},
|
|
294
|
-
|
|
294
|
+
step.response.messages,
|
|
295
295
|
);
|
|
296
|
-
previousResponseMessageCount = step.response.messages.length;
|
|
297
296
|
outputMessages.push(
|
|
298
297
|
messages.map((messageWithMetadata, i) => {
|
|
299
298
|
return {
|
|
@@ -5,14 +5,14 @@ import type {
|
|
|
5
5
|
ModelMessage,
|
|
6
6
|
UserContent,
|
|
7
7
|
} from "ai";
|
|
8
|
-
import type { Id } from "
|
|
8
|
+
import type { Id } from "../../component/_generated/dataModel.js";
|
|
9
9
|
import type {
|
|
10
10
|
ActionCtx,
|
|
11
11
|
AgentComponent,
|
|
12
12
|
MutationCtx,
|
|
13
13
|
QueryCtx,
|
|
14
14
|
} from "./types.js";
|
|
15
|
-
import type { Message } from "
|
|
15
|
+
import type { Message } from "../../validators.js";
|
|
16
16
|
import { assert } from "convex-helpers";
|
|
17
17
|
import type { StorageReader } from "convex/server";
|
|
18
18
|
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
createTool,
|
|
6
6
|
filterOutOrphanedToolMessages,
|
|
7
7
|
type MessageDoc,
|
|
8
|
-
} from "
|
|
8
|
+
} from "../index.js";
|
|
9
9
|
import type { DataModelFromSchemaDefinition } from "convex/server";
|
|
10
10
|
import {
|
|
11
11
|
anyApi,
|
|
@@ -24,7 +24,7 @@ import { defineSchema } from "convex/server";
|
|
|
24
24
|
import { stepCountIs } from "ai";
|
|
25
25
|
import { components, initConvexTest } from "./setup.test.js";
|
|
26
26
|
import { z } from "zod/v4";
|
|
27
|
-
import { mockModel } from "./mockModel.js";
|
|
27
|
+
import { MockLanguageModel, mockModel } from "./mockModel.js";
|
|
28
28
|
|
|
29
29
|
const schema = defineSchema({});
|
|
30
30
|
type DataModel = DataModelFromSchemaDefinition<typeof schema>;
|
|
@@ -35,12 +35,50 @@ const action = actionGeneric as ActionBuilder<DataModel, "public">;
|
|
|
35
35
|
|
|
36
36
|
const TEST_TEXT = JSON.stringify({ hello: "world" });
|
|
37
37
|
|
|
38
|
+
const agentModel = new MockLanguageModel({
|
|
39
|
+
content: [{ type: "text", text: TEST_TEXT }],
|
|
40
|
+
});
|
|
38
41
|
const agent = new Agent(components.agent, {
|
|
39
42
|
name: "test",
|
|
40
43
|
instructions: "You are a test agent",
|
|
44
|
+
languageModel: agentModel,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
let capturedRawBodies: { request?: unknown; response?: unknown } | undefined;
|
|
48
|
+
const rawBodyAgent = new Agent(components.agent, {
|
|
49
|
+
name: "raw-body-test",
|
|
41
50
|
languageModel: mockModel({
|
|
42
|
-
|
|
51
|
+
doGenerate: async () => ({
|
|
52
|
+
content: [{ type: "text", text: "raw" }],
|
|
53
|
+
finishReason: { unified: "stop", raw: undefined },
|
|
54
|
+
usage: {
|
|
55
|
+
inputTokens: { total: 1, noCache: 1, cacheRead: 0, cacheWrite: 0 },
|
|
56
|
+
outputTokens: { total: 1, text: 1, reasoning: 0 },
|
|
57
|
+
},
|
|
58
|
+
request: { body: { prompt: "request-body" } },
|
|
59
|
+
response: { body: { text: "response-body" }, headers: {} },
|
|
60
|
+
warnings: [],
|
|
61
|
+
}),
|
|
43
62
|
}),
|
|
63
|
+
rawRequestResponseHandler: async (_ctx, event) => {
|
|
64
|
+
capturedRawBodies = {
|
|
65
|
+
request: event.request.body,
|
|
66
|
+
response: event.response.body,
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
export const captureRawBodies = action({
|
|
72
|
+
args: {},
|
|
73
|
+
handler: async (ctx) => {
|
|
74
|
+
capturedRawBodies = undefined;
|
|
75
|
+
await rawBodyAgent.generateText(
|
|
76
|
+
ctx,
|
|
77
|
+
{ userId: "raw-body-user" },
|
|
78
|
+
{ prompt: "raw" },
|
|
79
|
+
);
|
|
80
|
+
return capturedRawBodies;
|
|
81
|
+
},
|
|
44
82
|
});
|
|
45
83
|
|
|
46
84
|
export const testQuery = query({
|
|
@@ -90,7 +128,7 @@ const saveStepAgent = new Agent(components.agent, {
|
|
|
90
128
|
});
|
|
91
129
|
|
|
92
130
|
export const replayStepsViaSaveStep = action({
|
|
93
|
-
args: {
|
|
131
|
+
args: { withPreviousStep: v.boolean() },
|
|
94
132
|
handler: async (ctx, args) => {
|
|
95
133
|
const { thread } = await saveStepAgent.createThread(ctx, {
|
|
96
134
|
userId: "ss-gen",
|
|
@@ -101,18 +139,21 @@ export const replayStepsViaSaveStep = action({
|
|
|
101
139
|
const { threadId } = await saveStepAgent.createThread(ctx, {
|
|
102
140
|
userId: "ss-replay",
|
|
103
141
|
});
|
|
104
|
-
const { messageId: promptMessageId } = await saveStepAgent.saveMessage(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
142
|
+
const { messageId: promptMessageId } = await saveStepAgent.saveMessage(
|
|
143
|
+
ctx,
|
|
144
|
+
{
|
|
145
|
+
threadId,
|
|
146
|
+
message: { role: "user", content: "echo hi" },
|
|
147
|
+
skipEmbeddings: true,
|
|
148
|
+
},
|
|
149
|
+
);
|
|
109
150
|
let previousStep: (typeof steps)[number] | undefined;
|
|
110
151
|
for (const step of steps) {
|
|
111
152
|
await saveStepAgent.saveStep(ctx, {
|
|
112
153
|
threadId,
|
|
113
154
|
promptMessageId,
|
|
114
155
|
step,
|
|
115
|
-
previousStep: args.
|
|
156
|
+
previousStep: args.withPreviousStep ? previousStep : undefined,
|
|
116
157
|
});
|
|
117
158
|
previousStep = step;
|
|
118
159
|
}
|
|
@@ -231,6 +272,7 @@ const testApi: ApiFromModules<{
|
|
|
231
272
|
generateTextAction: typeof generateTextAction;
|
|
232
273
|
generateObjectAction: typeof generateObjectAction;
|
|
233
274
|
saveMessageMutation: typeof saveMessageMutation;
|
|
275
|
+
captureRawBodies: typeof captureRawBodies;
|
|
234
276
|
replayStepsViaSaveStep: typeof replayStepsViaSaveStep;
|
|
235
277
|
};
|
|
236
278
|
}>["fns"] = anyApi["index.test"] as any;
|
|
@@ -247,27 +289,26 @@ describe("Agent thick client", () => {
|
|
|
247
289
|
expect(result).toBeDefined();
|
|
248
290
|
expect(result).toMatch(TEST_TEXT);
|
|
249
291
|
});
|
|
250
|
-
test(
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
});
|
|
292
|
+
test.each([true, false])(
|
|
293
|
+
"saveStep persists each SDK 7 step once (previousStep: %s)",
|
|
294
|
+
async (withPreviousStep) => {
|
|
295
|
+
const t = initConvexTest(schema);
|
|
296
|
+
const res = await t.action(testApi.replayStepsViaSaveStep, {
|
|
297
|
+
withPreviousStep,
|
|
298
|
+
});
|
|
299
|
+
expect(res.stepCount).toBe(2);
|
|
300
|
+
const toolCalls = res.contentTypes.filter(
|
|
301
|
+
(t) => t === "tool-call",
|
|
302
|
+
).length;
|
|
303
|
+
const toolResults = res.contentTypes.filter(
|
|
304
|
+
(t) => t === "tool-result",
|
|
305
|
+
).length;
|
|
306
|
+
expect({ toolCalls, toolResults }).toEqual({
|
|
307
|
+
toolCalls: 1,
|
|
308
|
+
toolResults: 1,
|
|
309
|
+
});
|
|
310
|
+
},
|
|
311
|
+
);
|
|
271
312
|
});
|
|
272
313
|
|
|
273
314
|
describe("filterOutOrphanedToolMessages", () => {
|
|
@@ -335,6 +376,14 @@ describe("filterOutOrphanedToolMessages", () => {
|
|
|
335
376
|
});
|
|
336
377
|
|
|
337
378
|
describe("Agent option variations and normal behavior", () => {
|
|
379
|
+
test("raw handler opts into retained SDK 7 request and response bodies", async () => {
|
|
380
|
+
const t = initConvexTest(schema);
|
|
381
|
+
await expect(t.action(testApi.captureRawBodies, {})).resolves.toEqual({
|
|
382
|
+
request: { prompt: "request-body" },
|
|
383
|
+
response: { text: "response-body" },
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
|
|
338
387
|
test("Agent can be constructed with minimal options", () => {
|
|
339
388
|
const a = new Agent(components.agent, {
|
|
340
389
|
name: "minimal",
|
|
@@ -469,6 +518,25 @@ describe("Agent-generated mutations/actions/queries", () => {
|
|
|
469
518
|
expect(objResult.object).toBeDefined();
|
|
470
519
|
});
|
|
471
520
|
|
|
521
|
+
test("asTextAction maps its system wire field to AI SDK instructions", async () => {
|
|
522
|
+
const t = initConvexTest(schema);
|
|
523
|
+
const before = agentModel.doGenerateCalls.length;
|
|
524
|
+
|
|
525
|
+
await t.action(testApi.generateTextAction, {
|
|
526
|
+
userId: "8",
|
|
527
|
+
system: "Action-scoped instructions",
|
|
528
|
+
prompt: "Say hi",
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
const call = agentModel.doGenerateCalls.at(-1);
|
|
532
|
+
expect(agentModel.doGenerateCalls).toHaveLength(before + 1);
|
|
533
|
+
expect(call?.prompt[0]).toEqual({
|
|
534
|
+
role: "system",
|
|
535
|
+
content: "Action-scoped instructions",
|
|
536
|
+
});
|
|
537
|
+
expect(call).not.toHaveProperty("system");
|
|
538
|
+
});
|
|
539
|
+
|
|
472
540
|
test("asSaveMessagesMutation works via t.mutation", async () => {
|
|
473
541
|
const t = initConvexTest(schema);
|
|
474
542
|
const threadId = await t.run(async (ctx) =>
|