@convex-dev/agent 0.5.0-alpha.1 → 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/README.md +32 -27
- package/dist/UIMessages.d.ts +46 -0
- package/dist/UIMessages.d.ts.map +1 -0
- package/dist/UIMessages.js +546 -0
- package/dist/UIMessages.js.map +1 -0
- package/dist/client/createTool.d.ts +129 -27
- package/dist/client/createTool.d.ts.map +1 -1
- package/dist/client/createTool.js +66 -12
- package/dist/client/createTool.js.map +1 -1
- package/dist/client/defaultComponent.d.ts +11 -0
- package/dist/client/defaultComponent.d.ts.map +1 -0
- package/dist/client/defaultComponent.js +7 -0
- package/dist/client/defaultComponent.js.map +1 -0
- package/dist/client/definePlaygroundAPI.d.ts +1323 -192
- package/dist/client/definePlaygroundAPI.d.ts.map +1 -1
- package/dist/client/definePlaygroundAPI.js +52 -28
- package/dist/client/definePlaygroundAPI.js.map +1 -1
- package/dist/client/files.d.ts +20 -7
- package/dist/client/files.d.ts.map +1 -1
- package/dist/client/files.js +68 -11
- package/dist/client/files.js.map +1 -1
- package/dist/client/index.d.ts +1056 -965
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +242 -748
- package/dist/client/index.js.map +1 -1
- package/dist/client/messages.d.ts +461 -0
- package/dist/client/messages.d.ts.map +1 -0
- package/dist/client/messages.js +106 -0
- package/dist/client/messages.js.map +1 -0
- package/dist/client/mockModel.d.ts +42 -0
- package/dist/client/mockModel.d.ts.map +1 -0
- package/dist/client/mockModel.js +175 -0
- package/dist/client/mockModel.js.map +1 -0
- package/dist/client/saveInputMessages.d.ts +20 -0
- package/dist/client/saveInputMessages.d.ts.map +1 -0
- package/dist/client/saveInputMessages.js +58 -0
- package/dist/client/saveInputMessages.js.map +1 -0
- package/dist/client/search.d.ts +346 -35
- package/dist/client/search.d.ts.map +1 -1
- package/dist/client/search.js +350 -39
- package/dist/client/search.js.map +1 -1
- package/dist/client/start.d.ts +84 -0
- package/dist/client/start.d.ts.map +1 -0
- package/dist/client/start.js +171 -0
- package/dist/client/start.js.map +1 -0
- package/dist/client/streamText.d.ts +46 -0
- package/dist/client/streamText.d.ts.map +1 -0
- package/dist/client/streamText.js +93 -0
- package/dist/client/streamText.js.map +1 -0
- package/dist/client/streaming.d.ts +3705 -32
- package/dist/client/streaming.d.ts.map +1 -1
- package/dist/client/streaming.js +141 -59
- package/dist/client/streaming.js.map +1 -1
- package/dist/client/threads.d.ts +46 -0
- package/dist/client/threads.d.ts.map +1 -0
- package/dist/client/threads.js +49 -0
- package/dist/client/threads.js.map +1 -0
- package/dist/client/types.d.ts +265 -128
- package/dist/client/types.d.ts.map +1 -1
- package/dist/client/utils.d.ts +4 -0
- package/dist/client/utils.d.ts.map +1 -0
- package/dist/client/utils.js +21 -0
- package/dist/client/utils.js.map +1 -0
- package/dist/component/_generated/api.d.ts +24 -2178
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js +10 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/_generated/component.d.ts +3119 -0
- package/dist/component/_generated/component.d.ts.map +1 -0
- package/dist/component/_generated/component.js +11 -0
- package/dist/component/_generated/component.js.map +1 -0
- package/dist/component/_generated/dataModel.d.ts +4 -18
- package/dist/component/_generated/dataModel.d.ts.map +1 -0
- package/dist/component/_generated/dataModel.js +11 -0
- package/dist/component/_generated/dataModel.js.map +1 -0
- package/dist/component/_generated/server.d.ts +10 -38
- package/dist/component/_generated/server.d.ts.map +1 -1
- package/dist/component/_generated/server.js +9 -5
- package/dist/component/_generated/server.js.map +1 -1
- package/dist/component/files.d.ts +16 -10
- 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 +2553 -342
- package/dist/component/messages.d.ts.map +1 -1
- package/dist/component/messages.js +387 -154
- package/dist/component/messages.js.map +1 -1
- package/dist/component/schema.d.ts +5697 -3584
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +18 -41
- package/dist/component/schema.js.map +1 -1
- package/dist/component/streams.d.ts +35 -335
- package/dist/component/streams.d.ts.map +1 -1
- package/dist/component/streams.js +114 -73
- package/dist/component/streams.js.map +1 -1
- package/dist/component/threads.d.ts +16 -16
- package/dist/component/users.d.ts +4 -4
- package/dist/component/vector/index.d.ts +1 -1
- package/dist/component/vector/index.d.ts.map +1 -1
- package/dist/component/vector/index.js +1 -3
- package/dist/component/vector/index.js.map +1 -1
- package/dist/deltas.d.ts +43 -0
- package/dist/deltas.d.ts.map +1 -0
- package/dist/deltas.js +447 -0
- package/dist/deltas.js.map +1 -0
- package/dist/mapping.d.ts +20 -20
- package/dist/mapping.d.ts.map +1 -1
- package/dist/mapping.js +313 -96
- package/dist/mapping.js.map +1 -1
- package/dist/react/SmoothText.d.ts +5 -0
- package/dist/react/SmoothText.d.ts.map +1 -0
- package/dist/react/SmoothText.js +6 -0
- package/dist/react/SmoothText.js.map +1 -0
- package/dist/react/index.d.ts +5 -77
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +6 -160
- package/dist/react/index.js.map +1 -1
- package/dist/react/optimisticallySendMessage.d.ts +36 -3
- package/dist/react/optimisticallySendMessage.d.ts.map +1 -1
- package/dist/react/optimisticallySendMessage.js +35 -9
- package/dist/react/optimisticallySendMessage.js.map +1 -1
- package/dist/react/types.d.ts +4 -18
- package/dist/react/types.d.ts.map +1 -1
- package/dist/react/useDeltaStreams.d.ts +10 -0
- package/dist/react/useDeltaStreams.d.ts.map +1 -0
- package/dist/react/useDeltaStreams.js +101 -0
- package/dist/react/useDeltaStreams.js.map +1 -0
- package/dist/react/useSmoothText.d.ts +13 -12
- package/dist/react/useSmoothText.d.ts.map +1 -1
- package/dist/react/useSmoothText.js +32 -15
- package/dist/react/useSmoothText.js.map +1 -1
- package/dist/react/useStreamingUIMessages.d.ts +22 -0
- package/dist/react/useStreamingUIMessages.d.ts.map +1 -0
- package/dist/react/useStreamingUIMessages.js +92 -0
- package/dist/react/useStreamingUIMessages.js.map +1 -0
- package/dist/react/useThreadMessages.d.ts +104 -0
- package/dist/react/useThreadMessages.d.ts.map +1 -0
- package/dist/react/useThreadMessages.js +148 -0
- package/dist/react/useThreadMessages.js.map +1 -0
- package/dist/react/useUIMessages.d.ts +96 -0
- package/dist/react/useUIMessages.d.ts.map +1 -0
- package/dist/react/useUIMessages.js +108 -0
- package/dist/react/useUIMessages.js.map +1 -0
- package/dist/shared.d.ts +20 -4
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +45 -8
- package/dist/shared.js.map +1 -1
- package/dist/validators.d.ts +22981 -5666
- package/dist/validators.d.ts.map +1 -1
- package/dist/validators.js +245 -137
- package/dist/validators.js.map +1 -1
- package/package.json +98 -50
- package/src/UIMessages.combineUIMessages.test.ts +239 -0
- package/src/UIMessages.test.ts +273 -0
- package/src/UIMessages.ts +739 -0
- package/src/client/createTool.ts +293 -76
- package/src/client/defaultComponent.ts +17 -0
- package/src/client/definePlaygroundAPI.ts +67 -31
- package/src/client/files.ts +100 -20
- package/src/client/index.test.ts +40 -85
- package/src/client/index.ts +520 -1290
- package/src/client/messages.ts +237 -0
- package/src/client/mockModel.ts +245 -0
- package/src/client/saveInputMessages.test.ts +583 -0
- package/src/client/saveInputMessages.ts +101 -0
- package/src/client/search.test.ts +1207 -0
- package/src/client/search.ts +577 -70
- package/src/client/start.ts +310 -0
- package/src/client/streamText.ts +163 -0
- package/src/client/streaming.test.ts +186 -0
- package/src/client/streaming.ts +219 -97
- package/src/client/threads.ts +83 -0
- package/src/client/types.ts +368 -219
- package/src/client/utils.ts +27 -0
- package/src/component/_generated/api.ts +64 -0
- package/src/component/_generated/component.ts +4913 -0
- package/src/component/_generated/{server.d.ts → server.ts} +33 -21
- package/src/component/files.ts +11 -2
- package/src/component/messages.test.ts +195 -51
- package/src/component/messages.ts +490 -201
- package/src/component/schema.ts +20 -46
- package/src/component/setup.test.ts +7 -0
- package/src/component/streams.ts +184 -83
- package/src/component/users.test.ts +0 -1
- package/src/component/vector/index.ts +1 -3
- package/src/deltas.test.ts +626 -0
- package/src/deltas.ts +570 -0
- package/src/fromUIMessages.test.ts +497 -0
- package/src/mapping.test.ts +103 -6
- package/src/mapping.ts +422 -161
- package/src/react/SmoothText.tsx +9 -0
- package/src/react/index.ts +10 -230
- package/src/react/optimisticallySendMessage.ts +55 -12
- package/src/react/types.ts +6 -39
- package/src/react/useDeltaStreams.ts +154 -0
- package/src/react/useSmoothText.ts +56 -36
- package/src/react/useStreamingUIMessages.ts +143 -0
- package/src/react/useThreadMessages.ts +262 -0
- package/src/react/useUIMessages.test.ts +255 -0
- package/src/react/useUIMessages.ts +195 -0
- package/src/shared.ts +88 -12
- package/src/test.ts +18 -0
- package/src/toUIMessages.test.ts +1269 -0
- package/src/validators.test.ts +18 -19
- package/src/validators.ts +325 -185
- package/dist/client/_generated/_ignore.d.ts +0 -1
- package/dist/client/_generated/_ignore.d.ts.map +0 -1
- package/dist/client/_generated/_ignore.js +0 -3
- package/dist/client/_generated/_ignore.js.map +0 -1
- package/dist/client/listMessages.d.ts +0 -22
- package/dist/client/listMessages.d.ts.map +0 -1
- package/dist/client/listMessages.js +0 -25
- package/dist/client/listMessages.js.map +0 -1
- package/dist/package.json +0 -3
- package/dist/react/deltas.d.ts +0 -26
- package/dist/react/deltas.d.ts.map +0 -1
- package/dist/react/deltas.js +0 -384
- package/dist/react/deltas.js.map +0 -1
- package/dist/react/toUIMessages.d.ts +0 -15
- package/dist/react/toUIMessages.d.ts.map +0 -1
- package/dist/react/toUIMessages.js +0 -211
- package/dist/react/toUIMessages.js.map +0 -1
- package/src/client/listMessages.ts +0 -38
- package/src/component/_generated/api.d.ts +0 -2202
- package/src/component/_generated/api.js +0 -23
- package/src/component/_generated/server.js +0 -90
- package/src/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/src/react/deltas.test.ts +0 -315
- package/src/react/deltas.ts +0 -478
- package/src/react/toUIMessages.test.ts +0 -420
- package/src/react/toUIMessages.ts +0 -253
- package/src/vitest.config.ts +0 -7
- /package/src/component/_generated/{dataModel.d.ts → dataModel.ts} +0 -0
package/src/client/createTool.ts
CHANGED
|
@@ -1,93 +1,281 @@
|
|
|
1
|
-
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";
|
|
2
9
|
import { tool } from "ai";
|
|
3
|
-
import { z } from "zod";
|
|
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> & {
|
|
10
|
-
agent
|
|
25
|
+
agent?: Agent;
|
|
11
26
|
userId?: string;
|
|
12
27
|
threadId?: string;
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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`)");
|
|
80
244
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
+
}
|
|
257
|
+
|
|
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>({
|
|
85
266
|
type: "function",
|
|
86
267
|
__acceptsCtx: true,
|
|
87
268
|
ctx: def.ctx,
|
|
88
269
|
description: def.description,
|
|
89
|
-
|
|
90
|
-
|
|
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
|
+
|
|
91
279
|
if (!getCtx(this)) {
|
|
92
280
|
throw new Error(
|
|
93
281
|
"To use a Convex tool, you must either provide the ctx" +
|
|
@@ -95,23 +283,56 @@ export function createTool<INPUT, OUTPUT, Ctx extends ToolCtx = ToolCtx>(def: {
|
|
|
95
283
|
" call it (which injects the ctx, userId and threadId)",
|
|
96
284
|
);
|
|
97
285
|
}
|
|
98
|
-
return
|
|
286
|
+
return needsApproval(getCtx(this), input, options);
|
|
99
287
|
},
|
|
100
|
-
|
|
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,
|
|
101
308
|
});
|
|
102
309
|
if (def.onInputStart) {
|
|
103
|
-
|
|
310
|
+
const origOnInputStart = def.onInputStart;
|
|
311
|
+
t.onInputStart = function (this: Tool<INPUT, OUTPUT>, options) {
|
|
312
|
+
return origOnInputStart.call(this, getCtx(this), options);
|
|
313
|
+
};
|
|
104
314
|
}
|
|
105
315
|
if (def.onInputDelta) {
|
|
106
|
-
|
|
316
|
+
const origOnInputDelta = def.onInputDelta;
|
|
317
|
+
t.onInputDelta = function (this: Tool<INPUT, OUTPUT>, options) {
|
|
318
|
+
return origOnInputDelta.call(this, getCtx(this), options);
|
|
319
|
+
};
|
|
107
320
|
}
|
|
108
321
|
if (def.onInputAvailable) {
|
|
109
|
-
|
|
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
|
+
};
|
|
110
332
|
}
|
|
111
333
|
return t;
|
|
112
334
|
}
|
|
113
335
|
|
|
114
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
115
336
|
function getCtx<Ctx extends ToolCtx>(tool: any): Ctx {
|
|
116
337
|
return (tool as { ctx: Ctx }).ctx;
|
|
117
338
|
}
|
|
@@ -126,8 +347,7 @@ export function wrapTools(
|
|
|
126
347
|
continue;
|
|
127
348
|
}
|
|
128
349
|
for (const [name, tool] of Object.entries(toolSet)) {
|
|
129
|
-
|
|
130
|
-
if (!(tool as any).__acceptsCtx) {
|
|
350
|
+
if (tool && !(tool as any).__acceptsCtx) {
|
|
131
351
|
output[name] = tool;
|
|
132
352
|
} else {
|
|
133
353
|
const out = { ...tool, ctx };
|
|
@@ -137,6 +357,3 @@ export function wrapTools(
|
|
|
137
357
|
}
|
|
138
358
|
return output;
|
|
139
359
|
}
|
|
140
|
-
|
|
141
|
-
// Vendoring in from "ai" package since it wasn't exported
|
|
142
|
-
type ToolParameters<T> = z.Schema<T> | Schema<T>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { componentsGeneric } from "convex/server";
|
|
2
|
+
import type { AgentComponent } from "./types.js";
|
|
3
|
+
|
|
4
|
+
export type CustomComponent = {
|
|
5
|
+
/**
|
|
6
|
+
* If you have a custom name for the agent component, you can pass it here
|
|
7
|
+
* as components.myAgentName.
|
|
8
|
+
*/
|
|
9
|
+
component?: AgentComponent;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function componentAPI(args?: CustomComponent): AgentComponent {
|
|
13
|
+
return args?.component ?? defaultComponent;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const defaultComponent = componentsGeneric()
|
|
17
|
+
.agent as unknown as AgentComponent;
|
|
@@ -12,7 +12,7 @@ import { v } from "convex/values";
|
|
|
12
12
|
import {
|
|
13
13
|
createThread as createThread_,
|
|
14
14
|
listMessages as listMessages_,
|
|
15
|
-
|
|
15
|
+
toModelMessage,
|
|
16
16
|
vContextOptions,
|
|
17
17
|
vMessage,
|
|
18
18
|
vMessageDoc,
|
|
@@ -21,7 +21,15 @@ import {
|
|
|
21
21
|
vThreadDoc,
|
|
22
22
|
type Agent,
|
|
23
23
|
type AgentComponent,
|
|
24
|
+
vStreamArgs,
|
|
25
|
+
syncStreams,
|
|
26
|
+
vStreamMessagesReturnValue,
|
|
27
|
+
isTool,
|
|
28
|
+
extractText,
|
|
29
|
+
type MessageDoc,
|
|
24
30
|
} from "./index.js";
|
|
31
|
+
import { serializeNewMessagesInStep } from "../mapping.js";
|
|
32
|
+
import { getModelName, getProviderName } from "../shared.js";
|
|
25
33
|
|
|
26
34
|
export type PlaygroundAPI = ApiFromModules<{
|
|
27
35
|
playground: ReturnType<typeof definePlaygroundAPI>;
|
|
@@ -61,9 +69,7 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
61
69
|
}
|
|
62
70
|
|
|
63
71
|
const isApiKeyValid = queryGeneric({
|
|
64
|
-
args: {
|
|
65
|
-
apiKey: v.string(),
|
|
66
|
-
},
|
|
72
|
+
args: { apiKey: v.string() },
|
|
67
73
|
handler: async (ctx, args) => {
|
|
68
74
|
try {
|
|
69
75
|
await validateApiKey(ctx, args.apiKey);
|
|
@@ -107,17 +113,14 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
107
113
|
instructions: agent.options.instructions,
|
|
108
114
|
contextOptions: agent.options.contextOptions,
|
|
109
115
|
storageOptions: agent.options.storageOptions,
|
|
110
|
-
maxRetries: agent.options.maxRetries,
|
|
116
|
+
maxRetries: agent.options.callSettings?.maxRetries,
|
|
111
117
|
tools: agent.options.tools ? Object.keys(agent.options.tools) : [],
|
|
112
118
|
}));
|
|
113
119
|
},
|
|
114
120
|
});
|
|
115
121
|
|
|
116
122
|
const listUsers = queryGeneric({
|
|
117
|
-
args: {
|
|
118
|
-
apiKey: v.string(),
|
|
119
|
-
paginationOpts: paginationOptsValidator,
|
|
120
|
-
},
|
|
123
|
+
args: { apiKey: v.string(), paginationOpts: paginationOptsValidator },
|
|
121
124
|
handler: async (ctx, args) => {
|
|
122
125
|
await validateApiKey(ctx, args.apiKey);
|
|
123
126
|
const users = await ctx.runQuery(component.users.listUsersWithThreads, {
|
|
@@ -133,12 +136,7 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
133
136
|
),
|
|
134
137
|
};
|
|
135
138
|
},
|
|
136
|
-
returns: vPaginationResult(
|
|
137
|
-
v.object({
|
|
138
|
-
_id: v.string(),
|
|
139
|
-
name: v.string(),
|
|
140
|
-
}),
|
|
141
|
-
),
|
|
139
|
+
returns: vPaginationResult(v.object({ _id: v.string(), name: v.string() })),
|
|
142
140
|
});
|
|
143
141
|
|
|
144
142
|
// List threads for a user (query)
|
|
@@ -167,10 +165,7 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
167
165
|
} = await ctx.runQuery(component.messages.listMessagesByThreadId, {
|
|
168
166
|
threadId: thread._id,
|
|
169
167
|
order: "desc",
|
|
170
|
-
paginationOpts: {
|
|
171
|
-
numItems: 1,
|
|
172
|
-
cursor: null,
|
|
173
|
-
},
|
|
168
|
+
paginationOpts: { numItems: 1, cursor: null },
|
|
174
169
|
});
|
|
175
170
|
return {
|
|
176
171
|
...thread,
|
|
@@ -198,16 +193,20 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
198
193
|
apiKey: v.string(),
|
|
199
194
|
threadId: v.string(),
|
|
200
195
|
paginationOpts: paginationOptsValidator,
|
|
196
|
+
streamArgs: vStreamArgs,
|
|
201
197
|
},
|
|
202
198
|
handler: async (ctx, args) => {
|
|
203
199
|
await validateApiKey(ctx, args.apiKey);
|
|
204
|
-
|
|
200
|
+
const paginated = await listMessages_(ctx, component, {
|
|
205
201
|
threadId: args.threadId,
|
|
206
202
|
paginationOpts: args.paginationOpts,
|
|
207
203
|
statuses: ["success", "failed", "pending"],
|
|
208
204
|
});
|
|
205
|
+
const streams = await syncStreams(ctx, component, args);
|
|
206
|
+
|
|
207
|
+
return { ...paginated, streams };
|
|
209
208
|
},
|
|
210
|
-
returns:
|
|
209
|
+
returns: vStreamMessagesReturnValue,
|
|
211
210
|
});
|
|
212
211
|
|
|
213
212
|
// Create a thread (mutation)
|
|
@@ -267,18 +266,46 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
267
266
|
const namedAgent = agents.find(({ name }) => name === agentName);
|
|
268
267
|
if (!namedAgent) throw new Error(`Unknown agent: ${agentName}`);
|
|
269
268
|
const { agent } = namedAgent;
|
|
270
|
-
const {
|
|
269
|
+
const { text, steps } = await agent.streamText(
|
|
271
270
|
ctx,
|
|
272
271
|
{ threadId, userId },
|
|
273
272
|
{
|
|
274
273
|
...rest,
|
|
275
274
|
...(system ? { system } : {}),
|
|
276
|
-
...(messages ? { messages: messages.map(
|
|
275
|
+
...(messages ? { messages: messages.map(toModelMessage) } : {}),
|
|
277
276
|
},
|
|
278
|
-
{ contextOptions, storageOptions },
|
|
277
|
+
{ contextOptions, storageOptions, saveStreamDeltas: true },
|
|
279
278
|
);
|
|
280
|
-
|
|
279
|
+
const outputMessages = await Promise.all(
|
|
280
|
+
(await steps).map(async (step) => {
|
|
281
|
+
const { messages } = await serializeNewMessagesInStep(
|
|
282
|
+
ctx,
|
|
283
|
+
component,
|
|
284
|
+
step,
|
|
285
|
+
{
|
|
286
|
+
model: getModelName(agent.options.languageModel),
|
|
287
|
+
provider: getProviderName(agent.options.languageModel),
|
|
288
|
+
},
|
|
289
|
+
);
|
|
290
|
+
return messages.map((messageWithMetadata, i) => {
|
|
291
|
+
return {
|
|
292
|
+
...messageWithMetadata,
|
|
293
|
+
tool: isTool(messageWithMetadata.message),
|
|
294
|
+
text: extractText(messageWithMetadata.message),
|
|
295
|
+
status: "success",
|
|
296
|
+
providerMetadata: {},
|
|
297
|
+
threadId,
|
|
298
|
+
_id: crypto.randomUUID(),
|
|
299
|
+
_creationTime: Date.now(),
|
|
300
|
+
order: 0,
|
|
301
|
+
stepOrder: i + 1,
|
|
302
|
+
} satisfies MessageDoc;
|
|
303
|
+
});
|
|
304
|
+
}),
|
|
305
|
+
);
|
|
306
|
+
return { text: await text, messages: outputMessages.flat() };
|
|
281
307
|
},
|
|
308
|
+
returns: v.object({ text: v.string(), messages: v.array(vMessageDoc) }),
|
|
282
309
|
});
|
|
283
310
|
|
|
284
311
|
// Fetch prompt context (action)
|
|
@@ -288,8 +315,11 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
288
315
|
agentName: v.string(),
|
|
289
316
|
userId: v.optional(v.string()),
|
|
290
317
|
threadId: v.optional(v.string()),
|
|
291
|
-
|
|
318
|
+
searchText: v.optional(v.string()),
|
|
319
|
+
targetMessageId: v.optional(v.string()),
|
|
292
320
|
contextOptions: vContextOptions,
|
|
321
|
+
// @deprecated use searchText and targetMessageId instead
|
|
322
|
+
messages: v.optional(v.array(vMessage)),
|
|
293
323
|
beforeMessageId: v.optional(v.string()),
|
|
294
324
|
},
|
|
295
325
|
handler: async (ctx, args) => {
|
|
@@ -302,20 +332,26 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
302
332
|
if (!namedAgent) throw new Error(`Unknown agent: ${args.agentName}`);
|
|
303
333
|
const { agent } = namedAgent;
|
|
304
334
|
const contextOptions = args.contextOptions;
|
|
305
|
-
|
|
335
|
+
const targetMessageId = args.targetMessageId ?? args.beforeMessageId;
|
|
336
|
+
if (targetMessageId) {
|
|
306
337
|
contextOptions.recentMessages =
|
|
307
338
|
(contextOptions.recentMessages ?? 10) + 1;
|
|
308
339
|
}
|
|
309
340
|
const messages = await agent.fetchContextMessages(ctx, {
|
|
310
341
|
userId: args.userId,
|
|
311
342
|
threadId: args.threadId,
|
|
312
|
-
|
|
343
|
+
targetMessageId,
|
|
344
|
+
searchText: args.searchText,
|
|
313
345
|
contextOptions: args.contextOptions,
|
|
314
|
-
|
|
346
|
+
messages: args.messages?.map(toModelMessage),
|
|
315
347
|
});
|
|
316
|
-
|
|
317
|
-
(m) =>
|
|
348
|
+
const targetMessageIndex = messages.findIndex(
|
|
349
|
+
(m) => m._id === targetMessageId,
|
|
318
350
|
);
|
|
351
|
+
if (targetMessageIndex !== -1) {
|
|
352
|
+
return messages.slice(0, targetMessageIndex);
|
|
353
|
+
}
|
|
354
|
+
return messages;
|
|
319
355
|
},
|
|
320
356
|
});
|
|
321
357
|
|