zeitlich 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/dist/index.cjs +268 -129
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -6
- package/dist/index.d.ts +8 -6
- package/dist/index.js +244 -109
- package/dist/index.js.map +1 -1
- package/dist/{workflow-uVNF7zoe.d.cts → workflow-BQf5EfNN.d.cts} +236 -55
- package/dist/{workflow-uVNF7zoe.d.ts → workflow-BQf5EfNN.d.ts} +236 -55
- package/dist/workflow.cjs +237 -107
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +4 -2
- package/dist/workflow.d.ts +4 -2
- package/dist/workflow.js +214 -86
- package/dist/workflow.js.map +1 -1
- package/package.json +6 -7
- package/src/index.ts +3 -0
- package/src/lib/session.ts +50 -24
- package/src/lib/state-manager.ts +9 -2
- package/src/lib/tool-router.ts +205 -23
- package/src/lib/types.ts +79 -4
- package/src/tools/ask-user-question/handler.ts +1 -1
- package/src/tools/bash/bash.test.ts +31 -31
- package/src/tools/bash/handler.ts +18 -9
- package/src/tools/bash/tool.ts +19 -3
- package/src/tools/edit/handler.ts +14 -14
- package/src/tools/glob/handler.ts +4 -4
- package/src/tools/task/handler.ts +17 -7
- package/src/tools/task/tool.ts +1 -1
- package/src/tools/task-create/handler.ts +7 -10
- package/src/tools/task-get/handler.ts +4 -4
- package/src/tools/task-list/handler.ts +2 -2
- package/src/tools/task-update/handler.ts +4 -4
- package/src/workflow.ts +3 -1
- package/tsup.config.ts +3 -1
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var workflow = require('@temporalio/workflow');
|
|
4
|
-
var
|
|
4
|
+
var z5 = require('zod');
|
|
5
5
|
var plugin = require('@temporalio/plugin');
|
|
6
6
|
var messages = require('@langchain/core/messages');
|
|
7
7
|
var crypto = require('crypto');
|
|
@@ -10,7 +10,7 @@ var justBash = require('just-bash');
|
|
|
10
10
|
|
|
11
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var z5__default = /*#__PURE__*/_interopDefault(z5);
|
|
14
14
|
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
15
15
|
|
|
16
16
|
// src/lib/session.ts
|
|
@@ -46,10 +46,10 @@ function createTaskTool(subagents) {
|
|
|
46
46
|
return {
|
|
47
47
|
name: TASK_TOOL,
|
|
48
48
|
description: buildTaskDescription(subagents),
|
|
49
|
-
schema:
|
|
50
|
-
subagent:
|
|
51
|
-
description:
|
|
52
|
-
prompt:
|
|
49
|
+
schema: z5__default.default.object({
|
|
50
|
+
subagent: z5__default.default.enum(names).describe("The type of subagent to launch"),
|
|
51
|
+
description: z5__default.default.string().describe("A short (3-5 word) description of the task"),
|
|
52
|
+
prompt: z5__default.default.string().describe("The task for the agent to perform")
|
|
53
53
|
})
|
|
54
54
|
};
|
|
55
55
|
}
|
|
@@ -63,16 +63,21 @@ function createTaskHandler(subagents) {
|
|
|
63
63
|
);
|
|
64
64
|
}
|
|
65
65
|
const childWorkflowId = `${parentWorkflowId}-${args.subagent}-${workflow.uuid4()}`;
|
|
66
|
-
const
|
|
66
|
+
const input = {
|
|
67
|
+
prompt: args.prompt,
|
|
68
|
+
...config.context && { context: config.context }
|
|
69
|
+
};
|
|
70
|
+
const childOpts = {
|
|
67
71
|
workflowId: childWorkflowId,
|
|
68
|
-
args: [
|
|
72
|
+
args: [input],
|
|
69
73
|
taskQueue: config.taskQueue ?? parentTaskQueue
|
|
70
|
-
}
|
|
74
|
+
};
|
|
75
|
+
const childResult = typeof config.workflow === "string" ? await workflow.executeChild(config.workflow, childOpts) : await workflow.executeChild(config.workflow, childOpts);
|
|
71
76
|
const validated = config.resultSchema ? config.resultSchema.parse(childResult) : childResult;
|
|
72
|
-
const
|
|
77
|
+
const toolResponse = typeof validated === "string" ? validated : JSON.stringify(validated, null, 2);
|
|
73
78
|
return {
|
|
74
|
-
|
|
75
|
-
|
|
79
|
+
toolResponse,
|
|
80
|
+
data: {
|
|
76
81
|
result: validated,
|
|
77
82
|
childWorkflowId
|
|
78
83
|
}
|
|
@@ -81,12 +86,28 @@ function createTaskHandler(subagents) {
|
|
|
81
86
|
}
|
|
82
87
|
var createBashToolDescription = ({
|
|
83
88
|
fileTree
|
|
84
|
-
}) => `
|
|
89
|
+
}) => `Execute shell commands in a bash environment.
|
|
90
|
+
|
|
91
|
+
Use this tool to:
|
|
92
|
+
- Run shell commands (ls, cat, grep, find, etc.)
|
|
93
|
+
- Execute scripts and chain commands with pipes (|) or logical operators (&&, ||)
|
|
94
|
+
- Inspect files and directories
|
|
95
|
+
|
|
96
|
+
Current file tree:
|
|
97
|
+
${fileTree}`;
|
|
85
98
|
var bashTool = {
|
|
86
99
|
name: "Bash",
|
|
87
|
-
description:
|
|
88
|
-
|
|
89
|
-
|
|
100
|
+
description: `Execute shell commands in a sandboxed bash environment.
|
|
101
|
+
|
|
102
|
+
Use this tool to:
|
|
103
|
+
- Run shell commands (ls, cat, grep, find, etc.)
|
|
104
|
+
- Execute scripts and chain commands with pipes (|) or logical operators (&&, ||)
|
|
105
|
+
- Inspect files and directories
|
|
106
|
+
`,
|
|
107
|
+
schema: z5__default.default.object({
|
|
108
|
+
command: z5__default.default.string().describe(
|
|
109
|
+
"The bash command to execute. Can include pipes (|), redirects (>, >>), logical operators (&&, ||), and shell features like command substitution $(...)."
|
|
110
|
+
)
|
|
90
111
|
}),
|
|
91
112
|
strict: true
|
|
92
113
|
};
|
|
@@ -131,17 +152,17 @@ var taskCreateTool = {
|
|
|
131
152
|
- Include enough detail in the description for another agent to understand and complete the task
|
|
132
153
|
- After creating tasks, use TaskUpdate to set up dependencies (blocks/blockedBy) if needed
|
|
133
154
|
- Check TaskList first to avoid creating duplicate tasks`,
|
|
134
|
-
schema:
|
|
135
|
-
subject:
|
|
155
|
+
schema: z5__default.default.object({
|
|
156
|
+
subject: z5__default.default.string().describe(
|
|
136
157
|
'A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")'
|
|
137
158
|
),
|
|
138
|
-
description:
|
|
159
|
+
description: z5__default.default.string().describe(
|
|
139
160
|
"Detailed description of what needs to be done, including context and acceptance criteria"
|
|
140
161
|
),
|
|
141
|
-
activeForm:
|
|
162
|
+
activeForm: z5__default.default.string().describe(
|
|
142
163
|
'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.'
|
|
143
164
|
),
|
|
144
|
-
metadata:
|
|
165
|
+
metadata: z5__default.default.record(z5__default.default.string(), z5__default.default.string()).describe("Arbitrary key-value pairs for tracking")
|
|
145
166
|
})
|
|
146
167
|
};
|
|
147
168
|
|
|
@@ -165,9 +186,30 @@ function createToolRouter(options) {
|
|
|
165
186
|
toolMap.set(tool.name, tool);
|
|
166
187
|
}
|
|
167
188
|
if (options.subagents) {
|
|
189
|
+
const subagentHooksMap = /* @__PURE__ */ new Map();
|
|
190
|
+
for (const s of options.subagents) {
|
|
191
|
+
if (s.hooks) subagentHooksMap.set(s.name, s.hooks);
|
|
192
|
+
}
|
|
193
|
+
const resolveSubagentName = (args) => args.subagent;
|
|
168
194
|
toolMap.set("Task", {
|
|
169
195
|
...createTaskTool(options.subagents),
|
|
170
|
-
handler: createTaskHandler(options.subagents)
|
|
196
|
+
handler: createTaskHandler(options.subagents),
|
|
197
|
+
...subagentHooksMap.size > 0 && {
|
|
198
|
+
hooks: {
|
|
199
|
+
onPreToolUse: async (ctx) => {
|
|
200
|
+
const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
|
|
201
|
+
return hooks?.onPreExecution?.(ctx) ?? {};
|
|
202
|
+
},
|
|
203
|
+
onPostToolUse: async (ctx) => {
|
|
204
|
+
const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
|
|
205
|
+
await hooks?.onPostExecution?.(ctx);
|
|
206
|
+
},
|
|
207
|
+
onPostToolUseFailure: async (ctx) => {
|
|
208
|
+
const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
|
|
209
|
+
return hooks?.onExecutionFailure?.(ctx) ?? {};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
171
213
|
});
|
|
172
214
|
}
|
|
173
215
|
if (options.buildInTools) {
|
|
@@ -190,6 +232,8 @@ function createToolRouter(options) {
|
|
|
190
232
|
}
|
|
191
233
|
async function processToolCall(toolCall, turn, handlerContext) {
|
|
192
234
|
const startTime = Date.now();
|
|
235
|
+
const tool = toolMap.get(toolCall.name);
|
|
236
|
+
const toolHooks = tool?.hooks;
|
|
193
237
|
let effectiveArgs = toolCall.args;
|
|
194
238
|
if (options.hooks?.onPreToolUse) {
|
|
195
239
|
const preResult = await options.hooks.onPreToolUse({
|
|
@@ -212,7 +256,27 @@ function createToolRouter(options) {
|
|
|
212
256
|
effectiveArgs = preResult.modifiedArgs;
|
|
213
257
|
}
|
|
214
258
|
}
|
|
215
|
-
|
|
259
|
+
if (toolHooks?.onPreToolUse) {
|
|
260
|
+
const preResult = await toolHooks.onPreToolUse({
|
|
261
|
+
args: effectiveArgs,
|
|
262
|
+
threadId: options.threadId,
|
|
263
|
+
turn
|
|
264
|
+
});
|
|
265
|
+
if (preResult?.skip) {
|
|
266
|
+
await appendToolResult({
|
|
267
|
+
threadId: options.threadId,
|
|
268
|
+
toolCallId: toolCall.id,
|
|
269
|
+
content: JSON.stringify({
|
|
270
|
+
skipped: true,
|
|
271
|
+
reason: "Skipped by tool PreToolUse hook"
|
|
272
|
+
})
|
|
273
|
+
});
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
if (preResult?.modifiedArgs !== void 0) {
|
|
277
|
+
effectiveArgs = preResult.modifiedArgs;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
216
280
|
let result;
|
|
217
281
|
let content;
|
|
218
282
|
try {
|
|
@@ -221,30 +285,50 @@ function createToolRouter(options) {
|
|
|
221
285
|
effectiveArgs,
|
|
222
286
|
handlerContext ?? {}
|
|
223
287
|
);
|
|
224
|
-
result = response.
|
|
225
|
-
content = response.
|
|
288
|
+
result = response.data;
|
|
289
|
+
content = response.toolResponse;
|
|
226
290
|
} else {
|
|
227
291
|
result = { error: `Unknown tool: ${toolCall.name}` };
|
|
228
292
|
content = JSON.stringify(result, null, 2);
|
|
229
293
|
}
|
|
230
294
|
} catch (error) {
|
|
231
|
-
|
|
295
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
296
|
+
let recovered = false;
|
|
297
|
+
if (toolHooks?.onPostToolUseFailure) {
|
|
298
|
+
const failureResult = await toolHooks.onPostToolUseFailure({
|
|
299
|
+
args: effectiveArgs,
|
|
300
|
+
error: err,
|
|
301
|
+
threadId: options.threadId,
|
|
302
|
+
turn
|
|
303
|
+
});
|
|
304
|
+
if (failureResult?.fallbackContent !== void 0) {
|
|
305
|
+
content = failureResult.fallbackContent;
|
|
306
|
+
result = { error: String(error), recovered: true };
|
|
307
|
+
recovered = true;
|
|
308
|
+
} else if (failureResult?.suppress) {
|
|
309
|
+
content = JSON.stringify({ error: String(error), suppressed: true });
|
|
310
|
+
result = { error: String(error), suppressed: true };
|
|
311
|
+
recovered = true;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (!recovered && options.hooks?.onPostToolUseFailure) {
|
|
232
315
|
const failureResult = await options.hooks.onPostToolUseFailure({
|
|
233
316
|
toolCall,
|
|
234
|
-
error:
|
|
317
|
+
error: err,
|
|
235
318
|
threadId: options.threadId,
|
|
236
319
|
turn
|
|
237
320
|
});
|
|
238
321
|
if (failureResult?.fallbackContent !== void 0) {
|
|
239
322
|
content = failureResult.fallbackContent;
|
|
240
323
|
result = { error: String(error), recovered: true };
|
|
324
|
+
recovered = true;
|
|
241
325
|
} else if (failureResult?.suppress) {
|
|
242
326
|
content = JSON.stringify({ error: String(error), suppressed: true });
|
|
243
327
|
result = { error: String(error), suppressed: true };
|
|
244
|
-
|
|
245
|
-
throw error;
|
|
328
|
+
recovered = true;
|
|
246
329
|
}
|
|
247
|
-
}
|
|
330
|
+
}
|
|
331
|
+
if (!recovered) {
|
|
248
332
|
throw error;
|
|
249
333
|
}
|
|
250
334
|
}
|
|
@@ -256,10 +340,19 @@ function createToolRouter(options) {
|
|
|
256
340
|
const toolResult = {
|
|
257
341
|
toolCallId: toolCall.id,
|
|
258
342
|
name: toolCall.name,
|
|
259
|
-
result
|
|
343
|
+
data: result
|
|
260
344
|
};
|
|
345
|
+
const durationMs = Date.now() - startTime;
|
|
346
|
+
if (toolHooks?.onPostToolUse) {
|
|
347
|
+
await toolHooks.onPostToolUse({
|
|
348
|
+
args: effectiveArgs,
|
|
349
|
+
result,
|
|
350
|
+
threadId: options.threadId,
|
|
351
|
+
turn,
|
|
352
|
+
durationMs
|
|
353
|
+
});
|
|
354
|
+
}
|
|
261
355
|
if (options.hooks?.onPostToolUse) {
|
|
262
|
-
const durationMs = Date.now() - startTime;
|
|
263
356
|
await options.hooks.onPostToolUse({
|
|
264
357
|
toolCall,
|
|
265
358
|
result: toolResult,
|
|
@@ -340,12 +433,12 @@ function createToolRouter(options) {
|
|
|
340
433
|
await appendToolResult({
|
|
341
434
|
threadId: options.threadId,
|
|
342
435
|
toolCallId: toolCall.id,
|
|
343
|
-
content: response.
|
|
436
|
+
content: response.toolResponse
|
|
344
437
|
});
|
|
345
438
|
return {
|
|
346
439
|
toolCallId: toolCall.id,
|
|
347
440
|
name: toolCall.name,
|
|
348
|
-
|
|
441
|
+
data: response.data ?? null
|
|
349
442
|
};
|
|
350
443
|
};
|
|
351
444
|
if (options.parallel) {
|
|
@@ -371,6 +464,12 @@ function createToolRouter(options) {
|
|
|
371
464
|
}
|
|
372
465
|
};
|
|
373
466
|
}
|
|
467
|
+
function defineTool(tool) {
|
|
468
|
+
return tool;
|
|
469
|
+
}
|
|
470
|
+
function defineSubagent(config) {
|
|
471
|
+
return config;
|
|
472
|
+
}
|
|
374
473
|
function hasNoOtherToolCalls(toolCalls, excludeName) {
|
|
375
474
|
return toolCalls.filter((tc) => tc.name !== excludeName).length === 0;
|
|
376
475
|
}
|
|
@@ -475,17 +574,47 @@ var createSession = async ({
|
|
|
475
574
|
return message;
|
|
476
575
|
}
|
|
477
576
|
const rawToolCalls = await parseToolCalls(message);
|
|
478
|
-
const parsedToolCalls =
|
|
479
|
-
const
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
577
|
+
const parsedToolCalls = [];
|
|
578
|
+
for (const tc of rawToolCalls.filter(
|
|
579
|
+
(tc2) => tc2.name !== "Task"
|
|
580
|
+
)) {
|
|
581
|
+
try {
|
|
582
|
+
parsedToolCalls.push(toolRouter.parseToolCall(tc));
|
|
583
|
+
} catch (error) {
|
|
584
|
+
await appendToolResult({
|
|
585
|
+
threadId,
|
|
586
|
+
toolCallId: tc.id ?? "",
|
|
587
|
+
content: JSON.stringify({
|
|
588
|
+
error: `Invalid tool call for "${tc.name}": ${error instanceof Error ? error.message : String(error)}`
|
|
589
|
+
})
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
const taskToolCalls = [];
|
|
594
|
+
if (subagents && subagents.length > 0) {
|
|
595
|
+
for (const tc of rawToolCalls.filter(
|
|
596
|
+
(tc2) => tc2.name === "Task"
|
|
597
|
+
)) {
|
|
598
|
+
try {
|
|
599
|
+
const parsedArgs = createTaskTool(subagents).schema.parse(
|
|
600
|
+
tc.args
|
|
601
|
+
);
|
|
602
|
+
taskToolCalls.push({
|
|
603
|
+
id: tc.id ?? "",
|
|
604
|
+
name: tc.name,
|
|
605
|
+
args: parsedArgs
|
|
606
|
+
});
|
|
607
|
+
} catch (error) {
|
|
608
|
+
await appendToolResult({
|
|
609
|
+
threadId,
|
|
610
|
+
toolCallId: tc.id ?? "",
|
|
611
|
+
content: JSON.stringify({
|
|
612
|
+
error: `Invalid tool call for "Task": ${error instanceof Error ? error.message : String(error)}`
|
|
613
|
+
})
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
489
618
|
await toolRouter.processToolCalls(
|
|
490
619
|
[...parsedToolCalls, ...taskToolCalls],
|
|
491
620
|
{
|
|
@@ -515,8 +644,6 @@ var createSession = async ({
|
|
|
515
644
|
function isTerminalStatus(status) {
|
|
516
645
|
return status === "COMPLETED" || status === "FAILED" || status === "CANCELLED";
|
|
517
646
|
}
|
|
518
|
-
|
|
519
|
-
// src/lib/state-manager.ts
|
|
520
647
|
var getStateQuery = workflow.defineQuery("getState");
|
|
521
648
|
function createAgentStateManager(initialState) {
|
|
522
649
|
let status = initialState?.status ?? "RUNNING";
|
|
@@ -611,7 +738,13 @@ function createAgentStateManager(initialState) {
|
|
|
611
738
|
version++;
|
|
612
739
|
},
|
|
613
740
|
setTools(newTools) {
|
|
614
|
-
tools = newTools
|
|
741
|
+
tools = newTools.map((tool) => ({
|
|
742
|
+
name: tool.name,
|
|
743
|
+
description: tool.description,
|
|
744
|
+
schema: z5.z.toJSONSchema(tool.schema),
|
|
745
|
+
strict: tool.strict,
|
|
746
|
+
max_uses: tool.max_uses
|
|
747
|
+
}));
|
|
615
748
|
},
|
|
616
749
|
deleteTask(id) {
|
|
617
750
|
const deleted = tasks.delete(id);
|
|
@@ -642,18 +775,18 @@ Usage notes:
|
|
|
642
775
|
* Use multiSelect: true to allow multiple answers to be selected for a question
|
|
643
776
|
* If you recommend a specific option, make that the first option in the list and add "(Recommended)" at the end of the label
|
|
644
777
|
`,
|
|
645
|
-
schema:
|
|
646
|
-
questions:
|
|
647
|
-
|
|
648
|
-
question:
|
|
649
|
-
header:
|
|
650
|
-
options:
|
|
651
|
-
|
|
652
|
-
label:
|
|
653
|
-
description:
|
|
778
|
+
schema: z5__default.default.object({
|
|
779
|
+
questions: z5__default.default.array(
|
|
780
|
+
z5__default.default.object({
|
|
781
|
+
question: z5__default.default.string().describe("The full question text to display"),
|
|
782
|
+
header: z5__default.default.string().describe("Short label for the question (max 12 characters)"),
|
|
783
|
+
options: z5__default.default.array(
|
|
784
|
+
z5__default.default.object({
|
|
785
|
+
label: z5__default.default.string(),
|
|
786
|
+
description: z5__default.default.string()
|
|
654
787
|
})
|
|
655
788
|
).min(0).max(4).describe("Array of 0-4 choices, each with label and description"),
|
|
656
|
-
multiSelect:
|
|
789
|
+
multiSelect: z5__default.default.boolean().describe("If true, users can select multiple options")
|
|
657
790
|
})
|
|
658
791
|
)
|
|
659
792
|
}),
|
|
@@ -673,9 +806,9 @@ Examples:
|
|
|
673
806
|
- "**/*.test.ts" - Find all test files recursively
|
|
674
807
|
- "src/**/*.ts" - Find all TypeScript files in src directory
|
|
675
808
|
`,
|
|
676
|
-
schema:
|
|
677
|
-
pattern:
|
|
678
|
-
root:
|
|
809
|
+
schema: z5.z.object({
|
|
810
|
+
pattern: z5.z.string().describe("Glob pattern to match files against"),
|
|
811
|
+
root: z5.z.string().optional().describe("Optional root directory to search from")
|
|
679
812
|
}),
|
|
680
813
|
strict: true
|
|
681
814
|
};
|
|
@@ -693,13 +826,13 @@ Examples:
|
|
|
693
826
|
- Search for function definitions with "function.*handleClick"
|
|
694
827
|
- Search case-insensitively with ignoreCase: true
|
|
695
828
|
`,
|
|
696
|
-
schema:
|
|
697
|
-
pattern:
|
|
698
|
-
ignoreCase:
|
|
699
|
-
maxMatches:
|
|
700
|
-
includePatterns:
|
|
701
|
-
excludePatterns:
|
|
702
|
-
contextLines:
|
|
829
|
+
schema: z5.z.object({
|
|
830
|
+
pattern: z5.z.string().describe("Regex pattern to search for in file contents"),
|
|
831
|
+
ignoreCase: z5.z.boolean().optional().describe("Case-insensitive search (default: false)"),
|
|
832
|
+
maxMatches: z5.z.number().optional().describe("Maximum number of matches to return (default: 50)"),
|
|
833
|
+
includePatterns: z5.z.array(z5.z.string()).optional().describe("Glob patterns to include (e.g., ['*.ts', '*.js'])"),
|
|
834
|
+
excludePatterns: z5.z.array(z5.z.string()).optional().describe("Glob patterns to exclude (e.g., ['*.test.ts'])"),
|
|
835
|
+
contextLines: z5.z.number().optional().describe("Number of context lines to show around matches")
|
|
703
836
|
}),
|
|
704
837
|
strict: true
|
|
705
838
|
};
|
|
@@ -717,12 +850,12 @@ The tool returns the file content in an appropriate format:
|
|
|
717
850
|
- Images: Base64-encoded image data
|
|
718
851
|
- PDFs: Extracted text content
|
|
719
852
|
`,
|
|
720
|
-
schema:
|
|
721
|
-
path:
|
|
722
|
-
offset:
|
|
853
|
+
schema: z5.z.object({
|
|
854
|
+
path: z5.z.string().describe("Virtual path to the file to read"),
|
|
855
|
+
offset: z5.z.number().optional().describe(
|
|
723
856
|
"Line number to start reading from (1-indexed, for text files)"
|
|
724
857
|
),
|
|
725
|
-
limit:
|
|
858
|
+
limit: z5.z.number().optional().describe("Maximum number of lines to read (for text files)")
|
|
726
859
|
}),
|
|
727
860
|
strict: true
|
|
728
861
|
};
|
|
@@ -740,9 +873,9 @@ IMPORTANT:
|
|
|
740
873
|
- This is an atomic write operation - the entire file is replaced
|
|
741
874
|
- Path must be absolute (e.g., "/docs/readme.md", not "docs/readme.md")
|
|
742
875
|
`,
|
|
743
|
-
schema:
|
|
744
|
-
file_path:
|
|
745
|
-
content:
|
|
876
|
+
schema: z5.z.object({
|
|
877
|
+
file_path: z5.z.string().describe("The absolute virtual path to the file to write"),
|
|
878
|
+
content: z5.z.string().describe("The content to write to the file")
|
|
746
879
|
}),
|
|
747
880
|
strict: true
|
|
748
881
|
};
|
|
@@ -762,27 +895,22 @@ IMPORTANT:
|
|
|
762
895
|
- The operation fails if old_string is not found
|
|
763
896
|
- old_string and new_string must be different
|
|
764
897
|
`,
|
|
765
|
-
schema:
|
|
766
|
-
file_path:
|
|
767
|
-
old_string:
|
|
768
|
-
new_string:
|
|
898
|
+
schema: z5.z.object({
|
|
899
|
+
file_path: z5.z.string().describe("The absolute virtual path to the file to modify"),
|
|
900
|
+
old_string: z5.z.string().describe("The exact text to replace"),
|
|
901
|
+
new_string: z5.z.string().describe(
|
|
769
902
|
"The text to replace it with (must be different from old_string)"
|
|
770
903
|
),
|
|
771
|
-
replace_all:
|
|
904
|
+
replace_all: z5.z.boolean().optional().describe(
|
|
772
905
|
"If true, replace all occurrences of old_string (default: false)"
|
|
773
906
|
)
|
|
774
907
|
}),
|
|
775
908
|
strict: true
|
|
776
909
|
};
|
|
777
|
-
|
|
778
|
-
// src/tools/task-create/handler.ts
|
|
779
|
-
function createTaskCreateHandler({
|
|
780
|
-
stateManager,
|
|
781
|
-
idGenerator
|
|
782
|
-
}) {
|
|
910
|
+
function createTaskCreateHandler(stateManager) {
|
|
783
911
|
return (args) => {
|
|
784
912
|
const task = {
|
|
785
|
-
id:
|
|
913
|
+
id: workflow.uuid4(),
|
|
786
914
|
subject: args.subject,
|
|
787
915
|
description: args.description,
|
|
788
916
|
activeForm: args.activeForm,
|
|
@@ -793,16 +921,16 @@ function createTaskCreateHandler({
|
|
|
793
921
|
};
|
|
794
922
|
stateManager.setTask(task);
|
|
795
923
|
return {
|
|
796
|
-
|
|
797
|
-
|
|
924
|
+
toolResponse: JSON.stringify(task, null, 2),
|
|
925
|
+
data: task
|
|
798
926
|
};
|
|
799
927
|
};
|
|
800
928
|
}
|
|
801
929
|
var taskGetTool = {
|
|
802
930
|
name: "TaskGet",
|
|
803
931
|
description: `Retrieve full task details including dependencies.`,
|
|
804
|
-
schema:
|
|
805
|
-
taskId:
|
|
932
|
+
schema: z5__default.default.object({
|
|
933
|
+
taskId: z5__default.default.string().describe("The ID of the task to get")
|
|
806
934
|
})
|
|
807
935
|
};
|
|
808
936
|
|
|
@@ -812,20 +940,20 @@ function createTaskGetHandler(stateManager) {
|
|
|
812
940
|
const task = stateManager.getTask(args.taskId) ?? null;
|
|
813
941
|
if (!task) {
|
|
814
942
|
return {
|
|
815
|
-
|
|
816
|
-
|
|
943
|
+
toolResponse: JSON.stringify({ error: `Task not found: ${args.taskId}` }),
|
|
944
|
+
data: null
|
|
817
945
|
};
|
|
818
946
|
}
|
|
819
947
|
return {
|
|
820
|
-
|
|
821
|
-
|
|
948
|
+
toolResponse: JSON.stringify(task, null, 2),
|
|
949
|
+
data: task
|
|
822
950
|
};
|
|
823
951
|
};
|
|
824
952
|
}
|
|
825
953
|
var taskListTool = {
|
|
826
954
|
name: "TaskList",
|
|
827
955
|
description: `List all tasks with current state.`,
|
|
828
|
-
schema:
|
|
956
|
+
schema: z5__default.default.object({})
|
|
829
957
|
};
|
|
830
958
|
|
|
831
959
|
// src/tools/task-list/handler.ts
|
|
@@ -833,19 +961,19 @@ function createTaskListHandler(stateManager) {
|
|
|
833
961
|
return (_args) => {
|
|
834
962
|
const taskList = stateManager.getTasks();
|
|
835
963
|
return {
|
|
836
|
-
|
|
837
|
-
|
|
964
|
+
toolResponse: JSON.stringify(taskList, null, 2),
|
|
965
|
+
data: taskList
|
|
838
966
|
};
|
|
839
967
|
};
|
|
840
968
|
}
|
|
841
969
|
var taskUpdateTool = {
|
|
842
970
|
name: "TaskUpdate",
|
|
843
971
|
description: `Update status, add blockers, modify details.`,
|
|
844
|
-
schema:
|
|
845
|
-
taskId:
|
|
846
|
-
status:
|
|
847
|
-
addBlockedBy:
|
|
848
|
-
addBlocks:
|
|
972
|
+
schema: z5__default.default.object({
|
|
973
|
+
taskId: z5__default.default.string().describe("The ID of the task to get"),
|
|
974
|
+
status: z5__default.default.enum(["pending", "in_progress", "completed"]).describe("The status of the task"),
|
|
975
|
+
addBlockedBy: z5__default.default.array(z5__default.default.string()).describe("The IDs of the tasks that are blocking this task"),
|
|
976
|
+
addBlocks: z5__default.default.array(z5__default.default.string()).describe("The IDs of the tasks that this task is blocking")
|
|
849
977
|
})
|
|
850
978
|
};
|
|
851
979
|
|
|
@@ -855,8 +983,8 @@ function createTaskUpdateHandler(stateManager) {
|
|
|
855
983
|
const task = stateManager.getTask(args.taskId);
|
|
856
984
|
if (!task) {
|
|
857
985
|
return {
|
|
858
|
-
|
|
859
|
-
|
|
986
|
+
toolResponse: JSON.stringify({ error: `Task not found: ${args.taskId}` }),
|
|
987
|
+
data: null
|
|
860
988
|
};
|
|
861
989
|
}
|
|
862
990
|
if (args.status) {
|
|
@@ -888,8 +1016,8 @@ function createTaskUpdateHandler(stateManager) {
|
|
|
888
1016
|
}
|
|
889
1017
|
stateManager.setTask(task);
|
|
890
1018
|
return {
|
|
891
|
-
|
|
892
|
-
|
|
1019
|
+
toolResponse: JSON.stringify(task, null, 2),
|
|
1020
|
+
data: task
|
|
893
1021
|
};
|
|
894
1022
|
};
|
|
895
1023
|
}
|
|
@@ -1096,13 +1224,13 @@ var handleAskUserQuestionToolResult = async (args) => {
|
|
|
1096
1224
|
}
|
|
1097
1225
|
}).toDict()
|
|
1098
1226
|
);
|
|
1099
|
-
return {
|
|
1227
|
+
return { toolResponse: "Question submitted", data: { chatMessages: messages$1 } };
|
|
1100
1228
|
};
|
|
1101
1229
|
async function globHandler(_args, fs) {
|
|
1102
1230
|
new justBash.Bash({ fs });
|
|
1103
1231
|
return Promise.resolve({
|
|
1104
|
-
|
|
1105
|
-
|
|
1232
|
+
toolResponse: "Hello, world!",
|
|
1233
|
+
data: { files: [] }
|
|
1106
1234
|
});
|
|
1107
1235
|
}
|
|
1108
1236
|
|
|
@@ -1114,8 +1242,8 @@ async function editHandler(args, fs) {
|
|
|
1114
1242
|
const { file_path, old_string, new_string, replace_all = false } = args;
|
|
1115
1243
|
if (old_string === new_string) {
|
|
1116
1244
|
return {
|
|
1117
|
-
|
|
1118
|
-
|
|
1245
|
+
toolResponse: `Error: old_string and new_string must be different.`,
|
|
1246
|
+
data: {
|
|
1119
1247
|
path: file_path,
|
|
1120
1248
|
success: false,
|
|
1121
1249
|
replacements: 0
|
|
@@ -1126,8 +1254,8 @@ async function editHandler(args, fs) {
|
|
|
1126
1254
|
const exists = await fs.exists(file_path);
|
|
1127
1255
|
if (!exists) {
|
|
1128
1256
|
return {
|
|
1129
|
-
|
|
1130
|
-
|
|
1257
|
+
toolResponse: `Error: File "${file_path}" does not exist.`,
|
|
1258
|
+
data: {
|
|
1131
1259
|
path: file_path,
|
|
1132
1260
|
success: false,
|
|
1133
1261
|
replacements: 0
|
|
@@ -1137,8 +1265,8 @@ async function editHandler(args, fs) {
|
|
|
1137
1265
|
const content = await fs.readFile(file_path);
|
|
1138
1266
|
if (!content.includes(old_string)) {
|
|
1139
1267
|
return {
|
|
1140
|
-
|
|
1141
|
-
|
|
1268
|
+
toolResponse: `Error: Could not find the specified text in "${file_path}". Make sure old_string matches exactly (whitespace-sensitive).`,
|
|
1269
|
+
data: {
|
|
1142
1270
|
path: file_path,
|
|
1143
1271
|
success: false,
|
|
1144
1272
|
replacements: 0
|
|
@@ -1150,8 +1278,8 @@ async function editHandler(args, fs) {
|
|
|
1150
1278
|
const occurrences = (content.match(globalRegex) || []).length;
|
|
1151
1279
|
if (!replace_all && occurrences > 1) {
|
|
1152
1280
|
return {
|
|
1153
|
-
|
|
1154
|
-
|
|
1281
|
+
toolResponse: `Error: old_string appears ${occurrences} times in "${file_path}". Either provide more context to make it unique, or use replace_all: true.`,
|
|
1282
|
+
data: {
|
|
1155
1283
|
path: file_path,
|
|
1156
1284
|
success: false,
|
|
1157
1285
|
replacements: 0
|
|
@@ -1171,8 +1299,8 @@ async function editHandler(args, fs) {
|
|
|
1171
1299
|
await fs.writeFile(file_path, newContent);
|
|
1172
1300
|
const summary = replace_all ? `Replaced ${replacements} occurrence(s)` : `Replaced 1 occurrence`;
|
|
1173
1301
|
return {
|
|
1174
|
-
|
|
1175
|
-
|
|
1302
|
+
toolResponse: `${summary} in ${file_path}`,
|
|
1303
|
+
data: {
|
|
1176
1304
|
path: file_path,
|
|
1177
1305
|
success: true,
|
|
1178
1306
|
replacements
|
|
@@ -1181,8 +1309,8 @@ async function editHandler(args, fs) {
|
|
|
1181
1309
|
} catch (error) {
|
|
1182
1310
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
1183
1311
|
return {
|
|
1184
|
-
|
|
1185
|
-
|
|
1312
|
+
toolResponse: `Error editing file "${file_path}": ${message}`,
|
|
1313
|
+
data: {
|
|
1186
1314
|
path: file_path,
|
|
1187
1315
|
success: false,
|
|
1188
1316
|
replacements: 0
|
|
@@ -1190,28 +1318,35 @@ async function editHandler(args, fs) {
|
|
|
1190
1318
|
};
|
|
1191
1319
|
}
|
|
1192
1320
|
}
|
|
1193
|
-
var handleBashTool = (
|
|
1321
|
+
var handleBashTool = (bashOptions) => async (args, _context) => {
|
|
1194
1322
|
const { command } = args;
|
|
1195
|
-
const
|
|
1196
|
-
|
|
1323
|
+
const mergedOptions = {
|
|
1324
|
+
...bashOptions,
|
|
1325
|
+
executionLimits: {
|
|
1326
|
+
maxStringLength: 52428800,
|
|
1327
|
+
// 50MB default
|
|
1328
|
+
...bashOptions.executionLimits
|
|
1329
|
+
}
|
|
1330
|
+
};
|
|
1331
|
+
const bash = new justBash.Bash(mergedOptions);
|
|
1197
1332
|
try {
|
|
1198
1333
|
const { exitCode, stderr, stdout } = await bash.exec(command);
|
|
1199
1334
|
const bashExecOut = { exitCode, stderr, stdout };
|
|
1200
1335
|
return {
|
|
1201
|
-
|
|
1336
|
+
toolResponse: `Exit code: ${exitCode}
|
|
1202
1337
|
|
|
1203
1338
|
stdout:
|
|
1204
1339
|
${stdout}
|
|
1205
1340
|
|
|
1206
1341
|
stderr:
|
|
1207
1342
|
${stderr}`,
|
|
1208
|
-
|
|
1343
|
+
data: bashExecOut
|
|
1209
1344
|
};
|
|
1210
1345
|
} catch (error) {
|
|
1211
1346
|
const err = error instanceof Error ? error : new Error("Unknown error");
|
|
1212
1347
|
return {
|
|
1213
|
-
|
|
1214
|
-
|
|
1348
|
+
toolResponse: `Error executing bash command: ${err.message}`,
|
|
1349
|
+
data: null
|
|
1215
1350
|
};
|
|
1216
1351
|
}
|
|
1217
1352
|
};
|
|
@@ -1292,9 +1427,13 @@ exports.createTaskGetHandler = createTaskGetHandler;
|
|
|
1292
1427
|
exports.createTaskListHandler = createTaskListHandler;
|
|
1293
1428
|
exports.createTaskTool = createTaskTool;
|
|
1294
1429
|
exports.createTaskUpdateHandler = createTaskUpdateHandler;
|
|
1430
|
+
exports.createThreadManager = createThreadManager;
|
|
1295
1431
|
exports.createToolRouter = createToolRouter;
|
|
1432
|
+
exports.defineSubagent = defineSubagent;
|
|
1433
|
+
exports.defineTool = defineTool;
|
|
1296
1434
|
exports.editHandler = editHandler;
|
|
1297
1435
|
exports.editTool = editTool;
|
|
1436
|
+
exports.getStateQuery = getStateQuery;
|
|
1298
1437
|
exports.globHandler = globHandler;
|
|
1299
1438
|
exports.globTool = globTool;
|
|
1300
1439
|
exports.grepTool = grepTool;
|