zeitlich 0.2.1 → 0.2.3

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 +36 -33
  2. package/dist/index.cjs +445 -385
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +25 -42
  5. package/dist/index.d.ts +25 -42
  6. package/dist/index.js +415 -362
  7. package/dist/index.js.map +1 -1
  8. package/dist/{workflow-CCoHnc3B.d.cts → workflow-D-2vp4Pq.d.cts} +456 -253
  9. package/dist/{workflow-CCoHnc3B.d.ts → workflow-D-2vp4Pq.d.ts} +456 -253
  10. package/dist/workflow.cjs +339 -272
  11. package/dist/workflow.cjs.map +1 -1
  12. package/dist/workflow.d.cts +4 -3
  13. package/dist/workflow.d.ts +4 -3
  14. package/dist/workflow.js +315 -252
  15. package/dist/workflow.js.map +1 -1
  16. package/package.json +3 -2
  17. package/src/activities.ts +1 -14
  18. package/src/index.ts +17 -11
  19. package/src/lib/session.ts +69 -86
  20. package/src/lib/state-manager.ts +9 -2
  21. package/src/lib/thread-manager.ts +45 -37
  22. package/src/lib/tool-router.ts +338 -116
  23. package/src/lib/types.ts +110 -28
  24. package/src/tools/ask-user-question/handler.ts +6 -6
  25. package/src/tools/ask-user-question/tool.ts +3 -2
  26. package/src/tools/bash/bash.test.ts +32 -32
  27. package/src/tools/bash/handler.ts +9 -9
  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/handler.ts +19 -9
  36. package/src/tools/task/tool.ts +3 -10
  37. package/src/tools/task-create/handler.ts +11 -20
  38. package/src/tools/task-create/tool.ts +3 -2
  39. package/src/tools/task-get/handler.ts +9 -14
  40. package/src/tools/task-get/tool.ts +3 -2
  41. package/src/tools/task-list/handler.ts +7 -12
  42. package/src/tools/task-list/tool.ts +3 -2
  43. package/src/tools/task-update/handler.ts +9 -16
  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 +25 -19
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { defineQuery, proxyActivities, setHandler, workflowInfo, uuid4, executeChild } from '@temporalio/workflow';
2
- import z4, { z } from 'zod';
1
+ import { defineQuery, proxyActivities, setHandler, uuid4, workflowInfo, executeChild } from '@temporalio/workflow';
2
+ import z3, { z } from 'zod';
3
3
  import { SimplePlugin } from '@temporalio/plugin';
4
- import { mapStoredMessageToChatMessage, mapStoredMessagesToChatMessages, AIMessage, SystemMessage, ToolMessage, HumanMessage } from '@langchain/core/messages';
4
+ import { mapStoredMessageToChatMessage, mapStoredMessagesToChatMessages, AIMessage, ToolMessage, HumanMessage } from '@langchain/core/messages';
5
5
  import crypto from 'crypto';
6
6
  import { Context } from '@temporalio/activity';
7
7
  import { Bash } from 'just-bash';
@@ -39,10 +39,10 @@ function createTaskTool(subagents) {
39
39
  return {
40
40
  name: TASK_TOOL,
41
41
  description: buildTaskDescription(subagents),
42
- schema: z4.object({
43
- subagent: z4.enum(names).describe("The type of subagent to launch"),
44
- description: z4.string().describe("A short (3-5 word) description of the task"),
45
- prompt: z4.string().describe("The task for the agent to perform")
42
+ schema: z3.object({
43
+ subagent: z3.enum(names).describe("The type of subagent to launch"),
44
+ description: z3.string().describe("A short (3-5 word) description of the task"),
45
+ prompt: z3.string().describe("The task for the agent to perform")
46
46
  })
47
47
  };
48
48
  }
@@ -56,149 +56,67 @@ function createTaskHandler(subagents) {
56
56
  );
57
57
  }
58
58
  const childWorkflowId = `${parentWorkflowId}-${args.subagent}-${uuid4()}`;
59
- const childResult = await executeChild(config.workflowType, {
59
+ const input = {
60
+ prompt: args.prompt,
61
+ ...config.context && { context: config.context }
62
+ };
63
+ const childOpts = {
60
64
  workflowId: childWorkflowId,
61
- args: [{ prompt: args.prompt }],
65
+ args: [input],
62
66
  taskQueue: config.taskQueue ?? parentTaskQueue
63
- });
67
+ };
68
+ const childResult = typeof config.workflow === "string" ? await executeChild(config.workflow, childOpts) : await executeChild(config.workflow, childOpts);
64
69
  const validated = config.resultSchema ? config.resultSchema.parse(childResult) : childResult;
65
- const content = typeof validated === "string" ? validated : JSON.stringify(validated, null, 2);
70
+ const toolResponse = typeof validated === "string" ? validated : JSON.stringify(validated, null, 2);
66
71
  return {
67
- content,
68
- result: {
72
+ toolResponse,
73
+ data: {
69
74
  result: validated,
70
75
  childWorkflowId
71
76
  }
72
77
  };
73
78
  };
74
79
  }
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: z4.object({
96
- command: z4.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: z4.object({
144
- subject: z4.string().describe(
145
- 'A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")'
146
- ),
147
- description: z4.string().describe(
148
- "Detailed description of what needs to be done, including context and acceptance criteria"
149
- ),
150
- activeForm: z4.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: z4.record(z4.string(), z4.string()).describe("Arbitrary key-value pairs for tracking")
154
- })
155
- };
156
80
 
157
81
  // src/lib/tool-router.ts
158
- var buildIntoolDefinitions = {
159
- [bashTool.name]: bashTool,
160
- [taskCreateTool.name]: taskCreateTool
161
- };
162
82
  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
- });
83
+ const { appendToolResult } = options;
172
84
  const toolMap = /* @__PURE__ */ new Map();
173
85
  for (const [_key, tool] of Object.entries(options.tools)) {
174
86
  toolMap.set(tool.name, tool);
175
87
  }
88
+ const isEnabled = (tool) => tool.enabled !== false;
176
89
  if (options.subagents) {
90
+ const subagentHooksMap = /* @__PURE__ */ new Map();
91
+ for (const s of options.subagents) {
92
+ if (s.hooks) subagentHooksMap.set(s.name, s.hooks);
93
+ }
94
+ const resolveSubagentName = (args) => args.subagent;
177
95
  toolMap.set("Task", {
178
96
  ...createTaskTool(options.subagents),
179
- handler: createTaskHandler(options.subagents)
180
- });
181
- }
182
- if (options.buildInTools) {
183
- for (const [key, value] of Object.entries(options.buildInTools)) {
184
- if (key === bashTool.name) {
185
- toolMap.set(key, {
186
- ...buildIntoolDefinitions[key],
187
- description: createBashToolDescription({
188
- fileTree: options.fileTree
189
- }),
190
- handler: value
191
- });
192
- } else {
193
- toolMap.set(key, {
194
- ...buildIntoolDefinitions[key],
195
- handler: value
196
- });
97
+ handler: createTaskHandler(options.subagents),
98
+ ...subagentHooksMap.size > 0 && {
99
+ hooks: {
100
+ onPreToolUse: async (ctx) => {
101
+ const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
102
+ return hooks?.onPreExecution?.(ctx) ?? {};
103
+ },
104
+ onPostToolUse: async (ctx) => {
105
+ const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
106
+ await hooks?.onPostExecution?.(ctx);
107
+ },
108
+ onPostToolUseFailure: async (ctx) => {
109
+ const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
110
+ return hooks?.onExecutionFailure?.(ctx) ?? {};
111
+ }
112
+ }
197
113
  }
198
- }
114
+ });
199
115
  }
200
116
  async function processToolCall(toolCall, turn, handlerContext) {
201
117
  const startTime = Date.now();
118
+ const tool = toolMap.get(toolCall.name);
119
+ const toolHooks = tool?.hooks;
202
120
  let effectiveArgs = toolCall.args;
203
121
  if (options.hooks?.onPreToolUse) {
204
122
  const preResult = await options.hooks.onPreToolUse({
@@ -210,6 +128,7 @@ function createToolRouter(options) {
210
128
  await appendToolResult({
211
129
  threadId: options.threadId,
212
130
  toolCallId: toolCall.id,
131
+ toolName: toolCall.name,
213
132
  content: JSON.stringify({
214
133
  skipped: true,
215
134
  reason: "Skipped by PreToolUse hook"
@@ -221,54 +140,115 @@ function createToolRouter(options) {
221
140
  effectiveArgs = preResult.modifiedArgs;
222
141
  }
223
142
  }
224
- const tool = toolMap.get(toolCall.name);
143
+ if (toolHooks?.onPreToolUse) {
144
+ const preResult = await toolHooks.onPreToolUse({
145
+ args: effectiveArgs,
146
+ threadId: options.threadId,
147
+ turn
148
+ });
149
+ if (preResult?.skip) {
150
+ await appendToolResult({
151
+ threadId: options.threadId,
152
+ toolCallId: toolCall.id,
153
+ toolName: toolCall.name,
154
+ content: JSON.stringify({
155
+ skipped: true,
156
+ reason: "Skipped by tool PreToolUse hook"
157
+ })
158
+ });
159
+ return null;
160
+ }
161
+ if (preResult?.modifiedArgs !== void 0) {
162
+ effectiveArgs = preResult.modifiedArgs;
163
+ }
164
+ }
225
165
  let result;
226
166
  let content;
167
+ let resultAppended = false;
227
168
  try {
228
169
  if (tool) {
170
+ const enrichedContext = {
171
+ ...handlerContext ?? {},
172
+ threadId: options.threadId,
173
+ toolCallId: toolCall.id,
174
+ toolName: toolCall.name
175
+ };
229
176
  const response = await tool.handler(
230
177
  effectiveArgs,
231
- handlerContext ?? {}
178
+ enrichedContext
232
179
  );
233
- result = response.result;
234
- content = response.content;
180
+ result = response.data;
181
+ content = response.toolResponse;
182
+ resultAppended = response.resultAppended === true;
235
183
  } else {
236
184
  result = { error: `Unknown tool: ${toolCall.name}` };
237
185
  content = JSON.stringify(result, null, 2);
238
186
  }
239
187
  } catch (error) {
240
- if (options.hooks?.onPostToolUseFailure) {
188
+ const err = error instanceof Error ? error : new Error(String(error));
189
+ let recovered = false;
190
+ if (toolHooks?.onPostToolUseFailure) {
191
+ const failureResult = await toolHooks.onPostToolUseFailure({
192
+ args: effectiveArgs,
193
+ error: err,
194
+ threadId: options.threadId,
195
+ turn
196
+ });
197
+ if (failureResult?.fallbackContent !== void 0) {
198
+ content = failureResult.fallbackContent;
199
+ result = { error: String(error), recovered: true };
200
+ recovered = true;
201
+ } else if (failureResult?.suppress) {
202
+ content = JSON.stringify({ error: String(error), suppressed: true });
203
+ result = { error: String(error), suppressed: true };
204
+ recovered = true;
205
+ }
206
+ }
207
+ if (!recovered && options.hooks?.onPostToolUseFailure) {
241
208
  const failureResult = await options.hooks.onPostToolUseFailure({
242
209
  toolCall,
243
- error: error instanceof Error ? error : new Error(String(error)),
210
+ error: err,
244
211
  threadId: options.threadId,
245
212
  turn
246
213
  });
247
214
  if (failureResult?.fallbackContent !== void 0) {
248
215
  content = failureResult.fallbackContent;
249
216
  result = { error: String(error), recovered: true };
217
+ recovered = true;
250
218
  } else if (failureResult?.suppress) {
251
219
  content = JSON.stringify({ error: String(error), suppressed: true });
252
220
  result = { error: String(error), suppressed: true };
253
- } else {
254
- throw error;
221
+ recovered = true;
255
222
  }
256
- } else {
223
+ }
224
+ if (!recovered) {
257
225
  throw error;
258
226
  }
259
227
  }
260
- await appendToolResult({
261
- threadId: options.threadId,
262
- toolCallId: toolCall.id,
263
- content
264
- });
228
+ if (!resultAppended) {
229
+ await appendToolResult({
230
+ threadId: options.threadId,
231
+ toolCallId: toolCall.id,
232
+ toolName: toolCall.name,
233
+ content
234
+ });
235
+ }
265
236
  const toolResult = {
266
237
  toolCallId: toolCall.id,
267
238
  name: toolCall.name,
268
- result
239
+ data: result
269
240
  };
241
+ const durationMs = Date.now() - startTime;
242
+ if (toolHooks?.onPostToolUse) {
243
+ await toolHooks.onPostToolUse({
244
+ args: effectiveArgs,
245
+ result,
246
+ threadId: options.threadId,
247
+ turn,
248
+ durationMs
249
+ });
250
+ }
270
251
  if (options.hooks?.onPostToolUse) {
271
- const durationMs = Date.now() - startTime;
272
252
  await options.hooks.onPostToolUse({
273
253
  toolCall,
274
254
  result: toolResult,
@@ -282,11 +262,11 @@ function createToolRouter(options) {
282
262
  return {
283
263
  // --- Methods from registry ---
284
264
  hasTools() {
285
- return toolMap.size > 0;
265
+ return Array.from(toolMap.values()).some(isEnabled);
286
266
  },
287
267
  parseToolCall(toolCall) {
288
268
  const tool = toolMap.get(toolCall.name);
289
- if (!tool) {
269
+ if (!tool || !isEnabled(tool)) {
290
270
  throw new Error(`Tool ${toolCall.name} not found`);
291
271
  }
292
272
  const parsedArgs = tool.schema.parse(toolCall.args);
@@ -297,13 +277,14 @@ function createToolRouter(options) {
297
277
  };
298
278
  },
299
279
  hasTool(name) {
300
- return toolMap.has(name);
280
+ const tool = toolMap.get(name);
281
+ return tool !== void 0 && isEnabled(tool);
301
282
  },
302
283
  getToolNames() {
303
- return Array.from(toolMap.keys());
284
+ return Array.from(toolMap.entries()).filter(([, tool]) => isEnabled(tool)).map(([name]) => name);
304
285
  },
305
286
  getToolDefinitions() {
306
- return Array.from(toolMap).map(([name, tool]) => ({
287
+ return Array.from(toolMap).filter(([, tool]) => isEnabled(tool)).map(([name, tool]) => ({
307
288
  name,
308
289
  description: tool.description,
309
290
  schema: tool.schema,
@@ -342,19 +323,28 @@ function createToolRouter(options) {
342
323
  }
343
324
  const handlerContext = context?.handlerContext ?? {};
344
325
  const processOne = async (toolCall) => {
326
+ const enrichedContext = {
327
+ ...handlerContext ?? {},
328
+ threadId: options.threadId,
329
+ toolCallId: toolCall.id,
330
+ toolName: toolCall.name
331
+ };
345
332
  const response = await handler(
346
333
  toolCall.args,
347
- handlerContext
334
+ enrichedContext
348
335
  );
349
- await appendToolResult({
350
- threadId: options.threadId,
351
- toolCallId: toolCall.id,
352
- content: response.content
353
- });
336
+ if (!response.resultAppended) {
337
+ await appendToolResult({
338
+ threadId: options.threadId,
339
+ toolCallId: toolCall.id,
340
+ toolName: toolCall.name,
341
+ content: response.toolResponse
342
+ });
343
+ }
354
344
  return {
355
345
  toolCallId: toolCall.id,
356
346
  name: toolCall.name,
357
- result: response.result
347
+ data: response.data
358
348
  };
359
349
  };
360
350
  if (options.parallel) {
@@ -380,56 +370,50 @@ function createToolRouter(options) {
380
370
  }
381
371
  };
382
372
  }
373
+ function withAutoAppend(threadHandler, handler) {
374
+ return async (args, context) => {
375
+ const response = await handler(args, context);
376
+ const threadId = context.threadId;
377
+ const toolCallId = context.toolCallId;
378
+ const toolName = context.toolName;
379
+ await threadHandler({
380
+ threadId,
381
+ toolCallId,
382
+ toolName,
383
+ content: response.toolResponse
384
+ });
385
+ return { toolResponse: "", data: response.data, resultAppended: true };
386
+ };
387
+ }
388
+ function defineTool(tool) {
389
+ return tool;
390
+ }
391
+ function defineSubagent(config) {
392
+ return config;
393
+ }
383
394
  function hasNoOtherToolCalls(toolCalls, excludeName) {
384
395
  return toolCalls.filter((tc) => tc.name !== excludeName).length === 0;
385
396
  }
386
397
 
387
398
  // src/lib/session.ts
388
- async function resolvePrompt(prompt) {
389
- if (typeof prompt === "function") {
390
- return prompt();
391
- }
392
- return prompt;
393
- }
394
399
  var createSession = async ({
395
400
  threadId,
396
401
  agentName,
397
402
  maxTurns = 50,
398
403
  metadata = {},
399
404
  runAgent,
400
- baseSystemPrompt,
401
- instructionsPrompt,
405
+ threadOps,
402
406
  buildContextMessage,
403
- buildFileTree = async () => "",
404
407
  subagents,
405
408
  tools = {},
406
409
  processToolsInParallel = true,
407
- buildInTools = {},
408
410
  hooks = {}
409
411
  }) => {
410
- const {
411
- initializeThread,
412
- appendHumanMessage,
413
- parseToolCalls,
414
- appendToolResult,
415
- appendSystemMessage
416
- } = proxyActivities({
417
- startToCloseTimeout: "30m",
418
- retry: {
419
- maximumAttempts: 6,
420
- initialInterval: "5s",
421
- maximumInterval: "15m",
422
- backoffCoefficient: 4
423
- },
424
- heartbeatTimeout: "5m"
425
- });
426
- const fileTree = await buildFileTree();
427
412
  const toolRouter = createToolRouter({
428
413
  tools,
414
+ appendToolResult: threadOps.appendToolResult,
429
415
  threadId,
430
416
  hooks,
431
- buildInTools,
432
- fileTree,
433
417
  subagents,
434
418
  parallel: processToolsInParallel
435
419
  });
@@ -454,15 +438,8 @@ var createSession = async ({
454
438
  });
455
439
  }
456
440
  stateManager.setTools(toolRouter.getToolDefinitions());
457
- await initializeThread(threadId);
458
- await appendSystemMessage(
459
- threadId,
460
- [
461
- await resolvePrompt(baseSystemPrompt),
462
- await resolvePrompt(instructionsPrompt)
463
- ].join("\n")
464
- );
465
- await appendHumanMessage(threadId, await buildContextMessage());
441
+ await threadOps.initializeThread(threadId);
442
+ await threadOps.appendHumanMessage(threadId, await buildContextMessage());
466
443
  let exitReason = "completed";
467
444
  try {
468
445
  while (stateManager.isRunning() && !stateManager.isTerminal() && stateManager.getTurns() < maxTurns) {
@@ -483,24 +460,25 @@ var createSession = async ({
483
460
  exitReason = "completed";
484
461
  return message;
485
462
  }
486
- const rawToolCalls = await parseToolCalls(message);
487
- const parsedToolCalls = rawToolCalls.filter((tc) => tc.name !== "Task").map((tc) => toolRouter.parseToolCall(tc));
488
- const taskToolCalls = subagents && subagents.length > 0 ? rawToolCalls.filter((tc) => tc.name === "Task").map((tc) => {
489
- const parsedArgs = createTaskTool(subagents).schema.parse(
490
- tc.args
491
- );
492
- return {
493
- id: tc.id ?? "",
494
- name: tc.name,
495
- args: parsedArgs
496
- };
497
- }) : [];
498
- await toolRouter.processToolCalls(
499
- [...parsedToolCalls, ...taskToolCalls],
500
- {
501
- turn: currentTurn
463
+ const rawToolCalls = await threadOps.parseToolCalls(message);
464
+ const parsedToolCalls = [];
465
+ for (const tc of rawToolCalls) {
466
+ try {
467
+ parsedToolCalls.push(toolRouter.parseToolCall(tc));
468
+ } catch (error) {
469
+ await threadOps.appendToolResult({
470
+ threadId,
471
+ toolCallId: tc.id ?? "",
472
+ toolName: tc.name,
473
+ content: JSON.stringify({
474
+ error: `Invalid tool call for "${tc.name}": ${error instanceof Error ? error.message : String(error)}`
475
+ })
476
+ });
502
477
  }
503
- );
478
+ }
479
+ await toolRouter.processToolCalls(parsedToolCalls, {
480
+ turn: currentTurn
481
+ });
504
482
  if (stateManager.getStatus() === "WAITING_FOR_INPUT") {
505
483
  exitReason = "waiting_for_input";
506
484
  break;
@@ -519,13 +497,31 @@ var createSession = async ({
519
497
  }
520
498
  };
521
499
  };
500
+ function proxyDefaultThreadOps(options) {
501
+ const activities = proxyActivities(
502
+ options ?? {
503
+ startToCloseTimeout: "30m",
504
+ retry: {
505
+ maximumAttempts: 6,
506
+ initialInterval: "5s",
507
+ maximumInterval: "15m",
508
+ backoffCoefficient: 4
509
+ },
510
+ heartbeatTimeout: "5m"
511
+ }
512
+ );
513
+ return {
514
+ initializeThread: activities.initializeThread,
515
+ appendHumanMessage: activities.appendHumanMessage,
516
+ appendToolResult: activities.appendToolResult,
517
+ parseToolCalls: activities.parseToolCalls
518
+ };
519
+ }
522
520
 
523
521
  // src/lib/types.ts
524
522
  function isTerminalStatus(status) {
525
523
  return status === "COMPLETED" || status === "FAILED" || status === "CANCELLED";
526
524
  }
527
-
528
- // src/lib/state-manager.ts
529
525
  var getStateQuery = defineQuery("getState");
530
526
  function createAgentStateManager(initialState) {
531
527
  let status = initialState?.status ?? "RUNNING";
@@ -620,7 +616,13 @@ function createAgentStateManager(initialState) {
620
616
  version++;
621
617
  },
622
618
  setTools(newTools) {
623
- tools = newTools;
619
+ tools = newTools.map((tool) => ({
620
+ name: tool.name,
621
+ description: tool.description,
622
+ schema: z.toJSONSchema(tool.schema),
623
+ strict: tool.strict,
624
+ max_uses: tool.max_uses
625
+ }));
624
626
  },
625
627
  deleteTask(id) {
626
628
  const deleted = tasks.delete(id);
@@ -651,18 +653,18 @@ Usage notes:
651
653
  * Use multiSelect: true to allow multiple answers to be selected for a question
652
654
  * If you recommend a specific option, make that the first option in the list and add "(Recommended)" at the end of the label
653
655
  `,
654
- schema: z4.object({
655
- questions: z4.array(
656
- z4.object({
657
- question: z4.string().describe("The full question text to display"),
658
- header: z4.string().describe("Short label for the question (max 12 characters)"),
659
- options: z4.array(
660
- z4.object({
661
- label: z4.string(),
662
- description: z4.string()
656
+ schema: z3.object({
657
+ questions: z3.array(
658
+ z3.object({
659
+ question: z3.string().describe("The full question text to display"),
660
+ header: z3.string().describe("Short label for the question (max 12 characters)"),
661
+ options: z3.array(
662
+ z3.object({
663
+ label: z3.string(),
664
+ description: z3.string()
663
665
  })
664
666
  ).min(0).max(4).describe("Array of 0-4 choices, each with label and description"),
665
- multiSelect: z4.boolean().describe("If true, users can select multiple options")
667
+ multiSelect: z3.boolean().describe("If true, users can select multiple options")
666
668
  })
667
669
  )
668
670
  }),
@@ -740,7 +742,7 @@ var writeTool = {
740
742
  description: `Create or overwrite a file with new content.
741
743
 
742
744
  Usage:
743
- - Provide the absolute virtual path to the file
745
+ - Provide the absolute path to the file
744
746
  - The file will be created if it doesn't exist
745
747
  - If the file exists, it will be completely overwritten
746
748
 
@@ -750,7 +752,7 @@ IMPORTANT:
750
752
  - Path must be absolute (e.g., "/docs/readme.md", not "docs/readme.md")
751
753
  `,
752
754
  schema: z.object({
753
- file_path: z.string().describe("The absolute virtual path to the file to write"),
755
+ file_path: z.string().describe("The absolute path to the file to write"),
754
756
  content: z.string().describe("The content to write to the file")
755
757
  }),
756
758
  strict: true
@@ -783,15 +785,64 @@ IMPORTANT:
783
785
  }),
784
786
  strict: true
785
787
  };
786
-
787
- // src/tools/task-create/handler.ts
788
- function createTaskCreateHandler({
789
- stateManager,
790
- idGenerator
791
- }) {
788
+ var taskCreateTool = {
789
+ name: "TaskCreate",
790
+ 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.
791
+ It also helps the user understand the progress of the task and overall progress of their requests.
792
+
793
+ ## When to Use This Tool
794
+
795
+ Use this tool proactively in these scenarios:
796
+
797
+ - Complex multi-step tasks - When a task requires 3 or more distinct steps or actions
798
+ - Non-trivial and complex tasks - Tasks that require careful planning or multiple operations
799
+ - User explicitly requests todo list - When the user directly asks you to use the todo list
800
+ - User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated)
801
+ - After receiving new instructions - Immediately capture user requirements as tasks
802
+ - When you start working on a task - Mark it as in_progress BEFORE beginning work
803
+ - After completing a task - Mark it as completed and add any new follow-up tasks discovered during implementation
804
+
805
+ ## When NOT to Use This Tool
806
+
807
+ Skip using this tool when:
808
+ - There is only a single, straightforward task
809
+ - The task is trivial and tracking it provides no organizational benefit
810
+ - The task can be completed in less than 3 trivial steps
811
+ - The task is purely conversational or informational
812
+
813
+ 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.
814
+
815
+ ## Task Fields
816
+
817
+ - **subject**: A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")
818
+ - **description**: Detailed description of what needs to be done, including context and acceptance criteria
819
+ - **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.
820
+
821
+ **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\`.
822
+
823
+ ## Tips
824
+
825
+ - Create tasks with clear, specific subjects that describe the outcome
826
+ - Include enough detail in the description for another agent to understand and complete the task
827
+ - After creating tasks, use TaskUpdate to set up dependencies (blocks/blockedBy) if needed
828
+ - Check TaskList first to avoid creating duplicate tasks`,
829
+ schema: z3.object({
830
+ subject: z3.string().describe(
831
+ 'A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")'
832
+ ),
833
+ description: z3.string().describe(
834
+ "Detailed description of what needs to be done, including context and acceptance criteria"
835
+ ),
836
+ activeForm: z3.string().describe(
837
+ '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.'
838
+ ),
839
+ metadata: z3.record(z3.string(), z3.string()).describe("Arbitrary key-value pairs for tracking")
840
+ })
841
+ };
842
+ function createTaskCreateHandler(stateManager) {
792
843
  return (args) => {
793
844
  const task = {
794
- id: idGenerator(),
845
+ id: uuid4(),
795
846
  subject: args.subject,
796
847
  description: args.description,
797
848
  activeForm: args.activeForm,
@@ -802,16 +853,16 @@ function createTaskCreateHandler({
802
853
  };
803
854
  stateManager.setTask(task);
804
855
  return {
805
- content: JSON.stringify(task, null, 2),
806
- result: task
856
+ toolResponse: JSON.stringify(task, null, 2),
857
+ data: task
807
858
  };
808
859
  };
809
860
  }
810
861
  var taskGetTool = {
811
862
  name: "TaskGet",
812
863
  description: `Retrieve full task details including dependencies.`,
813
- schema: z4.object({
814
- taskId: z4.string().describe("The ID of the task to get")
864
+ schema: z3.object({
865
+ taskId: z3.string().describe("The ID of the task to get")
815
866
  })
816
867
  };
817
868
 
@@ -821,40 +872,40 @@ function createTaskGetHandler(stateManager) {
821
872
  const task = stateManager.getTask(args.taskId) ?? null;
822
873
  if (!task) {
823
874
  return {
824
- content: JSON.stringify({ error: `Task not found: ${args.taskId}` }),
825
- result: null
875
+ toolResponse: JSON.stringify({ error: `Task not found: ${args.taskId}` }),
876
+ data: null
826
877
  };
827
878
  }
828
879
  return {
829
- content: JSON.stringify(task, null, 2),
830
- result: task
880
+ toolResponse: JSON.stringify(task, null, 2),
881
+ data: task
831
882
  };
832
883
  };
833
884
  }
834
885
  var taskListTool = {
835
886
  name: "TaskList",
836
887
  description: `List all tasks with current state.`,
837
- schema: z4.object({})
888
+ schema: z3.object({})
838
889
  };
839
890
 
840
891
  // src/tools/task-list/handler.ts
841
892
  function createTaskListHandler(stateManager) {
842
- return (_args) => {
893
+ return () => {
843
894
  const taskList = stateManager.getTasks();
844
895
  return {
845
- content: JSON.stringify(taskList, null, 2),
846
- result: taskList
896
+ toolResponse: JSON.stringify(taskList, null, 2),
897
+ data: taskList
847
898
  };
848
899
  };
849
900
  }
850
901
  var taskUpdateTool = {
851
902
  name: "TaskUpdate",
852
903
  description: `Update status, add blockers, modify details.`,
853
- schema: z4.object({
854
- taskId: z4.string().describe("The ID of the task to get"),
855
- status: z4.enum(["pending", "in_progress", "completed"]).describe("The status of the task"),
856
- addBlockedBy: z4.array(z4.string()).describe("The IDs of the tasks that are blocking this task"),
857
- addBlocks: z4.array(z4.string()).describe("The IDs of the tasks that this task is blocking")
904
+ schema: z3.object({
905
+ taskId: z3.string().describe("The ID of the task to get"),
906
+ status: z3.enum(["pending", "in_progress", "completed"]).describe("The status of the task"),
907
+ addBlockedBy: z3.array(z3.string()).describe("The IDs of the tasks that are blocking this task"),
908
+ addBlocks: z3.array(z3.string()).describe("The IDs of the tasks that this task is blocking")
858
909
  })
859
910
  };
860
911
 
@@ -864,8 +915,8 @@ function createTaskUpdateHandler(stateManager) {
864
915
  const task = stateManager.getTask(args.taskId);
865
916
  if (!task) {
866
917
  return {
867
- content: JSON.stringify({ error: `Task not found: ${args.taskId}` }),
868
- result: null
918
+ toolResponse: JSON.stringify({ error: `Task not found: ${args.taskId}` }),
919
+ data: null
869
920
  };
870
921
  }
871
922
  if (args.status) {
@@ -897,11 +948,38 @@ function createTaskUpdateHandler(stateManager) {
897
948
  }
898
949
  stateManager.setTask(task);
899
950
  return {
900
- content: JSON.stringify(task, null, 2),
901
- result: task
951
+ toolResponse: JSON.stringify(task, null, 2),
952
+ data: task
902
953
  };
903
954
  };
904
955
  }
956
+ var createBashToolDescription = ({
957
+ fileTree
958
+ }) => `Execute shell commands in a bash environment.
959
+
960
+ Use this tool to:
961
+ - Run shell commands (ls, cat, grep, find, etc.)
962
+ - Execute scripts and chain commands with pipes (|) or logical operators (&&, ||)
963
+ - Inspect files and directories
964
+
965
+ Current file tree:
966
+ ${fileTree}`;
967
+ var bashTool = {
968
+ name: "Bash",
969
+ description: `Execute shell commands in a sandboxed bash environment.
970
+
971
+ Use this tool to:
972
+ - Run shell commands (ls, cat, grep, find, etc.)
973
+ - Execute scripts and chain commands with pipes (|) or logical operators (&&, ||)
974
+ - Inspect files and directories
975
+ `,
976
+ schema: z3.object({
977
+ command: z3.string().describe(
978
+ "The bash command to execute. Can include pipes (|), redirects (>, >>), logical operators (&&, ||), and shell features like command substitution $(...)."
979
+ )
980
+ }),
981
+ strict: true
982
+ };
905
983
 
906
984
  // node_modules/uuid/dist/esm-node/stringify.js
907
985
  var byteToHex = [];
@@ -950,25 +1028,33 @@ function getThreadKey(threadId, key) {
950
1028
  return `thread:${threadId}:${key}`;
951
1029
  }
952
1030
  function createThreadManager(config) {
953
- const { redis, threadId, key = "messages" } = config;
1031
+ const {
1032
+ redis,
1033
+ threadId,
1034
+ key = "messages",
1035
+ serialize = (m) => JSON.stringify(m),
1036
+ deserialize = (raw) => JSON.parse(raw)
1037
+ } = config;
954
1038
  const redisKey = getThreadKey(threadId, key);
955
- return {
1039
+ const base = {
956
1040
  async initialize() {
957
1041
  await redis.del(redisKey);
958
1042
  },
959
1043
  async load() {
960
1044
  const data = await redis.lrange(redisKey, 0, -1);
961
- return data.map((item) => JSON.parse(item));
1045
+ return data.map(deserialize);
962
1046
  },
963
1047
  async append(messages) {
964
1048
  if (messages.length > 0) {
965
- await redis.rpush(redisKey, ...messages.map((m) => JSON.stringify(m)));
1049
+ await redis.rpush(redisKey, ...messages.map(serialize));
966
1050
  await redis.expire(redisKey, THREAD_TTL_SECONDS);
967
1051
  }
968
1052
  },
969
1053
  async delete() {
970
1054
  await redis.del(redisKey);
971
- },
1055
+ }
1056
+ };
1057
+ const helpers = {
972
1058
  createHumanMessage(content) {
973
1059
  return new HumanMessage({
974
1060
  id: v4_default(),
@@ -988,40 +1074,27 @@ function createThreadManager(config) {
988
1074
  },
989
1075
  createToolMessage(content, toolCallId) {
990
1076
  return new ToolMessage({
991
- // Cast needed due to langchain type compatibility
992
1077
  content,
993
1078
  tool_call_id: toolCallId
994
1079
  }).toDict();
995
1080
  },
996
- createSystemMessage(content) {
997
- return new SystemMessage({
998
- content
999
- }).toDict();
1000
- },
1001
- async appendSystemMessage(content) {
1002
- const message = this.createSystemMessage(content);
1003
- await this.append([message]);
1004
- },
1005
1081
  async appendHumanMessage(content) {
1006
- const message = this.createHumanMessage(content);
1007
- await this.append([message]);
1082
+ const message = helpers.createHumanMessage(content);
1083
+ await base.append([message]);
1008
1084
  },
1009
1085
  async appendToolMessage(content, toolCallId) {
1010
- const message = this.createToolMessage(content, toolCallId);
1011
- await this.append([message]);
1086
+ const message = helpers.createToolMessage(content, toolCallId);
1087
+ await base.append([message]);
1012
1088
  },
1013
1089
  async appendAIMessage(content) {
1014
- const message = this.createAIMessage(content);
1015
- await this.append([message]);
1090
+ const message = helpers.createAIMessage(content);
1091
+ await base.append([message]);
1016
1092
  }
1017
1093
  };
1094
+ return Object.assign(base, helpers);
1018
1095
  }
1019
1096
  function createSharedActivities(redis) {
1020
1097
  return {
1021
- async appendSystemMessage(threadId, content) {
1022
- const thread = createThreadManager({ redis, threadId });
1023
- await thread.appendSystemMessage(content);
1024
- },
1025
1098
  async appendToolResult(config) {
1026
1099
  const { threadId, toolCallId, content } = config;
1027
1100
  const thread = createThreadManager({ redis, threadId });
@@ -1094,7 +1167,7 @@ async function invokeModel({
1094
1167
  }
1095
1168
  };
1096
1169
  }
1097
- var handleAskUserQuestionToolResult = async (args) => {
1170
+ var createAskUserQuestionHandler = () => async (args) => {
1098
1171
  const messages = args.questions.map(
1099
1172
  ({ question, header, options, multiSelect }) => new AIMessage({
1100
1173
  content: question,
@@ -1105,101 +1178,81 @@ var handleAskUserQuestionToolResult = async (args) => {
1105
1178
  }
1106
1179
  }).toDict()
1107
1180
  );
1108
- return { content: "Question submitted", result: { chatMessages: messages } };
1181
+ return { toolResponse: "Question submitted", data: { chatMessages: messages } };
1109
1182
  };
1110
- async function globHandler(_args, fs) {
1111
- new Bash({ fs });
1112
- return Promise.resolve({
1113
- content: "Hello, world!",
1114
- result: { files: [] }
1115
- });
1183
+ function createGlobHandler(fs) {
1184
+ return async (_args) => {
1185
+ new Bash({ fs });
1186
+ return {
1187
+ toolResponse: "Hello, world!",
1188
+ data: { files: [] }
1189
+ };
1190
+ };
1116
1191
  }
1117
1192
 
1118
1193
  // src/tools/edit/handler.ts
1119
1194
  function escapeRegExp(str) {
1120
1195
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1121
1196
  }
1122
- async function editHandler(args, fs) {
1123
- const { file_path, old_string, new_string, replace_all = false } = args;
1124
- if (old_string === new_string) {
1125
- return {
1126
- content: `Error: old_string and new_string must be different.`,
1127
- result: {
1128
- path: file_path,
1129
- success: false,
1130
- replacements: 0
1131
- }
1132
- };
1133
- }
1134
- try {
1135
- const exists = await fs.exists(file_path);
1136
- if (!exists) {
1197
+ function createEditHandler(fs) {
1198
+ return async (args) => {
1199
+ const { file_path, old_string, new_string, replace_all = false } = args;
1200
+ if (old_string === new_string) {
1137
1201
  return {
1138
- content: `Error: File "${file_path}" does not exist.`,
1139
- result: {
1140
- path: file_path,
1141
- success: false,
1142
- replacements: 0
1143
- }
1202
+ toolResponse: `Error: old_string and new_string must be different.`,
1203
+ data: { path: file_path, success: false, replacements: 0 }
1144
1204
  };
1145
1205
  }
1146
- const content = await fs.readFile(file_path);
1147
- if (!content.includes(old_string)) {
1206
+ try {
1207
+ const exists = await fs.exists(file_path);
1208
+ if (!exists) {
1209
+ return {
1210
+ toolResponse: `Error: File "${file_path}" does not exist.`,
1211
+ data: { path: file_path, success: false, replacements: 0 }
1212
+ };
1213
+ }
1214
+ const content = await fs.readFile(file_path);
1215
+ if (!content.includes(old_string)) {
1216
+ return {
1217
+ toolResponse: `Error: Could not find the specified text in "${file_path}". Make sure old_string matches exactly (whitespace-sensitive).`,
1218
+ data: { path: file_path, success: false, replacements: 0 }
1219
+ };
1220
+ }
1221
+ const escapedOldString = escapeRegExp(old_string);
1222
+ const globalRegex = new RegExp(escapedOldString, "g");
1223
+ const occurrences = (content.match(globalRegex) || []).length;
1224
+ if (!replace_all && occurrences > 1) {
1225
+ return {
1226
+ toolResponse: `Error: old_string appears ${occurrences} times in "${file_path}". Either provide more context to make it unique, or use replace_all: true.`,
1227
+ data: { path: file_path, success: false, replacements: 0 }
1228
+ };
1229
+ }
1230
+ let newContent;
1231
+ let replacements;
1232
+ if (replace_all) {
1233
+ newContent = content.split(old_string).join(new_string);
1234
+ replacements = occurrences;
1235
+ } else {
1236
+ const index = content.indexOf(old_string);
1237
+ newContent = content.slice(0, index) + new_string + content.slice(index + old_string.length);
1238
+ replacements = 1;
1239
+ }
1240
+ await fs.writeFile(file_path, newContent);
1241
+ const summary = replace_all ? `Replaced ${replacements} occurrence(s)` : `Replaced 1 occurrence`;
1148
1242
  return {
1149
- content: `Error: Could not find the specified text in "${file_path}". Make sure old_string matches exactly (whitespace-sensitive).`,
1150
- result: {
1151
- path: file_path,
1152
- success: false,
1153
- replacements: 0
1154
- }
1243
+ toolResponse: `${summary} in ${file_path}`,
1244
+ data: { path: file_path, success: true, replacements }
1155
1245
  };
1156
- }
1157
- const escapedOldString = escapeRegExp(old_string);
1158
- const globalRegex = new RegExp(escapedOldString, "g");
1159
- const occurrences = (content.match(globalRegex) || []).length;
1160
- if (!replace_all && occurrences > 1) {
1246
+ } catch (error) {
1247
+ const message = error instanceof Error ? error.message : "Unknown error";
1161
1248
  return {
1162
- content: `Error: old_string appears ${occurrences} times in "${file_path}". Either provide more context to make it unique, or use replace_all: true.`,
1163
- result: {
1164
- path: file_path,
1165
- success: false,
1166
- replacements: 0
1167
- }
1249
+ toolResponse: `Error editing file "${file_path}": ${message}`,
1250
+ data: { path: file_path, success: false, replacements: 0 }
1168
1251
  };
1169
1252
  }
1170
- let newContent;
1171
- let replacements;
1172
- if (replace_all) {
1173
- newContent = content.split(old_string).join(new_string);
1174
- replacements = occurrences;
1175
- } else {
1176
- const index = content.indexOf(old_string);
1177
- newContent = content.slice(0, index) + new_string + content.slice(index + old_string.length);
1178
- replacements = 1;
1179
- }
1180
- await fs.writeFile(file_path, newContent);
1181
- const summary = replace_all ? `Replaced ${replacements} occurrence(s)` : `Replaced 1 occurrence`;
1182
- return {
1183
- content: `${summary} in ${file_path}`,
1184
- result: {
1185
- path: file_path,
1186
- success: true,
1187
- replacements
1188
- }
1189
- };
1190
- } catch (error) {
1191
- const message = error instanceof Error ? error.message : "Unknown error";
1192
- return {
1193
- content: `Error editing file "${file_path}": ${message}`,
1194
- result: {
1195
- path: file_path,
1196
- success: false,
1197
- replacements: 0
1198
- }
1199
- };
1200
- }
1253
+ };
1201
1254
  }
1202
- var handleBashTool = (bashOptions) => async (args, _context) => {
1255
+ var createBashHandler = (bashOptions) => async (args, _context) => {
1203
1256
  const { command } = args;
1204
1257
  const mergedOptions = {
1205
1258
  ...bashOptions,
@@ -1214,20 +1267,20 @@ var handleBashTool = (bashOptions) => async (args, _context) => {
1214
1267
  const { exitCode, stderr, stdout } = await bash.exec(command);
1215
1268
  const bashExecOut = { exitCode, stderr, stdout };
1216
1269
  return {
1217
- content: `Exit code: ${exitCode}
1270
+ toolResponse: `Exit code: ${exitCode}
1218
1271
 
1219
1272
  stdout:
1220
1273
  ${stdout}
1221
1274
 
1222
1275
  stderr:
1223
1276
  ${stderr}`,
1224
- result: bashExecOut
1277
+ data: bashExecOut
1225
1278
  };
1226
1279
  } catch (error) {
1227
1280
  const err = error instanceof Error ? error : new Error("Unknown error");
1228
1281
  return {
1229
- content: `Error executing bash command: ${err.message}`,
1230
- result: null
1282
+ toolResponse: `Error executing bash command: ${err.message}`,
1283
+ data: null
1231
1284
  };
1232
1285
  }
1233
1286
  };
@@ -1296,6 +1349,6 @@ var toTree = async (fs, opts = {}) => {
1296
1349
  return base + subtree;
1297
1350
  };
1298
1351
 
1299
- export { AGENT_HANDLER_NAMES, ZeitlichPlugin, askUserQuestionTool, bashTool, createAgentStateManager, createSession, createSharedActivities, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskTool, createTaskUpdateHandler, createToolRouter, editHandler, editTool, globHandler, globTool, grepTool, handleAskUserQuestionToolResult, handleBashTool, hasNoOtherToolCalls, invokeModel, isTerminalStatus, readTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, toTree, writeTool };
1352
+ export { AGENT_HANDLER_NAMES, ZeitlichPlugin, askUserQuestionTool, bashTool, createAgentStateManager, createAskUserQuestionHandler, createBashHandler, createBashToolDescription, createEditHandler, createGlobHandler, createSession, createSharedActivities, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskTool, createTaskUpdateHandler, createThreadManager, createToolRouter, defineSubagent, defineTool, editTool, getStateQuery, globTool, grepTool, hasNoOtherToolCalls, invokeModel, isTerminalStatus, proxyDefaultThreadOps, readTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, toTree, withAutoAppend, writeTool };
1300
1353
  //# sourceMappingURL=index.js.map
1301
1354
  //# sourceMappingURL=index.js.map