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.js CHANGED
@@ -1,47 +1,47 @@
1
1
  import { defineQuery, proxyActivities, setHandler, uuid4, workflowInfo, executeChild } from '@temporalio/workflow';
2
- import z5, { z } from 'zod';
2
+ import z3, { z } from 'zod';
3
3
 
4
4
  // src/lib/session.ts
5
- var TASK_TOOL = "Task";
6
- function buildTaskDescription(subagents) {
5
+ var SUBAGENT_TOOL = "Subagent";
6
+ function buildSubagentDescription(subagents) {
7
7
  const subagentList = subagents.map((s) => `- **${s.name}**: ${s.description}`).join("\n");
8
- return `Launch a new agent to handle complex, multi-step tasks autonomously.
8
+ return `Launch a new agent to handle complex tasks autonomously.
9
9
 
10
- The ${TASK_TOOL} tool launches specialized agents (subprocesses) that autonomously handle complex tasks. Each agent type has specific capabilities and tools available to it.
10
+ The ${SUBAGENT_TOOL} tool launches specialized agents (subprocesses) that autonomously handle complex tasks. Each agent type has specific capabilities and tools available to it.
11
11
 
12
12
  Available agent types:
13
13
 
14
14
  ${subagentList}
15
15
 
16
- When using the ${TASK_TOOL} tool, you must specify a subagent parameter to select which agent type to use.
16
+ When using the ${SUBAGENT_TOOL} tool, you must specify a subagent parameter to select which agent type to use.
17
17
 
18
18
  Usage notes:
19
19
 
20
20
  - Always include a short description (3-5 words) summarizing what the agent will do
21
21
  - Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses
22
- - 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.
22
+ - When the agent is done, it will return a single message back to you.
23
23
  - Each invocation starts fresh - provide a detailed task description with all necessary context.
24
24
  - Provide clear, detailed prompts so the agent can work autonomously and return exactly the information you need.
25
25
  - The agent's outputs should generally be trusted
26
26
  - Clearly tell the agent what type of work you expect since it is not aware of the user's intent
27
27
  - 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.`;
28
28
  }
29
- function createTaskTool(subagents) {
29
+ function createSubagentTool(subagents) {
30
30
  if (subagents.length === 0) {
31
31
  throw new Error("createTaskTool requires at least one subagent");
32
32
  }
33
33
  const names = subagents.map((s) => s.name);
34
34
  return {
35
- name: TASK_TOOL,
36
- description: buildTaskDescription(subagents),
37
- schema: z5.object({
38
- subagent: z5.enum(names).describe("The type of subagent to launch"),
39
- description: z5.string().describe("A short (3-5 word) description of the task"),
40
- prompt: z5.string().describe("The task for the agent to perform")
35
+ name: SUBAGENT_TOOL,
36
+ description: buildSubagentDescription(subagents),
37
+ schema: z3.object({
38
+ subagent: z3.enum(names).describe("The type of subagent to launch"),
39
+ description: z3.string().describe("A short (3-5 word) description of the task"),
40
+ prompt: z3.string().describe("The task for the agent to perform")
41
41
  })
42
42
  };
43
43
  }
44
- function createTaskHandler(subagents) {
44
+ function createSubagentHandler(subagents) {
45
45
  const { workflowId: parentWorkflowId, taskQueue: parentTaskQueue } = workflowInfo();
46
46
  return async (args) => {
47
47
  const config = subagents.find((s) => s.name === args.subagent);
@@ -60,128 +60,32 @@ function createTaskHandler(subagents) {
60
60
  args: [input],
61
61
  taskQueue: config.taskQueue ?? parentTaskQueue
62
62
  };
63
- const childResult = typeof config.workflow === "string" ? await executeChild(config.workflow, childOpts) : await executeChild(config.workflow, childOpts);
64
- const validated = config.resultSchema ? config.resultSchema.parse(childResult) : childResult;
65
- const toolResponse = typeof validated === "string" ? validated : JSON.stringify(validated, null, 2);
63
+ const { toolResponse, data } = typeof config.workflow === "string" ? await executeChild(config.workflow, childOpts) : await executeChild(config.workflow, childOpts);
64
+ const validated = config.resultSchema ? config.resultSchema.parse(data) : null;
66
65
  return {
67
66
  toolResponse,
68
- data: {
69
- result: validated,
70
- childWorkflowId
71
- }
67
+ data: validated
72
68
  };
73
69
  };
74
70
  }
75
- var createBashToolDescription = ({
76
- fileTree
77
- }) => `Execute shell commands in a bash environment.
78
-
79
- Use this tool to:
80
- - Run shell commands (ls, cat, grep, find, etc.)
81
- - Execute scripts and chain commands with pipes (|) or logical operators (&&, ||)
82
- - Inspect files and directories
83
-
84
- Current file tree:
85
- ${fileTree}`;
86
- var bashTool = {
87
- name: "Bash",
88
- description: `Execute shell commands in a sandboxed bash environment.
89
-
90
- Use this tool to:
91
- - Run shell commands (ls, cat, grep, find, etc.)
92
- - Execute scripts and chain commands with pipes (|) or logical operators (&&, ||)
93
- - Inspect files and directories
94
- `,
95
- schema: z5.object({
96
- command: z5.string().describe(
97
- "The bash command to execute. Can include pipes (|), redirects (>, >>), logical operators (&&, ||), and shell features like command substitution $(...)."
98
- )
99
- }),
100
- strict: true
101
- };
102
- var taskCreateTool = {
103
- name: "TaskCreate",
104
- 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.
105
- It also helps the user understand the progress of the task and overall progress of their requests.
106
-
107
- ## When to Use This Tool
108
-
109
- Use this tool proactively in these scenarios:
110
-
111
- - Complex multi-step tasks - When a task requires 3 or more distinct steps or actions
112
- - Non-trivial and complex tasks - Tasks that require careful planning or multiple operations
113
- - User explicitly requests todo list - When the user directly asks you to use the todo list
114
- - User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated)
115
- - After receiving new instructions - Immediately capture user requirements as tasks
116
- - When you start working on a task - Mark it as in_progress BEFORE beginning work
117
- - After completing a task - Mark it as completed and add any new follow-up tasks discovered during implementation
118
-
119
- ## When NOT to Use This Tool
120
-
121
- Skip using this tool when:
122
- - There is only a single, straightforward task
123
- - The task is trivial and tracking it provides no organizational benefit
124
- - The task can be completed in less than 3 trivial steps
125
- - The task is purely conversational or informational
126
-
127
- 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.
128
-
129
- ## Task Fields
130
-
131
- - **subject**: A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")
132
- - **description**: Detailed description of what needs to be done, including context and acceptance criteria
133
- - **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.
134
-
135
- **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\`.
136
-
137
- ## Tips
138
-
139
- - Create tasks with clear, specific subjects that describe the outcome
140
- - Include enough detail in the description for another agent to understand and complete the task
141
- - After creating tasks, use TaskUpdate to set up dependencies (blocks/blockedBy) if needed
142
- - Check TaskList first to avoid creating duplicate tasks`,
143
- schema: z5.object({
144
- subject: z5.string().describe(
145
- 'A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")'
146
- ),
147
- description: z5.string().describe(
148
- "Detailed description of what needs to be done, including context and acceptance criteria"
149
- ),
150
- activeForm: z5.string().describe(
151
- '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.'
152
- ),
153
- metadata: z5.record(z5.string(), z5.string()).describe("Arbitrary key-value pairs for tracking")
154
- })
155
- };
156
71
 
157
72
  // src/lib/tool-router.ts
158
- var buildIntoolDefinitions = {
159
- [bashTool.name]: bashTool,
160
- [taskCreateTool.name]: taskCreateTool
161
- };
162
73
  function createToolRouter(options) {
163
- const { appendToolResult } = proxyActivities({
164
- startToCloseTimeout: "2m",
165
- retry: {
166
- maximumAttempts: 3,
167
- initialInterval: "5s",
168
- maximumInterval: "15m",
169
- backoffCoefficient: 4
170
- }
171
- });
74
+ const { appendToolResult } = options;
172
75
  const toolMap = /* @__PURE__ */ new Map();
173
76
  for (const [_key, tool] of Object.entries(options.tools)) {
174
77
  toolMap.set(tool.name, tool);
175
78
  }
79
+ const isEnabled = (tool) => tool.enabled !== false;
176
80
  if (options.subagents) {
177
81
  const subagentHooksMap = /* @__PURE__ */ new Map();
178
82
  for (const s of options.subagents) {
179
83
  if (s.hooks) subagentHooksMap.set(s.name, s.hooks);
180
84
  }
181
85
  const resolveSubagentName = (args) => args.subagent;
182
- toolMap.set("Task", {
183
- ...createTaskTool(options.subagents),
184
- handler: createTaskHandler(options.subagents),
86
+ toolMap.set("Subagent", {
87
+ ...createSubagentTool(options.subagents),
88
+ handler: createSubagentHandler(options.subagents),
185
89
  ...subagentHooksMap.size > 0 && {
186
90
  hooks: {
187
91
  onPreToolUse: async (ctx) => {
@@ -200,24 +104,6 @@ function createToolRouter(options) {
200
104
  }
201
105
  });
202
106
  }
203
- if (options.buildInTools) {
204
- for (const [key, value] of Object.entries(options.buildInTools)) {
205
- if (key === bashTool.name) {
206
- toolMap.set(key, {
207
- ...buildIntoolDefinitions[key],
208
- description: createBashToolDescription({
209
- fileTree: options.fileTree
210
- }),
211
- handler: value
212
- });
213
- } else {
214
- toolMap.set(key, {
215
- ...buildIntoolDefinitions[key],
216
- handler: value
217
- });
218
- }
219
- }
220
- }
221
107
  async function processToolCall(toolCall, turn, handlerContext) {
222
108
  const startTime = Date.now();
223
109
  const tool = toolMap.get(toolCall.name);
@@ -233,6 +119,7 @@ function createToolRouter(options) {
233
119
  await appendToolResult({
234
120
  threadId: options.threadId,
235
121
  toolCallId: toolCall.id,
122
+ toolName: toolCall.name,
236
123
  content: JSON.stringify({
237
124
  skipped: true,
238
125
  reason: "Skipped by PreToolUse hook"
@@ -254,6 +141,7 @@ function createToolRouter(options) {
254
141
  await appendToolResult({
255
142
  threadId: options.threadId,
256
143
  toolCallId: toolCall.id,
144
+ toolName: toolCall.name,
257
145
  content: JSON.stringify({
258
146
  skipped: true,
259
147
  reason: "Skipped by tool PreToolUse hook"
@@ -267,14 +155,22 @@ function createToolRouter(options) {
267
155
  }
268
156
  let result;
269
157
  let content;
158
+ let resultAppended = false;
270
159
  try {
271
160
  if (tool) {
161
+ const enrichedContext = {
162
+ ...handlerContext ?? {},
163
+ threadId: options.threadId,
164
+ toolCallId: toolCall.id,
165
+ toolName: toolCall.name
166
+ };
272
167
  const response = await tool.handler(
273
168
  effectiveArgs,
274
- handlerContext ?? {}
169
+ enrichedContext
275
170
  );
276
171
  result = response.data;
277
172
  content = response.toolResponse;
173
+ resultAppended = response.resultAppended === true;
278
174
  } else {
279
175
  result = { error: `Unknown tool: ${toolCall.name}` };
280
176
  content = JSON.stringify(result, null, 2);
@@ -320,11 +216,14 @@ function createToolRouter(options) {
320
216
  throw error;
321
217
  }
322
218
  }
323
- await appendToolResult({
324
- threadId: options.threadId,
325
- toolCallId: toolCall.id,
326
- content
327
- });
219
+ if (!resultAppended) {
220
+ await appendToolResult({
221
+ threadId: options.threadId,
222
+ toolCallId: toolCall.id,
223
+ toolName: toolCall.name,
224
+ content
225
+ });
226
+ }
328
227
  const toolResult = {
329
228
  toolCallId: toolCall.id,
330
229
  name: toolCall.name,
@@ -354,11 +253,11 @@ function createToolRouter(options) {
354
253
  return {
355
254
  // --- Methods from registry ---
356
255
  hasTools() {
357
- return toolMap.size > 0;
256
+ return Array.from(toolMap.values()).some(isEnabled);
358
257
  },
359
258
  parseToolCall(toolCall) {
360
259
  const tool = toolMap.get(toolCall.name);
361
- if (!tool) {
260
+ if (!tool || !isEnabled(tool)) {
362
261
  throw new Error(`Tool ${toolCall.name} not found`);
363
262
  }
364
263
  const parsedArgs = tool.schema.parse(toolCall.args);
@@ -369,13 +268,14 @@ function createToolRouter(options) {
369
268
  };
370
269
  },
371
270
  hasTool(name) {
372
- return toolMap.has(name);
271
+ const tool = toolMap.get(name);
272
+ return tool !== void 0 && isEnabled(tool);
373
273
  },
374
274
  getToolNames() {
375
- return Array.from(toolMap.keys());
275
+ return Array.from(toolMap.entries()).filter(([, tool]) => isEnabled(tool)).map(([name]) => name);
376
276
  },
377
277
  getToolDefinitions() {
378
- return Array.from(toolMap).map(([name, tool]) => ({
278
+ return Array.from(toolMap).filter(([, tool]) => isEnabled(tool)).map(([name, tool]) => ({
379
279
  name,
380
280
  description: tool.description,
381
281
  schema: tool.schema,
@@ -414,19 +314,28 @@ function createToolRouter(options) {
414
314
  }
415
315
  const handlerContext = context?.handlerContext ?? {};
416
316
  const processOne = async (toolCall) => {
317
+ const enrichedContext = {
318
+ ...handlerContext ?? {},
319
+ threadId: options.threadId,
320
+ toolCallId: toolCall.id,
321
+ toolName: toolCall.name
322
+ };
417
323
  const response = await handler(
418
324
  toolCall.args,
419
- handlerContext
325
+ enrichedContext
420
326
  );
421
- await appendToolResult({
422
- threadId: options.threadId,
423
- toolCallId: toolCall.id,
424
- content: response.toolResponse
425
- });
327
+ if (!response.resultAppended) {
328
+ await appendToolResult({
329
+ threadId: options.threadId,
330
+ toolCallId: toolCall.id,
331
+ toolName: toolCall.name,
332
+ content: response.toolResponse
333
+ });
334
+ }
426
335
  return {
427
336
  toolCallId: toolCall.id,
428
337
  name: toolCall.name,
429
- data: response.data ?? null
338
+ data: response.data
430
339
  };
431
340
  };
432
341
  if (options.parallel) {
@@ -463,51 +372,24 @@ function hasNoOtherToolCalls(toolCalls, excludeName) {
463
372
  }
464
373
 
465
374
  // src/lib/session.ts
466
- async function resolvePrompt(prompt) {
467
- if (typeof prompt === "function") {
468
- return prompt();
469
- }
470
- return prompt;
471
- }
472
375
  var createSession = async ({
473
376
  threadId,
474
377
  agentName,
475
378
  maxTurns = 50,
476
379
  metadata = {},
477
380
  runAgent,
478
- baseSystemPrompt,
479
- instructionsPrompt,
381
+ threadOps,
480
382
  buildContextMessage,
481
- buildFileTree = async () => "",
482
383
  subagents,
483
384
  tools = {},
484
385
  processToolsInParallel = true,
485
- buildInTools = {},
486
386
  hooks = {}
487
387
  }) => {
488
- const {
489
- initializeThread,
490
- appendHumanMessage,
491
- parseToolCalls,
492
- appendToolResult,
493
- appendSystemMessage
494
- } = proxyActivities({
495
- startToCloseTimeout: "30m",
496
- retry: {
497
- maximumAttempts: 6,
498
- initialInterval: "5s",
499
- maximumInterval: "15m",
500
- backoffCoefficient: 4
501
- },
502
- heartbeatTimeout: "5m"
503
- });
504
- const fileTree = await buildFileTree();
505
388
  const toolRouter = createToolRouter({
506
389
  tools,
390
+ appendToolResult: threadOps.appendToolResult,
507
391
  threadId,
508
392
  hooks,
509
- buildInTools,
510
- fileTree,
511
393
  subagents,
512
394
  parallel: processToolsInParallel
513
395
  });
@@ -532,83 +414,41 @@ var createSession = async ({
532
414
  });
533
415
  }
534
416
  stateManager.setTools(toolRouter.getToolDefinitions());
535
- await initializeThread(threadId);
536
- await appendSystemMessage(
537
- threadId,
538
- [
539
- await resolvePrompt(baseSystemPrompt),
540
- await resolvePrompt(instructionsPrompt)
541
- ].join("\n")
542
- );
543
- await appendHumanMessage(threadId, await buildContextMessage());
417
+ await threadOps.initializeThread(threadId);
418
+ await threadOps.appendHumanMessage(threadId, await buildContextMessage());
544
419
  let exitReason = "completed";
545
420
  try {
546
421
  while (stateManager.isRunning() && !stateManager.isTerminal() && stateManager.getTurns() < maxTurns) {
547
422
  stateManager.incrementTurns();
548
423
  const currentTurn = stateManager.getTurns();
549
- const { message, stopReason } = await runAgent({
424
+ const { message, rawToolCalls } = await runAgent({
550
425
  threadId,
551
426
  agentName,
552
427
  metadata
553
428
  });
554
- if (stopReason === "end_turn") {
429
+ if (!toolRouter.hasTools() || rawToolCalls.length === 0) {
555
430
  stateManager.complete();
556
431
  exitReason = "completed";
557
432
  return message;
558
433
  }
559
- if (!toolRouter.hasTools()) {
560
- stateManager.complete();
561
- exitReason = "completed";
562
- return message;
563
- }
564
- const rawToolCalls = await parseToolCalls(message);
565
434
  const parsedToolCalls = [];
566
- for (const tc of rawToolCalls.filter(
567
- (tc2) => tc2.name !== "Task"
568
- )) {
435
+ for (const tc of rawToolCalls) {
569
436
  try {
570
437
  parsedToolCalls.push(toolRouter.parseToolCall(tc));
571
438
  } catch (error) {
572
- await appendToolResult({
439
+ await threadOps.appendToolResult({
573
440
  threadId,
574
441
  toolCallId: tc.id ?? "",
442
+ toolName: tc.name,
575
443
  content: JSON.stringify({
576
444
  error: `Invalid tool call for "${tc.name}": ${error instanceof Error ? error.message : String(error)}`
577
445
  })
578
446
  });
579
447
  }
580
448
  }
581
- const taskToolCalls = [];
582
- if (subagents && subagents.length > 0) {
583
- for (const tc of rawToolCalls.filter(
584
- (tc2) => tc2.name === "Task"
585
- )) {
586
- try {
587
- const parsedArgs = createTaskTool(subagents).schema.parse(
588
- tc.args
589
- );
590
- taskToolCalls.push({
591
- id: tc.id ?? "",
592
- name: tc.name,
593
- args: parsedArgs
594
- });
595
- } catch (error) {
596
- await appendToolResult({
597
- threadId,
598
- toolCallId: tc.id ?? "",
599
- content: JSON.stringify({
600
- error: `Invalid tool call for "Task": ${error instanceof Error ? error.message : String(error)}`
601
- })
602
- });
603
- }
604
- }
605
- }
606
- await toolRouter.processToolCalls(
607
- [...parsedToolCalls, ...taskToolCalls],
608
- {
609
- turn: currentTurn
610
- }
611
- );
449
+ await toolRouter.processToolCalls(parsedToolCalls, {
450
+ turn: currentTurn
451
+ });
612
452
  if (stateManager.getStatus() === "WAITING_FOR_INPUT") {
613
453
  exitReason = "waiting_for_input";
614
454
  break;
@@ -627,6 +467,25 @@ var createSession = async ({
627
467
  }
628
468
  };
629
469
  };
470
+ function proxyDefaultThreadOps(options) {
471
+ const activities = proxyActivities(
472
+ options ?? {
473
+ startToCloseTimeout: "30m",
474
+ retry: {
475
+ maximumAttempts: 6,
476
+ initialInterval: "5s",
477
+ maximumInterval: "15m",
478
+ backoffCoefficient: 4
479
+ },
480
+ heartbeatTimeout: "5m"
481
+ }
482
+ );
483
+ return {
484
+ initializeThread: activities.initializeThread,
485
+ appendHumanMessage: activities.appendHumanMessage,
486
+ appendToolResult: activities.appendToolResult
487
+ };
488
+ }
630
489
 
631
490
  // src/lib/types.ts
632
491
  function isTerminalStatus(status) {
@@ -763,18 +622,18 @@ Usage notes:
763
622
  * Use multiSelect: true to allow multiple answers to be selected for a question
764
623
  * If you recommend a specific option, make that the first option in the list and add "(Recommended)" at the end of the label
765
624
  `,
766
- schema: z5.object({
767
- questions: z5.array(
768
- z5.object({
769
- question: z5.string().describe("The full question text to display"),
770
- header: z5.string().describe("Short label for the question (max 12 characters)"),
771
- options: z5.array(
772
- z5.object({
773
- label: z5.string(),
774
- description: z5.string()
625
+ schema: z3.object({
626
+ questions: z3.array(
627
+ z3.object({
628
+ question: z3.string().describe("The full question text to display"),
629
+ header: z3.string().describe("Short label for the question (max 12 characters)"),
630
+ options: z3.array(
631
+ z3.object({
632
+ label: z3.string(),
633
+ description: z3.string()
775
634
  })
776
635
  ).min(0).max(4).describe("Array of 0-4 choices, each with label and description"),
777
- multiSelect: z5.boolean().describe("If true, users can select multiple options")
636
+ multiSelect: z3.boolean().describe("If true, users can select multiple options")
778
637
  })
779
638
  )
780
639
  }),
@@ -852,7 +711,7 @@ var writeTool = {
852
711
  description: `Create or overwrite a file with new content.
853
712
 
854
713
  Usage:
855
- - Provide the absolute virtual path to the file
714
+ - Provide the absolute path to the file
856
715
  - The file will be created if it doesn't exist
857
716
  - If the file exists, it will be completely overwritten
858
717
 
@@ -862,7 +721,7 @@ IMPORTANT:
862
721
  - Path must be absolute (e.g., "/docs/readme.md", not "docs/readme.md")
863
722
  `,
864
723
  schema: z.object({
865
- file_path: z.string().describe("The absolute virtual path to the file to write"),
724
+ file_path: z.string().describe("The absolute path to the file to write"),
866
725
  content: z.string().describe("The content to write to the file")
867
726
  }),
868
727
  strict: true
@@ -895,6 +754,60 @@ IMPORTANT:
895
754
  }),
896
755
  strict: true
897
756
  };
757
+ var taskCreateTool = {
758
+ name: "TaskCreate",
759
+ 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.
760
+ It also helps the user understand the progress of the task and overall progress of their requests.
761
+
762
+ ## When to Use This Tool
763
+
764
+ Use this tool proactively in these scenarios:
765
+
766
+ - Complex multi-step tasks - When a task requires 3 or more distinct steps or actions
767
+ - Non-trivial and complex tasks - Tasks that require careful planning or multiple operations
768
+ - User explicitly requests todo list - When the user directly asks you to use the todo list
769
+ - User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated)
770
+ - After receiving new instructions - Immediately capture user requirements as tasks
771
+ - When you start working on a task - Mark it as in_progress BEFORE beginning work
772
+ - After completing a task - Mark it as completed and add any new follow-up tasks discovered during implementation
773
+
774
+ ## When NOT to Use This Tool
775
+
776
+ Skip using this tool when:
777
+ - There is only a single, straightforward task
778
+ - The task is trivial and tracking it provides no organizational benefit
779
+ - The task can be completed in less than 3 trivial steps
780
+ - The task is purely conversational or informational
781
+
782
+ 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.
783
+
784
+ ## Task Fields
785
+
786
+ - **subject**: A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")
787
+ - **description**: Detailed description of what needs to be done, including context and acceptance criteria
788
+ - **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.
789
+
790
+ **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\`.
791
+
792
+ ## Tips
793
+
794
+ - Create tasks with clear, specific subjects that describe the outcome
795
+ - Include enough detail in the description for another agent to understand and complete the task
796
+ - After creating tasks, use TaskUpdate to set up dependencies (blocks/blockedBy) if needed
797
+ - Check TaskList first to avoid creating duplicate tasks`,
798
+ schema: z3.object({
799
+ subject: z3.string().describe(
800
+ 'A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")'
801
+ ),
802
+ description: z3.string().describe(
803
+ "Detailed description of what needs to be done, including context and acceptance criteria"
804
+ ),
805
+ activeForm: z3.string().describe(
806
+ '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.'
807
+ ),
808
+ metadata: z3.record(z3.string(), z3.string()).describe("Arbitrary key-value pairs for tracking")
809
+ })
810
+ };
898
811
  function createTaskCreateHandler(stateManager) {
899
812
  return (args) => {
900
813
  const task = {
@@ -917,8 +830,8 @@ function createTaskCreateHandler(stateManager) {
917
830
  var taskGetTool = {
918
831
  name: "TaskGet",
919
832
  description: `Retrieve full task details including dependencies.`,
920
- schema: z5.object({
921
- taskId: z5.string().describe("The ID of the task to get")
833
+ schema: z3.object({
834
+ taskId: z3.string().describe("The ID of the task to get")
922
835
  })
923
836
  };
924
837
 
@@ -941,12 +854,12 @@ function createTaskGetHandler(stateManager) {
941
854
  var taskListTool = {
942
855
  name: "TaskList",
943
856
  description: `List all tasks with current state.`,
944
- schema: z5.object({})
857
+ schema: z3.object({})
945
858
  };
946
859
 
947
860
  // src/tools/task-list/handler.ts
948
861
  function createTaskListHandler(stateManager) {
949
- return (_args) => {
862
+ return () => {
950
863
  const taskList = stateManager.getTasks();
951
864
  return {
952
865
  toolResponse: JSON.stringify(taskList, null, 2),
@@ -957,11 +870,11 @@ function createTaskListHandler(stateManager) {
957
870
  var taskUpdateTool = {
958
871
  name: "TaskUpdate",
959
872
  description: `Update status, add blockers, modify details.`,
960
- schema: z5.object({
961
- taskId: z5.string().describe("The ID of the task to get"),
962
- status: z5.enum(["pending", "in_progress", "completed"]).describe("The status of the task"),
963
- addBlockedBy: z5.array(z5.string()).describe("The IDs of the tasks that are blocking this task"),
964
- addBlocks: z5.array(z5.string()).describe("The IDs of the tasks that this task is blocking")
873
+ schema: z3.object({
874
+ taskId: z3.string().describe("The ID of the task to get"),
875
+ status: z3.enum(["pending", "in_progress", "completed"]).describe("The status of the task"),
876
+ addBlockedBy: z3.array(z3.string()).describe("The IDs of the tasks that are blocking this task"),
877
+ addBlocks: z3.array(z3.string()).describe("The IDs of the tasks that this task is blocking")
965
878
  })
966
879
  };
967
880
 
@@ -1009,7 +922,34 @@ function createTaskUpdateHandler(stateManager) {
1009
922
  };
1010
923
  };
1011
924
  }
925
+ var createBashToolDescription = ({
926
+ fileTree
927
+ }) => `Execute shell commands in a bash environment.
928
+
929
+ Use this tool to:
930
+ - Run shell commands (ls, cat, grep, find, etc.)
931
+ - Execute scripts and chain commands with pipes (|) or logical operators (&&, ||)
932
+ - Inspect files and directories
933
+
934
+ Current file tree:
935
+ ${fileTree}`;
936
+ var bashTool = {
937
+ name: "Bash",
938
+ description: `Execute shell commands in a sandboxed bash environment.
939
+
940
+ Use this tool to:
941
+ - Run shell commands (ls, cat, grep, find, etc.)
942
+ - Execute scripts and chain commands with pipes (|) or logical operators (&&, ||)
943
+ - Inspect files and directories
944
+ `,
945
+ schema: z3.object({
946
+ command: z3.string().describe(
947
+ "The bash command to execute. Can include pipes (|), redirects (>, >>), logical operators (&&, ||), and shell features like command substitution $(...)."
948
+ )
949
+ }),
950
+ strict: true
951
+ };
1012
952
 
1013
- export { AGENT_HANDLER_NAMES, askUserQuestionTool, bashTool, createAgentStateManager, createSession, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskTool, createTaskUpdateHandler, createToolRouter, defineSubagent, defineTool, editTool, globTool, grepTool, hasNoOtherToolCalls, isTerminalStatus, readTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, writeTool };
953
+ export { AGENT_HANDLER_NAMES, askUserQuestionTool, bashTool, createAgentStateManager, createBashToolDescription, createSession, createSubagentTool, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskUpdateHandler, createToolRouter, defineSubagent, defineTool, editTool, globTool, grepTool, hasNoOtherToolCalls, isTerminalStatus, proxyDefaultThreadOps, readTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, writeTool };
1014
954
  //# sourceMappingURL=workflow.js.map
1015
955
  //# sourceMappingURL=workflow.js.map