@convex-dev/agent 0.1.18 → 0.2.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/client/createTool.d.ts +30 -11
- package/dist/client/createTool.d.ts.map +1 -1
- package/dist/client/createTool.js +24 -10
- package/dist/client/createTool.js.map +1 -1
- package/dist/client/defaultComponent.d.ts +11 -0
- package/dist/client/defaultComponent.d.ts.map +1 -0
- package/dist/client/defaultComponent.js +7 -0
- package/dist/client/defaultComponent.js.map +1 -0
- package/dist/client/definePlaygroundAPI.d.ts +68 -23
- package/dist/client/definePlaygroundAPI.d.ts.map +1 -1
- package/dist/client/definePlaygroundAPI.js +7 -20
- package/dist/client/definePlaygroundAPI.js.map +1 -1
- package/dist/client/files.d.ts +14 -4
- package/dist/client/files.d.ts.map +1 -1
- package/dist/client/files.js +66 -11
- package/dist/client/files.js.map +1 -1
- package/dist/client/index.d.ts +323 -780
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +445 -543
- package/dist/client/index.js.map +1 -1
- package/dist/client/messages.d.ts +256 -0
- package/dist/client/messages.d.ts.map +1 -0
- package/dist/client/messages.js +97 -0
- package/dist/client/messages.js.map +1 -0
- package/dist/client/search.d.ts +35 -12
- package/dist/client/search.d.ts.map +1 -1
- package/dist/client/search.js +21 -4
- package/dist/client/search.js.map +1 -1
- package/dist/client/streaming.d.ts +21 -21
- package/dist/client/streaming.d.ts.map +1 -1
- package/dist/client/streaming.js +35 -40
- 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 +159 -75
- package/dist/client/types.d.ts.map +1 -1
- package/dist/component/_generated/api.d.ts +261 -209
- package/dist/component/messages.d.ts +314 -105
- package/dist/component/messages.d.ts.map +1 -1
- package/dist/component/messages.js +141 -83
- package/dist/component/messages.js.map +1 -1
- package/dist/component/schema.d.ts +631 -870
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +11 -16
- package/dist/component/schema.js.map +1 -1
- package/dist/component/streams.d.ts +29 -149
- package/dist/component/streams.d.ts.map +1 -1
- package/dist/component/streams.js +104 -60
- package/dist/component/streams.js.map +1 -1
- package/dist/component/threads.d.ts +4 -4
- package/dist/component/users.d.ts +3 -3
- package/dist/mapping.d.ts +15 -16
- package/dist/mapping.d.ts.map +1 -1
- package/dist/mapping.js +208 -62
- package/dist/mapping.js.map +1 -1
- package/dist/parts.d.ts +3 -0
- package/dist/parts.d.ts.map +1 -0
- package/dist/parts.js +34 -0
- package/dist/parts.js.map +1 -0
- 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/deltas.d.ts +3 -5
- package/dist/react/deltas.d.ts.map +1 -1
- package/dist/react/deltas.js +89 -53
- package/dist/react/deltas.js.map +1 -1
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +31 -11
- package/dist/react/index.js.map +1 -1
- package/dist/react/optimisticallySendMessage.d.ts.map +1 -1
- package/dist/react/optimisticallySendMessage.js +2 -8
- package/dist/react/optimisticallySendMessage.js.map +1 -1
- package/dist/react/toUIMessages.d.ts +5 -4
- package/dist/react/toUIMessages.d.ts.map +1 -1
- package/dist/react/toUIMessages.js +103 -40
- package/dist/react/toUIMessages.js.map +1 -1
- package/dist/react/useSmoothText.d.ts +13 -12
- package/dist/react/useSmoothText.d.ts.map +1 -1
- package/dist/react/useSmoothText.js +1 -1
- package/dist/react/useSmoothText.js.map +1 -1
- package/dist/validators.d.ts +751 -1464
- package/dist/validators.d.ts.map +1 -1
- package/dist/validators.js +39 -80
- package/dist/validators.js.map +1 -1
- package/package.json +34 -30
- package/src/client/createTool.ts +66 -40
- package/src/client/defaultComponent.ts +17 -0
- package/src/client/definePlaygroundAPI.ts +17 -31
- package/src/client/files.ts +94 -17
- package/src/client/index.test.ts +28 -38
- package/src/client/index.ts +785 -977
- package/src/client/messages.ts +205 -0
- package/src/client/search.ts +37 -10
- package/src/client/streaming.ts +53 -56
- package/src/client/threads.ts +78 -0
- package/src/client/types.ts +239 -131
- package/src/component/_generated/api.d.ts +261 -209
- package/src/component/messages.test.ts +182 -40
- package/src/component/messages.ts +165 -108
- package/src/component/schema.ts +11 -17
- package/src/component/streams.ts +180 -69
- package/src/mapping.ts +253 -96
- package/src/parts.ts +39 -0
- package/src/react/SmoothText.tsx +9 -0
- package/src/react/deltas.test.ts +38 -42
- package/src/react/deltas.ts +116 -65
- package/src/react/index.ts +35 -13
- package/src/react/optimisticallySendMessage.ts +2 -8
- package/src/react/toUIMessages.test.ts +154 -36
- package/src/react/toUIMessages.ts +136 -57
- package/src/react/useSmoothText.ts +14 -15
- package/src/validators.test.ts +1 -117
- package/src/validators.ts +57 -107
- package/dist/client/listMessages.d.ts +0 -22
- package/dist/client/listMessages.d.ts.map +0 -1
- package/dist/client/listMessages.js +0 -25
- package/dist/client/listMessages.js.map +0 -1
- package/src/client/listMessages.ts +0 -38
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
|
+
actionGeneric,
|
|
3
|
+
mutationGeneric,
|
|
2
4
|
paginationOptsValidator,
|
|
3
5
|
queryGeneric,
|
|
4
|
-
mutationGeneric,
|
|
5
|
-
actionGeneric,
|
|
6
|
-
type GenericDataModel,
|
|
7
|
-
type GenericQueryCtx,
|
|
8
6
|
type ApiFromModules,
|
|
9
7
|
type GenericActionCtx,
|
|
8
|
+
type GenericDataModel,
|
|
9
|
+
type GenericQueryCtx,
|
|
10
10
|
} from "convex/server";
|
|
11
|
+
import { v } from "convex/values";
|
|
11
12
|
import {
|
|
13
|
+
createThread as createThread_,
|
|
14
|
+
listMessages as listMessages_,
|
|
15
|
+
deserializeMessage,
|
|
16
|
+
vContextOptions,
|
|
17
|
+
vMessage,
|
|
12
18
|
vMessageDoc,
|
|
13
|
-
vThreadDoc,
|
|
14
19
|
vPaginationResult,
|
|
15
|
-
vMessage,
|
|
16
|
-
vContextOptions,
|
|
17
20
|
vStorageOptions,
|
|
18
|
-
|
|
21
|
+
vThreadDoc,
|
|
19
22
|
type Agent,
|
|
20
|
-
|
|
21
|
-
createThread as createThread_,
|
|
23
|
+
type AgentComponent,
|
|
22
24
|
} from "./index.js";
|
|
23
|
-
import { v } from "convex/values";
|
|
24
|
-
import { deserializeMessage } from "../mapping.js";
|
|
25
25
|
|
|
26
26
|
export type PlaygroundAPI = ApiFromModules<{
|
|
27
27
|
playground: ReturnType<typeof definePlaygroundAPI>;
|
|
@@ -61,9 +61,7 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
const isApiKeyValid = queryGeneric({
|
|
64
|
-
args: {
|
|
65
|
-
apiKey: v.string(),
|
|
66
|
-
},
|
|
64
|
+
args: { apiKey: v.string() },
|
|
67
65
|
handler: async (ctx, args) => {
|
|
68
66
|
try {
|
|
69
67
|
await validateApiKey(ctx, args.apiKey);
|
|
@@ -107,18 +105,14 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
107
105
|
instructions: agent.options.instructions,
|
|
108
106
|
contextOptions: agent.options.contextOptions,
|
|
109
107
|
storageOptions: agent.options.storageOptions,
|
|
110
|
-
|
|
111
|
-
maxRetries: agent.options.maxRetries,
|
|
108
|
+
maxRetries: agent.options.callSettings?.maxRetries,
|
|
112
109
|
tools: agent.options.tools ? Object.keys(agent.options.tools) : [],
|
|
113
110
|
}));
|
|
114
111
|
},
|
|
115
112
|
});
|
|
116
113
|
|
|
117
114
|
const listUsers = queryGeneric({
|
|
118
|
-
args: {
|
|
119
|
-
apiKey: v.string(),
|
|
120
|
-
paginationOpts: paginationOptsValidator,
|
|
121
|
-
},
|
|
115
|
+
args: { apiKey: v.string(), paginationOpts: paginationOptsValidator },
|
|
122
116
|
handler: async (ctx, args) => {
|
|
123
117
|
await validateApiKey(ctx, args.apiKey);
|
|
124
118
|
const users = await ctx.runQuery(component.users.listUsersWithThreads, {
|
|
@@ -134,12 +128,7 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
134
128
|
),
|
|
135
129
|
};
|
|
136
130
|
},
|
|
137
|
-
returns: vPaginationResult(
|
|
138
|
-
v.object({
|
|
139
|
-
_id: v.string(),
|
|
140
|
-
name: v.string(),
|
|
141
|
-
}),
|
|
142
|
-
),
|
|
131
|
+
returns: vPaginationResult(v.object({ _id: v.string(), name: v.string() })),
|
|
143
132
|
});
|
|
144
133
|
|
|
145
134
|
// List threads for a user (query)
|
|
@@ -168,10 +157,7 @@ export function definePlaygroundAPI<DataModel extends GenericDataModel>(
|
|
|
168
157
|
} = await ctx.runQuery(component.messages.listMessagesByThreadId, {
|
|
169
158
|
threadId: thread._id,
|
|
170
159
|
order: "desc",
|
|
171
|
-
paginationOpts: {
|
|
172
|
-
numItems: 1,
|
|
173
|
-
cursor: null,
|
|
174
|
-
},
|
|
160
|
+
paginationOpts: { numItems: 1, cursor: null },
|
|
175
161
|
});
|
|
176
162
|
return {
|
|
177
163
|
...thread,
|
package/src/client/files.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
AssistantContent,
|
|
3
|
+
FilePart,
|
|
4
|
+
ImagePart,
|
|
5
|
+
ModelMessage,
|
|
6
|
+
UserContent,
|
|
7
|
+
} from "ai";
|
|
2
8
|
import type { Id } from "../component/_generated/dataModel.js";
|
|
3
9
|
import type {
|
|
4
10
|
ActionCtx,
|
|
@@ -6,6 +12,8 @@ import type {
|
|
|
6
12
|
QueryCtx,
|
|
7
13
|
RunMutationCtx,
|
|
8
14
|
} from "./types.js";
|
|
15
|
+
import type { Message } from "../validators.js";
|
|
16
|
+
import { assert } from "convex-helpers";
|
|
9
17
|
|
|
10
18
|
export const MAX_FILE_SIZE = 1024 * 64;
|
|
11
19
|
|
|
@@ -22,8 +30,8 @@ type File = {
|
|
|
22
30
|
* @param ctx A ctx object from an action.
|
|
23
31
|
* @param component The agent component.
|
|
24
32
|
* @param blob The blob to store.
|
|
25
|
-
* @param filename The filename to store.
|
|
26
|
-
* @param sha256 The sha256 hash of the file. If not provided, it will be
|
|
33
|
+
* @param args.filename The filename to store.
|
|
34
|
+
* @param args.sha256 The sha256 hash of the file. If not provided, it will be
|
|
27
35
|
* computed. However, to ensure no corruption during transfer, you can
|
|
28
36
|
* calculate this on the client to enforce integrity.
|
|
29
37
|
* @returns The URL, fileId, and storageId of the stored file.
|
|
@@ -32,8 +40,7 @@ export async function storeFile(
|
|
|
32
40
|
ctx: ActionCtx | RunMutationCtx,
|
|
33
41
|
component: AgentComponent,
|
|
34
42
|
blob: Blob,
|
|
35
|
-
filename?: string,
|
|
36
|
-
sha256?: string,
|
|
43
|
+
{ filename, sha256 }: { filename?: string; sha256?: string } = {},
|
|
37
44
|
): Promise<{
|
|
38
45
|
file: File;
|
|
39
46
|
filePart: FilePart;
|
|
@@ -148,24 +155,94 @@ export async function getFile(
|
|
|
148
155
|
|
|
149
156
|
function getParts(
|
|
150
157
|
url: string,
|
|
151
|
-
|
|
158
|
+
mediaType: string,
|
|
152
159
|
filename: string | undefined,
|
|
153
|
-
): {
|
|
154
|
-
filePart: FilePart;
|
|
155
|
-
imagePart: ImagePart | undefined;
|
|
156
|
-
} {
|
|
160
|
+
): { filePart: FilePart; imagePart: ImagePart | undefined } {
|
|
157
161
|
const filePart: FilePart = {
|
|
158
162
|
type: "file",
|
|
159
163
|
data: new URL(url),
|
|
160
|
-
|
|
164
|
+
mediaType,
|
|
161
165
|
filename,
|
|
162
166
|
};
|
|
163
|
-
const imagePart: ImagePart | undefined =
|
|
164
|
-
? {
|
|
165
|
-
type: "image",
|
|
166
|
-
image: new URL(url),
|
|
167
|
-
mimeType,
|
|
168
|
-
}
|
|
167
|
+
const imagePart: ImagePart | undefined = mediaType.startsWith("image/")
|
|
168
|
+
? { type: "image", image: new URL(url), mediaType }
|
|
169
169
|
: undefined;
|
|
170
170
|
return { filePart, imagePart };
|
|
171
171
|
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Check if a URL points to localhost
|
|
175
|
+
*/
|
|
176
|
+
function isLocalhostUrl(url: URL): boolean {
|
|
177
|
+
return (
|
|
178
|
+
url.hostname === "localhost" ||
|
|
179
|
+
url.hostname === "127.0.0.1" ||
|
|
180
|
+
url.hostname === "::1" ||
|
|
181
|
+
url.hostname === "0.0.0.0"
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Download a file from a URL
|
|
187
|
+
*/
|
|
188
|
+
async function downloadFile(url: URL): Promise<ArrayBuffer> {
|
|
189
|
+
// Fetch the file
|
|
190
|
+
const response = await fetch(url);
|
|
191
|
+
if (!response.ok) {
|
|
192
|
+
throw new Error(`Failed to fetch ${url}: ${response.statusText}`);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return await response.arrayBuffer();
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Process messages to inline file and image URLs that point to localhost
|
|
200
|
+
* by converting them to base64. This solves the problem of LLMs not being
|
|
201
|
+
* able to access localhost URLs.
|
|
202
|
+
*/
|
|
203
|
+
export async function inlineMessagesFiles(
|
|
204
|
+
messages: (ModelMessage | Message)[],
|
|
205
|
+
): Promise<(ModelMessage | Message)[]> {
|
|
206
|
+
// Process each message to convert localhost URLs to base64
|
|
207
|
+
return Promise.all(
|
|
208
|
+
messages.map(async (message): Promise<ModelMessage | Message> => {
|
|
209
|
+
if (
|
|
210
|
+
(message.role !== "user" && message.role !== "assistant") ||
|
|
211
|
+
typeof message.content === "string" ||
|
|
212
|
+
!Array.isArray(message.content)
|
|
213
|
+
) {
|
|
214
|
+
return message;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const processedContent = await Promise.all(
|
|
218
|
+
message.content.map(async (part) => {
|
|
219
|
+
if (part.type === "image" && part.image instanceof URL) {
|
|
220
|
+
assert(
|
|
221
|
+
message.role === "user",
|
|
222
|
+
"Images can only be in user messages",
|
|
223
|
+
);
|
|
224
|
+
if (isLocalhostUrl(part.image)) {
|
|
225
|
+
const imageData = await downloadFile(part.image);
|
|
226
|
+
return { ...part, image: imageData } as ImagePart;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Handle file parts
|
|
231
|
+
if (part.type === "file" && part.data instanceof URL) {
|
|
232
|
+
if (isLocalhostUrl(part.data)) {
|
|
233
|
+
const fileData = await downloadFile(part.data);
|
|
234
|
+
return { ...part, data: fileData } as FilePart;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return part;
|
|
239
|
+
}),
|
|
240
|
+
);
|
|
241
|
+
if (message.role === "user") {
|
|
242
|
+
return { ...message, content: processedContent as UserContent };
|
|
243
|
+
} else {
|
|
244
|
+
return { ...message, content: processedContent as AssistantContent };
|
|
245
|
+
}
|
|
246
|
+
}),
|
|
247
|
+
);
|
|
248
|
+
}
|
package/src/client/index.test.ts
CHANGED
|
@@ -19,11 +19,14 @@ import type {
|
|
|
19
19
|
} from "convex/server";
|
|
20
20
|
import { v } from "convex/values";
|
|
21
21
|
import { defineSchema } from "convex/server";
|
|
22
|
-
import {
|
|
23
|
-
import type {
|
|
24
|
-
|
|
22
|
+
import { MockLanguageModelV2 } from "ai/test";
|
|
23
|
+
import type {
|
|
24
|
+
LanguageModelV2,
|
|
25
|
+
LanguageModelV2StreamPart,
|
|
26
|
+
} from "@ai-sdk/provider";
|
|
27
|
+
import { simulateReadableStream, stepCountIs } from "ai";
|
|
25
28
|
import { components, initConvexTest } from "./setup.test.js";
|
|
26
|
-
import { z } from "zod";
|
|
29
|
+
import { z } from "zod/v4";
|
|
27
30
|
|
|
28
31
|
const schema = defineSchema({});
|
|
29
32
|
type DataModel = DataModelFromSchemaDefinition<typeof schema>;
|
|
@@ -36,7 +39,7 @@ const agent = new Agent(components.agent, {
|
|
|
36
39
|
name: "test",
|
|
37
40
|
instructions: "You are a test agent",
|
|
38
41
|
// TODO: get mock model that works in v8
|
|
39
|
-
|
|
42
|
+
languageModel: mockModel(),
|
|
40
43
|
});
|
|
41
44
|
|
|
42
45
|
export const testQuery = query({
|
|
@@ -44,10 +47,7 @@ export const testQuery = query({
|
|
|
44
47
|
handler: async (ctx, args) => {
|
|
45
48
|
return await agent.listMessages(ctx, {
|
|
46
49
|
threadId: args.threadId,
|
|
47
|
-
paginationOpts: {
|
|
48
|
-
cursor: null,
|
|
49
|
-
numItems: 10,
|
|
50
|
-
},
|
|
50
|
+
paginationOpts: { cursor: null, numItems: 10 },
|
|
51
51
|
excludeToolMessages: true,
|
|
52
52
|
statuses: ["success"],
|
|
53
53
|
});
|
|
@@ -57,18 +57,14 @@ export const testQuery = query({
|
|
|
57
57
|
export const createThread = mutation({
|
|
58
58
|
args: {},
|
|
59
59
|
handler: async (ctx) => {
|
|
60
|
-
const { threadId } = await agent.createThread(ctx, {
|
|
61
|
-
userId: "1",
|
|
62
|
-
});
|
|
60
|
+
const { threadId } = await agent.createThread(ctx, { userId: "1" });
|
|
63
61
|
return { threadId };
|
|
64
62
|
},
|
|
65
63
|
});
|
|
66
64
|
|
|
67
65
|
export const createThreadMutation = agent.createThreadMutation();
|
|
68
66
|
export const generateObjectAction = agent.asObjectAction({
|
|
69
|
-
schema: z.object({
|
|
70
|
-
prompt: z.any().describe("The prompt passed in"),
|
|
71
|
-
}),
|
|
67
|
+
schema: z.object({ prompt: z.any().describe("The prompt passed in") }),
|
|
72
68
|
});
|
|
73
69
|
export const generateTextAction = agent.asTextAction({});
|
|
74
70
|
export const streamTextAction = agent.asTextAction({ stream: true });
|
|
@@ -77,9 +73,7 @@ export const saveMessageMutation = agent.asSaveMessagesMutation();
|
|
|
77
73
|
export const createAndGenerate = action({
|
|
78
74
|
args: {},
|
|
79
75
|
handler: async (ctx) => {
|
|
80
|
-
const { thread } = await agent.createThread(ctx, {
|
|
81
|
-
userId: "1",
|
|
82
|
-
});
|
|
76
|
+
const { thread } = await agent.createThread(ctx, { userId: "1" });
|
|
83
77
|
const result = await thread.generateText({
|
|
84
78
|
messages: [{ role: "user", content: "Hello" }],
|
|
85
79
|
});
|
|
@@ -233,10 +227,7 @@ describe("filterOutOrphanedToolMessages", () => {
|
|
|
233
227
|
order: 1,
|
|
234
228
|
stepOrder: 2,
|
|
235
229
|
tool: true,
|
|
236
|
-
message: {
|
|
237
|
-
role: "assistant",
|
|
238
|
-
content: [{ type: "text", text: "Hello" }],
|
|
239
|
-
},
|
|
230
|
+
message: { role: "assistant", content: [{ type: "text", text: "Hello" }] },
|
|
240
231
|
status: "success",
|
|
241
232
|
threadId: "1",
|
|
242
233
|
};
|
|
@@ -252,16 +243,16 @@ describe("filterOutOrphanedToolMessages", () => {
|
|
|
252
243
|
});
|
|
253
244
|
});
|
|
254
245
|
|
|
255
|
-
function mockModel():
|
|
256
|
-
return new
|
|
246
|
+
function mockModel(): LanguageModelV2 {
|
|
247
|
+
return new MockLanguageModelV2({
|
|
257
248
|
provider: "mock",
|
|
258
249
|
modelId: "mock",
|
|
259
|
-
defaultObjectGenerationMode: "json",
|
|
260
250
|
// supportsStructuredOutputs: true,
|
|
261
251
|
doGenerate: async ({ prompt }) => ({
|
|
262
252
|
finishReason: "stop",
|
|
263
|
-
|
|
264
|
-
|
|
253
|
+
content: [{ type: "text", text: JSON.stringify({ prompt }) }],
|
|
254
|
+
warnings: [],
|
|
255
|
+
usage: { outputTokens: 10, inputTokens: 3, totalTokens: 13 },
|
|
265
256
|
rawCall: { rawPrompt: null, rawSettings: {} },
|
|
266
257
|
text: JSON.stringify({ prompt }),
|
|
267
258
|
}),
|
|
@@ -277,10 +268,9 @@ function mockModel(): LanguageModelV1 {
|
|
|
277
268
|
{
|
|
278
269
|
type: "finish",
|
|
279
270
|
finishReason: "stop",
|
|
280
|
-
|
|
281
|
-
usage: { completionTokens: 10, promptTokens: 3 },
|
|
271
|
+
usage: { outputTokens: 10, inputTokens: 3, totalTokens: 13 },
|
|
282
272
|
},
|
|
283
|
-
] as
|
|
273
|
+
] as LanguageModelV2StreamPart[],
|
|
284
274
|
}),
|
|
285
275
|
rawCall: { rawPrompt: null, rawSettings: {} },
|
|
286
276
|
}),
|
|
@@ -289,19 +279,19 @@ function mockModel(): LanguageModelV1 {
|
|
|
289
279
|
|
|
290
280
|
describe("Agent option variations and normal behavior", () => {
|
|
291
281
|
test("Agent can be constructed with minimal options", () => {
|
|
292
|
-
const a = new Agent(components.agent, {
|
|
282
|
+
const a = new Agent(components.agent, { languageModel: mockModel() });
|
|
293
283
|
expect(a).toBeInstanceOf(Agent);
|
|
294
284
|
});
|
|
295
285
|
|
|
296
286
|
test("Agent can be constructed with all options", () => {
|
|
297
287
|
const a = new Agent(components.agent, {
|
|
298
288
|
name: "full",
|
|
299
|
-
|
|
289
|
+
languageModel: mockModel(),
|
|
300
290
|
instructions: "Test instructions",
|
|
301
291
|
contextOptions: { recentMessages: 5 },
|
|
302
292
|
storageOptions: { saveMessages: "all" },
|
|
303
|
-
|
|
304
|
-
maxRetries: 1,
|
|
293
|
+
stopWhen: stepCountIs(2),
|
|
294
|
+
callSettings: { maxRetries: 1 },
|
|
305
295
|
usageHandler: async () => {},
|
|
306
296
|
rawRequestResponseHandler: async () => {},
|
|
307
297
|
});
|
|
@@ -346,7 +336,7 @@ describe("Agent message operations", () => {
|
|
|
346
336
|
);
|
|
347
337
|
expect(messageId).toBeTypeOf("string");
|
|
348
338
|
|
|
349
|
-
const {
|
|
339
|
+
const { messages } = await t.run(async (ctx) =>
|
|
350
340
|
agent.saveMessages(ctx, {
|
|
351
341
|
threadId,
|
|
352
342
|
userId: "4",
|
|
@@ -357,7 +347,7 @@ describe("Agent message operations", () => {
|
|
|
357
347
|
}),
|
|
358
348
|
);
|
|
359
349
|
expect(messages.length).toBe(2);
|
|
360
|
-
expect(
|
|
350
|
+
expect(messages[1]._id).toBeDefined();
|
|
361
351
|
});
|
|
362
352
|
});
|
|
363
353
|
|
|
@@ -433,8 +423,8 @@ describe("Agent-generated mutations/actions/queries", () => {
|
|
|
433
423
|
},
|
|
434
424
|
],
|
|
435
425
|
});
|
|
436
|
-
expect(result.
|
|
437
|
-
expect(result.
|
|
426
|
+
expect(result.messages.length).toBe(1);
|
|
427
|
+
expect(result.messages[0]._id).toBeDefined();
|
|
438
428
|
});
|
|
439
429
|
});
|
|
440
430
|
|