zeitlich 0.2.1 → 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 +2 -2
- package/dist/index.cjs +240 -124
- 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 +216 -104
- package/dist/index.js.map +1 -1
- package/dist/{workflow-CCoHnc3B.d.cts → workflow-BQf5EfNN.d.cts} +232 -53
- package/dist/{workflow-CCoHnc3B.d.ts → workflow-BQf5EfNN.d.ts} +232 -53
- package/dist/workflow.cjs +219 -105
- 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 +196 -84
- package/dist/workflow.js.map +1 -1
- package/package.json +1 -1
- 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 +4 -4
- 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/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
|
}
|
|
@@ -99,8 +104,8 @@ Use this tool to:
|
|
|
99
104
|
- Execute scripts and chain commands with pipes (|) or logical operators (&&, ||)
|
|
100
105
|
- Inspect files and directories
|
|
101
106
|
`,
|
|
102
|
-
schema:
|
|
103
|
-
command:
|
|
107
|
+
schema: z5__default.default.object({
|
|
108
|
+
command: z5__default.default.string().describe(
|
|
104
109
|
"The bash command to execute. Can include pipes (|), redirects (>, >>), logical operators (&&, ||), and shell features like command substitution $(...)."
|
|
105
110
|
)
|
|
106
111
|
}),
|
|
@@ -147,17 +152,17 @@ var taskCreateTool = {
|
|
|
147
152
|
- Include enough detail in the description for another agent to understand and complete the task
|
|
148
153
|
- After creating tasks, use TaskUpdate to set up dependencies (blocks/blockedBy) if needed
|
|
149
154
|
- Check TaskList first to avoid creating duplicate tasks`,
|
|
150
|
-
schema:
|
|
151
|
-
subject:
|
|
155
|
+
schema: z5__default.default.object({
|
|
156
|
+
subject: z5__default.default.string().describe(
|
|
152
157
|
'A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")'
|
|
153
158
|
),
|
|
154
|
-
description:
|
|
159
|
+
description: z5__default.default.string().describe(
|
|
155
160
|
"Detailed description of what needs to be done, including context and acceptance criteria"
|
|
156
161
|
),
|
|
157
|
-
activeForm:
|
|
162
|
+
activeForm: z5__default.default.string().describe(
|
|
158
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.'
|
|
159
164
|
),
|
|
160
|
-
metadata:
|
|
165
|
+
metadata: z5__default.default.record(z5__default.default.string(), z5__default.default.string()).describe("Arbitrary key-value pairs for tracking")
|
|
161
166
|
})
|
|
162
167
|
};
|
|
163
168
|
|
|
@@ -181,9 +186,30 @@ function createToolRouter(options) {
|
|
|
181
186
|
toolMap.set(tool.name, tool);
|
|
182
187
|
}
|
|
183
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;
|
|
184
194
|
toolMap.set("Task", {
|
|
185
195
|
...createTaskTool(options.subagents),
|
|
186
|
-
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
|
+
}
|
|
187
213
|
});
|
|
188
214
|
}
|
|
189
215
|
if (options.buildInTools) {
|
|
@@ -206,6 +232,8 @@ function createToolRouter(options) {
|
|
|
206
232
|
}
|
|
207
233
|
async function processToolCall(toolCall, turn, handlerContext) {
|
|
208
234
|
const startTime = Date.now();
|
|
235
|
+
const tool = toolMap.get(toolCall.name);
|
|
236
|
+
const toolHooks = tool?.hooks;
|
|
209
237
|
let effectiveArgs = toolCall.args;
|
|
210
238
|
if (options.hooks?.onPreToolUse) {
|
|
211
239
|
const preResult = await options.hooks.onPreToolUse({
|
|
@@ -228,7 +256,27 @@ function createToolRouter(options) {
|
|
|
228
256
|
effectiveArgs = preResult.modifiedArgs;
|
|
229
257
|
}
|
|
230
258
|
}
|
|
231
|
-
|
|
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
|
+
}
|
|
232
280
|
let result;
|
|
233
281
|
let content;
|
|
234
282
|
try {
|
|
@@ -237,30 +285,50 @@ function createToolRouter(options) {
|
|
|
237
285
|
effectiveArgs,
|
|
238
286
|
handlerContext ?? {}
|
|
239
287
|
);
|
|
240
|
-
result = response.
|
|
241
|
-
content = response.
|
|
288
|
+
result = response.data;
|
|
289
|
+
content = response.toolResponse;
|
|
242
290
|
} else {
|
|
243
291
|
result = { error: `Unknown tool: ${toolCall.name}` };
|
|
244
292
|
content = JSON.stringify(result, null, 2);
|
|
245
293
|
}
|
|
246
294
|
} catch (error) {
|
|
247
|
-
|
|
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) {
|
|
248
315
|
const failureResult = await options.hooks.onPostToolUseFailure({
|
|
249
316
|
toolCall,
|
|
250
|
-
error:
|
|
317
|
+
error: err,
|
|
251
318
|
threadId: options.threadId,
|
|
252
319
|
turn
|
|
253
320
|
});
|
|
254
321
|
if (failureResult?.fallbackContent !== void 0) {
|
|
255
322
|
content = failureResult.fallbackContent;
|
|
256
323
|
result = { error: String(error), recovered: true };
|
|
324
|
+
recovered = true;
|
|
257
325
|
} else if (failureResult?.suppress) {
|
|
258
326
|
content = JSON.stringify({ error: String(error), suppressed: true });
|
|
259
327
|
result = { error: String(error), suppressed: true };
|
|
260
|
-
|
|
261
|
-
throw error;
|
|
328
|
+
recovered = true;
|
|
262
329
|
}
|
|
263
|
-
}
|
|
330
|
+
}
|
|
331
|
+
if (!recovered) {
|
|
264
332
|
throw error;
|
|
265
333
|
}
|
|
266
334
|
}
|
|
@@ -272,10 +340,19 @@ function createToolRouter(options) {
|
|
|
272
340
|
const toolResult = {
|
|
273
341
|
toolCallId: toolCall.id,
|
|
274
342
|
name: toolCall.name,
|
|
275
|
-
result
|
|
343
|
+
data: result
|
|
276
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
|
+
}
|
|
277
355
|
if (options.hooks?.onPostToolUse) {
|
|
278
|
-
const durationMs = Date.now() - startTime;
|
|
279
356
|
await options.hooks.onPostToolUse({
|
|
280
357
|
toolCall,
|
|
281
358
|
result: toolResult,
|
|
@@ -356,12 +433,12 @@ function createToolRouter(options) {
|
|
|
356
433
|
await appendToolResult({
|
|
357
434
|
threadId: options.threadId,
|
|
358
435
|
toolCallId: toolCall.id,
|
|
359
|
-
content: response.
|
|
436
|
+
content: response.toolResponse
|
|
360
437
|
});
|
|
361
438
|
return {
|
|
362
439
|
toolCallId: toolCall.id,
|
|
363
440
|
name: toolCall.name,
|
|
364
|
-
|
|
441
|
+
data: response.data ?? null
|
|
365
442
|
};
|
|
366
443
|
};
|
|
367
444
|
if (options.parallel) {
|
|
@@ -387,6 +464,12 @@ function createToolRouter(options) {
|
|
|
387
464
|
}
|
|
388
465
|
};
|
|
389
466
|
}
|
|
467
|
+
function defineTool(tool) {
|
|
468
|
+
return tool;
|
|
469
|
+
}
|
|
470
|
+
function defineSubagent(config) {
|
|
471
|
+
return config;
|
|
472
|
+
}
|
|
390
473
|
function hasNoOtherToolCalls(toolCalls, excludeName) {
|
|
391
474
|
return toolCalls.filter((tc) => tc.name !== excludeName).length === 0;
|
|
392
475
|
}
|
|
@@ -491,17 +574,47 @@ var createSession = async ({
|
|
|
491
574
|
return message;
|
|
492
575
|
}
|
|
493
576
|
const rawToolCalls = await parseToolCalls(message);
|
|
494
|
-
const parsedToolCalls =
|
|
495
|
-
const
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
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
|
+
}
|
|
505
618
|
await toolRouter.processToolCalls(
|
|
506
619
|
[...parsedToolCalls, ...taskToolCalls],
|
|
507
620
|
{
|
|
@@ -531,8 +644,6 @@ var createSession = async ({
|
|
|
531
644
|
function isTerminalStatus(status) {
|
|
532
645
|
return status === "COMPLETED" || status === "FAILED" || status === "CANCELLED";
|
|
533
646
|
}
|
|
534
|
-
|
|
535
|
-
// src/lib/state-manager.ts
|
|
536
647
|
var getStateQuery = workflow.defineQuery("getState");
|
|
537
648
|
function createAgentStateManager(initialState) {
|
|
538
649
|
let status = initialState?.status ?? "RUNNING";
|
|
@@ -627,7 +738,13 @@ function createAgentStateManager(initialState) {
|
|
|
627
738
|
version++;
|
|
628
739
|
},
|
|
629
740
|
setTools(newTools) {
|
|
630
|
-
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
|
+
}));
|
|
631
748
|
},
|
|
632
749
|
deleteTask(id) {
|
|
633
750
|
const deleted = tasks.delete(id);
|
|
@@ -658,18 +775,18 @@ Usage notes:
|
|
|
658
775
|
* Use multiSelect: true to allow multiple answers to be selected for a question
|
|
659
776
|
* If you recommend a specific option, make that the first option in the list and add "(Recommended)" at the end of the label
|
|
660
777
|
`,
|
|
661
|
-
schema:
|
|
662
|
-
questions:
|
|
663
|
-
|
|
664
|
-
question:
|
|
665
|
-
header:
|
|
666
|
-
options:
|
|
667
|
-
|
|
668
|
-
label:
|
|
669
|
-
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()
|
|
670
787
|
})
|
|
671
788
|
).min(0).max(4).describe("Array of 0-4 choices, each with label and description"),
|
|
672
|
-
multiSelect:
|
|
789
|
+
multiSelect: z5__default.default.boolean().describe("If true, users can select multiple options")
|
|
673
790
|
})
|
|
674
791
|
)
|
|
675
792
|
}),
|
|
@@ -689,9 +806,9 @@ Examples:
|
|
|
689
806
|
- "**/*.test.ts" - Find all test files recursively
|
|
690
807
|
- "src/**/*.ts" - Find all TypeScript files in src directory
|
|
691
808
|
`,
|
|
692
|
-
schema:
|
|
693
|
-
pattern:
|
|
694
|
-
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")
|
|
695
812
|
}),
|
|
696
813
|
strict: true
|
|
697
814
|
};
|
|
@@ -709,13 +826,13 @@ Examples:
|
|
|
709
826
|
- Search for function definitions with "function.*handleClick"
|
|
710
827
|
- Search case-insensitively with ignoreCase: true
|
|
711
828
|
`,
|
|
712
|
-
schema:
|
|
713
|
-
pattern:
|
|
714
|
-
ignoreCase:
|
|
715
|
-
maxMatches:
|
|
716
|
-
includePatterns:
|
|
717
|
-
excludePatterns:
|
|
718
|
-
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")
|
|
719
836
|
}),
|
|
720
837
|
strict: true
|
|
721
838
|
};
|
|
@@ -733,12 +850,12 @@ The tool returns the file content in an appropriate format:
|
|
|
733
850
|
- Images: Base64-encoded image data
|
|
734
851
|
- PDFs: Extracted text content
|
|
735
852
|
`,
|
|
736
|
-
schema:
|
|
737
|
-
path:
|
|
738
|
-
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(
|
|
739
856
|
"Line number to start reading from (1-indexed, for text files)"
|
|
740
857
|
),
|
|
741
|
-
limit:
|
|
858
|
+
limit: z5.z.number().optional().describe("Maximum number of lines to read (for text files)")
|
|
742
859
|
}),
|
|
743
860
|
strict: true
|
|
744
861
|
};
|
|
@@ -756,9 +873,9 @@ IMPORTANT:
|
|
|
756
873
|
- This is an atomic write operation - the entire file is replaced
|
|
757
874
|
- Path must be absolute (e.g., "/docs/readme.md", not "docs/readme.md")
|
|
758
875
|
`,
|
|
759
|
-
schema:
|
|
760
|
-
file_path:
|
|
761
|
-
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")
|
|
762
879
|
}),
|
|
763
880
|
strict: true
|
|
764
881
|
};
|
|
@@ -778,27 +895,22 @@ IMPORTANT:
|
|
|
778
895
|
- The operation fails if old_string is not found
|
|
779
896
|
- old_string and new_string must be different
|
|
780
897
|
`,
|
|
781
|
-
schema:
|
|
782
|
-
file_path:
|
|
783
|
-
old_string:
|
|
784
|
-
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(
|
|
785
902
|
"The text to replace it with (must be different from old_string)"
|
|
786
903
|
),
|
|
787
|
-
replace_all:
|
|
904
|
+
replace_all: z5.z.boolean().optional().describe(
|
|
788
905
|
"If true, replace all occurrences of old_string (default: false)"
|
|
789
906
|
)
|
|
790
907
|
}),
|
|
791
908
|
strict: true
|
|
792
909
|
};
|
|
793
|
-
|
|
794
|
-
// src/tools/task-create/handler.ts
|
|
795
|
-
function createTaskCreateHandler({
|
|
796
|
-
stateManager,
|
|
797
|
-
idGenerator
|
|
798
|
-
}) {
|
|
910
|
+
function createTaskCreateHandler(stateManager) {
|
|
799
911
|
return (args) => {
|
|
800
912
|
const task = {
|
|
801
|
-
id:
|
|
913
|
+
id: workflow.uuid4(),
|
|
802
914
|
subject: args.subject,
|
|
803
915
|
description: args.description,
|
|
804
916
|
activeForm: args.activeForm,
|
|
@@ -809,16 +921,16 @@ function createTaskCreateHandler({
|
|
|
809
921
|
};
|
|
810
922
|
stateManager.setTask(task);
|
|
811
923
|
return {
|
|
812
|
-
|
|
813
|
-
|
|
924
|
+
toolResponse: JSON.stringify(task, null, 2),
|
|
925
|
+
data: task
|
|
814
926
|
};
|
|
815
927
|
};
|
|
816
928
|
}
|
|
817
929
|
var taskGetTool = {
|
|
818
930
|
name: "TaskGet",
|
|
819
931
|
description: `Retrieve full task details including dependencies.`,
|
|
820
|
-
schema:
|
|
821
|
-
taskId:
|
|
932
|
+
schema: z5__default.default.object({
|
|
933
|
+
taskId: z5__default.default.string().describe("The ID of the task to get")
|
|
822
934
|
})
|
|
823
935
|
};
|
|
824
936
|
|
|
@@ -828,20 +940,20 @@ function createTaskGetHandler(stateManager) {
|
|
|
828
940
|
const task = stateManager.getTask(args.taskId) ?? null;
|
|
829
941
|
if (!task) {
|
|
830
942
|
return {
|
|
831
|
-
|
|
832
|
-
|
|
943
|
+
toolResponse: JSON.stringify({ error: `Task not found: ${args.taskId}` }),
|
|
944
|
+
data: null
|
|
833
945
|
};
|
|
834
946
|
}
|
|
835
947
|
return {
|
|
836
|
-
|
|
837
|
-
|
|
948
|
+
toolResponse: JSON.stringify(task, null, 2),
|
|
949
|
+
data: task
|
|
838
950
|
};
|
|
839
951
|
};
|
|
840
952
|
}
|
|
841
953
|
var taskListTool = {
|
|
842
954
|
name: "TaskList",
|
|
843
955
|
description: `List all tasks with current state.`,
|
|
844
|
-
schema:
|
|
956
|
+
schema: z5__default.default.object({})
|
|
845
957
|
};
|
|
846
958
|
|
|
847
959
|
// src/tools/task-list/handler.ts
|
|
@@ -849,19 +961,19 @@ function createTaskListHandler(stateManager) {
|
|
|
849
961
|
return (_args) => {
|
|
850
962
|
const taskList = stateManager.getTasks();
|
|
851
963
|
return {
|
|
852
|
-
|
|
853
|
-
|
|
964
|
+
toolResponse: JSON.stringify(taskList, null, 2),
|
|
965
|
+
data: taskList
|
|
854
966
|
};
|
|
855
967
|
};
|
|
856
968
|
}
|
|
857
969
|
var taskUpdateTool = {
|
|
858
970
|
name: "TaskUpdate",
|
|
859
971
|
description: `Update status, add blockers, modify details.`,
|
|
860
|
-
schema:
|
|
861
|
-
taskId:
|
|
862
|
-
status:
|
|
863
|
-
addBlockedBy:
|
|
864
|
-
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")
|
|
865
977
|
})
|
|
866
978
|
};
|
|
867
979
|
|
|
@@ -871,8 +983,8 @@ function createTaskUpdateHandler(stateManager) {
|
|
|
871
983
|
const task = stateManager.getTask(args.taskId);
|
|
872
984
|
if (!task) {
|
|
873
985
|
return {
|
|
874
|
-
|
|
875
|
-
|
|
986
|
+
toolResponse: JSON.stringify({ error: `Task not found: ${args.taskId}` }),
|
|
987
|
+
data: null
|
|
876
988
|
};
|
|
877
989
|
}
|
|
878
990
|
if (args.status) {
|
|
@@ -904,8 +1016,8 @@ function createTaskUpdateHandler(stateManager) {
|
|
|
904
1016
|
}
|
|
905
1017
|
stateManager.setTask(task);
|
|
906
1018
|
return {
|
|
907
|
-
|
|
908
|
-
|
|
1019
|
+
toolResponse: JSON.stringify(task, null, 2),
|
|
1020
|
+
data: task
|
|
909
1021
|
};
|
|
910
1022
|
};
|
|
911
1023
|
}
|
|
@@ -1112,13 +1224,13 @@ var handleAskUserQuestionToolResult = async (args) => {
|
|
|
1112
1224
|
}
|
|
1113
1225
|
}).toDict()
|
|
1114
1226
|
);
|
|
1115
|
-
return {
|
|
1227
|
+
return { toolResponse: "Question submitted", data: { chatMessages: messages$1 } };
|
|
1116
1228
|
};
|
|
1117
1229
|
async function globHandler(_args, fs) {
|
|
1118
1230
|
new justBash.Bash({ fs });
|
|
1119
1231
|
return Promise.resolve({
|
|
1120
|
-
|
|
1121
|
-
|
|
1232
|
+
toolResponse: "Hello, world!",
|
|
1233
|
+
data: { files: [] }
|
|
1122
1234
|
});
|
|
1123
1235
|
}
|
|
1124
1236
|
|
|
@@ -1130,8 +1242,8 @@ async function editHandler(args, fs) {
|
|
|
1130
1242
|
const { file_path, old_string, new_string, replace_all = false } = args;
|
|
1131
1243
|
if (old_string === new_string) {
|
|
1132
1244
|
return {
|
|
1133
|
-
|
|
1134
|
-
|
|
1245
|
+
toolResponse: `Error: old_string and new_string must be different.`,
|
|
1246
|
+
data: {
|
|
1135
1247
|
path: file_path,
|
|
1136
1248
|
success: false,
|
|
1137
1249
|
replacements: 0
|
|
@@ -1142,8 +1254,8 @@ async function editHandler(args, fs) {
|
|
|
1142
1254
|
const exists = await fs.exists(file_path);
|
|
1143
1255
|
if (!exists) {
|
|
1144
1256
|
return {
|
|
1145
|
-
|
|
1146
|
-
|
|
1257
|
+
toolResponse: `Error: File "${file_path}" does not exist.`,
|
|
1258
|
+
data: {
|
|
1147
1259
|
path: file_path,
|
|
1148
1260
|
success: false,
|
|
1149
1261
|
replacements: 0
|
|
@@ -1153,8 +1265,8 @@ async function editHandler(args, fs) {
|
|
|
1153
1265
|
const content = await fs.readFile(file_path);
|
|
1154
1266
|
if (!content.includes(old_string)) {
|
|
1155
1267
|
return {
|
|
1156
|
-
|
|
1157
|
-
|
|
1268
|
+
toolResponse: `Error: Could not find the specified text in "${file_path}". Make sure old_string matches exactly (whitespace-sensitive).`,
|
|
1269
|
+
data: {
|
|
1158
1270
|
path: file_path,
|
|
1159
1271
|
success: false,
|
|
1160
1272
|
replacements: 0
|
|
@@ -1166,8 +1278,8 @@ async function editHandler(args, fs) {
|
|
|
1166
1278
|
const occurrences = (content.match(globalRegex) || []).length;
|
|
1167
1279
|
if (!replace_all && occurrences > 1) {
|
|
1168
1280
|
return {
|
|
1169
|
-
|
|
1170
|
-
|
|
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: {
|
|
1171
1283
|
path: file_path,
|
|
1172
1284
|
success: false,
|
|
1173
1285
|
replacements: 0
|
|
@@ -1187,8 +1299,8 @@ async function editHandler(args, fs) {
|
|
|
1187
1299
|
await fs.writeFile(file_path, newContent);
|
|
1188
1300
|
const summary = replace_all ? `Replaced ${replacements} occurrence(s)` : `Replaced 1 occurrence`;
|
|
1189
1301
|
return {
|
|
1190
|
-
|
|
1191
|
-
|
|
1302
|
+
toolResponse: `${summary} in ${file_path}`,
|
|
1303
|
+
data: {
|
|
1192
1304
|
path: file_path,
|
|
1193
1305
|
success: true,
|
|
1194
1306
|
replacements
|
|
@@ -1197,8 +1309,8 @@ async function editHandler(args, fs) {
|
|
|
1197
1309
|
} catch (error) {
|
|
1198
1310
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
1199
1311
|
return {
|
|
1200
|
-
|
|
1201
|
-
|
|
1312
|
+
toolResponse: `Error editing file "${file_path}": ${message}`,
|
|
1313
|
+
data: {
|
|
1202
1314
|
path: file_path,
|
|
1203
1315
|
success: false,
|
|
1204
1316
|
replacements: 0
|
|
@@ -1221,20 +1333,20 @@ var handleBashTool = (bashOptions) => async (args, _context) => {
|
|
|
1221
1333
|
const { exitCode, stderr, stdout } = await bash.exec(command);
|
|
1222
1334
|
const bashExecOut = { exitCode, stderr, stdout };
|
|
1223
1335
|
return {
|
|
1224
|
-
|
|
1336
|
+
toolResponse: `Exit code: ${exitCode}
|
|
1225
1337
|
|
|
1226
1338
|
stdout:
|
|
1227
1339
|
${stdout}
|
|
1228
1340
|
|
|
1229
1341
|
stderr:
|
|
1230
1342
|
${stderr}`,
|
|
1231
|
-
|
|
1343
|
+
data: bashExecOut
|
|
1232
1344
|
};
|
|
1233
1345
|
} catch (error) {
|
|
1234
1346
|
const err = error instanceof Error ? error : new Error("Unknown error");
|
|
1235
1347
|
return {
|
|
1236
|
-
|
|
1237
|
-
|
|
1348
|
+
toolResponse: `Error executing bash command: ${err.message}`,
|
|
1349
|
+
data: null
|
|
1238
1350
|
};
|
|
1239
1351
|
}
|
|
1240
1352
|
};
|
|
@@ -1315,9 +1427,13 @@ exports.createTaskGetHandler = createTaskGetHandler;
|
|
|
1315
1427
|
exports.createTaskListHandler = createTaskListHandler;
|
|
1316
1428
|
exports.createTaskTool = createTaskTool;
|
|
1317
1429
|
exports.createTaskUpdateHandler = createTaskUpdateHandler;
|
|
1430
|
+
exports.createThreadManager = createThreadManager;
|
|
1318
1431
|
exports.createToolRouter = createToolRouter;
|
|
1432
|
+
exports.defineSubagent = defineSubagent;
|
|
1433
|
+
exports.defineTool = defineTool;
|
|
1319
1434
|
exports.editHandler = editHandler;
|
|
1320
1435
|
exports.editTool = editTool;
|
|
1436
|
+
exports.getStateQuery = getStateQuery;
|
|
1321
1437
|
exports.globHandler = globHandler;
|
|
1322
1438
|
exports.globTool = globTool;
|
|
1323
1439
|
exports.grepTool = grepTool;
|