zeitlich 0.2.2 → 0.2.4

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.
Files changed (46) hide show
  1. package/README.md +34 -31
  2. package/dist/index.cjs +330 -399
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +24 -43
  5. package/dist/index.d.ts +24 -43
  6. package/dist/index.js +301 -373
  7. package/dist/index.js.map +1 -1
  8. package/dist/{workflow-BQf5EfNN.d.cts → workflow-PjeURKw4.d.cts} +265 -258
  9. package/dist/{workflow-BQf5EfNN.d.ts → workflow-PjeURKw4.d.ts} +265 -258
  10. package/dist/workflow.cjs +223 -281
  11. package/dist/workflow.cjs.map +1 -1
  12. package/dist/workflow.d.cts +2 -3
  13. package/dist/workflow.d.ts +2 -3
  14. package/dist/workflow.js +198 -258
  15. package/dist/workflow.js.map +1 -1
  16. package/package.json +3 -2
  17. package/src/activities.ts +0 -32
  18. package/src/index.ts +14 -11
  19. package/src/lib/model-invoker.ts +7 -1
  20. package/src/lib/session.ts +54 -109
  21. package/src/lib/thread-manager.ts +45 -37
  22. package/src/lib/tool-router.ts +148 -108
  23. package/src/lib/types.ts +35 -26
  24. package/src/tools/ask-user-question/handler.ts +5 -5
  25. package/src/tools/ask-user-question/tool.ts +3 -2
  26. package/src/tools/bash/bash.test.ts +12 -12
  27. package/src/tools/bash/handler.ts +5 -5
  28. package/src/tools/bash/tool.ts +3 -2
  29. package/src/tools/edit/handler.ts +78 -123
  30. package/src/tools/edit/tool.ts +3 -2
  31. package/src/tools/glob/handler.ts +17 -48
  32. package/src/tools/glob/tool.ts +3 -2
  33. package/src/tools/grep/tool.ts +3 -2
  34. package/src/tools/{read → read-file}/tool.ts +3 -2
  35. package/src/tools/{task → subagent}/handler.ts +18 -31
  36. package/src/tools/{task → subagent}/tool.ts +13 -20
  37. package/src/tools/task-create/handler.ts +5 -11
  38. package/src/tools/task-create/tool.ts +3 -2
  39. package/src/tools/task-get/handler.ts +5 -10
  40. package/src/tools/task-get/tool.ts +3 -2
  41. package/src/tools/task-list/handler.ts +5 -10
  42. package/src/tools/task-list/tool.ts +3 -2
  43. package/src/tools/task-update/handler.ts +5 -12
  44. package/src/tools/task-update/tool.ts +3 -2
  45. package/src/tools/{write → write-file}/tool.ts +5 -6
  46. package/src/workflow.ts +24 -21
package/dist/workflow.cjs CHANGED
@@ -1,53 +1,53 @@
1
1
  'use strict';
2
2
 
3
3
  var workflow = require('@temporalio/workflow');
4
- var z5 = require('zod');
4
+ var z3 = require('zod');
5
5
 
6
6
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
7
 
8
- var z5__default = /*#__PURE__*/_interopDefault(z5);
8
+ var z3__default = /*#__PURE__*/_interopDefault(z3);
9
9
 
10
10
  // src/lib/session.ts
11
- var TASK_TOOL = "Task";
12
- function buildTaskDescription(subagents) {
11
+ var SUBAGENT_TOOL = "Subagent";
12
+ function buildSubagentDescription(subagents) {
13
13
  const subagentList = subagents.map((s) => `- **${s.name}**: ${s.description}`).join("\n");
14
- return `Launch a new agent to handle complex, multi-step tasks autonomously.
14
+ return `Launch a new agent to handle complex tasks autonomously.
15
15
 
16
- The ${TASK_TOOL} tool launches specialized agents (subprocesses) that autonomously handle complex tasks. Each agent type has specific capabilities and tools available to it.
16
+ The ${SUBAGENT_TOOL} tool launches specialized agents (subprocesses) that autonomously handle complex tasks. Each agent type has specific capabilities and tools available to it.
17
17
 
18
18
  Available agent types:
19
19
 
20
20
  ${subagentList}
21
21
 
22
- When using the ${TASK_TOOL} tool, you must specify a subagent parameter to select which agent type to use.
22
+ When using the ${SUBAGENT_TOOL} tool, you must specify a subagent parameter to select which agent type to use.
23
23
 
24
24
  Usage notes:
25
25
 
26
26
  - Always include a short description (3-5 words) summarizing what the agent will do
27
27
  - Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses
28
- - When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.
28
+ - When the agent is done, it will return a single message back to you.
29
29
  - Each invocation starts fresh - provide a detailed task description with all necessary context.
30
30
  - Provide clear, detailed prompts so the agent can work autonomously and return exactly the information you need.
31
31
  - The agent's outputs should generally be trusted
32
32
  - Clearly tell the agent what type of work you expect since it is not aware of the user's intent
33
33
  - If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.`;
34
34
  }
35
- function createTaskTool(subagents) {
35
+ function createSubagentTool(subagents) {
36
36
  if (subagents.length === 0) {
37
37
  throw new Error("createTaskTool requires at least one subagent");
38
38
  }
39
39
  const names = subagents.map((s) => s.name);
40
40
  return {
41
- name: TASK_TOOL,
42
- description: buildTaskDescription(subagents),
43
- schema: z5__default.default.object({
44
- subagent: z5__default.default.enum(names).describe("The type of subagent to launch"),
45
- description: z5__default.default.string().describe("A short (3-5 word) description of the task"),
46
- prompt: z5__default.default.string().describe("The task for the agent to perform")
41
+ name: SUBAGENT_TOOL,
42
+ description: buildSubagentDescription(subagents),
43
+ schema: z3__default.default.object({
44
+ subagent: z3__default.default.enum(names).describe("The type of subagent to launch"),
45
+ description: z3__default.default.string().describe("A short (3-5 word) description of the task"),
46
+ prompt: z3__default.default.string().describe("The task for the agent to perform")
47
47
  })
48
48
  };
49
49
  }
50
- function createTaskHandler(subagents) {
50
+ function createSubagentHandler(subagents) {
51
51
  const { workflowId: parentWorkflowId, taskQueue: parentTaskQueue } = workflow.workflowInfo();
52
52
  return async (args) => {
53
53
  const config = subagents.find((s) => s.name === args.subagent);
@@ -66,128 +66,32 @@ function createTaskHandler(subagents) {
66
66
  args: [input],
67
67
  taskQueue: config.taskQueue ?? parentTaskQueue
68
68
  };
69
- const childResult = typeof config.workflow === "string" ? await workflow.executeChild(config.workflow, childOpts) : await workflow.executeChild(config.workflow, childOpts);
70
- const validated = config.resultSchema ? config.resultSchema.parse(childResult) : childResult;
71
- const toolResponse = typeof validated === "string" ? validated : JSON.stringify(validated, null, 2);
69
+ const { toolResponse, data } = typeof config.workflow === "string" ? await workflow.executeChild(config.workflow, childOpts) : await workflow.executeChild(config.workflow, childOpts);
70
+ const validated = config.resultSchema ? config.resultSchema.parse(data) : null;
72
71
  return {
73
72
  toolResponse,
74
- data: {
75
- result: validated,
76
- childWorkflowId
77
- }
73
+ data: validated
78
74
  };
79
75
  };
80
76
  }
81
- var createBashToolDescription = ({
82
- fileTree
83
- }) => `Execute shell commands in a bash environment.
84
-
85
- Use this tool to:
86
- - Run shell commands (ls, cat, grep, find, etc.)
87
- - Execute scripts and chain commands with pipes (|) or logical operators (&&, ||)
88
- - Inspect files and directories
89
-
90
- Current file tree:
91
- ${fileTree}`;
92
- var bashTool = {
93
- name: "Bash",
94
- description: `Execute shell commands in a sandboxed bash environment.
95
-
96
- Use this tool to:
97
- - Run shell commands (ls, cat, grep, find, etc.)
98
- - Execute scripts and chain commands with pipes (|) or logical operators (&&, ||)
99
- - Inspect files and directories
100
- `,
101
- schema: z5__default.default.object({
102
- command: z5__default.default.string().describe(
103
- "The bash command to execute. Can include pipes (|), redirects (>, >>), logical operators (&&, ||), and shell features like command substitution $(...)."
104
- )
105
- }),
106
- strict: true
107
- };
108
- var taskCreateTool = {
109
- name: "TaskCreate",
110
- description: `Use this tool to create a structured task list for the control test. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
111
- It also helps the user understand the progress of the task and overall progress of their requests.
112
-
113
- ## When to Use This Tool
114
-
115
- Use this tool proactively in these scenarios:
116
-
117
- - Complex multi-step tasks - When a task requires 3 or more distinct steps or actions
118
- - Non-trivial and complex tasks - Tasks that require careful planning or multiple operations
119
- - User explicitly requests todo list - When the user directly asks you to use the todo list
120
- - User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated)
121
- - After receiving new instructions - Immediately capture user requirements as tasks
122
- - When you start working on a task - Mark it as in_progress BEFORE beginning work
123
- - After completing a task - Mark it as completed and add any new follow-up tasks discovered during implementation
124
-
125
- ## When NOT to Use This Tool
126
-
127
- Skip using this tool when:
128
- - There is only a single, straightforward task
129
- - The task is trivial and tracking it provides no organizational benefit
130
- - The task can be completed in less than 3 trivial steps
131
- - The task is purely conversational or informational
132
-
133
- NOTE that you should not use this tool if there is only one trivial task to do. In this case you are better off just doing the task directly.
134
-
135
- ## Task Fields
136
-
137
- - **subject**: A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")
138
- - **description**: Detailed description of what needs to be done, including context and acceptance criteria
139
- - **activeForm**: Present continuous form shown in spinner when task is in_progress (e.g., "Fixing authentication bug"). This is displayed to the user while you work on the task.
140
-
141
- **IMPORTANT**: Always provide activeForm when creating tasks. The subject should be imperative ("Run tests") while activeForm should be present continuous ("Running tests"). All tasks are created with status \`pending\`.
142
-
143
- ## Tips
144
-
145
- - Create tasks with clear, specific subjects that describe the outcome
146
- - Include enough detail in the description for another agent to understand and complete the task
147
- - After creating tasks, use TaskUpdate to set up dependencies (blocks/blockedBy) if needed
148
- - Check TaskList first to avoid creating duplicate tasks`,
149
- schema: z5__default.default.object({
150
- subject: z5__default.default.string().describe(
151
- 'A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")'
152
- ),
153
- description: z5__default.default.string().describe(
154
- "Detailed description of what needs to be done, including context and acceptance criteria"
155
- ),
156
- activeForm: z5__default.default.string().describe(
157
- 'Present continuous form shown in spinner when task is in_progress (e.g., "Fixing authentication bug"). This is displayed to the user while you work on the task.'
158
- ),
159
- metadata: z5__default.default.record(z5__default.default.string(), z5__default.default.string()).describe("Arbitrary key-value pairs for tracking")
160
- })
161
- };
162
77
 
163
78
  // src/lib/tool-router.ts
164
- var buildIntoolDefinitions = {
165
- [bashTool.name]: bashTool,
166
- [taskCreateTool.name]: taskCreateTool
167
- };
168
79
  function createToolRouter(options) {
169
- const { appendToolResult } = workflow.proxyActivities({
170
- startToCloseTimeout: "2m",
171
- retry: {
172
- maximumAttempts: 3,
173
- initialInterval: "5s",
174
- maximumInterval: "15m",
175
- backoffCoefficient: 4
176
- }
177
- });
80
+ const { appendToolResult } = options;
178
81
  const toolMap = /* @__PURE__ */ new Map();
179
82
  for (const [_key, tool] of Object.entries(options.tools)) {
180
83
  toolMap.set(tool.name, tool);
181
84
  }
85
+ const isEnabled = (tool) => tool.enabled !== false;
182
86
  if (options.subagents) {
183
87
  const subagentHooksMap = /* @__PURE__ */ new Map();
184
88
  for (const s of options.subagents) {
185
89
  if (s.hooks) subagentHooksMap.set(s.name, s.hooks);
186
90
  }
187
91
  const resolveSubagentName = (args) => args.subagent;
188
- toolMap.set("Task", {
189
- ...createTaskTool(options.subagents),
190
- handler: createTaskHandler(options.subagents),
92
+ toolMap.set("Subagent", {
93
+ ...createSubagentTool(options.subagents),
94
+ handler: createSubagentHandler(options.subagents),
191
95
  ...subagentHooksMap.size > 0 && {
192
96
  hooks: {
193
97
  onPreToolUse: async (ctx) => {
@@ -206,24 +110,6 @@ function createToolRouter(options) {
206
110
  }
207
111
  });
208
112
  }
209
- if (options.buildInTools) {
210
- for (const [key, value] of Object.entries(options.buildInTools)) {
211
- if (key === bashTool.name) {
212
- toolMap.set(key, {
213
- ...buildIntoolDefinitions[key],
214
- description: createBashToolDescription({
215
- fileTree: options.fileTree
216
- }),
217
- handler: value
218
- });
219
- } else {
220
- toolMap.set(key, {
221
- ...buildIntoolDefinitions[key],
222
- handler: value
223
- });
224
- }
225
- }
226
- }
227
113
  async function processToolCall(toolCall, turn, handlerContext) {
228
114
  const startTime = Date.now();
229
115
  const tool = toolMap.get(toolCall.name);
@@ -239,6 +125,7 @@ function createToolRouter(options) {
239
125
  await appendToolResult({
240
126
  threadId: options.threadId,
241
127
  toolCallId: toolCall.id,
128
+ toolName: toolCall.name,
242
129
  content: JSON.stringify({
243
130
  skipped: true,
244
131
  reason: "Skipped by PreToolUse hook"
@@ -260,6 +147,7 @@ function createToolRouter(options) {
260
147
  await appendToolResult({
261
148
  threadId: options.threadId,
262
149
  toolCallId: toolCall.id,
150
+ toolName: toolCall.name,
263
151
  content: JSON.stringify({
264
152
  skipped: true,
265
153
  reason: "Skipped by tool PreToolUse hook"
@@ -273,14 +161,22 @@ function createToolRouter(options) {
273
161
  }
274
162
  let result;
275
163
  let content;
164
+ let resultAppended = false;
276
165
  try {
277
166
  if (tool) {
167
+ const enrichedContext = {
168
+ ...handlerContext ?? {},
169
+ threadId: options.threadId,
170
+ toolCallId: toolCall.id,
171
+ toolName: toolCall.name
172
+ };
278
173
  const response = await tool.handler(
279
174
  effectiveArgs,
280
- handlerContext ?? {}
175
+ enrichedContext
281
176
  );
282
177
  result = response.data;
283
178
  content = response.toolResponse;
179
+ resultAppended = response.resultAppended === true;
284
180
  } else {
285
181
  result = { error: `Unknown tool: ${toolCall.name}` };
286
182
  content = JSON.stringify(result, null, 2);
@@ -326,11 +222,14 @@ function createToolRouter(options) {
326
222
  throw error;
327
223
  }
328
224
  }
329
- await appendToolResult({
330
- threadId: options.threadId,
331
- toolCallId: toolCall.id,
332
- content
333
- });
225
+ if (!resultAppended) {
226
+ await appendToolResult({
227
+ threadId: options.threadId,
228
+ toolCallId: toolCall.id,
229
+ toolName: toolCall.name,
230
+ content
231
+ });
232
+ }
334
233
  const toolResult = {
335
234
  toolCallId: toolCall.id,
336
235
  name: toolCall.name,
@@ -360,11 +259,11 @@ function createToolRouter(options) {
360
259
  return {
361
260
  // --- Methods from registry ---
362
261
  hasTools() {
363
- return toolMap.size > 0;
262
+ return Array.from(toolMap.values()).some(isEnabled);
364
263
  },
365
264
  parseToolCall(toolCall) {
366
265
  const tool = toolMap.get(toolCall.name);
367
- if (!tool) {
266
+ if (!tool || !isEnabled(tool)) {
368
267
  throw new Error(`Tool ${toolCall.name} not found`);
369
268
  }
370
269
  const parsedArgs = tool.schema.parse(toolCall.args);
@@ -375,13 +274,14 @@ function createToolRouter(options) {
375
274
  };
376
275
  },
377
276
  hasTool(name) {
378
- return toolMap.has(name);
277
+ const tool = toolMap.get(name);
278
+ return tool !== void 0 && isEnabled(tool);
379
279
  },
380
280
  getToolNames() {
381
- return Array.from(toolMap.keys());
281
+ return Array.from(toolMap.entries()).filter(([, tool]) => isEnabled(tool)).map(([name]) => name);
382
282
  },
383
283
  getToolDefinitions() {
384
- return Array.from(toolMap).map(([name, tool]) => ({
284
+ return Array.from(toolMap).filter(([, tool]) => isEnabled(tool)).map(([name, tool]) => ({
385
285
  name,
386
286
  description: tool.description,
387
287
  schema: tool.schema,
@@ -420,19 +320,28 @@ function createToolRouter(options) {
420
320
  }
421
321
  const handlerContext = context?.handlerContext ?? {};
422
322
  const processOne = async (toolCall) => {
323
+ const enrichedContext = {
324
+ ...handlerContext ?? {},
325
+ threadId: options.threadId,
326
+ toolCallId: toolCall.id,
327
+ toolName: toolCall.name
328
+ };
423
329
  const response = await handler(
424
330
  toolCall.args,
425
- handlerContext
331
+ enrichedContext
426
332
  );
427
- await appendToolResult({
428
- threadId: options.threadId,
429
- toolCallId: toolCall.id,
430
- content: response.toolResponse
431
- });
333
+ if (!response.resultAppended) {
334
+ await appendToolResult({
335
+ threadId: options.threadId,
336
+ toolCallId: toolCall.id,
337
+ toolName: toolCall.name,
338
+ content: response.toolResponse
339
+ });
340
+ }
432
341
  return {
433
342
  toolCallId: toolCall.id,
434
343
  name: toolCall.name,
435
- data: response.data ?? null
344
+ data: response.data
436
345
  };
437
346
  };
438
347
  if (options.parallel) {
@@ -469,51 +378,24 @@ function hasNoOtherToolCalls(toolCalls, excludeName) {
469
378
  }
470
379
 
471
380
  // src/lib/session.ts
472
- async function resolvePrompt(prompt) {
473
- if (typeof prompt === "function") {
474
- return prompt();
475
- }
476
- return prompt;
477
- }
478
381
  var createSession = async ({
479
382
  threadId,
480
383
  agentName,
481
384
  maxTurns = 50,
482
385
  metadata = {},
483
386
  runAgent,
484
- baseSystemPrompt,
485
- instructionsPrompt,
387
+ threadOps,
486
388
  buildContextMessage,
487
- buildFileTree = async () => "",
488
389
  subagents,
489
390
  tools = {},
490
391
  processToolsInParallel = true,
491
- buildInTools = {},
492
392
  hooks = {}
493
393
  }) => {
494
- const {
495
- initializeThread,
496
- appendHumanMessage,
497
- parseToolCalls,
498
- appendToolResult,
499
- appendSystemMessage
500
- } = workflow.proxyActivities({
501
- startToCloseTimeout: "30m",
502
- retry: {
503
- maximumAttempts: 6,
504
- initialInterval: "5s",
505
- maximumInterval: "15m",
506
- backoffCoefficient: 4
507
- },
508
- heartbeatTimeout: "5m"
509
- });
510
- const fileTree = await buildFileTree();
511
394
  const toolRouter = createToolRouter({
512
395
  tools,
396
+ appendToolResult: threadOps.appendToolResult,
513
397
  threadId,
514
398
  hooks,
515
- buildInTools,
516
- fileTree,
517
399
  subagents,
518
400
  parallel: processToolsInParallel
519
401
  });
@@ -538,83 +420,41 @@ var createSession = async ({
538
420
  });
539
421
  }
540
422
  stateManager.setTools(toolRouter.getToolDefinitions());
541
- await initializeThread(threadId);
542
- await appendSystemMessage(
543
- threadId,
544
- [
545
- await resolvePrompt(baseSystemPrompt),
546
- await resolvePrompt(instructionsPrompt)
547
- ].join("\n")
548
- );
549
- await appendHumanMessage(threadId, await buildContextMessage());
423
+ await threadOps.initializeThread(threadId);
424
+ await threadOps.appendHumanMessage(threadId, await buildContextMessage());
550
425
  let exitReason = "completed";
551
426
  try {
552
427
  while (stateManager.isRunning() && !stateManager.isTerminal() && stateManager.getTurns() < maxTurns) {
553
428
  stateManager.incrementTurns();
554
429
  const currentTurn = stateManager.getTurns();
555
- const { message, stopReason } = await runAgent({
430
+ const { message, rawToolCalls } = await runAgent({
556
431
  threadId,
557
432
  agentName,
558
433
  metadata
559
434
  });
560
- if (stopReason === "end_turn") {
435
+ if (!toolRouter.hasTools() || rawToolCalls.length === 0) {
561
436
  stateManager.complete();
562
437
  exitReason = "completed";
563
438
  return message;
564
439
  }
565
- if (!toolRouter.hasTools()) {
566
- stateManager.complete();
567
- exitReason = "completed";
568
- return message;
569
- }
570
- const rawToolCalls = await parseToolCalls(message);
571
440
  const parsedToolCalls = [];
572
- for (const tc of rawToolCalls.filter(
573
- (tc2) => tc2.name !== "Task"
574
- )) {
441
+ for (const tc of rawToolCalls) {
575
442
  try {
576
443
  parsedToolCalls.push(toolRouter.parseToolCall(tc));
577
444
  } catch (error) {
578
- await appendToolResult({
445
+ await threadOps.appendToolResult({
579
446
  threadId,
580
447
  toolCallId: tc.id ?? "",
448
+ toolName: tc.name,
581
449
  content: JSON.stringify({
582
450
  error: `Invalid tool call for "${tc.name}": ${error instanceof Error ? error.message : String(error)}`
583
451
  })
584
452
  });
585
453
  }
586
454
  }
587
- const taskToolCalls = [];
588
- if (subagents && subagents.length > 0) {
589
- for (const tc of rawToolCalls.filter(
590
- (tc2) => tc2.name === "Task"
591
- )) {
592
- try {
593
- const parsedArgs = createTaskTool(subagents).schema.parse(
594
- tc.args
595
- );
596
- taskToolCalls.push({
597
- id: tc.id ?? "",
598
- name: tc.name,
599
- args: parsedArgs
600
- });
601
- } catch (error) {
602
- await appendToolResult({
603
- threadId,
604
- toolCallId: tc.id ?? "",
605
- content: JSON.stringify({
606
- error: `Invalid tool call for "Task": ${error instanceof Error ? error.message : String(error)}`
607
- })
608
- });
609
- }
610
- }
611
- }
612
- await toolRouter.processToolCalls(
613
- [...parsedToolCalls, ...taskToolCalls],
614
- {
615
- turn: currentTurn
616
- }
617
- );
455
+ await toolRouter.processToolCalls(parsedToolCalls, {
456
+ turn: currentTurn
457
+ });
618
458
  if (stateManager.getStatus() === "WAITING_FOR_INPUT") {
619
459
  exitReason = "waiting_for_input";
620
460
  break;
@@ -633,6 +473,25 @@ var createSession = async ({
633
473
  }
634
474
  };
635
475
  };
476
+ function proxyDefaultThreadOps(options) {
477
+ const activities = workflow.proxyActivities(
478
+ options ?? {
479
+ startToCloseTimeout: "30m",
480
+ retry: {
481
+ maximumAttempts: 6,
482
+ initialInterval: "5s",
483
+ maximumInterval: "15m",
484
+ backoffCoefficient: 4
485
+ },
486
+ heartbeatTimeout: "5m"
487
+ }
488
+ );
489
+ return {
490
+ initializeThread: activities.initializeThread,
491
+ appendHumanMessage: activities.appendHumanMessage,
492
+ appendToolResult: activities.appendToolResult
493
+ };
494
+ }
636
495
 
637
496
  // src/lib/types.ts
638
497
  function isTerminalStatus(status) {
@@ -735,7 +594,7 @@ function createAgentStateManager(initialState) {
735
594
  tools = newTools.map((tool) => ({
736
595
  name: tool.name,
737
596
  description: tool.description,
738
- schema: z5.z.toJSONSchema(tool.schema),
597
+ schema: z3.z.toJSONSchema(tool.schema),
739
598
  strict: tool.strict,
740
599
  max_uses: tool.max_uses
741
600
  }));
@@ -769,18 +628,18 @@ Usage notes:
769
628
  * Use multiSelect: true to allow multiple answers to be selected for a question
770
629
  * If you recommend a specific option, make that the first option in the list and add "(Recommended)" at the end of the label
771
630
  `,
772
- schema: z5__default.default.object({
773
- questions: z5__default.default.array(
774
- z5__default.default.object({
775
- question: z5__default.default.string().describe("The full question text to display"),
776
- header: z5__default.default.string().describe("Short label for the question (max 12 characters)"),
777
- options: z5__default.default.array(
778
- z5__default.default.object({
779
- label: z5__default.default.string(),
780
- description: z5__default.default.string()
631
+ schema: z3__default.default.object({
632
+ questions: z3__default.default.array(
633
+ z3__default.default.object({
634
+ question: z3__default.default.string().describe("The full question text to display"),
635
+ header: z3__default.default.string().describe("Short label for the question (max 12 characters)"),
636
+ options: z3__default.default.array(
637
+ z3__default.default.object({
638
+ label: z3__default.default.string(),
639
+ description: z3__default.default.string()
781
640
  })
782
641
  ).min(0).max(4).describe("Array of 0-4 choices, each with label and description"),
783
- multiSelect: z5__default.default.boolean().describe("If true, users can select multiple options")
642
+ multiSelect: z3__default.default.boolean().describe("If true, users can select multiple options")
784
643
  })
785
644
  )
786
645
  }),
@@ -800,9 +659,9 @@ Examples:
800
659
  - "**/*.test.ts" - Find all test files recursively
801
660
  - "src/**/*.ts" - Find all TypeScript files in src directory
802
661
  `,
803
- schema: z5.z.object({
804
- pattern: z5.z.string().describe("Glob pattern to match files against"),
805
- root: z5.z.string().optional().describe("Optional root directory to search from")
662
+ schema: z3.z.object({
663
+ pattern: z3.z.string().describe("Glob pattern to match files against"),
664
+ root: z3.z.string().optional().describe("Optional root directory to search from")
806
665
  }),
807
666
  strict: true
808
667
  };
@@ -820,13 +679,13 @@ Examples:
820
679
  - Search for function definitions with "function.*handleClick"
821
680
  - Search case-insensitively with ignoreCase: true
822
681
  `,
823
- schema: z5.z.object({
824
- pattern: z5.z.string().describe("Regex pattern to search for in file contents"),
825
- ignoreCase: z5.z.boolean().optional().describe("Case-insensitive search (default: false)"),
826
- maxMatches: z5.z.number().optional().describe("Maximum number of matches to return (default: 50)"),
827
- includePatterns: z5.z.array(z5.z.string()).optional().describe("Glob patterns to include (e.g., ['*.ts', '*.js'])"),
828
- excludePatterns: z5.z.array(z5.z.string()).optional().describe("Glob patterns to exclude (e.g., ['*.test.ts'])"),
829
- contextLines: z5.z.number().optional().describe("Number of context lines to show around matches")
682
+ schema: z3.z.object({
683
+ pattern: z3.z.string().describe("Regex pattern to search for in file contents"),
684
+ ignoreCase: z3.z.boolean().optional().describe("Case-insensitive search (default: false)"),
685
+ maxMatches: z3.z.number().optional().describe("Maximum number of matches to return (default: 50)"),
686
+ includePatterns: z3.z.array(z3.z.string()).optional().describe("Glob patterns to include (e.g., ['*.ts', '*.js'])"),
687
+ excludePatterns: z3.z.array(z3.z.string()).optional().describe("Glob patterns to exclude (e.g., ['*.test.ts'])"),
688
+ contextLines: z3.z.number().optional().describe("Number of context lines to show around matches")
830
689
  }),
831
690
  strict: true
832
691
  };
@@ -844,12 +703,12 @@ The tool returns the file content in an appropriate format:
844
703
  - Images: Base64-encoded image data
845
704
  - PDFs: Extracted text content
846
705
  `,
847
- schema: z5.z.object({
848
- path: z5.z.string().describe("Virtual path to the file to read"),
849
- offset: z5.z.number().optional().describe(
706
+ schema: z3.z.object({
707
+ path: z3.z.string().describe("Virtual path to the file to read"),
708
+ offset: z3.z.number().optional().describe(
850
709
  "Line number to start reading from (1-indexed, for text files)"
851
710
  ),
852
- limit: z5.z.number().optional().describe("Maximum number of lines to read (for text files)")
711
+ limit: z3.z.number().optional().describe("Maximum number of lines to read (for text files)")
853
712
  }),
854
713
  strict: true
855
714
  };
@@ -858,7 +717,7 @@ var writeTool = {
858
717
  description: `Create or overwrite a file with new content.
859
718
 
860
719
  Usage:
861
- - Provide the absolute virtual path to the file
720
+ - Provide the absolute path to the file
862
721
  - The file will be created if it doesn't exist
863
722
  - If the file exists, it will be completely overwritten
864
723
 
@@ -867,9 +726,9 @@ IMPORTANT:
867
726
  - This is an atomic write operation - the entire file is replaced
868
727
  - Path must be absolute (e.g., "/docs/readme.md", not "docs/readme.md")
869
728
  `,
870
- schema: z5.z.object({
871
- file_path: z5.z.string().describe("The absolute virtual path to the file to write"),
872
- content: z5.z.string().describe("The content to write to the file")
729
+ schema: z3.z.object({
730
+ file_path: z3.z.string().describe("The absolute path to the file to write"),
731
+ content: z3.z.string().describe("The content to write to the file")
873
732
  }),
874
733
  strict: true
875
734
  };
@@ -889,18 +748,72 @@ IMPORTANT:
889
748
  - The operation fails if old_string is not found
890
749
  - old_string and new_string must be different
891
750
  `,
892
- schema: z5.z.object({
893
- file_path: z5.z.string().describe("The absolute virtual path to the file to modify"),
894
- old_string: z5.z.string().describe("The exact text to replace"),
895
- new_string: z5.z.string().describe(
751
+ schema: z3.z.object({
752
+ file_path: z3.z.string().describe("The absolute virtual path to the file to modify"),
753
+ old_string: z3.z.string().describe("The exact text to replace"),
754
+ new_string: z3.z.string().describe(
896
755
  "The text to replace it with (must be different from old_string)"
897
756
  ),
898
- replace_all: z5.z.boolean().optional().describe(
757
+ replace_all: z3.z.boolean().optional().describe(
899
758
  "If true, replace all occurrences of old_string (default: false)"
900
759
  )
901
760
  }),
902
761
  strict: true
903
762
  };
763
+ var taskCreateTool = {
764
+ name: "TaskCreate",
765
+ description: `Use this tool to create a structured task list for the control test. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
766
+ It also helps the user understand the progress of the task and overall progress of their requests.
767
+
768
+ ## When to Use This Tool
769
+
770
+ Use this tool proactively in these scenarios:
771
+
772
+ - Complex multi-step tasks - When a task requires 3 or more distinct steps or actions
773
+ - Non-trivial and complex tasks - Tasks that require careful planning or multiple operations
774
+ - User explicitly requests todo list - When the user directly asks you to use the todo list
775
+ - User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated)
776
+ - After receiving new instructions - Immediately capture user requirements as tasks
777
+ - When you start working on a task - Mark it as in_progress BEFORE beginning work
778
+ - After completing a task - Mark it as completed and add any new follow-up tasks discovered during implementation
779
+
780
+ ## When NOT to Use This Tool
781
+
782
+ Skip using this tool when:
783
+ - There is only a single, straightforward task
784
+ - The task is trivial and tracking it provides no organizational benefit
785
+ - The task can be completed in less than 3 trivial steps
786
+ - The task is purely conversational or informational
787
+
788
+ NOTE that you should not use this tool if there is only one trivial task to do. In this case you are better off just doing the task directly.
789
+
790
+ ## Task Fields
791
+
792
+ - **subject**: A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")
793
+ - **description**: Detailed description of what needs to be done, including context and acceptance criteria
794
+ - **activeForm**: Present continuous form shown in spinner when task is in_progress (e.g., "Fixing authentication bug"). This is displayed to the user while you work on the task.
795
+
796
+ **IMPORTANT**: Always provide activeForm when creating tasks. The subject should be imperative ("Run tests") while activeForm should be present continuous ("Running tests"). All tasks are created with status \`pending\`.
797
+
798
+ ## Tips
799
+
800
+ - Create tasks with clear, specific subjects that describe the outcome
801
+ - Include enough detail in the description for another agent to understand and complete the task
802
+ - After creating tasks, use TaskUpdate to set up dependencies (blocks/blockedBy) if needed
803
+ - Check TaskList first to avoid creating duplicate tasks`,
804
+ schema: z3__default.default.object({
805
+ subject: z3__default.default.string().describe(
806
+ 'A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")'
807
+ ),
808
+ description: z3__default.default.string().describe(
809
+ "Detailed description of what needs to be done, including context and acceptance criteria"
810
+ ),
811
+ activeForm: z3__default.default.string().describe(
812
+ 'Present continuous form shown in spinner when task is in_progress (e.g., "Fixing authentication bug"). This is displayed to the user while you work on the task.'
813
+ ),
814
+ metadata: z3__default.default.record(z3__default.default.string(), z3__default.default.string()).describe("Arbitrary key-value pairs for tracking")
815
+ })
816
+ };
904
817
  function createTaskCreateHandler(stateManager) {
905
818
  return (args) => {
906
819
  const task = {
@@ -923,8 +836,8 @@ function createTaskCreateHandler(stateManager) {
923
836
  var taskGetTool = {
924
837
  name: "TaskGet",
925
838
  description: `Retrieve full task details including dependencies.`,
926
- schema: z5__default.default.object({
927
- taskId: z5__default.default.string().describe("The ID of the task to get")
839
+ schema: z3__default.default.object({
840
+ taskId: z3__default.default.string().describe("The ID of the task to get")
928
841
  })
929
842
  };
930
843
 
@@ -947,12 +860,12 @@ function createTaskGetHandler(stateManager) {
947
860
  var taskListTool = {
948
861
  name: "TaskList",
949
862
  description: `List all tasks with current state.`,
950
- schema: z5__default.default.object({})
863
+ schema: z3__default.default.object({})
951
864
  };
952
865
 
953
866
  // src/tools/task-list/handler.ts
954
867
  function createTaskListHandler(stateManager) {
955
- return (_args) => {
868
+ return () => {
956
869
  const taskList = stateManager.getTasks();
957
870
  return {
958
871
  toolResponse: JSON.stringify(taskList, null, 2),
@@ -963,11 +876,11 @@ function createTaskListHandler(stateManager) {
963
876
  var taskUpdateTool = {
964
877
  name: "TaskUpdate",
965
878
  description: `Update status, add blockers, modify details.`,
966
- schema: z5__default.default.object({
967
- taskId: z5__default.default.string().describe("The ID of the task to get"),
968
- status: z5__default.default.enum(["pending", "in_progress", "completed"]).describe("The status of the task"),
969
- addBlockedBy: z5__default.default.array(z5__default.default.string()).describe("The IDs of the tasks that are blocking this task"),
970
- addBlocks: z5__default.default.array(z5__default.default.string()).describe("The IDs of the tasks that this task is blocking")
879
+ schema: z3__default.default.object({
880
+ taskId: z3__default.default.string().describe("The ID of the task to get"),
881
+ status: z3__default.default.enum(["pending", "in_progress", "completed"]).describe("The status of the task"),
882
+ addBlockedBy: z3__default.default.array(z3__default.default.string()).describe("The IDs of the tasks that are blocking this task"),
883
+ addBlocks: z3__default.default.array(z3__default.default.string()).describe("The IDs of the tasks that this task is blocking")
971
884
  })
972
885
  };
973
886
 
@@ -1015,16 +928,44 @@ function createTaskUpdateHandler(stateManager) {
1015
928
  };
1016
929
  };
1017
930
  }
931
+ var createBashToolDescription = ({
932
+ fileTree
933
+ }) => `Execute shell commands in a bash environment.
934
+
935
+ Use this tool to:
936
+ - Run shell commands (ls, cat, grep, find, etc.)
937
+ - Execute scripts and chain commands with pipes (|) or logical operators (&&, ||)
938
+ - Inspect files and directories
939
+
940
+ Current file tree:
941
+ ${fileTree}`;
942
+ var bashTool = {
943
+ name: "Bash",
944
+ description: `Execute shell commands in a sandboxed bash environment.
945
+
946
+ Use this tool to:
947
+ - Run shell commands (ls, cat, grep, find, etc.)
948
+ - Execute scripts and chain commands with pipes (|) or logical operators (&&, ||)
949
+ - Inspect files and directories
950
+ `,
951
+ schema: z3__default.default.object({
952
+ command: z3__default.default.string().describe(
953
+ "The bash command to execute. Can include pipes (|), redirects (>, >>), logical operators (&&, ||), and shell features like command substitution $(...)."
954
+ )
955
+ }),
956
+ strict: true
957
+ };
1018
958
 
1019
959
  exports.AGENT_HANDLER_NAMES = AGENT_HANDLER_NAMES;
1020
960
  exports.askUserQuestionTool = askUserQuestionTool;
1021
961
  exports.bashTool = bashTool;
1022
962
  exports.createAgentStateManager = createAgentStateManager;
963
+ exports.createBashToolDescription = createBashToolDescription;
1023
964
  exports.createSession = createSession;
965
+ exports.createSubagentTool = createSubagentTool;
1024
966
  exports.createTaskCreateHandler = createTaskCreateHandler;
1025
967
  exports.createTaskGetHandler = createTaskGetHandler;
1026
968
  exports.createTaskListHandler = createTaskListHandler;
1027
- exports.createTaskTool = createTaskTool;
1028
969
  exports.createTaskUpdateHandler = createTaskUpdateHandler;
1029
970
  exports.createToolRouter = createToolRouter;
1030
971
  exports.defineSubagent = defineSubagent;
@@ -1034,6 +975,7 @@ exports.globTool = globTool;
1034
975
  exports.grepTool = grepTool;
1035
976
  exports.hasNoOtherToolCalls = hasNoOtherToolCalls;
1036
977
  exports.isTerminalStatus = isTerminalStatus;
978
+ exports.proxyDefaultThreadOps = proxyDefaultThreadOps;
1037
979
  exports.readTool = readTool;
1038
980
  exports.taskCreateTool = taskCreateTool;
1039
981
  exports.taskGetTool = taskGetTool;