zeitlich 0.2.17 → 0.2.19
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/adapters/sandbox/virtual/index.d.cts +3 -3
- package/dist/adapters/sandbox/virtual/index.d.ts +3 -3
- package/dist/adapters/thread/google-genai/index.d.cts +2 -2
- package/dist/adapters/thread/google-genai/index.d.ts +2 -2
- package/dist/adapters/thread/langchain/index.d.cts +2 -2
- package/dist/adapters/thread/langchain/index.d.ts +2 -2
- package/dist/index.cjs +11 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +11 -14
- package/dist/index.js.map +1 -1
- package/dist/{queries-DlJ3jE48.d.cts → queries-D22uWTOb.d.cts} +1 -1
- package/dist/{queries-BlC1I3DK.d.ts → queries-D8T4pEeu.d.ts} +1 -1
- package/dist/{types-Bh-BbfCp.d.cts → types-CCfJb5Jl.d.cts} +2 -2
- package/dist/{types-NkiAxU4t.d.ts → types-CxWLeJTB.d.ts} +2 -2
- package/dist/{types-BMXzv7TN.d.cts → types-DjT78Sdp.d.cts} +4 -4
- package/dist/{types-BMXzv7TN.d.ts → types-DjT78Sdp.d.ts} +4 -4
- package/dist/workflow.cjs +11 -14
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +7 -7
- package/dist/workflow.d.ts +7 -7
- package/dist/workflow.js +11 -14
- package/dist/workflow.js.map +1 -1
- package/package.json +1 -1
- package/src/lib/subagent/define.ts +1 -1
- package/src/lib/subagent/register.ts +10 -13
- package/src/lib/subagent/subagent.integration.test.ts +119 -70
- package/src/lib/subagent/types.ts +1 -1
- package/src/lib/tool-router/router.ts +8 -5
- package/src/lib/tool-router/types.ts +4 -4
package/package.json
CHANGED
|
@@ -40,7 +40,7 @@ export function defineSubagent<
|
|
|
40
40
|
overrides?: {
|
|
41
41
|
context?: TContext;
|
|
42
42
|
hooks?: SubagentHooks<SubagentArgs, z.infer<TResult>>;
|
|
43
|
-
enabled?: boolean;
|
|
43
|
+
enabled?: boolean | (() => boolean);
|
|
44
44
|
taskQueue?: string;
|
|
45
45
|
allowThreadContinuation?: boolean;
|
|
46
46
|
sandbox?: "inherit" | "own";
|
|
@@ -13,9 +13,9 @@ import { createSubagentHandler } from "./handler";
|
|
|
13
13
|
* Builds a fully wired tool entry for the Subagent tool,
|
|
14
14
|
* including per-subagent hook delegation.
|
|
15
15
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* time getToolDefinitions() is called.
|
|
16
|
+
* Lazily evaluates `enabled` (supports `boolean | () => boolean`)
|
|
17
|
+
* so that `description` and `schema` reflect the current set of
|
|
18
|
+
* active subagents each time getToolDefinitions() is called.
|
|
19
19
|
*
|
|
20
20
|
* Returns null if no subagents are configured.
|
|
21
21
|
*/
|
|
@@ -24,7 +24,10 @@ export function buildSubagentRegistration(
|
|
|
24
24
|
): ToolMap[string] | null {
|
|
25
25
|
if (subagents.length === 0) return null;
|
|
26
26
|
|
|
27
|
-
const getEnabled = (): SubagentConfig[] =>
|
|
27
|
+
const getEnabled = (): SubagentConfig[] =>
|
|
28
|
+
subagents.filter((s) =>
|
|
29
|
+
typeof s.enabled === "function" ? s.enabled() : (s.enabled ?? true),
|
|
30
|
+
);
|
|
28
31
|
|
|
29
32
|
const subagentHooksMap = new Map<string, SubagentHooks>();
|
|
30
33
|
for (const s of subagents) {
|
|
@@ -36,15 +39,9 @@ export function buildSubagentRegistration(
|
|
|
36
39
|
|
|
37
40
|
return {
|
|
38
41
|
name: SUBAGENT_TOOL_NAME,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
get description(): string {
|
|
43
|
-
return createSubagentTool(getEnabled()).description;
|
|
44
|
-
},
|
|
45
|
-
get schema(): z.ZodObject<z.ZodRawShape> {
|
|
46
|
-
return createSubagentTool(getEnabled()).schema;
|
|
47
|
-
},
|
|
42
|
+
enabled: (): boolean => getEnabled().length > 0,
|
|
43
|
+
description: (): string => createSubagentTool(getEnabled()).description,
|
|
44
|
+
schema: (): z.ZodObject<z.ZodRawShape> => createSubagentTool(getEnabled()).schema,
|
|
48
45
|
handler: createSubagentHandler(subagents),
|
|
49
46
|
...(subagentHooksMap.size > 0 && {
|
|
50
47
|
hooks: {
|
|
@@ -5,19 +5,21 @@ vi.mock("@temporalio/workflow", () => {
|
|
|
5
5
|
let counter = 0;
|
|
6
6
|
return {
|
|
7
7
|
workflowInfo: () => ({ taskQueue: "default-queue" }),
|
|
8
|
-
executeChild: vi.fn(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
executeChild: vi.fn(
|
|
9
|
+
async (_workflow: unknown, opts: { args: unknown[] }) => {
|
|
10
|
+
const prompt = (opts.args as [string])[0];
|
|
11
|
+
return {
|
|
12
|
+
toolResponse: `Response to: ${prompt}`,
|
|
13
|
+
data: { result: "child-data" },
|
|
14
|
+
threadId: "child-thread-1",
|
|
15
|
+
usage: { inputTokens: 100, outputTokens: 50 },
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
),
|
|
17
19
|
uuid4: () => {
|
|
18
20
|
counter++;
|
|
19
21
|
const bytes = Array.from({ length: 16 }, (_, i) =>
|
|
20
|
-
((counter * 31 + i * 7) & 0xff).toString(16).padStart(2, "0")
|
|
22
|
+
((counter * 31 + i * 7) & 0xff).toString(16).padStart(2, "0")
|
|
21
23
|
).join("");
|
|
22
24
|
return `${bytes.slice(0, 8)}-${bytes.slice(8, 12)}-${bytes.slice(12, 16)}-${bytes.slice(16, 20)}-${bytes.slice(20, 32)}`;
|
|
23
25
|
},
|
|
@@ -28,6 +30,7 @@ import { createSubagentTool, SUBAGENT_TOOL_NAME } from "./tool";
|
|
|
28
30
|
import { createSubagentHandler } from "./handler";
|
|
29
31
|
import { buildSubagentRegistration } from "./register";
|
|
30
32
|
import { defineSubagentWorkflow } from "./workflow";
|
|
33
|
+
import { defineSubagent } from "./define";
|
|
31
34
|
import type {
|
|
32
35
|
SubagentConfig,
|
|
33
36
|
SubagentSessionInput,
|
|
@@ -146,7 +149,7 @@ describe("createSubagentTool", () => {
|
|
|
146
149
|
|
|
147
150
|
it("throws when no subagents are provided", () => {
|
|
148
151
|
expect(() => createSubagentTool([])).toThrow(
|
|
149
|
-
"createSubagentTool requires at least one subagent"
|
|
152
|
+
"createSubagentTool requires at least one subagent"
|
|
150
153
|
);
|
|
151
154
|
});
|
|
152
155
|
|
|
@@ -180,7 +183,7 @@ describe("createSubagentHandler", () => {
|
|
|
180
183
|
|
|
181
184
|
const result = await handler(
|
|
182
185
|
{ subagent: "researcher", description: "test", prompt: "Find info" },
|
|
183
|
-
{ threadId: "parent-thread", toolCallId: "tc-1", toolName: "Subagent" }
|
|
186
|
+
{ threadId: "parent-thread", toolCallId: "tc-1", toolName: "Subagent" }
|
|
184
187
|
);
|
|
185
188
|
|
|
186
189
|
expect(result.toolResponse).toContain("Response to: Find info");
|
|
@@ -193,8 +196,8 @@ describe("createSubagentHandler", () => {
|
|
|
193
196
|
await expect(
|
|
194
197
|
handler(
|
|
195
198
|
{ subagent: "nonexistent", description: "test", prompt: "test" },
|
|
196
|
-
{ threadId: "t", toolCallId: "tc", toolName: "Subagent" }
|
|
197
|
-
)
|
|
199
|
+
{ threadId: "t", toolCallId: "tc", toolName: "Subagent" }
|
|
200
|
+
)
|
|
198
201
|
).rejects.toThrow("Unknown subagent: nonexistent");
|
|
199
202
|
});
|
|
200
203
|
|
|
@@ -211,8 +214,8 @@ describe("createSubagentHandler", () => {
|
|
|
211
214
|
await expect(
|
|
212
215
|
handler(
|
|
213
216
|
{ subagent: "bad", description: "test", prompt: "test" },
|
|
214
|
-
{ threadId: "t", toolCallId: "tc", toolName: "Subagent" }
|
|
215
|
-
)
|
|
217
|
+
{ threadId: "t", toolCallId: "tc", toolName: "Subagent" }
|
|
218
|
+
)
|
|
216
219
|
).rejects.toThrow(/researcher.*writer/);
|
|
217
220
|
});
|
|
218
221
|
|
|
@@ -235,7 +238,7 @@ describe("createSubagentHandler", () => {
|
|
|
235
238
|
|
|
236
239
|
const result = await handler(
|
|
237
240
|
{ subagent: "validated", description: "test", prompt: "test" },
|
|
238
|
-
{ threadId: "t", toolCallId: "tc", toolName: "Subagent" }
|
|
241
|
+
{ threadId: "t", toolCallId: "tc", toolName: "Subagent" }
|
|
239
242
|
);
|
|
240
243
|
|
|
241
244
|
expect(result.toolResponse).toContain("invalid data");
|
|
@@ -261,7 +264,7 @@ describe("createSubagentHandler", () => {
|
|
|
261
264
|
|
|
262
265
|
const result = await handler(
|
|
263
266
|
{ subagent: "cont", description: "test", prompt: "test" },
|
|
264
|
-
{ threadId: "t", toolCallId: "tc", toolName: "Subagent" }
|
|
267
|
+
{ threadId: "t", toolCallId: "tc", toolName: "Subagent" }
|
|
265
268
|
);
|
|
266
269
|
|
|
267
270
|
expect(result.toolResponse).toContain("Thread ID: child-thread-99");
|
|
@@ -279,7 +282,7 @@ describe("createSubagentHandler", () => {
|
|
|
279
282
|
|
|
280
283
|
const result = await handler(
|
|
281
284
|
{ subagent: "researcher", description: "test", prompt: "test" },
|
|
282
|
-
{ threadId: "t", toolCallId: "tc", toolName: "Subagent" }
|
|
285
|
+
{ threadId: "t", toolCallId: "tc", toolName: "Subagent" }
|
|
283
286
|
);
|
|
284
287
|
|
|
285
288
|
expect(result.toolResponse).toContain("no response");
|
|
@@ -306,7 +309,12 @@ describe("createSubagentHandler", () => {
|
|
|
306
309
|
|
|
307
310
|
await handler(
|
|
308
311
|
{ subagent: "inherit-agent", description: "test", prompt: "test" },
|
|
309
|
-
{
|
|
312
|
+
{
|
|
313
|
+
threadId: "t",
|
|
314
|
+
toolCallId: "tc",
|
|
315
|
+
toolName: "Subagent",
|
|
316
|
+
sandboxId: "parent-sb",
|
|
317
|
+
}
|
|
310
318
|
);
|
|
311
319
|
|
|
312
320
|
const lastCall = execMock.mock.calls[execMock.mock.calls.length - 1];
|
|
@@ -335,7 +343,12 @@ describe("createSubagentHandler", () => {
|
|
|
335
343
|
|
|
336
344
|
await handler(
|
|
337
345
|
{ subagent: "own-agent", description: "test", prompt: "test" },
|
|
338
|
-
{
|
|
346
|
+
{
|
|
347
|
+
threadId: "t",
|
|
348
|
+
toolCallId: "tc",
|
|
349
|
+
toolName: "Subagent",
|
|
350
|
+
sandboxId: "parent-sb",
|
|
351
|
+
}
|
|
339
352
|
);
|
|
340
353
|
|
|
341
354
|
const lastCall = execMock.mock.calls[execMock.mock.calls.length - 1];
|
|
@@ -371,21 +384,23 @@ describe("buildSubagentRegistration", () => {
|
|
|
371
384
|
}
|
|
372
385
|
});
|
|
373
386
|
|
|
374
|
-
it("enabled
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
387
|
+
it("enabled function is re-evaluated dynamically", () => {
|
|
388
|
+
let flag = true;
|
|
389
|
+
const reg = buildSubagentRegistration([
|
|
390
|
+
{
|
|
391
|
+
agentName: "toggle",
|
|
392
|
+
description: "Toggleable",
|
|
393
|
+
workflow: "workflow",
|
|
394
|
+
enabled: () => flag,
|
|
395
|
+
},
|
|
396
|
+
]);
|
|
381
397
|
|
|
382
|
-
const reg = buildSubagentRegistration([config]);
|
|
383
398
|
expect(reg).toBeDefined();
|
|
384
399
|
if (!reg) return;
|
|
385
|
-
expect(reg.enabled).toBe(true);
|
|
400
|
+
expect((reg.enabled as () => boolean)()).toBe(true);
|
|
386
401
|
|
|
387
|
-
|
|
388
|
-
expect(reg.enabled).toBe(false);
|
|
402
|
+
flag = false;
|
|
403
|
+
expect((reg.enabled as () => boolean)()).toBe(false);
|
|
389
404
|
});
|
|
390
405
|
|
|
391
406
|
it("disabled when all subagents are disabled", () => {
|
|
@@ -400,7 +415,7 @@ describe("buildSubagentRegistration", () => {
|
|
|
400
415
|
|
|
401
416
|
expect(reg).toBeDefined();
|
|
402
417
|
if (reg) {
|
|
403
|
-
expect(reg.enabled).toBe(false);
|
|
418
|
+
expect((reg.enabled as () => boolean)()).toBe(false);
|
|
404
419
|
}
|
|
405
420
|
});
|
|
406
421
|
|
|
@@ -442,28 +457,29 @@ describe("buildSubagentRegistration", () => {
|
|
|
442
457
|
}
|
|
443
458
|
});
|
|
444
459
|
|
|
445
|
-
it("dynamic schema/description updates when
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
+
it("dynamic schema/description updates when enabled function changes", () => {
|
|
461
|
+
let bEnabled = true;
|
|
462
|
+
const reg = buildSubagentRegistration([
|
|
463
|
+
{
|
|
464
|
+
agentName: "a",
|
|
465
|
+
description: "Agent A",
|
|
466
|
+
workflow: "workflow",
|
|
467
|
+
enabled: true,
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
agentName: "b",
|
|
471
|
+
description: "Agent B",
|
|
472
|
+
workflow: "workflow",
|
|
473
|
+
enabled: () => bEnabled,
|
|
474
|
+
},
|
|
475
|
+
]);
|
|
460
476
|
|
|
461
477
|
expect(reg).toBeDefined();
|
|
462
478
|
if (reg) {
|
|
463
479
|
expect(reg.description).toContain("Agent A");
|
|
464
480
|
expect(reg.description).toContain("Agent B");
|
|
465
481
|
|
|
466
|
-
|
|
482
|
+
bEnabled = false;
|
|
467
483
|
|
|
468
484
|
expect(reg.description).toContain("Agent A");
|
|
469
485
|
expect(reg.description).not.toContain("Agent B");
|
|
@@ -471,6 +487,45 @@ describe("buildSubagentRegistration", () => {
|
|
|
471
487
|
});
|
|
472
488
|
});
|
|
473
489
|
|
|
490
|
+
// ---------------------------------------------------------------------------
|
|
491
|
+
// defineSubagent
|
|
492
|
+
// ---------------------------------------------------------------------------
|
|
493
|
+
|
|
494
|
+
describe("defineSubagent", () => {
|
|
495
|
+
const makeDef = (name: string) =>
|
|
496
|
+
defineSubagentWorkflow(
|
|
497
|
+
{ name, description: `${name} agent` },
|
|
498
|
+
async () => ({ toolResponse: "ok", data: null, threadId: "t" })
|
|
499
|
+
);
|
|
500
|
+
|
|
501
|
+
it("enabled function is re-evaluated dynamically", () => {
|
|
502
|
+
let flag = true;
|
|
503
|
+
const config = defineSubagent(makeDef("dynamic"), {
|
|
504
|
+
enabled: () => flag,
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
const resolve = config.enabled as () => boolean;
|
|
508
|
+
expect(resolve()).toBe(true);
|
|
509
|
+
flag = false;
|
|
510
|
+
expect(resolve()).toBe(false);
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
it("enabled function works through buildSubagentRegistration", () => {
|
|
514
|
+
let flag = true;
|
|
515
|
+
const config = defineSubagent(makeDef("dynamic"), {
|
|
516
|
+
enabled: () => flag,
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
const reg = buildSubagentRegistration([config]);
|
|
520
|
+
expect(reg).toBeDefined();
|
|
521
|
+
if (!reg) return;
|
|
522
|
+
expect((reg.enabled as () => boolean)()).toBe(true);
|
|
523
|
+
|
|
524
|
+
flag = false;
|
|
525
|
+
expect((reg.enabled as () => boolean)()).toBe(false);
|
|
526
|
+
});
|
|
527
|
+
});
|
|
528
|
+
|
|
474
529
|
// ---------------------------------------------------------------------------
|
|
475
530
|
// defineSubagentWorkflow
|
|
476
531
|
// ---------------------------------------------------------------------------
|
|
@@ -486,7 +541,7 @@ describe("defineSubagentWorkflow", () => {
|
|
|
486
541
|
capturedPrompt = prompt;
|
|
487
542
|
capturedSession = sessionInput;
|
|
488
543
|
return { toolResponse: "ok", data: null, threadId: "t" };
|
|
489
|
-
}
|
|
544
|
+
}
|
|
490
545
|
);
|
|
491
546
|
|
|
492
547
|
await workflow("go", { previousThreadId: "prev-42" });
|
|
@@ -506,7 +561,7 @@ describe("defineSubagentWorkflow", () => {
|
|
|
506
561
|
async (_prompt, sessionInput) => {
|
|
507
562
|
capturedSession = sessionInput;
|
|
508
563
|
return { toolResponse: "ok", data: null, threadId: "t" };
|
|
509
|
-
}
|
|
564
|
+
}
|
|
510
565
|
);
|
|
511
566
|
|
|
512
567
|
await workflow("go", { sandboxId: "sb-123" });
|
|
@@ -520,7 +575,7 @@ describe("defineSubagentWorkflow", () => {
|
|
|
520
575
|
async (_prompt, _sessionInput, context) => {
|
|
521
576
|
capturedContext = context;
|
|
522
577
|
return { toolResponse: "ok", data: null, threadId: "t" };
|
|
523
|
-
}
|
|
578
|
+
}
|
|
524
579
|
);
|
|
525
580
|
|
|
526
581
|
await workflow("go", {}, { key: "val" });
|
|
@@ -528,28 +583,18 @@ describe("defineSubagentWorkflow", () => {
|
|
|
528
583
|
expect(capturedContext).toEqual({ key: "val" });
|
|
529
584
|
});
|
|
530
585
|
|
|
531
|
-
it("supports omitted context", async () => {
|
|
532
|
-
let capturedContext: Record<string, unknown> | undefined;
|
|
533
|
-
const workflow = defineSubagentWorkflow(
|
|
534
|
-
{ name: "test", description: "test agent" },
|
|
535
|
-
async (_prompt, _sessionInput, context) => {
|
|
536
|
-
capturedContext = context;
|
|
537
|
-
return { toolResponse: "ok", data: null, threadId: "t" };
|
|
538
|
-
},
|
|
539
|
-
);
|
|
540
|
-
|
|
541
|
-
await workflow("go", { sandboxId: "sb" });
|
|
542
|
-
expect(capturedContext).toBeUndefined();
|
|
543
|
-
});
|
|
544
|
-
|
|
545
586
|
it("returns the handler response unchanged", async () => {
|
|
546
587
|
const workflow = defineSubagentWorkflow(
|
|
547
|
-
{
|
|
588
|
+
{
|
|
589
|
+
name: "test",
|
|
590
|
+
description: "test agent",
|
|
591
|
+
resultSchema: z.object({ count: z.number() }),
|
|
592
|
+
},
|
|
548
593
|
async () => ({
|
|
549
594
|
toolResponse: "result text",
|
|
550
595
|
data: { count: 42 },
|
|
551
596
|
threadId: "child-thread",
|
|
552
|
-
})
|
|
597
|
+
})
|
|
553
598
|
);
|
|
554
599
|
|
|
555
600
|
const result = await workflow("go", {});
|
|
@@ -562,8 +607,12 @@ describe("defineSubagentWorkflow", () => {
|
|
|
562
607
|
it("attaches metadata to the returned workflow function", () => {
|
|
563
608
|
const schema = z.object({ findings: z.string() });
|
|
564
609
|
const workflow = defineSubagentWorkflow(
|
|
565
|
-
{
|
|
566
|
-
|
|
610
|
+
{
|
|
611
|
+
name: "researcher",
|
|
612
|
+
description: "Researches topics",
|
|
613
|
+
resultSchema: schema,
|
|
614
|
+
},
|
|
615
|
+
async () => ({ toolResponse: "ok", data: null, threadId: "t" })
|
|
567
616
|
);
|
|
568
617
|
|
|
569
618
|
expect(workflow.agentName).toBe("researcher");
|
|
@@ -58,7 +58,7 @@ export interface SubagentConfig<TResult extends z.ZodType = z.ZodType> {
|
|
|
58
58
|
/** Description shown to the parent agent explaining what this subagent does */
|
|
59
59
|
description: string;
|
|
60
60
|
/** Whether this subagent is available (default: true). Disabled subagents are excluded from the Subagent tool. */
|
|
61
|
-
enabled?: boolean;
|
|
61
|
+
enabled?: boolean | (() => boolean);
|
|
62
62
|
/** Temporal workflow function or type name (used with executeChild) */
|
|
63
63
|
workflow: string | SubagentWorkflow<TResult>;
|
|
64
64
|
/** Optional task queue - defaults to parent's queue if not specified */
|
|
@@ -63,8 +63,11 @@ export function createToolRouter<T extends ToolMap>(
|
|
|
63
63
|
toolMap.set(tool.name, tool as T[keyof T]);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
const resolve = <T,>(v: T | (() => T)): T =>
|
|
67
|
+
typeof v === "function" ? (v as () => T)() : v;
|
|
68
|
+
|
|
69
|
+
const isEnabled = (tool: ToolMap[string]): boolean =>
|
|
70
|
+
resolve(tool.enabled) ?? true;
|
|
68
71
|
|
|
69
72
|
if (options.plugins) {
|
|
70
73
|
for (const plugin of options.plugins) {
|
|
@@ -268,7 +271,7 @@ export function createToolRouter<T extends ToolMap>(
|
|
|
268
271
|
throw new Error(`Tool ${toolCall.name} not found`);
|
|
269
272
|
}
|
|
270
273
|
|
|
271
|
-
const parsedArgs = tool.schema.parse(toolCall.args);
|
|
274
|
+
const parsedArgs = resolve(tool.schema).parse(toolCall.args);
|
|
272
275
|
|
|
273
276
|
return {
|
|
274
277
|
id: toolCall.id ?? "",
|
|
@@ -293,8 +296,8 @@ export function createToolRouter<T extends ToolMap>(
|
|
|
293
296
|
.filter(([, tool]) => isEnabled(tool))
|
|
294
297
|
.map(([name, tool]) => ({
|
|
295
298
|
name,
|
|
296
|
-
description: tool.description,
|
|
297
|
-
schema: tool.schema,
|
|
299
|
+
description: resolve(tool.description),
|
|
300
|
+
schema: resolve(tool.schema),
|
|
298
301
|
strict: tool.strict,
|
|
299
302
|
max_uses: tool.max_uses,
|
|
300
303
|
}));
|
|
@@ -41,7 +41,7 @@ export interface ToolWithHandler<
|
|
|
41
41
|
strict?: boolean;
|
|
42
42
|
max_uses?: number;
|
|
43
43
|
/** Whether this tool is available to the agent (default: true). Disabled tools are excluded from definitions and rejected at parse time. */
|
|
44
|
-
enabled?: boolean;
|
|
44
|
+
enabled?: boolean | (() => boolean);
|
|
45
45
|
/** Per-tool lifecycle hooks (run in addition to global hooks) */
|
|
46
46
|
hooks?: ToolHooks<z.infer<TSchema>, TResult>;
|
|
47
47
|
}
|
|
@@ -58,13 +58,13 @@ export type ToolMap = Record<
|
|
|
58
58
|
string,
|
|
59
59
|
{
|
|
60
60
|
name: string;
|
|
61
|
-
description: string;
|
|
62
|
-
schema: z.ZodType;
|
|
61
|
+
description: string | (() => string);
|
|
62
|
+
schema: z.ZodType | (() => z.ZodType);
|
|
63
63
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
64
64
|
handler: ToolHandler<any, any, any>;
|
|
65
65
|
strict?: boolean;
|
|
66
66
|
max_uses?: number;
|
|
67
|
-
enabled?: boolean;
|
|
67
|
+
enabled?: boolean | (() => boolean);
|
|
68
68
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
69
69
|
hooks?: ToolHooks<any, any>;
|
|
70
70
|
}
|