@livekit/agents 1.0.14 → 1.0.16
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/cli.cjs +12 -12
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +3 -3
- package/dist/cli.d.ts +3 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +13 -13
- package/dist/cli.js.map +1 -1
- package/dist/inference/stt.cjs.map +1 -1
- package/dist/inference/stt.d.ts.map +1 -1
- package/dist/inference/stt.js +1 -1
- package/dist/inference/stt.js.map +1 -1
- package/dist/inference/tts.cjs.map +1 -1
- package/dist/inference/tts.d.cts +2 -1
- package/dist/inference/tts.d.ts +2 -1
- package/dist/inference/tts.d.ts.map +1 -1
- package/dist/inference/tts.js +1 -5
- package/dist/inference/tts.js.map +1 -1
- package/dist/llm/chat_context.cjs +78 -0
- package/dist/llm/chat_context.cjs.map +1 -1
- package/dist/llm/chat_context.d.cts +16 -0
- package/dist/llm/chat_context.d.ts +16 -0
- package/dist/llm/chat_context.d.ts.map +1 -1
- package/dist/llm/chat_context.js +78 -0
- package/dist/llm/chat_context.js.map +1 -1
- package/dist/llm/chat_context.test.cjs +531 -0
- package/dist/llm/chat_context.test.cjs.map +1 -1
- package/dist/llm/chat_context.test.js +531 -0
- package/dist/llm/chat_context.test.js.map +1 -1
- package/dist/llm/tool_context.cjs +43 -2
- package/dist/llm/tool_context.cjs.map +1 -1
- package/dist/llm/tool_context.d.cts +39 -11
- package/dist/llm/tool_context.d.ts +39 -11
- package/dist/llm/tool_context.d.ts.map +1 -1
- package/dist/llm/tool_context.js +42 -3
- package/dist/llm/tool_context.js.map +1 -1
- package/dist/llm/tool_context.test.cjs +197 -0
- package/dist/llm/tool_context.test.cjs.map +1 -1
- package/dist/llm/tool_context.test.js +175 -0
- package/dist/llm/tool_context.test.js.map +1 -1
- package/dist/llm/utils.cjs +17 -11
- package/dist/llm/utils.cjs.map +1 -1
- package/dist/llm/utils.d.cts +1 -2
- package/dist/llm/utils.d.ts +1 -2
- package/dist/llm/utils.d.ts.map +1 -1
- package/dist/llm/utils.js +17 -11
- package/dist/llm/utils.js.map +1 -1
- package/dist/llm/zod-utils.cjs +99 -0
- package/dist/llm/zod-utils.cjs.map +1 -0
- package/dist/llm/zod-utils.d.cts +65 -0
- package/dist/llm/zod-utils.d.ts +65 -0
- package/dist/llm/zod-utils.d.ts.map +1 -0
- package/dist/llm/zod-utils.js +61 -0
- package/dist/llm/zod-utils.js.map +1 -0
- package/dist/llm/zod-utils.test.cjs +389 -0
- package/dist/llm/zod-utils.test.cjs.map +1 -0
- package/dist/llm/zod-utils.test.js +372 -0
- package/dist/llm/zod-utils.test.js.map +1 -0
- package/dist/metrics/base.cjs.map +1 -1
- package/dist/metrics/base.d.cts +7 -0
- package/dist/metrics/base.d.ts +7 -0
- package/dist/metrics/base.d.ts.map +1 -1
- package/dist/stt/stt.cjs +1 -0
- package/dist/stt/stt.cjs.map +1 -1
- package/dist/stt/stt.d.cts +7 -1
- package/dist/stt/stt.d.ts +7 -1
- package/dist/stt/stt.d.ts.map +1 -1
- package/dist/stt/stt.js +1 -0
- package/dist/stt/stt.js.map +1 -1
- package/dist/vad.cjs +16 -0
- package/dist/vad.cjs.map +1 -1
- package/dist/vad.d.cts +6 -0
- package/dist/vad.d.ts +6 -0
- package/dist/vad.d.ts.map +1 -1
- package/dist/vad.js +16 -0
- package/dist/vad.js.map +1 -1
- package/dist/voice/agent_activity.cjs +83 -8
- package/dist/voice/agent_activity.cjs.map +1 -1
- package/dist/voice/agent_activity.d.cts +6 -2
- package/dist/voice/agent_activity.d.ts +6 -2
- package/dist/voice/agent_activity.d.ts.map +1 -1
- package/dist/voice/agent_activity.js +83 -8
- package/dist/voice/agent_activity.js.map +1 -1
- package/dist/voice/agent_session.cjs +3 -2
- package/dist/voice/agent_session.cjs.map +1 -1
- package/dist/voice/agent_session.d.cts +2 -1
- package/dist/voice/agent_session.d.ts +2 -1
- package/dist/voice/agent_session.d.ts.map +1 -1
- package/dist/voice/agent_session.js +3 -2
- package/dist/voice/agent_session.js.map +1 -1
- package/dist/voice/audio_recognition.cjs +138 -16
- package/dist/voice/audio_recognition.cjs.map +1 -1
- package/dist/voice/audio_recognition.d.cts +11 -0
- package/dist/voice/audio_recognition.d.ts +11 -0
- package/dist/voice/audio_recognition.d.ts.map +1 -1
- package/dist/voice/audio_recognition.js +138 -16
- package/dist/voice/audio_recognition.js.map +1 -1
- package/dist/voice/generation.cjs +8 -3
- package/dist/voice/generation.cjs.map +1 -1
- package/dist/voice/generation.d.ts.map +1 -1
- package/dist/voice/generation.js +8 -3
- package/dist/voice/generation.js.map +1 -1
- package/dist/voice/room_io/_input.cjs.map +1 -1
- package/dist/voice/room_io/_input.d.ts.map +1 -1
- package/dist/voice/room_io/_input.js +0 -1
- package/dist/voice/room_io/_input.js.map +1 -1
- package/dist/worker.cjs +17 -11
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.d.cts +16 -9
- package/dist/worker.d.ts +16 -9
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +16 -12
- package/dist/worker.js.map +1 -1
- package/package.json +5 -4
- package/src/cli.ts +17 -17
- package/src/inference/stt.ts +2 -1
- package/src/inference/tts.ts +2 -5
- package/src/llm/__snapshots__/zod-utils.test.ts.snap +341 -0
- package/src/llm/chat_context.test.ts +607 -0
- package/src/llm/chat_context.ts +106 -0
- package/src/llm/tool_context.test.ts +210 -1
- package/src/llm/tool_context.ts +101 -17
- package/src/llm/utils.ts +18 -15
- package/src/llm/zod-utils.test.ts +476 -0
- package/src/llm/zod-utils.ts +144 -0
- package/src/metrics/base.ts +7 -0
- package/src/stt/stt.ts +6 -0
- package/src/vad.ts +18 -0
- package/src/voice/agent_activity.ts +119 -9
- package/src/voice/agent_session.ts +3 -1
- package/src/voice/audio_recognition.ts +235 -57
- package/src/voice/generation.ts +8 -3
- package/src/voice/room_io/_input.ts +1 -1
- package/src/worker.ts +29 -18
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (let key of __getOwnPropNames(from))
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
12
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
13
|
+
}
|
|
14
|
+
return to;
|
|
15
|
+
};
|
|
16
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
2
24
|
var import_vitest = require("vitest");
|
|
3
25
|
var import_zod = require("zod");
|
|
26
|
+
var z3 = __toESM(require("zod/v3"), 1);
|
|
27
|
+
var z4 = __toESM(require("zod/v4"), 1);
|
|
4
28
|
var import_tool_context = require("./tool_context.cjs");
|
|
5
29
|
var import_utils = require("./utils.cjs");
|
|
6
30
|
(0, import_vitest.describe)("Tool Context", () => {
|
|
@@ -136,6 +160,31 @@ var import_utils = require("./utils.cjs");
|
|
|
136
160
|
const result = await simpleAction.execute({}, (0, import_utils.createToolOptions)("123"));
|
|
137
161
|
(0, import_vitest.expect)(result).toBe("Action performed");
|
|
138
162
|
});
|
|
163
|
+
(0, import_vitest.it)("should support .optional() fields in tool parameters", async () => {
|
|
164
|
+
const weatherTool = (0, import_tool_context.tool)({
|
|
165
|
+
description: "Get weather information",
|
|
166
|
+
parameters: import_zod.z.object({
|
|
167
|
+
location: import_zod.z.string().describe("The city or location").optional(),
|
|
168
|
+
units: import_zod.z.enum(["celsius", "fahrenheit"]).describe("Temperature units").optional()
|
|
169
|
+
}),
|
|
170
|
+
execute: async ({ location, units }) => {
|
|
171
|
+
const loc = location ?? "Unknown";
|
|
172
|
+
const unit = units ?? "celsius";
|
|
173
|
+
return `Weather in ${loc} (${unit})`;
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
(0, import_vitest.expect)(weatherTool.type).toBe("function");
|
|
177
|
+
(0, import_vitest.expect)(weatherTool.description).toBe("Get weather information");
|
|
178
|
+
const result1 = await weatherTool.execute(
|
|
179
|
+
{ location: "London", units: "celsius" },
|
|
180
|
+
(0, import_utils.createToolOptions)("123")
|
|
181
|
+
);
|
|
182
|
+
(0, import_vitest.expect)(result1).toBe("Weather in London (celsius)");
|
|
183
|
+
const result2 = await weatherTool.execute({}, (0, import_utils.createToolOptions)("123"));
|
|
184
|
+
(0, import_vitest.expect)(result2).toBe("Weather in Unknown (celsius)");
|
|
185
|
+
const result3 = await weatherTool.execute({ location: "Paris" }, (0, import_utils.createToolOptions)("123"));
|
|
186
|
+
(0, import_vitest.expect)(result3).toBe("Weather in Paris (celsius)");
|
|
187
|
+
});
|
|
139
188
|
(0, import_vitest.it)("should handle tools with context but no parameters", async () => {
|
|
140
189
|
const greetUser = (0, import_tool_context.tool)({
|
|
141
190
|
description: "Greet the current user",
|
|
@@ -157,6 +206,154 @@ var import_utils = require("./utils.cjs");
|
|
|
157
206
|
(0, import_vitest.expect)(result).toBe("Tool call ID: test-id-456");
|
|
158
207
|
});
|
|
159
208
|
});
|
|
209
|
+
(0, import_vitest.describe)("Zod v3 and v4 compatibility", () => {
|
|
210
|
+
(0, import_vitest.it)("should work with Zod v3 schemas", async () => {
|
|
211
|
+
const v3Tool = (0, import_tool_context.tool)({
|
|
212
|
+
description: "A tool using Zod v3 schema",
|
|
213
|
+
parameters: z3.object({
|
|
214
|
+
name: z3.string(),
|
|
215
|
+
count: z3.number()
|
|
216
|
+
}),
|
|
217
|
+
execute: async ({ name, count }) => {
|
|
218
|
+
return `${name}: ${count}`;
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
const result = await v3Tool.execute(
|
|
222
|
+
{ name: "Test", count: 42 },
|
|
223
|
+
(0, import_utils.createToolOptions)("v3-test")
|
|
224
|
+
);
|
|
225
|
+
(0, import_vitest.expect)(result).toBe("Test: 42");
|
|
226
|
+
});
|
|
227
|
+
(0, import_vitest.it)("should work with Zod v4 schemas", async () => {
|
|
228
|
+
const v4Tool = (0, import_tool_context.tool)({
|
|
229
|
+
description: "A tool using Zod v4 schema",
|
|
230
|
+
parameters: z4.object({
|
|
231
|
+
name: z4.string(),
|
|
232
|
+
count: z4.number()
|
|
233
|
+
}),
|
|
234
|
+
execute: async ({ name, count }) => {
|
|
235
|
+
return `${name}: ${count}`;
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
const result = await v4Tool.execute(
|
|
239
|
+
{ name: "Test", count: 42 },
|
|
240
|
+
(0, import_utils.createToolOptions)("v4-test")
|
|
241
|
+
);
|
|
242
|
+
(0, import_vitest.expect)(result).toBe("Test: 42");
|
|
243
|
+
});
|
|
244
|
+
(0, import_vitest.it)("should handle v4 schemas with optional fields", async () => {
|
|
245
|
+
const v4Tool = (0, import_tool_context.tool)({
|
|
246
|
+
description: "Tool with optional field using v4",
|
|
247
|
+
parameters: z4.object({
|
|
248
|
+
required: z4.string(),
|
|
249
|
+
optional: z4.string().optional()
|
|
250
|
+
}),
|
|
251
|
+
execute: async ({ required, optional }) => {
|
|
252
|
+
return optional ? `${required} - ${optional}` : required;
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
const result1 = await v4Tool.execute({ required: "Hello" }, (0, import_utils.createToolOptions)("test-1"));
|
|
256
|
+
(0, import_vitest.expect)(result1).toBe("Hello");
|
|
257
|
+
const result2 = await v4Tool.execute(
|
|
258
|
+
{ required: "Hello", optional: "World" },
|
|
259
|
+
(0, import_utils.createToolOptions)("test-2")
|
|
260
|
+
);
|
|
261
|
+
(0, import_vitest.expect)(result2).toBe("Hello - World");
|
|
262
|
+
});
|
|
263
|
+
(0, import_vitest.it)("should handle v4 enum schemas", async () => {
|
|
264
|
+
const v4Tool = (0, import_tool_context.tool)({
|
|
265
|
+
description: "Tool with enum using v4",
|
|
266
|
+
parameters: z4.object({
|
|
267
|
+
color: z4.enum(["red", "blue", "green"])
|
|
268
|
+
}),
|
|
269
|
+
execute: async ({ color }) => {
|
|
270
|
+
return `Selected color: ${color}`;
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
const result = await v4Tool.execute({ color: "blue" }, (0, import_utils.createToolOptions)("test-enum"));
|
|
274
|
+
(0, import_vitest.expect)(result).toBe("Selected color: blue");
|
|
275
|
+
});
|
|
276
|
+
(0, import_vitest.it)("should handle v4 array schemas", async () => {
|
|
277
|
+
const v4Tool = (0, import_tool_context.tool)({
|
|
278
|
+
description: "Tool with array using v4",
|
|
279
|
+
parameters: z4.object({
|
|
280
|
+
tags: z4.array(z4.string())
|
|
281
|
+
}),
|
|
282
|
+
execute: async ({ tags }) => {
|
|
283
|
+
return `Tags: ${tags.join(", ")}`;
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
const result = await v4Tool.execute(
|
|
287
|
+
{ tags: ["nodejs", "typescript", "testing"] },
|
|
288
|
+
(0, import_utils.createToolOptions)("test-array")
|
|
289
|
+
);
|
|
290
|
+
(0, import_vitest.expect)(result).toBe("Tags: nodejs, typescript, testing");
|
|
291
|
+
});
|
|
292
|
+
(0, import_vitest.it)("should handle v4 nested object schemas", async () => {
|
|
293
|
+
const v4Tool = (0, import_tool_context.tool)({
|
|
294
|
+
description: "Tool with nested object using v4",
|
|
295
|
+
parameters: z4.object({
|
|
296
|
+
user: z4.object({
|
|
297
|
+
name: z4.string(),
|
|
298
|
+
email: z4.string()
|
|
299
|
+
})
|
|
300
|
+
}),
|
|
301
|
+
execute: async ({ user }) => {
|
|
302
|
+
return `${user.name} (${user.email})`;
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
const result = await v4Tool.execute(
|
|
306
|
+
{ user: { name: "John Doe", email: "john@example.com" } },
|
|
307
|
+
(0, import_utils.createToolOptions)("test-nested")
|
|
308
|
+
);
|
|
309
|
+
(0, import_vitest.expect)(result).toBe("John Doe (john@example.com)");
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
(0, import_vitest.describe)("oaiParams with v4 schemas", () => {
|
|
313
|
+
(0, import_vitest.it)("should convert v4 basic object schema", () => {
|
|
314
|
+
const schema = z4.object({
|
|
315
|
+
name: z4.string().describe("User name"),
|
|
316
|
+
age: z4.number().describe("User age")
|
|
317
|
+
});
|
|
318
|
+
const result = (0, import_utils.oaiParams)(schema);
|
|
319
|
+
(0, import_vitest.expect)(result.type).toBe("object");
|
|
320
|
+
(0, import_vitest.expect)(result.properties).toHaveProperty("name");
|
|
321
|
+
(0, import_vitest.expect)(result.properties).toHaveProperty("age");
|
|
322
|
+
(0, import_vitest.expect)(result.required).toContain("name");
|
|
323
|
+
(0, import_vitest.expect)(result.required).toContain("age");
|
|
324
|
+
});
|
|
325
|
+
(0, import_vitest.it)("should handle v4 optional fields", () => {
|
|
326
|
+
const schema = z4.object({
|
|
327
|
+
required: z4.string(),
|
|
328
|
+
optional: z4.string().optional()
|
|
329
|
+
});
|
|
330
|
+
const result = (0, import_utils.oaiParams)(schema);
|
|
331
|
+
(0, import_vitest.expect)(result.required).toContain("required");
|
|
332
|
+
(0, import_vitest.expect)(result.required).not.toContain("optional");
|
|
333
|
+
});
|
|
334
|
+
(0, import_vitest.it)("should handle v4 enum fields", () => {
|
|
335
|
+
var _a;
|
|
336
|
+
const schema = z4.object({
|
|
337
|
+
status: z4.enum(["pending", "approved", "rejected"])
|
|
338
|
+
});
|
|
339
|
+
const result = (0, import_utils.oaiParams)(schema);
|
|
340
|
+
const properties = result.properties;
|
|
341
|
+
(0, import_vitest.expect)((_a = properties.status) == null ? void 0 : _a.enum).toEqual(["pending", "approved", "rejected"]);
|
|
342
|
+
});
|
|
343
|
+
(0, import_vitest.it)("should handle v4 array fields", () => {
|
|
344
|
+
const schema = z4.object({
|
|
345
|
+
items: z4.array(z4.string())
|
|
346
|
+
});
|
|
347
|
+
const result = (0, import_utils.oaiParams)(schema);
|
|
348
|
+
const properties = result.properties;
|
|
349
|
+
(0, import_vitest.expect)(
|
|
350
|
+
properties.items && typeof properties.items === "object" ? properties.items.type : void 0
|
|
351
|
+
).toBe("array");
|
|
352
|
+
(0, import_vitest.expect)(
|
|
353
|
+
properties.items && properties.items.items && typeof properties.items.items === "object" ? properties.items.items.type : void 0
|
|
354
|
+
).toBe("string");
|
|
355
|
+
});
|
|
356
|
+
});
|
|
160
357
|
});
|
|
161
358
|
});
|
|
162
359
|
//# sourceMappingURL=tool_context.test.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/llm/tool_context.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { describe, expect, it } from 'vitest';\nimport { z } from 'zod';\nimport { type ToolOptions, tool } from './tool_context.js';\nimport { createToolOptions, oaiParams } from './utils.js';\n\ndescribe('Tool Context', () => {\n describe('oaiParams', () => {\n it('should handle basic object schema', () => {\n const schema = z.object({\n name: z.string().describe('The user name'),\n age: z.number().describe('The user age'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle enum fields', () => {\n const schema = z.object({\n color: z.enum(['red', 'blue', 'green']).describe('Choose a color'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle array fields', () => {\n const schema = z.object({\n tags: z.array(z.string()).describe('List of tags'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle array of enums', () => {\n const schema = z.object({\n colors: z.array(z.enum(['red', 'blue', 'green'])).describe('List of colors'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle optional fields', () => {\n const schema = z.object({\n name: z.string().describe('The user name'),\n age: z.number().optional().describe('The user age'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle fields without descriptions', () => {\n const schema = z.object({\n name: z.string(),\n age: z.number(),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n });\n\n describe('tool', () => {\n it('should create and execute a basic core tool', async () => {\n const getWeather = tool({\n description: 'Get the weather for a given location',\n parameters: z.object({\n location: z.string(),\n }),\n execute: async ({ location }, { ctx }: ToolOptions<{ name: string }>) => {\n return `The weather in ${location} is sunny, ${ctx.userData.name}`;\n },\n });\n\n const result = await getWeather.execute(\n { location: 'San Francisco' },\n createToolOptions('123', { name: 'John' }),\n );\n expect(result).toBe('The weather in San Francisco is sunny, John');\n });\n\n it('should properly type a callable function', async () => {\n const testFunction = tool({\n description: 'Test function',\n parameters: z.object({\n name: z.string().describe('The user name'),\n age: z.number().describe('The user age'),\n }),\n execute: async (args) => {\n return `${args.name} is ${args.age} years old`;\n },\n });\n\n const result = await testFunction.execute(\n { name: 'John', age: 30 },\n createToolOptions('123'),\n );\n expect(result).toBe('John is 30 years old');\n });\n\n it('should handle async execution', async () => {\n const testFunction = tool({\n description: 'Async test function',\n parameters: z.object({\n delay: z.number().describe('Delay in milliseconds'),\n }),\n execute: async (args) => {\n await new Promise((resolve) => setTimeout(resolve, args.delay));\n return args.delay;\n },\n });\n\n const start = Date.now();\n const result = await testFunction.execute({ delay: 100 }, createToolOptions('123'));\n const duration = Date.now() - start;\n\n expect(result).toBe(100);\n expect(duration).toBeGreaterThanOrEqual(95); // Allow for small timing variations\n });\n\n describe('nested array support', () => {\n it('should handle nested array fields', () => {\n const schema = z.object({\n items: z.array(\n z.object({\n name: z.string().describe('the item name'),\n modifiers: z\n .array(\n z.object({\n modifier_name: z.string(),\n modifier_value: z.string(),\n }),\n )\n .describe('list of the modifiers applied on this item, such as size'),\n }),\n ),\n });\n const result = oaiParams(schema);\n expect(result).toMatchSnapshot();\n });\n });\n\n describe('optional parameters', () => {\n it('should create a tool without parameters', async () => {\n const simpleAction = tool({\n description: 'Perform a simple action',\n execute: async () => {\n return 'Action performed';\n },\n });\n\n expect(simpleAction.type).toBe('function');\n expect(simpleAction.description).toBe('Perform a simple action');\n expect(simpleAction.parameters).toBeDefined();\n expect(simpleAction.parameters._def.typeName).toBe('ZodObject');\n\n const result = await simpleAction.execute({}, createToolOptions('123'));\n expect(result).toBe('Action performed');\n });\n\n it('should handle tools with context but no parameters', async () => {\n const greetUser = tool({\n description: 'Greet the current user',\n execute: async (_, { ctx }: ToolOptions<{ username: string }>) => {\n return `Hello, ${ctx.userData.username}!`;\n },\n });\n\n const result = await greetUser.execute({}, createToolOptions('123', { username: 'Alice' }));\n expect(result).toBe('Hello, Alice!');\n });\n\n it('should create a tool that accesses tool call id without parameters', async () => {\n const getCallId = tool({\n description: 'Get the current tool call ID',\n execute: async (_, { toolCallId }) => {\n return `Tool call ID: ${toolCallId}`;\n },\n });\n\n const result = await getCallId.execute({}, createToolOptions('test-id-456'));\n expect(result).toBe('Tool call ID: test-id-456');\n });\n });\n });\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/llm/tool_context.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { describe, expect, it } from 'vitest';\nimport { z } from 'zod';\nimport * as z3 from 'zod/v3';\nimport * as z4 from 'zod/v4';\nimport { type ToolOptions, tool } from './tool_context.js';\nimport { createToolOptions, oaiParams } from './utils.js';\n\ndescribe('Tool Context', () => {\n describe('oaiParams', () => {\n it('should handle basic object schema', () => {\n const schema = z.object({\n name: z.string().describe('The user name'),\n age: z.number().describe('The user age'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle enum fields', () => {\n const schema = z.object({\n color: z.enum(['red', 'blue', 'green']).describe('Choose a color'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle array fields', () => {\n const schema = z.object({\n tags: z.array(z.string()).describe('List of tags'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle array of enums', () => {\n const schema = z.object({\n colors: z.array(z.enum(['red', 'blue', 'green'])).describe('List of colors'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle optional fields', () => {\n const schema = z.object({\n name: z.string().describe('The user name'),\n age: z.number().optional().describe('The user age'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle fields without descriptions', () => {\n const schema = z.object({\n name: z.string(),\n age: z.number(),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n });\n\n describe('tool', () => {\n it('should create and execute a basic core tool', async () => {\n const getWeather = tool({\n description: 'Get the weather for a given location',\n parameters: z.object({\n location: z.string(),\n }),\n execute: async ({ location }, { ctx }: ToolOptions<{ name: string }>) => {\n return `The weather in ${location} is sunny, ${ctx.userData.name}`;\n },\n });\n\n const result = await getWeather.execute(\n { location: 'San Francisco' },\n createToolOptions('123', { name: 'John' }),\n );\n expect(result).toBe('The weather in San Francisco is sunny, John');\n });\n\n it('should properly type a callable function', async () => {\n const testFunction = tool({\n description: 'Test function',\n parameters: z.object({\n name: z.string().describe('The user name'),\n age: z.number().describe('The user age'),\n }),\n execute: async (args) => {\n return `${args.name} is ${args.age} years old`;\n },\n });\n\n const result = await testFunction.execute(\n { name: 'John', age: 30 },\n createToolOptions('123'),\n );\n expect(result).toBe('John is 30 years old');\n });\n\n it('should handle async execution', async () => {\n const testFunction = tool({\n description: 'Async test function',\n parameters: z.object({\n delay: z.number().describe('Delay in milliseconds'),\n }),\n execute: async (args) => {\n await new Promise((resolve) => setTimeout(resolve, args.delay));\n return args.delay;\n },\n });\n\n const start = Date.now();\n const result = await testFunction.execute({ delay: 100 }, createToolOptions('123'));\n const duration = Date.now() - start;\n\n expect(result).toBe(100);\n expect(duration).toBeGreaterThanOrEqual(95); // Allow for small timing variations\n });\n\n describe('nested array support', () => {\n it('should handle nested array fields', () => {\n const schema = z.object({\n items: z.array(\n z.object({\n name: z.string().describe('the item name'),\n modifiers: z\n .array(\n z.object({\n modifier_name: z.string(),\n modifier_value: z.string(),\n }),\n )\n .describe('list of the modifiers applied on this item, such as size'),\n }),\n ),\n });\n const result = oaiParams(schema);\n expect(result).toMatchSnapshot();\n });\n });\n\n describe('optional parameters', () => {\n it('should create a tool without parameters', async () => {\n const simpleAction = tool({\n description: 'Perform a simple action',\n execute: async () => {\n return 'Action performed';\n },\n });\n\n expect(simpleAction.type).toBe('function');\n expect(simpleAction.description).toBe('Perform a simple action');\n expect(simpleAction.parameters).toBeDefined();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n expect((simpleAction.parameters as any)._def.typeName).toBe('ZodObject');\n\n const result = await simpleAction.execute({}, createToolOptions('123'));\n expect(result).toBe('Action performed');\n });\n\n it('should support .optional() fields in tool parameters', async () => {\n const weatherTool = tool({\n description: 'Get weather information',\n parameters: z.object({\n location: z.string().describe('The city or location').optional(),\n units: z.enum(['celsius', 'fahrenheit']).describe('Temperature units').optional(),\n }),\n execute: async ({ location, units }) => {\n const loc = location ?? 'Unknown';\n const unit = units ?? 'celsius';\n return `Weather in ${loc} (${unit})`;\n },\n });\n\n expect(weatherTool.type).toBe('function');\n expect(weatherTool.description).toBe('Get weather information');\n\n const result1 = await weatherTool.execute(\n { location: 'London', units: 'celsius' },\n createToolOptions('123'),\n );\n expect(result1).toBe('Weather in London (celsius)');\n\n const result2 = await weatherTool.execute({}, createToolOptions('123'));\n expect(result2).toBe('Weather in Unknown (celsius)');\n\n const result3 = await weatherTool.execute({ location: 'Paris' }, createToolOptions('123'));\n expect(result3).toBe('Weather in Paris (celsius)');\n });\n\n it('should handle tools with context but no parameters', async () => {\n const greetUser = tool({\n description: 'Greet the current user',\n execute: async (_, { ctx }: ToolOptions<{ username: string }>) => {\n return `Hello, ${ctx.userData.username}!`;\n },\n });\n\n const result = await greetUser.execute({}, createToolOptions('123', { username: 'Alice' }));\n expect(result).toBe('Hello, Alice!');\n });\n\n it('should create a tool that accesses tool call id without parameters', async () => {\n const getCallId = tool({\n description: 'Get the current tool call ID',\n execute: async (_, { toolCallId }) => {\n return `Tool call ID: ${toolCallId}`;\n },\n });\n\n const result = await getCallId.execute({}, createToolOptions('test-id-456'));\n expect(result).toBe('Tool call ID: test-id-456');\n });\n });\n\n describe('Zod v3 and v4 compatibility', () => {\n it('should work with Zod v3 schemas', async () => {\n const v3Tool = tool({\n description: 'A tool using Zod v3 schema',\n parameters: z3.object({\n name: z3.string(),\n count: z3.number(),\n }),\n execute: async ({ name, count }) => {\n return `${name}: ${count}`;\n },\n });\n\n const result = await v3Tool.execute(\n { name: 'Test', count: 42 },\n createToolOptions('v3-test'),\n );\n expect(result).toBe('Test: 42');\n });\n\n it('should work with Zod v4 schemas', async () => {\n const v4Tool = tool({\n description: 'A tool using Zod v4 schema',\n parameters: z4.object({\n name: z4.string(),\n count: z4.number(),\n }),\n execute: async ({ name, count }) => {\n return `${name}: ${count}`;\n },\n });\n\n const result = await v4Tool.execute(\n { name: 'Test', count: 42 },\n createToolOptions('v4-test'),\n );\n expect(result).toBe('Test: 42');\n });\n\n it('should handle v4 schemas with optional fields', async () => {\n const v4Tool = tool({\n description: 'Tool with optional field using v4',\n parameters: z4.object({\n required: z4.string(),\n optional: z4.string().optional(),\n }),\n execute: async ({ required, optional }) => {\n return optional ? `${required} - ${optional}` : required;\n },\n });\n\n const result1 = await v4Tool.execute({ required: 'Hello' }, createToolOptions('test-1'));\n expect(result1).toBe('Hello');\n\n const result2 = await v4Tool.execute(\n { required: 'Hello', optional: 'World' },\n createToolOptions('test-2'),\n );\n expect(result2).toBe('Hello - World');\n });\n\n it('should handle v4 enum schemas', async () => {\n const v4Tool = tool({\n description: 'Tool with enum using v4',\n parameters: z4.object({\n color: z4.enum(['red', 'blue', 'green']),\n }),\n execute: async ({ color }) => {\n return `Selected color: ${color}`;\n },\n });\n\n const result = await v4Tool.execute({ color: 'blue' }, createToolOptions('test-enum'));\n expect(result).toBe('Selected color: blue');\n });\n\n it('should handle v4 array schemas', async () => {\n const v4Tool = tool({\n description: 'Tool with array using v4',\n parameters: z4.object({\n tags: z4.array(z4.string()),\n }),\n execute: async ({ tags }) => {\n return `Tags: ${tags.join(', ')}`;\n },\n });\n\n const result = await v4Tool.execute(\n { tags: ['nodejs', 'typescript', 'testing'] },\n createToolOptions('test-array'),\n );\n expect(result).toBe('Tags: nodejs, typescript, testing');\n });\n\n it('should handle v4 nested object schemas', async () => {\n const v4Tool = tool({\n description: 'Tool with nested object using v4',\n parameters: z4.object({\n user: z4.object({\n name: z4.string(),\n email: z4.string(),\n }),\n }),\n execute: async ({ user }) => {\n return `${user.name} (${user.email})`;\n },\n });\n\n const result = await v4Tool.execute(\n { user: { name: 'John Doe', email: 'john@example.com' } },\n createToolOptions('test-nested'),\n );\n expect(result).toBe('John Doe (john@example.com)');\n });\n });\n\n describe('oaiParams with v4 schemas', () => {\n it('should convert v4 basic object schema', () => {\n const schema = z4.object({\n name: z4.string().describe('User name'),\n age: z4.number().describe('User age'),\n });\n\n const result = oaiParams(schema);\n\n expect(result.type).toBe('object');\n expect(result.properties).toHaveProperty('name');\n expect(result.properties).toHaveProperty('age');\n expect(result.required).toContain('name');\n expect(result.required).toContain('age');\n });\n\n it('should handle v4 optional fields', () => {\n const schema = z4.object({\n required: z4.string(),\n optional: z4.string().optional(),\n });\n\n const result = oaiParams(schema);\n\n expect(result.required).toContain('required');\n expect(result.required).not.toContain('optional');\n });\n\n it('should handle v4 enum fields', () => {\n const schema = z4.object({\n status: z4.enum(['pending', 'approved', 'rejected']),\n });\n\n const result = oaiParams(schema);\n\n const properties = result.properties as Record<string, Record<string, unknown>>;\n expect(properties.status?.enum).toEqual(['pending', 'approved', 'rejected']);\n });\n\n it('should handle v4 array fields', () => {\n const schema = z4.object({\n items: z4.array(z4.string()),\n });\n\n const result = oaiParams(schema);\n\n const properties = result.properties as Record<string, any>;\n expect(\n properties.items && typeof properties.items === 'object'\n ? properties.items.type\n : undefined,\n ).toBe('array');\n expect(\n properties.items && properties.items.items && typeof properties.items.items === 'object'\n ? properties.items.items.type\n : undefined,\n ).toBe('string');\n });\n });\n });\n});\n"],"mappings":"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","names":[]}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import * as z3 from "zod/v3";
|
|
4
|
+
import * as z4 from "zod/v4";
|
|
3
5
|
import { tool } from "./tool_context.js";
|
|
4
6
|
import { createToolOptions, oaiParams } from "./utils.js";
|
|
5
7
|
describe("Tool Context", () => {
|
|
@@ -135,6 +137,31 @@ describe("Tool Context", () => {
|
|
|
135
137
|
const result = await simpleAction.execute({}, createToolOptions("123"));
|
|
136
138
|
expect(result).toBe("Action performed");
|
|
137
139
|
});
|
|
140
|
+
it("should support .optional() fields in tool parameters", async () => {
|
|
141
|
+
const weatherTool = tool({
|
|
142
|
+
description: "Get weather information",
|
|
143
|
+
parameters: z.object({
|
|
144
|
+
location: z.string().describe("The city or location").optional(),
|
|
145
|
+
units: z.enum(["celsius", "fahrenheit"]).describe("Temperature units").optional()
|
|
146
|
+
}),
|
|
147
|
+
execute: async ({ location, units }) => {
|
|
148
|
+
const loc = location ?? "Unknown";
|
|
149
|
+
const unit = units ?? "celsius";
|
|
150
|
+
return `Weather in ${loc} (${unit})`;
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
expect(weatherTool.type).toBe("function");
|
|
154
|
+
expect(weatherTool.description).toBe("Get weather information");
|
|
155
|
+
const result1 = await weatherTool.execute(
|
|
156
|
+
{ location: "London", units: "celsius" },
|
|
157
|
+
createToolOptions("123")
|
|
158
|
+
);
|
|
159
|
+
expect(result1).toBe("Weather in London (celsius)");
|
|
160
|
+
const result2 = await weatherTool.execute({}, createToolOptions("123"));
|
|
161
|
+
expect(result2).toBe("Weather in Unknown (celsius)");
|
|
162
|
+
const result3 = await weatherTool.execute({ location: "Paris" }, createToolOptions("123"));
|
|
163
|
+
expect(result3).toBe("Weather in Paris (celsius)");
|
|
164
|
+
});
|
|
138
165
|
it("should handle tools with context but no parameters", async () => {
|
|
139
166
|
const greetUser = tool({
|
|
140
167
|
description: "Greet the current user",
|
|
@@ -156,6 +183,154 @@ describe("Tool Context", () => {
|
|
|
156
183
|
expect(result).toBe("Tool call ID: test-id-456");
|
|
157
184
|
});
|
|
158
185
|
});
|
|
186
|
+
describe("Zod v3 and v4 compatibility", () => {
|
|
187
|
+
it("should work with Zod v3 schemas", async () => {
|
|
188
|
+
const v3Tool = tool({
|
|
189
|
+
description: "A tool using Zod v3 schema",
|
|
190
|
+
parameters: z3.object({
|
|
191
|
+
name: z3.string(),
|
|
192
|
+
count: z3.number()
|
|
193
|
+
}),
|
|
194
|
+
execute: async ({ name, count }) => {
|
|
195
|
+
return `${name}: ${count}`;
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
const result = await v3Tool.execute(
|
|
199
|
+
{ name: "Test", count: 42 },
|
|
200
|
+
createToolOptions("v3-test")
|
|
201
|
+
);
|
|
202
|
+
expect(result).toBe("Test: 42");
|
|
203
|
+
});
|
|
204
|
+
it("should work with Zod v4 schemas", async () => {
|
|
205
|
+
const v4Tool = tool({
|
|
206
|
+
description: "A tool using Zod v4 schema",
|
|
207
|
+
parameters: z4.object({
|
|
208
|
+
name: z4.string(),
|
|
209
|
+
count: z4.number()
|
|
210
|
+
}),
|
|
211
|
+
execute: async ({ name, count }) => {
|
|
212
|
+
return `${name}: ${count}`;
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
const result = await v4Tool.execute(
|
|
216
|
+
{ name: "Test", count: 42 },
|
|
217
|
+
createToolOptions("v4-test")
|
|
218
|
+
);
|
|
219
|
+
expect(result).toBe("Test: 42");
|
|
220
|
+
});
|
|
221
|
+
it("should handle v4 schemas with optional fields", async () => {
|
|
222
|
+
const v4Tool = tool({
|
|
223
|
+
description: "Tool with optional field using v4",
|
|
224
|
+
parameters: z4.object({
|
|
225
|
+
required: z4.string(),
|
|
226
|
+
optional: z4.string().optional()
|
|
227
|
+
}),
|
|
228
|
+
execute: async ({ required, optional }) => {
|
|
229
|
+
return optional ? `${required} - ${optional}` : required;
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
const result1 = await v4Tool.execute({ required: "Hello" }, createToolOptions("test-1"));
|
|
233
|
+
expect(result1).toBe("Hello");
|
|
234
|
+
const result2 = await v4Tool.execute(
|
|
235
|
+
{ required: "Hello", optional: "World" },
|
|
236
|
+
createToolOptions("test-2")
|
|
237
|
+
);
|
|
238
|
+
expect(result2).toBe("Hello - World");
|
|
239
|
+
});
|
|
240
|
+
it("should handle v4 enum schemas", async () => {
|
|
241
|
+
const v4Tool = tool({
|
|
242
|
+
description: "Tool with enum using v4",
|
|
243
|
+
parameters: z4.object({
|
|
244
|
+
color: z4.enum(["red", "blue", "green"])
|
|
245
|
+
}),
|
|
246
|
+
execute: async ({ color }) => {
|
|
247
|
+
return `Selected color: ${color}`;
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
const result = await v4Tool.execute({ color: "blue" }, createToolOptions("test-enum"));
|
|
251
|
+
expect(result).toBe("Selected color: blue");
|
|
252
|
+
});
|
|
253
|
+
it("should handle v4 array schemas", async () => {
|
|
254
|
+
const v4Tool = tool({
|
|
255
|
+
description: "Tool with array using v4",
|
|
256
|
+
parameters: z4.object({
|
|
257
|
+
tags: z4.array(z4.string())
|
|
258
|
+
}),
|
|
259
|
+
execute: async ({ tags }) => {
|
|
260
|
+
return `Tags: ${tags.join(", ")}`;
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
const result = await v4Tool.execute(
|
|
264
|
+
{ tags: ["nodejs", "typescript", "testing"] },
|
|
265
|
+
createToolOptions("test-array")
|
|
266
|
+
);
|
|
267
|
+
expect(result).toBe("Tags: nodejs, typescript, testing");
|
|
268
|
+
});
|
|
269
|
+
it("should handle v4 nested object schemas", async () => {
|
|
270
|
+
const v4Tool = tool({
|
|
271
|
+
description: "Tool with nested object using v4",
|
|
272
|
+
parameters: z4.object({
|
|
273
|
+
user: z4.object({
|
|
274
|
+
name: z4.string(),
|
|
275
|
+
email: z4.string()
|
|
276
|
+
})
|
|
277
|
+
}),
|
|
278
|
+
execute: async ({ user }) => {
|
|
279
|
+
return `${user.name} (${user.email})`;
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
const result = await v4Tool.execute(
|
|
283
|
+
{ user: { name: "John Doe", email: "john@example.com" } },
|
|
284
|
+
createToolOptions("test-nested")
|
|
285
|
+
);
|
|
286
|
+
expect(result).toBe("John Doe (john@example.com)");
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
describe("oaiParams with v4 schemas", () => {
|
|
290
|
+
it("should convert v4 basic object schema", () => {
|
|
291
|
+
const schema = z4.object({
|
|
292
|
+
name: z4.string().describe("User name"),
|
|
293
|
+
age: z4.number().describe("User age")
|
|
294
|
+
});
|
|
295
|
+
const result = oaiParams(schema);
|
|
296
|
+
expect(result.type).toBe("object");
|
|
297
|
+
expect(result.properties).toHaveProperty("name");
|
|
298
|
+
expect(result.properties).toHaveProperty("age");
|
|
299
|
+
expect(result.required).toContain("name");
|
|
300
|
+
expect(result.required).toContain("age");
|
|
301
|
+
});
|
|
302
|
+
it("should handle v4 optional fields", () => {
|
|
303
|
+
const schema = z4.object({
|
|
304
|
+
required: z4.string(),
|
|
305
|
+
optional: z4.string().optional()
|
|
306
|
+
});
|
|
307
|
+
const result = oaiParams(schema);
|
|
308
|
+
expect(result.required).toContain("required");
|
|
309
|
+
expect(result.required).not.toContain("optional");
|
|
310
|
+
});
|
|
311
|
+
it("should handle v4 enum fields", () => {
|
|
312
|
+
var _a;
|
|
313
|
+
const schema = z4.object({
|
|
314
|
+
status: z4.enum(["pending", "approved", "rejected"])
|
|
315
|
+
});
|
|
316
|
+
const result = oaiParams(schema);
|
|
317
|
+
const properties = result.properties;
|
|
318
|
+
expect((_a = properties.status) == null ? void 0 : _a.enum).toEqual(["pending", "approved", "rejected"]);
|
|
319
|
+
});
|
|
320
|
+
it("should handle v4 array fields", () => {
|
|
321
|
+
const schema = z4.object({
|
|
322
|
+
items: z4.array(z4.string())
|
|
323
|
+
});
|
|
324
|
+
const result = oaiParams(schema);
|
|
325
|
+
const properties = result.properties;
|
|
326
|
+
expect(
|
|
327
|
+
properties.items && typeof properties.items === "object" ? properties.items.type : void 0
|
|
328
|
+
).toBe("array");
|
|
329
|
+
expect(
|
|
330
|
+
properties.items && properties.items.items && typeof properties.items.items === "object" ? properties.items.items.type : void 0
|
|
331
|
+
).toBe("string");
|
|
332
|
+
});
|
|
333
|
+
});
|
|
159
334
|
});
|
|
160
335
|
});
|
|
161
336
|
//# sourceMappingURL=tool_context.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/llm/tool_context.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { describe, expect, it } from 'vitest';\nimport { z } from 'zod';\nimport { type ToolOptions, tool } from './tool_context.js';\nimport { createToolOptions, oaiParams } from './utils.js';\n\ndescribe('Tool Context', () => {\n describe('oaiParams', () => {\n it('should handle basic object schema', () => {\n const schema = z.object({\n name: z.string().describe('The user name'),\n age: z.number().describe('The user age'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle enum fields', () => {\n const schema = z.object({\n color: z.enum(['red', 'blue', 'green']).describe('Choose a color'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle array fields', () => {\n const schema = z.object({\n tags: z.array(z.string()).describe('List of tags'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle array of enums', () => {\n const schema = z.object({\n colors: z.array(z.enum(['red', 'blue', 'green'])).describe('List of colors'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle optional fields', () => {\n const schema = z.object({\n name: z.string().describe('The user name'),\n age: z.number().optional().describe('The user age'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle fields without descriptions', () => {\n const schema = z.object({\n name: z.string(),\n age: z.number(),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n });\n\n describe('tool', () => {\n it('should create and execute a basic core tool', async () => {\n const getWeather = tool({\n description: 'Get the weather for a given location',\n parameters: z.object({\n location: z.string(),\n }),\n execute: async ({ location }, { ctx }: ToolOptions<{ name: string }>) => {\n return `The weather in ${location} is sunny, ${ctx.userData.name}`;\n },\n });\n\n const result = await getWeather.execute(\n { location: 'San Francisco' },\n createToolOptions('123', { name: 'John' }),\n );\n expect(result).toBe('The weather in San Francisco is sunny, John');\n });\n\n it('should properly type a callable function', async () => {\n const testFunction = tool({\n description: 'Test function',\n parameters: z.object({\n name: z.string().describe('The user name'),\n age: z.number().describe('The user age'),\n }),\n execute: async (args) => {\n return `${args.name} is ${args.age} years old`;\n },\n });\n\n const result = await testFunction.execute(\n { name: 'John', age: 30 },\n createToolOptions('123'),\n );\n expect(result).toBe('John is 30 years old');\n });\n\n it('should handle async execution', async () => {\n const testFunction = tool({\n description: 'Async test function',\n parameters: z.object({\n delay: z.number().describe('Delay in milliseconds'),\n }),\n execute: async (args) => {\n await new Promise((resolve) => setTimeout(resolve, args.delay));\n return args.delay;\n },\n });\n\n const start = Date.now();\n const result = await testFunction.execute({ delay: 100 }, createToolOptions('123'));\n const duration = Date.now() - start;\n\n expect(result).toBe(100);\n expect(duration).toBeGreaterThanOrEqual(95); // Allow for small timing variations\n });\n\n describe('nested array support', () => {\n it('should handle nested array fields', () => {\n const schema = z.object({\n items: z.array(\n z.object({\n name: z.string().describe('the item name'),\n modifiers: z\n .array(\n z.object({\n modifier_name: z.string(),\n modifier_value: z.string(),\n }),\n )\n .describe('list of the modifiers applied on this item, such as size'),\n }),\n ),\n });\n const result = oaiParams(schema);\n expect(result).toMatchSnapshot();\n });\n });\n\n describe('optional parameters', () => {\n it('should create a tool without parameters', async () => {\n const simpleAction = tool({\n description: 'Perform a simple action',\n execute: async () => {\n return 'Action performed';\n },\n });\n\n expect(simpleAction.type).toBe('function');\n expect(simpleAction.description).toBe('Perform a simple action');\n expect(simpleAction.parameters).toBeDefined();\n expect(simpleAction.parameters._def.typeName).toBe('ZodObject');\n\n const result = await simpleAction.execute({}, createToolOptions('123'));\n expect(result).toBe('Action performed');\n });\n\n it('should handle tools with context but no parameters', async () => {\n const greetUser = tool({\n description: 'Greet the current user',\n execute: async (_, { ctx }: ToolOptions<{ username: string }>) => {\n return `Hello, ${ctx.userData.username}!`;\n },\n });\n\n const result = await greetUser.execute({}, createToolOptions('123', { username: 'Alice' }));\n expect(result).toBe('Hello, Alice!');\n });\n\n it('should create a tool that accesses tool call id without parameters', async () => {\n const getCallId = tool({\n description: 'Get the current tool call ID',\n execute: async (_, { toolCallId }) => {\n return `Tool call ID: ${toolCallId}`;\n },\n });\n\n const result = await getCallId.execute({}, createToolOptions('test-id-456'));\n expect(result).toBe('Tool call ID: test-id-456');\n });\n });\n });\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/llm/tool_context.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { describe, expect, it } from 'vitest';\nimport { z } from 'zod';\nimport * as z3 from 'zod/v3';\nimport * as z4 from 'zod/v4';\nimport { type ToolOptions, tool } from './tool_context.js';\nimport { createToolOptions, oaiParams } from './utils.js';\n\ndescribe('Tool Context', () => {\n describe('oaiParams', () => {\n it('should handle basic object schema', () => {\n const schema = z.object({\n name: z.string().describe('The user name'),\n age: z.number().describe('The user age'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle enum fields', () => {\n const schema = z.object({\n color: z.enum(['red', 'blue', 'green']).describe('Choose a color'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle array fields', () => {\n const schema = z.object({\n tags: z.array(z.string()).describe('List of tags'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle array of enums', () => {\n const schema = z.object({\n colors: z.array(z.enum(['red', 'blue', 'green'])).describe('List of colors'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle optional fields', () => {\n const schema = z.object({\n name: z.string().describe('The user name'),\n age: z.number().optional().describe('The user age'),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n\n it('should handle fields without descriptions', () => {\n const schema = z.object({\n name: z.string(),\n age: z.number(),\n });\n\n const result = oaiParams(schema);\n\n expect(result).toMatchSnapshot();\n });\n });\n\n describe('tool', () => {\n it('should create and execute a basic core tool', async () => {\n const getWeather = tool({\n description: 'Get the weather for a given location',\n parameters: z.object({\n location: z.string(),\n }),\n execute: async ({ location }, { ctx }: ToolOptions<{ name: string }>) => {\n return `The weather in ${location} is sunny, ${ctx.userData.name}`;\n },\n });\n\n const result = await getWeather.execute(\n { location: 'San Francisco' },\n createToolOptions('123', { name: 'John' }),\n );\n expect(result).toBe('The weather in San Francisco is sunny, John');\n });\n\n it('should properly type a callable function', async () => {\n const testFunction = tool({\n description: 'Test function',\n parameters: z.object({\n name: z.string().describe('The user name'),\n age: z.number().describe('The user age'),\n }),\n execute: async (args) => {\n return `${args.name} is ${args.age} years old`;\n },\n });\n\n const result = await testFunction.execute(\n { name: 'John', age: 30 },\n createToolOptions('123'),\n );\n expect(result).toBe('John is 30 years old');\n });\n\n it('should handle async execution', async () => {\n const testFunction = tool({\n description: 'Async test function',\n parameters: z.object({\n delay: z.number().describe('Delay in milliseconds'),\n }),\n execute: async (args) => {\n await new Promise((resolve) => setTimeout(resolve, args.delay));\n return args.delay;\n },\n });\n\n const start = Date.now();\n const result = await testFunction.execute({ delay: 100 }, createToolOptions('123'));\n const duration = Date.now() - start;\n\n expect(result).toBe(100);\n expect(duration).toBeGreaterThanOrEqual(95); // Allow for small timing variations\n });\n\n describe('nested array support', () => {\n it('should handle nested array fields', () => {\n const schema = z.object({\n items: z.array(\n z.object({\n name: z.string().describe('the item name'),\n modifiers: z\n .array(\n z.object({\n modifier_name: z.string(),\n modifier_value: z.string(),\n }),\n )\n .describe('list of the modifiers applied on this item, such as size'),\n }),\n ),\n });\n const result = oaiParams(schema);\n expect(result).toMatchSnapshot();\n });\n });\n\n describe('optional parameters', () => {\n it('should create a tool without parameters', async () => {\n const simpleAction = tool({\n description: 'Perform a simple action',\n execute: async () => {\n return 'Action performed';\n },\n });\n\n expect(simpleAction.type).toBe('function');\n expect(simpleAction.description).toBe('Perform a simple action');\n expect(simpleAction.parameters).toBeDefined();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n expect((simpleAction.parameters as any)._def.typeName).toBe('ZodObject');\n\n const result = await simpleAction.execute({}, createToolOptions('123'));\n expect(result).toBe('Action performed');\n });\n\n it('should support .optional() fields in tool parameters', async () => {\n const weatherTool = tool({\n description: 'Get weather information',\n parameters: z.object({\n location: z.string().describe('The city or location').optional(),\n units: z.enum(['celsius', 'fahrenheit']).describe('Temperature units').optional(),\n }),\n execute: async ({ location, units }) => {\n const loc = location ?? 'Unknown';\n const unit = units ?? 'celsius';\n return `Weather in ${loc} (${unit})`;\n },\n });\n\n expect(weatherTool.type).toBe('function');\n expect(weatherTool.description).toBe('Get weather information');\n\n const result1 = await weatherTool.execute(\n { location: 'London', units: 'celsius' },\n createToolOptions('123'),\n );\n expect(result1).toBe('Weather in London (celsius)');\n\n const result2 = await weatherTool.execute({}, createToolOptions('123'));\n expect(result2).toBe('Weather in Unknown (celsius)');\n\n const result3 = await weatherTool.execute({ location: 'Paris' }, createToolOptions('123'));\n expect(result3).toBe('Weather in Paris (celsius)');\n });\n\n it('should handle tools with context but no parameters', async () => {\n const greetUser = tool({\n description: 'Greet the current user',\n execute: async (_, { ctx }: ToolOptions<{ username: string }>) => {\n return `Hello, ${ctx.userData.username}!`;\n },\n });\n\n const result = await greetUser.execute({}, createToolOptions('123', { username: 'Alice' }));\n expect(result).toBe('Hello, Alice!');\n });\n\n it('should create a tool that accesses tool call id without parameters', async () => {\n const getCallId = tool({\n description: 'Get the current tool call ID',\n execute: async (_, { toolCallId }) => {\n return `Tool call ID: ${toolCallId}`;\n },\n });\n\n const result = await getCallId.execute({}, createToolOptions('test-id-456'));\n expect(result).toBe('Tool call ID: test-id-456');\n });\n });\n\n describe('Zod v3 and v4 compatibility', () => {\n it('should work with Zod v3 schemas', async () => {\n const v3Tool = tool({\n description: 'A tool using Zod v3 schema',\n parameters: z3.object({\n name: z3.string(),\n count: z3.number(),\n }),\n execute: async ({ name, count }) => {\n return `${name}: ${count}`;\n },\n });\n\n const result = await v3Tool.execute(\n { name: 'Test', count: 42 },\n createToolOptions('v3-test'),\n );\n expect(result).toBe('Test: 42');\n });\n\n it('should work with Zod v4 schemas', async () => {\n const v4Tool = tool({\n description: 'A tool using Zod v4 schema',\n parameters: z4.object({\n name: z4.string(),\n count: z4.number(),\n }),\n execute: async ({ name, count }) => {\n return `${name}: ${count}`;\n },\n });\n\n const result = await v4Tool.execute(\n { name: 'Test', count: 42 },\n createToolOptions('v4-test'),\n );\n expect(result).toBe('Test: 42');\n });\n\n it('should handle v4 schemas with optional fields', async () => {\n const v4Tool = tool({\n description: 'Tool with optional field using v4',\n parameters: z4.object({\n required: z4.string(),\n optional: z4.string().optional(),\n }),\n execute: async ({ required, optional }) => {\n return optional ? `${required} - ${optional}` : required;\n },\n });\n\n const result1 = await v4Tool.execute({ required: 'Hello' }, createToolOptions('test-1'));\n expect(result1).toBe('Hello');\n\n const result2 = await v4Tool.execute(\n { required: 'Hello', optional: 'World' },\n createToolOptions('test-2'),\n );\n expect(result2).toBe('Hello - World');\n });\n\n it('should handle v4 enum schemas', async () => {\n const v4Tool = tool({\n description: 'Tool with enum using v4',\n parameters: z4.object({\n color: z4.enum(['red', 'blue', 'green']),\n }),\n execute: async ({ color }) => {\n return `Selected color: ${color}`;\n },\n });\n\n const result = await v4Tool.execute({ color: 'blue' }, createToolOptions('test-enum'));\n expect(result).toBe('Selected color: blue');\n });\n\n it('should handle v4 array schemas', async () => {\n const v4Tool = tool({\n description: 'Tool with array using v4',\n parameters: z4.object({\n tags: z4.array(z4.string()),\n }),\n execute: async ({ tags }) => {\n return `Tags: ${tags.join(', ')}`;\n },\n });\n\n const result = await v4Tool.execute(\n { tags: ['nodejs', 'typescript', 'testing'] },\n createToolOptions('test-array'),\n );\n expect(result).toBe('Tags: nodejs, typescript, testing');\n });\n\n it('should handle v4 nested object schemas', async () => {\n const v4Tool = tool({\n description: 'Tool with nested object using v4',\n parameters: z4.object({\n user: z4.object({\n name: z4.string(),\n email: z4.string(),\n }),\n }),\n execute: async ({ user }) => {\n return `${user.name} (${user.email})`;\n },\n });\n\n const result = await v4Tool.execute(\n { user: { name: 'John Doe', email: 'john@example.com' } },\n createToolOptions('test-nested'),\n );\n expect(result).toBe('John Doe (john@example.com)');\n });\n });\n\n describe('oaiParams with v4 schemas', () => {\n it('should convert v4 basic object schema', () => {\n const schema = z4.object({\n name: z4.string().describe('User name'),\n age: z4.number().describe('User age'),\n });\n\n const result = oaiParams(schema);\n\n expect(result.type).toBe('object');\n expect(result.properties).toHaveProperty('name');\n expect(result.properties).toHaveProperty('age');\n expect(result.required).toContain('name');\n expect(result.required).toContain('age');\n });\n\n it('should handle v4 optional fields', () => {\n const schema = z4.object({\n required: z4.string(),\n optional: z4.string().optional(),\n });\n\n const result = oaiParams(schema);\n\n expect(result.required).toContain('required');\n expect(result.required).not.toContain('optional');\n });\n\n it('should handle v4 enum fields', () => {\n const schema = z4.object({\n status: z4.enum(['pending', 'approved', 'rejected']),\n });\n\n const result = oaiParams(schema);\n\n const properties = result.properties as Record<string, Record<string, unknown>>;\n expect(properties.status?.enum).toEqual(['pending', 'approved', 'rejected']);\n });\n\n it('should handle v4 array fields', () => {\n const schema = z4.object({\n items: z4.array(z4.string()),\n });\n\n const result = oaiParams(schema);\n\n const properties = result.properties as Record<string, any>;\n expect(\n properties.items && typeof properties.items === 'object'\n ? properties.items.type\n : undefined,\n ).toBe('array');\n expect(\n properties.items && properties.items.items && typeof properties.items.items === 'object'\n ? properties.items.items.type\n : undefined,\n ).toBe('string');\n });\n });\n });\n});\n"],"mappings":"AAGA,SAAS,UAAU,QAAQ,UAAU;AACrC,SAAS,SAAS;AAClB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,SAA2B,YAAY;AACvC,SAAS,mBAAmB,iBAAiB;AAE7C,SAAS,gBAAgB,MAAM;AAC7B,WAAS,aAAa,MAAM;AAC1B,OAAG,qCAAqC,MAAM;AAC5C,YAAM,SAAS,EAAE,OAAO;AAAA,QACtB,MAAM,EAAE,OAAO,EAAE,SAAS,eAAe;AAAA,QACzC,KAAK,EAAE,OAAO,EAAE,SAAS,cAAc;AAAA,MACzC,CAAC;AAED,YAAM,SAAS,UAAU,MAAM;AAE/B,aAAO,MAAM,EAAE,gBAAgB;AAAA,IACjC,CAAC;AAED,OAAG,6BAA6B,MAAM;AACpC,YAAM,SAAS,EAAE,OAAO;AAAA,QACtB,OAAO,EAAE,KAAK,CAAC,OAAO,QAAQ,OAAO,CAAC,EAAE,SAAS,gBAAgB;AAAA,MACnE,CAAC;AAED,YAAM,SAAS,UAAU,MAAM;AAE/B,aAAO,MAAM,EAAE,gBAAgB;AAAA,IACjC,CAAC;AAED,OAAG,8BAA8B,MAAM;AACrC,YAAM,SAAS,EAAE,OAAO;AAAA,QACtB,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,cAAc;AAAA,MACnD,CAAC;AAED,YAAM,SAAS,UAAU,MAAM;AAE/B,aAAO,MAAM,EAAE,gBAAgB;AAAA,IACjC,CAAC;AAED,OAAG,gCAAgC,MAAM;AACvC,YAAM,SAAS,EAAE,OAAO;AAAA,QACtB,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,OAAO,QAAQ,OAAO,CAAC,CAAC,EAAE,SAAS,gBAAgB;AAAA,MAC7E,CAAC;AAED,YAAM,SAAS,UAAU,MAAM;AAE/B,aAAO,MAAM,EAAE,gBAAgB;AAAA,IACjC,CAAC;AAED,OAAG,iCAAiC,MAAM;AACxC,YAAM,SAAS,EAAE,OAAO;AAAA,QACtB,MAAM,EAAE,OAAO,EAAE,SAAS,eAAe;AAAA,QACzC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,cAAc;AAAA,MACpD,CAAC;AAED,YAAM,SAAS,UAAU,MAAM;AAE/B,aAAO,MAAM,EAAE,gBAAgB;AAAA,IACjC,CAAC;AAED,OAAG,6CAA6C,MAAM;AACpD,YAAM,SAAS,EAAE,OAAO;AAAA,QACtB,MAAM,EAAE,OAAO;AAAA,QACf,KAAK,EAAE,OAAO;AAAA,MAChB,CAAC;AAED,YAAM,SAAS,UAAU,MAAM;AAE/B,aAAO,MAAM,EAAE,gBAAgB;AAAA,IACjC,CAAC;AAAA,EACH,CAAC;AAED,WAAS,QAAQ,MAAM;AACrB,OAAG,+CAA+C,YAAY;AAC5D,YAAM,aAAa,KAAK;AAAA,QACtB,aAAa;AAAA,QACb,YAAY,EAAE,OAAO;AAAA,UACnB,UAAU,EAAE,OAAO;AAAA,QACrB,CAAC;AAAA,QACD,SAAS,OAAO,EAAE,SAAS,GAAG,EAAE,IAAI,MAAqC;AACvE,iBAAO,kBAAkB,QAAQ,cAAc,IAAI,SAAS,IAAI;AAAA,QAClE;AAAA,MACF,CAAC;AAED,YAAM,SAAS,MAAM,WAAW;AAAA,QAC9B,EAAE,UAAU,gBAAgB;AAAA,QAC5B,kBAAkB,OAAO,EAAE,MAAM,OAAO,CAAC;AAAA,MAC3C;AACA,aAAO,MAAM,EAAE,KAAK,6CAA6C;AAAA,IACnE,CAAC;AAED,OAAG,4CAA4C,YAAY;AACzD,YAAM,eAAe,KAAK;AAAA,QACxB,aAAa;AAAA,QACb,YAAY,EAAE,OAAO;AAAA,UACnB,MAAM,EAAE,OAAO,EAAE,SAAS,eAAe;AAAA,UACzC,KAAK,EAAE,OAAO,EAAE,SAAS,cAAc;AAAA,QACzC,CAAC;AAAA,QACD,SAAS,OAAO,SAAS;AACvB,iBAAO,GAAG,KAAK,IAAI,OAAO,KAAK,GAAG;AAAA,QACpC;AAAA,MACF,CAAC;AAED,YAAM,SAAS,MAAM,aAAa;AAAA,QAChC,EAAE,MAAM,QAAQ,KAAK,GAAG;AAAA,QACxB,kBAAkB,KAAK;AAAA,MACzB;AACA,aAAO,MAAM,EAAE,KAAK,sBAAsB;AAAA,IAC5C,CAAC;AAED,OAAG,iCAAiC,YAAY;AAC9C,YAAM,eAAe,KAAK;AAAA,QACxB,aAAa;AAAA,QACb,YAAY,EAAE,OAAO;AAAA,UACnB,OAAO,EAAE,OAAO,EAAE,SAAS,uBAAuB;AAAA,QACpD,CAAC;AAAA,QACD,SAAS,OAAO,SAAS;AACvB,gBAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,KAAK,KAAK,CAAC;AAC9D,iBAAO,KAAK;AAAA,QACd;AAAA,MACF,CAAC;AAED,YAAM,QAAQ,KAAK,IAAI;AACvB,YAAM,SAAS,MAAM,aAAa,QAAQ,EAAE,OAAO,IAAI,GAAG,kBAAkB,KAAK,CAAC;AAClF,YAAM,WAAW,KAAK,IAAI,IAAI;AAE9B,aAAO,MAAM,EAAE,KAAK,GAAG;AACvB,aAAO,QAAQ,EAAE,uBAAuB,EAAE;AAAA,IAC5C,CAAC;AAED,aAAS,wBAAwB,MAAM;AACrC,SAAG,qCAAqC,MAAM;AAC5C,cAAM,SAAS,EAAE,OAAO;AAAA,UACtB,OAAO,EAAE;AAAA,YACP,EAAE,OAAO;AAAA,cACP,MAAM,EAAE,OAAO,EAAE,SAAS,eAAe;AAAA,cACzC,WAAW,EACR;AAAA,gBACC,EAAE,OAAO;AAAA,kBACP,eAAe,EAAE,OAAO;AAAA,kBACxB,gBAAgB,EAAE,OAAO;AAAA,gBAC3B,CAAC;AAAA,cACH,EACC,SAAS,0DAA0D;AAAA,YACxE,CAAC;AAAA,UACH;AAAA,QACF,CAAC;AACD,cAAM,SAAS,UAAU,MAAM;AAC/B,eAAO,MAAM,EAAE,gBAAgB;AAAA,MACjC,CAAC;AAAA,IACH,CAAC;AAED,aAAS,uBAAuB,MAAM;AACpC,SAAG,2CAA2C,YAAY;AACxD,cAAM,eAAe,KAAK;AAAA,UACxB,aAAa;AAAA,UACb,SAAS,YAAY;AACnB,mBAAO;AAAA,UACT;AAAA,QACF,CAAC;AAED,eAAO,aAAa,IAAI,EAAE,KAAK,UAAU;AACzC,eAAO,aAAa,WAAW,EAAE,KAAK,yBAAyB;AAC/D,eAAO,aAAa,UAAU,EAAE,YAAY;AAE5C,eAAQ,aAAa,WAAmB,KAAK,QAAQ,EAAE,KAAK,WAAW;AAEvE,cAAM,SAAS,MAAM,aAAa,QAAQ,CAAC,GAAG,kBAAkB,KAAK,CAAC;AACtE,eAAO,MAAM,EAAE,KAAK,kBAAkB;AAAA,MACxC,CAAC;AAED,SAAG,wDAAwD,YAAY;AACrE,cAAM,cAAc,KAAK;AAAA,UACvB,aAAa;AAAA,UACb,YAAY,EAAE,OAAO;AAAA,YACnB,UAAU,EAAE,OAAO,EAAE,SAAS,sBAAsB,EAAE,SAAS;AAAA,YAC/D,OAAO,EAAE,KAAK,CAAC,WAAW,YAAY,CAAC,EAAE,SAAS,mBAAmB,EAAE,SAAS;AAAA,UAClF,CAAC;AAAA,UACD,SAAS,OAAO,EAAE,UAAU,MAAM,MAAM;AACtC,kBAAM,MAAM,YAAY;AACxB,kBAAM,OAAO,SAAS;AACtB,mBAAO,cAAc,GAAG,KAAK,IAAI;AAAA,UACnC;AAAA,QACF,CAAC;AAED,eAAO,YAAY,IAAI,EAAE,KAAK,UAAU;AACxC,eAAO,YAAY,WAAW,EAAE,KAAK,yBAAyB;AAE9D,cAAM,UAAU,MAAM,YAAY;AAAA,UAChC,EAAE,UAAU,UAAU,OAAO,UAAU;AAAA,UACvC,kBAAkB,KAAK;AAAA,QACzB;AACA,eAAO,OAAO,EAAE,KAAK,6BAA6B;AAElD,cAAM,UAAU,MAAM,YAAY,QAAQ,CAAC,GAAG,kBAAkB,KAAK,CAAC;AACtE,eAAO,OAAO,EAAE,KAAK,8BAA8B;AAEnD,cAAM,UAAU,MAAM,YAAY,QAAQ,EAAE,UAAU,QAAQ,GAAG,kBAAkB,KAAK,CAAC;AACzF,eAAO,OAAO,EAAE,KAAK,4BAA4B;AAAA,MACnD,CAAC;AAED,SAAG,sDAAsD,YAAY;AACnE,cAAM,YAAY,KAAK;AAAA,UACrB,aAAa;AAAA,UACb,SAAS,OAAO,GAAG,EAAE,IAAI,MAAyC;AAChE,mBAAO,UAAU,IAAI,SAAS,QAAQ;AAAA,UACxC;AAAA,QACF,CAAC;AAED,cAAM,SAAS,MAAM,UAAU,QAAQ,CAAC,GAAG,kBAAkB,OAAO,EAAE,UAAU,QAAQ,CAAC,CAAC;AAC1F,eAAO,MAAM,EAAE,KAAK,eAAe;AAAA,MACrC,CAAC;AAED,SAAG,sEAAsE,YAAY;AACnF,cAAM,YAAY,KAAK;AAAA,UACrB,aAAa;AAAA,UACb,SAAS,OAAO,GAAG,EAAE,WAAW,MAAM;AACpC,mBAAO,iBAAiB,UAAU;AAAA,UACpC;AAAA,QACF,CAAC;AAED,cAAM,SAAS,MAAM,UAAU,QAAQ,CAAC,GAAG,kBAAkB,aAAa,CAAC;AAC3E,eAAO,MAAM,EAAE,KAAK,2BAA2B;AAAA,MACjD,CAAC;AAAA,IACH,CAAC;AAED,aAAS,+BAA+B,MAAM;AAC5C,SAAG,mCAAmC,YAAY;AAChD,cAAM,SAAS,KAAK;AAAA,UAClB,aAAa;AAAA,UACb,YAAY,GAAG,OAAO;AAAA,YACpB,MAAM,GAAG,OAAO;AAAA,YAChB,OAAO,GAAG,OAAO;AAAA,UACnB,CAAC;AAAA,UACD,SAAS,OAAO,EAAE,MAAM,MAAM,MAAM;AAClC,mBAAO,GAAG,IAAI,KAAK,KAAK;AAAA,UAC1B;AAAA,QACF,CAAC;AAED,cAAM,SAAS,MAAM,OAAO;AAAA,UAC1B,EAAE,MAAM,QAAQ,OAAO,GAAG;AAAA,UAC1B,kBAAkB,SAAS;AAAA,QAC7B;AACA,eAAO,MAAM,EAAE,KAAK,UAAU;AAAA,MAChC,CAAC;AAED,SAAG,mCAAmC,YAAY;AAChD,cAAM,SAAS,KAAK;AAAA,UAClB,aAAa;AAAA,UACb,YAAY,GAAG,OAAO;AAAA,YACpB,MAAM,GAAG,OAAO;AAAA,YAChB,OAAO,GAAG,OAAO;AAAA,UACnB,CAAC;AAAA,UACD,SAAS,OAAO,EAAE,MAAM,MAAM,MAAM;AAClC,mBAAO,GAAG,IAAI,KAAK,KAAK;AAAA,UAC1B;AAAA,QACF,CAAC;AAED,cAAM,SAAS,MAAM,OAAO;AAAA,UAC1B,EAAE,MAAM,QAAQ,OAAO,GAAG;AAAA,UAC1B,kBAAkB,SAAS;AAAA,QAC7B;AACA,eAAO,MAAM,EAAE,KAAK,UAAU;AAAA,MAChC,CAAC;AAED,SAAG,iDAAiD,YAAY;AAC9D,cAAM,SAAS,KAAK;AAAA,UAClB,aAAa;AAAA,UACb,YAAY,GAAG,OAAO;AAAA,YACpB,UAAU,GAAG,OAAO;AAAA,YACpB,UAAU,GAAG,OAAO,EAAE,SAAS;AAAA,UACjC,CAAC;AAAA,UACD,SAAS,OAAO,EAAE,UAAU,SAAS,MAAM;AACzC,mBAAO,WAAW,GAAG,QAAQ,MAAM,QAAQ,KAAK;AAAA,UAClD;AAAA,QACF,CAAC;AAED,cAAM,UAAU,MAAM,OAAO,QAAQ,EAAE,UAAU,QAAQ,GAAG,kBAAkB,QAAQ,CAAC;AACvF,eAAO,OAAO,EAAE,KAAK,OAAO;AAE5B,cAAM,UAAU,MAAM,OAAO;AAAA,UAC3B,EAAE,UAAU,SAAS,UAAU,QAAQ;AAAA,UACvC,kBAAkB,QAAQ;AAAA,QAC5B;AACA,eAAO,OAAO,EAAE,KAAK,eAAe;AAAA,MACtC,CAAC;AAED,SAAG,iCAAiC,YAAY;AAC9C,cAAM,SAAS,KAAK;AAAA,UAClB,aAAa;AAAA,UACb,YAAY,GAAG,OAAO;AAAA,YACpB,OAAO,GAAG,KAAK,CAAC,OAAO,QAAQ,OAAO,CAAC;AAAA,UACzC,CAAC;AAAA,UACD,SAAS,OAAO,EAAE,MAAM,MAAM;AAC5B,mBAAO,mBAAmB,KAAK;AAAA,UACjC;AAAA,QACF,CAAC;AAED,cAAM,SAAS,MAAM,OAAO,QAAQ,EAAE,OAAO,OAAO,GAAG,kBAAkB,WAAW,CAAC;AACrF,eAAO,MAAM,EAAE,KAAK,sBAAsB;AAAA,MAC5C,CAAC;AAED,SAAG,kCAAkC,YAAY;AAC/C,cAAM,SAAS,KAAK;AAAA,UAClB,aAAa;AAAA,UACb,YAAY,GAAG,OAAO;AAAA,YACpB,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAAA,UAC5B,CAAC;AAAA,UACD,SAAS,OAAO,EAAE,KAAK,MAAM;AAC3B,mBAAO,SAAS,KAAK,KAAK,IAAI,CAAC;AAAA,UACjC;AAAA,QACF,CAAC;AAED,cAAM,SAAS,MAAM,OAAO;AAAA,UAC1B,EAAE,MAAM,CAAC,UAAU,cAAc,SAAS,EAAE;AAAA,UAC5C,kBAAkB,YAAY;AAAA,QAChC;AACA,eAAO,MAAM,EAAE,KAAK,mCAAmC;AAAA,MACzD,CAAC;AAED,SAAG,0CAA0C,YAAY;AACvD,cAAM,SAAS,KAAK;AAAA,UAClB,aAAa;AAAA,UACb,YAAY,GAAG,OAAO;AAAA,YACpB,MAAM,GAAG,OAAO;AAAA,cACd,MAAM,GAAG,OAAO;AAAA,cAChB,OAAO,GAAG,OAAO;AAAA,YACnB,CAAC;AAAA,UACH,CAAC;AAAA,UACD,SAAS,OAAO,EAAE,KAAK,MAAM;AAC3B,mBAAO,GAAG,KAAK,IAAI,KAAK,KAAK,KAAK;AAAA,UACpC;AAAA,QACF,CAAC;AAED,cAAM,SAAS,MAAM,OAAO;AAAA,UAC1B,EAAE,MAAM,EAAE,MAAM,YAAY,OAAO,mBAAmB,EAAE;AAAA,UACxD,kBAAkB,aAAa;AAAA,QACjC;AACA,eAAO,MAAM,EAAE,KAAK,6BAA6B;AAAA,MACnD,CAAC;AAAA,IACH,CAAC;AAED,aAAS,6BAA6B,MAAM;AAC1C,SAAG,yCAAyC,MAAM;AAChD,cAAM,SAAS,GAAG,OAAO;AAAA,UACvB,MAAM,GAAG,OAAO,EAAE,SAAS,WAAW;AAAA,UACtC,KAAK,GAAG,OAAO,EAAE,SAAS,UAAU;AAAA,QACtC,CAAC;AAED,cAAM,SAAS,UAAU,MAAM;AAE/B,eAAO,OAAO,IAAI,EAAE,KAAK,QAAQ;AACjC,eAAO,OAAO,UAAU,EAAE,eAAe,MAAM;AAC/C,eAAO,OAAO,UAAU,EAAE,eAAe,KAAK;AAC9C,eAAO,OAAO,QAAQ,EAAE,UAAU,MAAM;AACxC,eAAO,OAAO,QAAQ,EAAE,UAAU,KAAK;AAAA,MACzC,CAAC;AAED,SAAG,oCAAoC,MAAM;AAC3C,cAAM,SAAS,GAAG,OAAO;AAAA,UACvB,UAAU,GAAG,OAAO;AAAA,UACpB,UAAU,GAAG,OAAO,EAAE,SAAS;AAAA,QACjC,CAAC;AAED,cAAM,SAAS,UAAU,MAAM;AAE/B,eAAO,OAAO,QAAQ,EAAE,UAAU,UAAU;AAC5C,eAAO,OAAO,QAAQ,EAAE,IAAI,UAAU,UAAU;AAAA,MAClD,CAAC;AAED,SAAG,gCAAgC,MAAM;AAtX/C;AAuXQ,cAAM,SAAS,GAAG,OAAO;AAAA,UACvB,QAAQ,GAAG,KAAK,CAAC,WAAW,YAAY,UAAU,CAAC;AAAA,QACrD,CAAC;AAED,cAAM,SAAS,UAAU,MAAM;AAE/B,cAAM,aAAa,OAAO;AAC1B,gBAAO,gBAAW,WAAX,mBAAmB,IAAI,EAAE,QAAQ,CAAC,WAAW,YAAY,UAAU,CAAC;AAAA,MAC7E,CAAC;AAED,SAAG,iCAAiC,MAAM;AACxC,cAAM,SAAS,GAAG,OAAO;AAAA,UACvB,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAAA,QAC7B,CAAC;AAED,cAAM,SAAS,UAAU,MAAM;AAE/B,cAAM,aAAa,OAAO;AAC1B;AAAA,UACE,WAAW,SAAS,OAAO,WAAW,UAAU,WAC5C,WAAW,MAAM,OACjB;AAAA,QACN,EAAE,KAAK,OAAO;AACd;AAAA,UACE,WAAW,SAAS,WAAW,MAAM,SAAS,OAAO,WAAW,MAAM,UAAU,WAC5E,WAAW,MAAM,MAAM,OACvB;AAAA,QACN,EAAE,KAAK,QAAQ;AAAA,MACjB,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH,CAAC;","names":[]}
|
package/dist/llm/utils.cjs
CHANGED
|
@@ -39,9 +39,8 @@ __export(utils_exports, {
|
|
|
39
39
|
module.exports = __toCommonJS(utils_exports);
|
|
40
40
|
var import_rtc_node = require("@livekit/rtc-node");
|
|
41
41
|
var import_sharp = __toESM(require("sharp"), 1);
|
|
42
|
-
var import_zod = require("zod");
|
|
43
|
-
var import_zod_to_json_schema = require("zod-to-json-schema");
|
|
44
42
|
var import_chat_context = require("./chat_context.cjs");
|
|
43
|
+
var import_zod_utils = require("./zod-utils.cjs");
|
|
45
44
|
function getChannelsFromVideoBufferType(type) {
|
|
46
45
|
switch (type) {
|
|
47
46
|
case import_rtc_node.VideoBufferType.RGBA:
|
|
@@ -128,11 +127,9 @@ async function serializeImage(image) {
|
|
|
128
127
|
const createToolOptions = (toolCallId, userData = {}) => {
|
|
129
128
|
return { ctx: { userData }, toolCallId };
|
|
130
129
|
};
|
|
131
|
-
const oaiParams = (
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
target: isOpenai ? "openAi" : "jsonSchema7"
|
|
135
|
-
});
|
|
130
|
+
const oaiParams = (schema, isOpenai = true) => {
|
|
131
|
+
const jsonSchema = (0, import_zod_utils.zodSchemaToJsonSchema)(schema, isOpenai);
|
|
132
|
+
const { properties, required, additionalProperties } = jsonSchema;
|
|
136
133
|
return {
|
|
137
134
|
type: "object",
|
|
138
135
|
properties,
|
|
@@ -165,8 +162,17 @@ async function executeToolCall(toolCall, toolCtx) {
|
|
|
165
162
|
});
|
|
166
163
|
}
|
|
167
164
|
try {
|
|
168
|
-
if (tool.parameters
|
|
169
|
-
|
|
165
|
+
if ((0, import_zod_utils.isZodSchema)(tool.parameters)) {
|
|
166
|
+
const result = await (0, import_zod_utils.parseZodSchema)(tool.parameters, args);
|
|
167
|
+
if (result.success) {
|
|
168
|
+
params = result.data;
|
|
169
|
+
} else {
|
|
170
|
+
return import_chat_context.FunctionCallOutput.create({
|
|
171
|
+
callId: toolCall.callId,
|
|
172
|
+
output: `Arguments parsing failed: ${result.error}`,
|
|
173
|
+
isError: true
|
|
174
|
+
});
|
|
175
|
+
}
|
|
170
176
|
} else {
|
|
171
177
|
params = args;
|
|
172
178
|
}
|
|
@@ -243,8 +249,8 @@ function computeChatCtxDiff(oldCtx, newCtx) {
|
|
|
243
249
|
};
|
|
244
250
|
}
|
|
245
251
|
function toJsonSchema(schema, isOpenai = true) {
|
|
246
|
-
if (
|
|
247
|
-
return
|
|
252
|
+
if ((0, import_zod_utils.isZodSchema)(schema)) {
|
|
253
|
+
return (0, import_zod_utils.zodSchemaToJsonSchema)(schema, isOpenai);
|
|
248
254
|
}
|
|
249
255
|
return schema;
|
|
250
256
|
}
|