zeitlich 0.1.1 → 0.2.0
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 +165 -180
- package/dist/index.cjs +1314 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +128 -0
- package/dist/index.d.ts +51 -75
- package/dist/index.js +741 -1091
- package/dist/index.js.map +1 -1
- package/dist/workflow-uVNF7zoe.d.cts +941 -0
- package/dist/workflow-uVNF7zoe.d.ts +941 -0
- package/dist/workflow.cjs +914 -0
- package/dist/workflow.cjs.map +1 -0
- package/dist/workflow.d.cts +5 -0
- package/dist/workflow.d.ts +2 -1
- package/dist/workflow.js +543 -423
- package/dist/workflow.js.map +1 -1
- package/package.json +19 -17
- package/src/activities.ts +112 -0
- package/src/index.ts +49 -0
- package/src/lib/fs.ts +80 -0
- package/src/lib/model-invoker.ts +75 -0
- package/src/lib/session.ts +216 -0
- package/src/lib/state-manager.ts +268 -0
- package/src/lib/thread-manager.ts +169 -0
- package/src/lib/tool-router.ts +717 -0
- package/src/lib/types.ts +354 -0
- package/src/plugin.ts +28 -0
- package/src/tools/ask-user-question/handler.ts +25 -0
- package/src/tools/ask-user-question/tool.ts +46 -0
- package/src/tools/bash/bash.test.ts +104 -0
- package/src/tools/bash/handler.ts +36 -0
- package/src/tools/bash/tool.ts +20 -0
- package/src/tools/edit/handler.ts +156 -0
- package/src/tools/edit/tool.ts +39 -0
- package/src/tools/glob/handler.ts +62 -0
- package/src/tools/glob/tool.ts +27 -0
- package/src/tools/grep/tool.ts +45 -0
- package/src/tools/read/tool.ts +33 -0
- package/src/tools/task/handler.ts +75 -0
- package/src/tools/task/tool.ts +96 -0
- package/src/tools/task-create/handler.ts +49 -0
- package/src/tools/task-create/tool.ts +66 -0
- package/src/tools/task-get/handler.ts +38 -0
- package/src/tools/task-get/tool.ts +11 -0
- package/src/tools/task-list/handler.ts +33 -0
- package/src/tools/task-list/tool.ts +9 -0
- package/src/tools/task-update/handler.ts +79 -0
- package/src/tools/task-update/tool.ts +20 -0
- package/src/tools/write/tool.ts +26 -0
- package/src/workflow.ts +138 -0
- package/tsup.config.ts +20 -0
- package/dist/index.d.mts +0 -152
- package/dist/index.mjs +0 -1587
- package/dist/index.mjs.map +0 -1
- package/dist/workflow-7_MT-5-w.d.mts +0 -1203
- package/dist/workflow-7_MT-5-w.d.ts +0 -1203
- package/dist/workflow.d.mts +0 -4
- package/dist/workflow.mjs +0 -739
- package/dist/workflow.mjs.map +0 -1
package/dist/workflow.js
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var workflow = require('@temporalio/workflow');
|
|
4
|
-
var z2 = require('zod');
|
|
5
|
-
var minimatch = require('minimatch');
|
|
6
|
-
|
|
7
|
-
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
-
|
|
9
|
-
var z2__default = /*#__PURE__*/_interopDefault(z2);
|
|
1
|
+
import { defineQuery, proxyActivities, setHandler, workflowInfo, uuid4, executeChild } from '@temporalio/workflow';
|
|
2
|
+
import z4, { z } from 'zod';
|
|
10
3
|
|
|
11
4
|
// src/lib/session.ts
|
|
12
5
|
var TASK_TOOL = "Task";
|
|
@@ -41,24 +34,24 @@ function createTaskTool(subagents) {
|
|
|
41
34
|
return {
|
|
42
35
|
name: TASK_TOOL,
|
|
43
36
|
description: buildTaskDescription(subagents),
|
|
44
|
-
schema:
|
|
45
|
-
subagent:
|
|
46
|
-
description:
|
|
47
|
-
prompt:
|
|
37
|
+
schema: z4.object({
|
|
38
|
+
subagent: z4.enum(names).describe("The type of subagent to launch"),
|
|
39
|
+
description: z4.string().describe("A short (3-5 word) description of the task"),
|
|
40
|
+
prompt: z4.string().describe("The task for the agent to perform")
|
|
48
41
|
})
|
|
49
42
|
};
|
|
50
43
|
}
|
|
51
44
|
function createTaskHandler(subagents) {
|
|
52
|
-
const { workflowId: parentWorkflowId, taskQueue: parentTaskQueue } =
|
|
53
|
-
return async (args
|
|
45
|
+
const { workflowId: parentWorkflowId, taskQueue: parentTaskQueue } = workflowInfo();
|
|
46
|
+
return async (args) => {
|
|
54
47
|
const config = subagents.find((s) => s.name === args.subagent);
|
|
55
48
|
if (!config) {
|
|
56
49
|
throw new Error(
|
|
57
50
|
`Unknown subagent: ${args.subagent}. Available: ${subagents.map((s) => s.name).join(", ")}`
|
|
58
51
|
);
|
|
59
52
|
}
|
|
60
|
-
const childWorkflowId = `${parentWorkflowId}-${args.subagent}-${
|
|
61
|
-
const childResult = await
|
|
53
|
+
const childWorkflowId = `${parentWorkflowId}-${args.subagent}-${uuid4()}`;
|
|
54
|
+
const childResult = await executeChild(config.workflowType, {
|
|
62
55
|
workflowId: childWorkflowId,
|
|
63
56
|
args: [{ prompt: args.prompt }],
|
|
64
57
|
taskQueue: config.taskQueue ?? parentTaskQueue
|
|
@@ -74,35 +67,332 @@ function createTaskHandler(subagents) {
|
|
|
74
67
|
};
|
|
75
68
|
};
|
|
76
69
|
}
|
|
70
|
+
var createBashToolDescription = ({
|
|
71
|
+
fileTree
|
|
72
|
+
}) => `tool to execute bash commands, the file tree is: ${fileTree}`;
|
|
73
|
+
var bashTool = {
|
|
74
|
+
name: "Bash",
|
|
75
|
+
description: "tool to execute bash commands",
|
|
76
|
+
schema: z4.object({
|
|
77
|
+
command: z4.string().describe("stringified command to be executed inside the Bash")
|
|
78
|
+
}),
|
|
79
|
+
strict: true
|
|
80
|
+
};
|
|
81
|
+
var taskCreateTool = {
|
|
82
|
+
name: "TaskCreate",
|
|
83
|
+
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.
|
|
84
|
+
It also helps the user understand the progress of the task and overall progress of their requests.
|
|
85
|
+
|
|
86
|
+
## When to Use This Tool
|
|
87
|
+
|
|
88
|
+
Use this tool proactively in these scenarios:
|
|
89
|
+
|
|
90
|
+
- Complex multi-step tasks - When a task requires 3 or more distinct steps or actions
|
|
91
|
+
- Non-trivial and complex tasks - Tasks that require careful planning or multiple operations
|
|
92
|
+
- User explicitly requests todo list - When the user directly asks you to use the todo list
|
|
93
|
+
- User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated)
|
|
94
|
+
- After receiving new instructions - Immediately capture user requirements as tasks
|
|
95
|
+
- When you start working on a task - Mark it as in_progress BEFORE beginning work
|
|
96
|
+
- After completing a task - Mark it as completed and add any new follow-up tasks discovered during implementation
|
|
97
|
+
|
|
98
|
+
## When NOT to Use This Tool
|
|
99
|
+
|
|
100
|
+
Skip using this tool when:
|
|
101
|
+
- There is only a single, straightforward task
|
|
102
|
+
- The task is trivial and tracking it provides no organizational benefit
|
|
103
|
+
- The task can be completed in less than 3 trivial steps
|
|
104
|
+
- The task is purely conversational or informational
|
|
105
|
+
|
|
106
|
+
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.
|
|
107
|
+
|
|
108
|
+
## Task Fields
|
|
109
|
+
|
|
110
|
+
- **subject**: A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")
|
|
111
|
+
- **description**: Detailed description of what needs to be done, including context and acceptance criteria
|
|
112
|
+
- **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.
|
|
113
|
+
|
|
114
|
+
**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\`.
|
|
115
|
+
|
|
116
|
+
## Tips
|
|
117
|
+
|
|
118
|
+
- Create tasks with clear, specific subjects that describe the outcome
|
|
119
|
+
- Include enough detail in the description for another agent to understand and complete the task
|
|
120
|
+
- After creating tasks, use TaskUpdate to set up dependencies (blocks/blockedBy) if needed
|
|
121
|
+
- Check TaskList first to avoid creating duplicate tasks`,
|
|
122
|
+
schema: z4.object({
|
|
123
|
+
subject: z4.string().describe(
|
|
124
|
+
'A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")'
|
|
125
|
+
),
|
|
126
|
+
description: z4.string().describe(
|
|
127
|
+
"Detailed description of what needs to be done, including context and acceptance criteria"
|
|
128
|
+
),
|
|
129
|
+
activeForm: z4.string().describe(
|
|
130
|
+
'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.'
|
|
131
|
+
),
|
|
132
|
+
metadata: z4.record(z4.string(), z4.string()).describe("Arbitrary key-value pairs for tracking")
|
|
133
|
+
})
|
|
134
|
+
};
|
|
77
135
|
|
|
78
|
-
// src/lib/
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
136
|
+
// src/lib/tool-router.ts
|
|
137
|
+
var buildIntoolDefinitions = {
|
|
138
|
+
[bashTool.name]: bashTool,
|
|
139
|
+
[taskCreateTool.name]: taskCreateTool
|
|
140
|
+
};
|
|
141
|
+
function createToolRouter(options) {
|
|
142
|
+
const { appendToolResult } = proxyActivities({
|
|
143
|
+
startToCloseTimeout: "2m",
|
|
144
|
+
retry: {
|
|
145
|
+
maximumAttempts: 3,
|
|
146
|
+
initialInterval: "5s",
|
|
147
|
+
maximumInterval: "15m",
|
|
148
|
+
backoffCoefficient: 4
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
const toolMap = /* @__PURE__ */ new Map();
|
|
152
|
+
for (const [_key, tool] of Object.entries(options.tools)) {
|
|
153
|
+
toolMap.set(tool.name, tool);
|
|
154
|
+
}
|
|
155
|
+
if (options.subagents) {
|
|
156
|
+
toolMap.set("Task", {
|
|
157
|
+
...createTaskTool(options.subagents),
|
|
158
|
+
handler: createTaskHandler(options.subagents)
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
if (options.buildInTools) {
|
|
162
|
+
for (const [key, value] of Object.entries(options.buildInTools)) {
|
|
163
|
+
if (key === bashTool.name) {
|
|
164
|
+
toolMap.set(key, {
|
|
165
|
+
...buildIntoolDefinitions[key],
|
|
166
|
+
description: createBashToolDescription({
|
|
167
|
+
fileTree: options.fileTree
|
|
168
|
+
}),
|
|
169
|
+
handler: value
|
|
170
|
+
});
|
|
171
|
+
} else {
|
|
172
|
+
toolMap.set(key, {
|
|
173
|
+
...buildIntoolDefinitions[key],
|
|
174
|
+
handler: value
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
async function processToolCall(toolCall, turn, handlerContext) {
|
|
180
|
+
const startTime = Date.now();
|
|
181
|
+
let effectiveArgs = toolCall.args;
|
|
182
|
+
if (options.hooks?.onPreToolUse) {
|
|
183
|
+
const preResult = await options.hooks.onPreToolUse({
|
|
184
|
+
toolCall,
|
|
185
|
+
threadId: options.threadId,
|
|
186
|
+
turn
|
|
187
|
+
});
|
|
188
|
+
if (preResult?.skip) {
|
|
189
|
+
await appendToolResult({
|
|
190
|
+
threadId: options.threadId,
|
|
191
|
+
toolCallId: toolCall.id,
|
|
192
|
+
content: JSON.stringify({
|
|
193
|
+
skipped: true,
|
|
194
|
+
reason: "Skipped by PreToolUse hook"
|
|
195
|
+
})
|
|
196
|
+
});
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
if (preResult?.modifiedArgs !== void 0) {
|
|
200
|
+
effectiveArgs = preResult.modifiedArgs;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const tool = toolMap.get(toolCall.name);
|
|
204
|
+
let result;
|
|
205
|
+
let content;
|
|
206
|
+
try {
|
|
207
|
+
if (tool) {
|
|
208
|
+
const response = await tool.handler(
|
|
209
|
+
effectiveArgs,
|
|
210
|
+
handlerContext ?? {}
|
|
211
|
+
);
|
|
212
|
+
result = response.result;
|
|
213
|
+
content = response.content;
|
|
214
|
+
} else {
|
|
215
|
+
result = { error: `Unknown tool: ${toolCall.name}` };
|
|
216
|
+
content = JSON.stringify(result, null, 2);
|
|
217
|
+
}
|
|
218
|
+
} catch (error) {
|
|
219
|
+
if (options.hooks?.onPostToolUseFailure) {
|
|
220
|
+
const failureResult = await options.hooks.onPostToolUseFailure({
|
|
221
|
+
toolCall,
|
|
222
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
223
|
+
threadId: options.threadId,
|
|
224
|
+
turn
|
|
225
|
+
});
|
|
226
|
+
if (failureResult?.fallbackContent !== void 0) {
|
|
227
|
+
content = failureResult.fallbackContent;
|
|
228
|
+
result = { error: String(error), recovered: true };
|
|
229
|
+
} else if (failureResult?.suppress) {
|
|
230
|
+
content = JSON.stringify({ error: String(error), suppressed: true });
|
|
231
|
+
result = { error: String(error), suppressed: true };
|
|
232
|
+
} else {
|
|
233
|
+
throw error;
|
|
234
|
+
}
|
|
235
|
+
} else {
|
|
236
|
+
throw error;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
await appendToolResult({
|
|
240
|
+
threadId: options.threadId,
|
|
241
|
+
toolCallId: toolCall.id,
|
|
242
|
+
content
|
|
243
|
+
});
|
|
244
|
+
const toolResult = {
|
|
245
|
+
toolCallId: toolCall.id,
|
|
246
|
+
name: toolCall.name,
|
|
247
|
+
result
|
|
248
|
+
};
|
|
249
|
+
if (options.hooks?.onPostToolUse) {
|
|
250
|
+
const durationMs = Date.now() - startTime;
|
|
251
|
+
await options.hooks.onPostToolUse({
|
|
252
|
+
toolCall,
|
|
253
|
+
result: toolResult,
|
|
254
|
+
threadId: options.threadId,
|
|
255
|
+
turn,
|
|
256
|
+
durationMs
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
return toolResult;
|
|
82
260
|
}
|
|
83
|
-
const taskTool = createTaskTool(config.subagents);
|
|
84
|
-
const taskHandler = createTaskHandler(config.subagents);
|
|
85
261
|
return {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
262
|
+
// --- Methods from registry ---
|
|
263
|
+
hasTools() {
|
|
264
|
+
return toolMap.size > 0;
|
|
265
|
+
},
|
|
266
|
+
parseToolCall(toolCall) {
|
|
267
|
+
const tool = toolMap.get(toolCall.name);
|
|
268
|
+
if (!tool) {
|
|
269
|
+
throw new Error(`Tool ${toolCall.name} not found`);
|
|
270
|
+
}
|
|
271
|
+
const parsedArgs = tool.schema.parse(toolCall.args);
|
|
272
|
+
return {
|
|
273
|
+
id: toolCall.id ?? "",
|
|
274
|
+
name: toolCall.name,
|
|
275
|
+
args: parsedArgs
|
|
276
|
+
};
|
|
277
|
+
},
|
|
278
|
+
hasTool(name) {
|
|
279
|
+
return toolMap.has(name);
|
|
280
|
+
},
|
|
281
|
+
getToolNames() {
|
|
282
|
+
return Array.from(toolMap.keys());
|
|
283
|
+
},
|
|
284
|
+
getToolDefinitions() {
|
|
285
|
+
return Array.from(toolMap).map(([name, tool]) => ({
|
|
286
|
+
name,
|
|
287
|
+
description: tool.description,
|
|
288
|
+
schema: tool.schema,
|
|
289
|
+
strict: tool.strict,
|
|
290
|
+
max_uses: tool.max_uses
|
|
291
|
+
}));
|
|
292
|
+
},
|
|
293
|
+
// --- Methods for processing tool calls ---
|
|
294
|
+
async processToolCalls(toolCalls, context) {
|
|
295
|
+
if (toolCalls.length === 0) {
|
|
296
|
+
return [];
|
|
297
|
+
}
|
|
298
|
+
const turn = context?.turn ?? 0;
|
|
299
|
+
const handlerContext = context?.handlerContext;
|
|
300
|
+
if (options.parallel) {
|
|
301
|
+
const results2 = await Promise.all(
|
|
302
|
+
toolCalls.map((tc) => processToolCall(tc, turn, handlerContext))
|
|
303
|
+
);
|
|
304
|
+
return results2.filter(
|
|
305
|
+
(r) => r !== null
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
const results = [];
|
|
309
|
+
for (const toolCall of toolCalls) {
|
|
310
|
+
const result = await processToolCall(toolCall, turn, handlerContext);
|
|
311
|
+
if (result !== null) {
|
|
312
|
+
results.push(result);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return results;
|
|
316
|
+
},
|
|
317
|
+
async processToolCallsByName(toolCalls, toolName, handler, context) {
|
|
318
|
+
const matchingCalls = toolCalls.filter((tc) => tc.name === toolName);
|
|
319
|
+
if (matchingCalls.length === 0) {
|
|
320
|
+
return [];
|
|
321
|
+
}
|
|
322
|
+
const handlerContext = context?.handlerContext ?? {};
|
|
323
|
+
const processOne = async (toolCall) => {
|
|
324
|
+
const response = await handler(
|
|
325
|
+
toolCall.args,
|
|
326
|
+
handlerContext
|
|
327
|
+
);
|
|
328
|
+
await appendToolResult({
|
|
329
|
+
threadId: options.threadId,
|
|
330
|
+
toolCallId: toolCall.id,
|
|
331
|
+
content: response.content
|
|
332
|
+
});
|
|
333
|
+
return {
|
|
334
|
+
toolCallId: toolCall.id,
|
|
335
|
+
name: toolCall.name,
|
|
336
|
+
result: response.result
|
|
337
|
+
};
|
|
338
|
+
};
|
|
339
|
+
if (options.parallel) {
|
|
340
|
+
return Promise.all(matchingCalls.map(processOne));
|
|
341
|
+
}
|
|
342
|
+
const results = [];
|
|
343
|
+
for (const toolCall of matchingCalls) {
|
|
344
|
+
results.push(await processOne(toolCall));
|
|
345
|
+
}
|
|
346
|
+
return results;
|
|
89
347
|
},
|
|
90
|
-
|
|
348
|
+
// --- Utility methods ---
|
|
349
|
+
filterByName(toolCalls, name) {
|
|
350
|
+
return toolCalls.filter(
|
|
351
|
+
(tc) => tc.name === name
|
|
352
|
+
);
|
|
353
|
+
},
|
|
354
|
+
hasToolCall(toolCalls, name) {
|
|
355
|
+
return toolCalls.some((tc) => tc.name === name);
|
|
356
|
+
},
|
|
357
|
+
getResultsByName(results, name) {
|
|
358
|
+
return results.filter((r) => r.name === name);
|
|
359
|
+
}
|
|
91
360
|
};
|
|
92
361
|
}
|
|
93
|
-
function
|
|
94
|
-
return
|
|
362
|
+
function hasNoOtherToolCalls(toolCalls, excludeName) {
|
|
363
|
+
return toolCalls.filter((tc) => tc.name !== excludeName).length === 0;
|
|
95
364
|
}
|
|
96
365
|
|
|
97
366
|
// src/lib/session.ts
|
|
98
|
-
|
|
367
|
+
async function resolvePrompt(prompt) {
|
|
368
|
+
if (typeof prompt === "function") {
|
|
369
|
+
return prompt();
|
|
370
|
+
}
|
|
371
|
+
return prompt;
|
|
372
|
+
}
|
|
373
|
+
var createSession = async ({
|
|
374
|
+
threadId,
|
|
375
|
+
agentName,
|
|
376
|
+
maxTurns = 50,
|
|
377
|
+
metadata = {},
|
|
99
378
|
runAgent,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
379
|
+
baseSystemPrompt,
|
|
380
|
+
instructionsPrompt,
|
|
381
|
+
buildContextMessage,
|
|
382
|
+
buildFileTree = async () => "",
|
|
383
|
+
subagents,
|
|
384
|
+
tools = {},
|
|
385
|
+
processToolsInParallel = true,
|
|
386
|
+
buildInTools = {},
|
|
103
387
|
hooks = {}
|
|
104
388
|
}) => {
|
|
105
|
-
const {
|
|
389
|
+
const {
|
|
390
|
+
initializeThread,
|
|
391
|
+
appendHumanMessage,
|
|
392
|
+
parseToolCalls,
|
|
393
|
+
appendToolResult,
|
|
394
|
+
appendSystemMessage
|
|
395
|
+
} = proxyActivities({
|
|
106
396
|
startToCloseTimeout: "30m",
|
|
107
397
|
retry: {
|
|
108
398
|
maximumAttempts: 6,
|
|
@@ -112,6 +402,16 @@ var createSession = async ({ threadId, agentName, maxTurns = 50, metadata = {} }
|
|
|
112
402
|
},
|
|
113
403
|
heartbeatTimeout: "5m"
|
|
114
404
|
});
|
|
405
|
+
const fileTree = await buildFileTree();
|
|
406
|
+
const toolRouter = createToolRouter({
|
|
407
|
+
tools,
|
|
408
|
+
threadId,
|
|
409
|
+
hooks,
|
|
410
|
+
buildInTools,
|
|
411
|
+
fileTree,
|
|
412
|
+
subagents,
|
|
413
|
+
parallel: processToolsInParallel
|
|
414
|
+
});
|
|
115
415
|
const callSessionEnd = async (exitReason, turns) => {
|
|
116
416
|
if (hooks.onSessionEnd) {
|
|
117
417
|
await hooks.onSessionEnd({
|
|
@@ -124,7 +424,7 @@ var createSession = async ({ threadId, agentName, maxTurns = 50, metadata = {} }
|
|
|
124
424
|
}
|
|
125
425
|
};
|
|
126
426
|
return {
|
|
127
|
-
runSession: async (
|
|
427
|
+
runSession: async ({ stateManager }) => {
|
|
128
428
|
if (hooks.onSessionStart) {
|
|
129
429
|
await hooks.onSessionStart({
|
|
130
430
|
threadId,
|
|
@@ -132,43 +432,54 @@ var createSession = async ({ threadId, agentName, maxTurns = 50, metadata = {} }
|
|
|
132
432
|
metadata
|
|
133
433
|
});
|
|
134
434
|
}
|
|
435
|
+
stateManager.setTools(toolRouter.getToolDefinitions());
|
|
135
436
|
await initializeThread(threadId);
|
|
136
|
-
await
|
|
437
|
+
await appendSystemMessage(
|
|
137
438
|
threadId,
|
|
138
|
-
|
|
439
|
+
[
|
|
440
|
+
await resolvePrompt(baseSystemPrompt),
|
|
441
|
+
await resolvePrompt(instructionsPrompt)
|
|
442
|
+
].join("\n")
|
|
139
443
|
);
|
|
444
|
+
await appendHumanMessage(threadId, await buildContextMessage());
|
|
140
445
|
let exitReason = "completed";
|
|
141
446
|
try {
|
|
142
447
|
while (stateManager.isRunning() && !stateManager.isTerminal() && stateManager.getTurns() < maxTurns) {
|
|
143
448
|
stateManager.incrementTurns();
|
|
144
449
|
const currentTurn = stateManager.getTurns();
|
|
145
|
-
const { message, stopReason } = await runAgent(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
systemPrompt: await promptManager.getSystemPrompt()
|
|
153
|
-
}
|
|
154
|
-
);
|
|
450
|
+
const { message, stopReason } = await runAgent({
|
|
451
|
+
threadId,
|
|
452
|
+
agentName,
|
|
453
|
+
metadata
|
|
454
|
+
});
|
|
155
455
|
if (stopReason === "end_turn") {
|
|
156
456
|
stateManager.complete();
|
|
157
457
|
exitReason = "completed";
|
|
158
458
|
return message;
|
|
159
459
|
}
|
|
160
|
-
if (!toolRouter
|
|
460
|
+
if (!toolRouter.hasTools()) {
|
|
161
461
|
stateManager.complete();
|
|
162
462
|
exitReason = "completed";
|
|
163
463
|
return message;
|
|
164
464
|
}
|
|
165
465
|
const rawToolCalls = await parseToolCalls(message);
|
|
166
|
-
const parsedToolCalls = rawToolCalls.map(
|
|
167
|
-
|
|
466
|
+
const parsedToolCalls = rawToolCalls.filter((tc) => tc.name !== "Task").map((tc) => toolRouter.parseToolCall(tc));
|
|
467
|
+
const taskToolCalls = subagents && subagents.length > 0 ? rawToolCalls.filter((tc) => tc.name === "Task").map((tc) => {
|
|
468
|
+
const parsedArgs = createTaskTool(subagents).schema.parse(
|
|
469
|
+
tc.args
|
|
470
|
+
);
|
|
471
|
+
return {
|
|
472
|
+
id: tc.id ?? "",
|
|
473
|
+
name: tc.name,
|
|
474
|
+
args: parsedArgs
|
|
475
|
+
};
|
|
476
|
+
}) : [];
|
|
477
|
+
await toolRouter.processToolCalls(
|
|
478
|
+
[...parsedToolCalls, ...taskToolCalls],
|
|
479
|
+
{
|
|
480
|
+
turn: currentTurn
|
|
481
|
+
}
|
|
168
482
|
);
|
|
169
|
-
await toolRouter.processToolCalls(parsedToolCalls, {
|
|
170
|
-
turn: currentTurn
|
|
171
|
-
});
|
|
172
483
|
if (stateManager.getStatus() === "WAITING_FOR_INPUT") {
|
|
173
484
|
exitReason = "waiting_for_input";
|
|
174
485
|
break;
|
|
@@ -194,19 +505,34 @@ function isTerminalStatus(status) {
|
|
|
194
505
|
}
|
|
195
506
|
|
|
196
507
|
// src/lib/state-manager.ts
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
let
|
|
200
|
-
let
|
|
201
|
-
|
|
508
|
+
var getStateQuery = defineQuery("getState");
|
|
509
|
+
function createAgentStateManager(initialState) {
|
|
510
|
+
let status = initialState?.status ?? "RUNNING";
|
|
511
|
+
let version = initialState?.version ?? 0;
|
|
512
|
+
let turns = initialState?.turns ?? 0;
|
|
513
|
+
let tools = initialState?.tools ?? [];
|
|
514
|
+
const tasks = new Map(initialState?.tasks);
|
|
515
|
+
const {
|
|
516
|
+
status: _,
|
|
517
|
+
version: __,
|
|
518
|
+
turns: ___,
|
|
519
|
+
tasks: ____,
|
|
520
|
+
tools: _____,
|
|
521
|
+
...custom
|
|
522
|
+
} = initialState ?? {};
|
|
523
|
+
const customState = custom;
|
|
202
524
|
function buildState() {
|
|
203
525
|
return {
|
|
204
526
|
status,
|
|
205
527
|
version,
|
|
206
528
|
turns,
|
|
529
|
+
tools,
|
|
207
530
|
...customState
|
|
208
531
|
};
|
|
209
532
|
}
|
|
533
|
+
setHandler(getStateQuery, () => {
|
|
534
|
+
return buildState();
|
|
535
|
+
});
|
|
210
536
|
return {
|
|
211
537
|
getStatus() {
|
|
212
538
|
return status;
|
|
@@ -261,222 +587,34 @@ function createAgentStateManager(config) {
|
|
|
261
587
|
},
|
|
262
588
|
shouldReturnFromWait(lastKnownVersion) {
|
|
263
589
|
return version > lastKnownVersion || isTerminalStatus(status);
|
|
264
|
-
}
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
var AGENT_HANDLER_NAMES = {
|
|
268
|
-
getAgentState: "getAgentState",
|
|
269
|
-
waitForStateChange: "waitForStateChange",
|
|
270
|
-
addMessage: "addMessage"
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
// src/lib/prompt-manager.ts
|
|
274
|
-
function createPromptManager(config) {
|
|
275
|
-
const { baseSystemPrompt, instructionsPrompt, buildContextMessage } = config;
|
|
276
|
-
async function resolvePrompt(prompt) {
|
|
277
|
-
if (typeof prompt === "function") {
|
|
278
|
-
return prompt();
|
|
279
|
-
}
|
|
280
|
-
return prompt;
|
|
281
|
-
}
|
|
282
|
-
return {
|
|
283
|
-
async getSystemPrompt() {
|
|
284
|
-
const base = await resolvePrompt(baseSystemPrompt);
|
|
285
|
-
const instructions = await resolvePrompt(instructionsPrompt);
|
|
286
|
-
return [base, instructions].join("\n");
|
|
287
|
-
},
|
|
288
|
-
async buildContextMessage(context) {
|
|
289
|
-
return buildContextMessage(context);
|
|
290
|
-
}
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// src/lib/tool-registry.ts
|
|
295
|
-
function createToolRegistry(tools) {
|
|
296
|
-
const toolMap = /* @__PURE__ */ new Map();
|
|
297
|
-
for (const [_key, tool] of Object.entries(tools)) {
|
|
298
|
-
toolMap.set(tool.name, tool);
|
|
299
|
-
}
|
|
300
|
-
return {
|
|
301
|
-
parseToolCall(toolCall) {
|
|
302
|
-
const tool = toolMap.get(toolCall.name);
|
|
303
|
-
if (!tool) {
|
|
304
|
-
throw new Error(`Tool ${toolCall.name} not found`);
|
|
305
|
-
}
|
|
306
|
-
const parsedArgs = tool.schema.parse(toolCall.args);
|
|
307
|
-
return {
|
|
308
|
-
id: toolCall.id ?? "",
|
|
309
|
-
name: toolCall.name,
|
|
310
|
-
args: parsedArgs
|
|
311
|
-
};
|
|
312
590
|
},
|
|
313
|
-
|
|
314
|
-
return
|
|
591
|
+
getTasks() {
|
|
592
|
+
return Array.from(tasks.values());
|
|
315
593
|
},
|
|
316
|
-
|
|
317
|
-
return
|
|
594
|
+
getTask(id) {
|
|
595
|
+
return tasks.get(id);
|
|
318
596
|
},
|
|
319
|
-
|
|
320
|
-
|
|
597
|
+
setTask(task) {
|
|
598
|
+
tasks.set(task.id, task);
|
|
599
|
+
version++;
|
|
321
600
|
},
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
// src/lib/tool-router.ts
|
|
329
|
-
function createToolRouter(options, handlers) {
|
|
330
|
-
const { parallel = true, threadId, appendToolResult, hooks } = options;
|
|
331
|
-
async function processToolCall(toolCall, turn) {
|
|
332
|
-
const startTime = Date.now();
|
|
333
|
-
let effectiveArgs = toolCall.args;
|
|
334
|
-
if (hooks?.onPreToolUse) {
|
|
335
|
-
const preResult = await hooks.onPreToolUse({
|
|
336
|
-
toolCall,
|
|
337
|
-
threadId,
|
|
338
|
-
turn
|
|
339
|
-
});
|
|
340
|
-
if (preResult?.skip) {
|
|
341
|
-
await appendToolResult({
|
|
342
|
-
threadId,
|
|
343
|
-
toolCallId: toolCall.id,
|
|
344
|
-
content: JSON.stringify({
|
|
345
|
-
skipped: true,
|
|
346
|
-
reason: "Skipped by PreToolUse hook"
|
|
347
|
-
})
|
|
348
|
-
});
|
|
349
|
-
return null;
|
|
350
|
-
}
|
|
351
|
-
if (preResult?.modifiedArgs !== void 0) {
|
|
352
|
-
effectiveArgs = preResult.modifiedArgs;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
const handler = handlers[toolCall.name];
|
|
356
|
-
let result;
|
|
357
|
-
let content;
|
|
358
|
-
try {
|
|
359
|
-
if (handler) {
|
|
360
|
-
const response = await handler(
|
|
361
|
-
effectiveArgs,
|
|
362
|
-
toolCall.id
|
|
363
|
-
);
|
|
364
|
-
result = response.result;
|
|
365
|
-
content = response.content;
|
|
366
|
-
} else {
|
|
367
|
-
result = { error: `Unknown tool: ${toolCall.name}` };
|
|
368
|
-
content = JSON.stringify(result, null, 2);
|
|
369
|
-
}
|
|
370
|
-
} catch (error) {
|
|
371
|
-
if (hooks?.onPostToolUseFailure) {
|
|
372
|
-
const failureResult = await hooks.onPostToolUseFailure({
|
|
373
|
-
toolCall,
|
|
374
|
-
error: error instanceof Error ? error : new Error(String(error)),
|
|
375
|
-
threadId,
|
|
376
|
-
turn
|
|
377
|
-
});
|
|
378
|
-
if (failureResult?.fallbackContent !== void 0) {
|
|
379
|
-
content = failureResult.fallbackContent;
|
|
380
|
-
result = { error: String(error), recovered: true };
|
|
381
|
-
} else if (failureResult?.suppress) {
|
|
382
|
-
content = JSON.stringify({ error: String(error), suppressed: true });
|
|
383
|
-
result = { error: String(error), suppressed: true };
|
|
384
|
-
} else {
|
|
385
|
-
throw error;
|
|
386
|
-
}
|
|
387
|
-
} else {
|
|
388
|
-
throw error;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
await appendToolResult({ threadId, toolCallId: toolCall.id, content });
|
|
392
|
-
const toolResult = {
|
|
393
|
-
toolCallId: toolCall.id,
|
|
394
|
-
name: toolCall.name,
|
|
395
|
-
result
|
|
396
|
-
};
|
|
397
|
-
if (hooks?.onPostToolUse) {
|
|
398
|
-
const durationMs = Date.now() - startTime;
|
|
399
|
-
await hooks.onPostToolUse({
|
|
400
|
-
toolCall,
|
|
401
|
-
result: toolResult,
|
|
402
|
-
threadId,
|
|
403
|
-
turn,
|
|
404
|
-
durationMs
|
|
405
|
-
});
|
|
406
|
-
}
|
|
407
|
-
return toolResult;
|
|
408
|
-
}
|
|
409
|
-
return {
|
|
410
|
-
async processToolCalls(toolCalls, context) {
|
|
411
|
-
if (toolCalls.length === 0) {
|
|
412
|
-
return [];
|
|
413
|
-
}
|
|
414
|
-
const turn = context?.turn ?? 0;
|
|
415
|
-
if (parallel) {
|
|
416
|
-
const results2 = await Promise.all(
|
|
417
|
-
toolCalls.map((tc) => processToolCall(tc, turn))
|
|
418
|
-
);
|
|
419
|
-
return results2.filter(
|
|
420
|
-
(r) => r !== null
|
|
421
|
-
);
|
|
422
|
-
}
|
|
423
|
-
const results = [];
|
|
424
|
-
for (const toolCall of toolCalls) {
|
|
425
|
-
const result = await processToolCall(toolCall, turn);
|
|
426
|
-
if (result !== null) {
|
|
427
|
-
results.push(result);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
return results;
|
|
601
|
+
setTools(newTools) {
|
|
602
|
+
tools = newTools;
|
|
431
603
|
},
|
|
432
|
-
|
|
433
|
-
const
|
|
434
|
-
if (
|
|
435
|
-
|
|
436
|
-
}
|
|
437
|
-
const processOne = async (toolCall) => {
|
|
438
|
-
const response = await handler(
|
|
439
|
-
toolCall.args,
|
|
440
|
-
toolCall.id
|
|
441
|
-
);
|
|
442
|
-
await appendToolResult({
|
|
443
|
-
threadId,
|
|
444
|
-
toolCallId: toolCall.id,
|
|
445
|
-
content: response.content
|
|
446
|
-
});
|
|
447
|
-
return {
|
|
448
|
-
toolCallId: toolCall.id,
|
|
449
|
-
name: toolCall.name,
|
|
450
|
-
result: response.result
|
|
451
|
-
};
|
|
452
|
-
};
|
|
453
|
-
if (parallel) {
|
|
454
|
-
return Promise.all(matchingCalls.map(processOne));
|
|
455
|
-
}
|
|
456
|
-
const results = [];
|
|
457
|
-
for (const toolCall of matchingCalls) {
|
|
458
|
-
results.push(await processOne(toolCall));
|
|
604
|
+
deleteTask(id) {
|
|
605
|
+
const deleted = tasks.delete(id);
|
|
606
|
+
if (deleted) {
|
|
607
|
+
version++;
|
|
459
608
|
}
|
|
460
|
-
return
|
|
461
|
-
},
|
|
462
|
-
filterByName(toolCalls, name) {
|
|
463
|
-
return toolCalls.filter(
|
|
464
|
-
(tc) => tc.name === name
|
|
465
|
-
);
|
|
466
|
-
},
|
|
467
|
-
hasToolCall(toolCalls, name) {
|
|
468
|
-
return toolCalls.some((tc) => tc.name === name);
|
|
469
|
-
},
|
|
470
|
-
getResultsByName(results, name) {
|
|
471
|
-
return results.filter(
|
|
472
|
-
(r) => r.name === name
|
|
473
|
-
);
|
|
609
|
+
return deleted;
|
|
474
610
|
}
|
|
475
611
|
};
|
|
476
612
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
613
|
+
var AGENT_HANDLER_NAMES = {
|
|
614
|
+
getAgentState: "getAgentState",
|
|
615
|
+
waitForStateChange: "waitForStateChange",
|
|
616
|
+
addMessage: "addMessage"
|
|
617
|
+
};
|
|
480
618
|
var askUserQuestionTool = {
|
|
481
619
|
name: "AskUserQuestion",
|
|
482
620
|
description: `Use this tool when you need to ask the user questions during execution. This allows you to:
|
|
@@ -492,18 +630,18 @@ Usage notes:
|
|
|
492
630
|
* Use multiSelect: true to allow multiple answers to be selected for a question
|
|
493
631
|
* If you recommend a specific option, make that the first option in the list and add "(Recommended)" at the end of the label
|
|
494
632
|
`,
|
|
495
|
-
schema:
|
|
496
|
-
questions:
|
|
497
|
-
|
|
498
|
-
question:
|
|
499
|
-
header:
|
|
500
|
-
options:
|
|
501
|
-
|
|
502
|
-
label:
|
|
503
|
-
description:
|
|
633
|
+
schema: z4.object({
|
|
634
|
+
questions: z4.array(
|
|
635
|
+
z4.object({
|
|
636
|
+
question: z4.string().describe("The full question text to display"),
|
|
637
|
+
header: z4.string().describe("Short label for the question (max 12 characters)"),
|
|
638
|
+
options: z4.array(
|
|
639
|
+
z4.object({
|
|
640
|
+
label: z4.string(),
|
|
641
|
+
description: z4.string()
|
|
504
642
|
})
|
|
505
643
|
).min(0).max(4).describe("Array of 0-4 choices, each with label and description"),
|
|
506
|
-
multiSelect:
|
|
644
|
+
multiSelect: z4.boolean().describe("If true, users can select multiple options")
|
|
507
645
|
})
|
|
508
646
|
)
|
|
509
647
|
}),
|
|
@@ -523,9 +661,9 @@ Examples:
|
|
|
523
661
|
- "**/*.test.ts" - Find all test files recursively
|
|
524
662
|
- "src/**/*.ts" - Find all TypeScript files in src directory
|
|
525
663
|
`,
|
|
526
|
-
schema:
|
|
527
|
-
pattern:
|
|
528
|
-
root:
|
|
664
|
+
schema: z.object({
|
|
665
|
+
pattern: z.string().describe("Glob pattern to match files against"),
|
|
666
|
+
root: z.string().optional().describe("Optional root directory to search from")
|
|
529
667
|
}),
|
|
530
668
|
strict: true
|
|
531
669
|
};
|
|
@@ -543,13 +681,13 @@ Examples:
|
|
|
543
681
|
- Search for function definitions with "function.*handleClick"
|
|
544
682
|
- Search case-insensitively with ignoreCase: true
|
|
545
683
|
`,
|
|
546
|
-
schema:
|
|
547
|
-
pattern:
|
|
548
|
-
ignoreCase:
|
|
549
|
-
maxMatches:
|
|
550
|
-
includePatterns:
|
|
551
|
-
excludePatterns:
|
|
552
|
-
contextLines:
|
|
684
|
+
schema: z.object({
|
|
685
|
+
pattern: z.string().describe("Regex pattern to search for in file contents"),
|
|
686
|
+
ignoreCase: z.boolean().optional().describe("Case-insensitive search (default: false)"),
|
|
687
|
+
maxMatches: z.number().optional().describe("Maximum number of matches to return (default: 50)"),
|
|
688
|
+
includePatterns: z.array(z.string()).optional().describe("Glob patterns to include (e.g., ['*.ts', '*.js'])"),
|
|
689
|
+
excludePatterns: z.array(z.string()).optional().describe("Glob patterns to exclude (e.g., ['*.test.ts'])"),
|
|
690
|
+
contextLines: z.number().optional().describe("Number of context lines to show around matches")
|
|
553
691
|
}),
|
|
554
692
|
strict: true
|
|
555
693
|
};
|
|
@@ -567,12 +705,12 @@ The tool returns the file content in an appropriate format:
|
|
|
567
705
|
- Images: Base64-encoded image data
|
|
568
706
|
- PDFs: Extracted text content
|
|
569
707
|
`,
|
|
570
|
-
schema:
|
|
571
|
-
path:
|
|
572
|
-
offset:
|
|
708
|
+
schema: z.object({
|
|
709
|
+
path: z.string().describe("Virtual path to the file to read"),
|
|
710
|
+
offset: z.number().optional().describe(
|
|
573
711
|
"Line number to start reading from (1-indexed, for text files)"
|
|
574
712
|
),
|
|
575
|
-
limit:
|
|
713
|
+
limit: z.number().optional().describe("Maximum number of lines to read (for text files)")
|
|
576
714
|
}),
|
|
577
715
|
strict: true
|
|
578
716
|
};
|
|
@@ -590,9 +728,9 @@ IMPORTANT:
|
|
|
590
728
|
- This is an atomic write operation - the entire file is replaced
|
|
591
729
|
- Path must be absolute (e.g., "/docs/readme.md", not "docs/readme.md")
|
|
592
730
|
`,
|
|
593
|
-
schema:
|
|
594
|
-
file_path:
|
|
595
|
-
content:
|
|
731
|
+
schema: z.object({
|
|
732
|
+
file_path: z.string().describe("The absolute virtual path to the file to write"),
|
|
733
|
+
content: z.string().describe("The content to write to the file")
|
|
596
734
|
}),
|
|
597
735
|
strict: true
|
|
598
736
|
};
|
|
@@ -612,156 +750,138 @@ IMPORTANT:
|
|
|
612
750
|
- The operation fails if old_string is not found
|
|
613
751
|
- old_string and new_string must be different
|
|
614
752
|
`,
|
|
615
|
-
schema:
|
|
616
|
-
file_path:
|
|
617
|
-
old_string:
|
|
618
|
-
new_string:
|
|
753
|
+
schema: z.object({
|
|
754
|
+
file_path: z.string().describe("The absolute virtual path to the file to modify"),
|
|
755
|
+
old_string: z.string().describe("The exact text to replace"),
|
|
756
|
+
new_string: z.string().describe(
|
|
619
757
|
"The text to replace it with (must be different from old_string)"
|
|
620
758
|
),
|
|
621
|
-
replace_all:
|
|
759
|
+
replace_all: z.boolean().optional().describe(
|
|
622
760
|
"If true, replace all occurrences of old_string (default: false)"
|
|
623
761
|
)
|
|
624
762
|
}),
|
|
625
763
|
strict: true
|
|
626
764
|
};
|
|
627
765
|
|
|
628
|
-
// src/
|
|
629
|
-
function
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
]
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
return false;
|
|
651
|
-
}
|
|
652
|
-
return excludePatterns.some((pattern) => minimatch.minimatch(path, pattern));
|
|
766
|
+
// src/tools/task-create/handler.ts
|
|
767
|
+
function createTaskCreateHandler({
|
|
768
|
+
stateManager,
|
|
769
|
+
idGenerator
|
|
770
|
+
}) {
|
|
771
|
+
return (args) => {
|
|
772
|
+
const task = {
|
|
773
|
+
id: idGenerator(),
|
|
774
|
+
subject: args.subject,
|
|
775
|
+
description: args.description,
|
|
776
|
+
activeForm: args.activeForm,
|
|
777
|
+
status: "pending",
|
|
778
|
+
metadata: args.metadata ?? {},
|
|
779
|
+
blockedBy: [],
|
|
780
|
+
blocks: []
|
|
781
|
+
};
|
|
782
|
+
stateManager.setTask(task);
|
|
783
|
+
return {
|
|
784
|
+
content: JSON.stringify(task, null, 2),
|
|
785
|
+
result: task
|
|
786
|
+
};
|
|
787
|
+
};
|
|
653
788
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
line += ` [${node.mimeType}]`;
|
|
672
|
-
}
|
|
673
|
-
if (options.showDescriptions !== false && node.description) {
|
|
674
|
-
line += ` - ${node.description}`;
|
|
675
|
-
}
|
|
676
|
-
lines.push(line);
|
|
677
|
-
if (node.type === "directory" && node.children) {
|
|
678
|
-
const childIndent = indent + " ";
|
|
679
|
-
for (const child of node.children) {
|
|
680
|
-
lines.push(...renderNode(child, options, depth + 1, childIndent));
|
|
789
|
+
var taskGetTool = {
|
|
790
|
+
name: "TaskGet",
|
|
791
|
+
description: `Retrieve full task details including dependencies.`,
|
|
792
|
+
schema: z4.object({
|
|
793
|
+
taskId: z4.string().describe("The ID of the task to get")
|
|
794
|
+
})
|
|
795
|
+
};
|
|
796
|
+
|
|
797
|
+
// src/tools/task-get/handler.ts
|
|
798
|
+
function createTaskGetHandler(stateManager) {
|
|
799
|
+
return (args) => {
|
|
800
|
+
const task = stateManager.getTask(args.taskId) ?? null;
|
|
801
|
+
if (!task) {
|
|
802
|
+
return {
|
|
803
|
+
content: JSON.stringify({ error: `Task not found: ${args.taskId}` }),
|
|
804
|
+
result: null
|
|
805
|
+
};
|
|
681
806
|
}
|
|
682
|
-
|
|
683
|
-
|
|
807
|
+
return {
|
|
808
|
+
content: JSON.stringify(task, null, 2),
|
|
809
|
+
result: task
|
|
810
|
+
};
|
|
811
|
+
};
|
|
684
812
|
}
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
lines.push(...renderNode(node, options, 0, ""));
|
|
691
|
-
}
|
|
692
|
-
if (lines.length === 0) {
|
|
693
|
-
return `<file_system>
|
|
694
|
-
${header}
|
|
695
|
-
|
|
696
|
-
${description}
|
|
697
|
-
|
|
698
|
-
(no files available)
|
|
699
|
-
</file_system>`;
|
|
700
|
-
}
|
|
701
|
-
return `<file_system>
|
|
702
|
-
${header}
|
|
813
|
+
var taskListTool = {
|
|
814
|
+
name: "TaskList",
|
|
815
|
+
description: `List all tasks with current state.`,
|
|
816
|
+
schema: z4.object({})
|
|
817
|
+
};
|
|
703
818
|
|
|
704
|
-
|
|
705
|
-
|
|
819
|
+
// src/tools/task-list/handler.ts
|
|
820
|
+
function createTaskListHandler(stateManager) {
|
|
821
|
+
return (_args) => {
|
|
822
|
+
const taskList = stateManager.getTasks();
|
|
823
|
+
return {
|
|
824
|
+
content: JSON.stringify(taskList, null, 2),
|
|
825
|
+
result: taskList
|
|
826
|
+
};
|
|
827
|
+
};
|
|
706
828
|
}
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
829
|
+
var taskUpdateTool = {
|
|
830
|
+
name: "TaskUpdate",
|
|
831
|
+
description: `Update status, add blockers, modify details.`,
|
|
832
|
+
schema: z4.object({
|
|
833
|
+
taskId: z4.string().describe("The ID of the task to get"),
|
|
834
|
+
status: z4.enum(["pending", "in_progress", "completed"]).describe("The status of the task"),
|
|
835
|
+
addBlockedBy: z4.array(z4.string()).describe("The IDs of the tasks that are blocking this task"),
|
|
836
|
+
addBlocks: z4.array(z4.string()).describe("The IDs of the tasks that this task is blocking")
|
|
837
|
+
})
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
// src/tools/task-update/handler.ts
|
|
841
|
+
function createTaskUpdateHandler(stateManager) {
|
|
842
|
+
return (args) => {
|
|
843
|
+
const task = stateManager.getTask(args.taskId);
|
|
844
|
+
if (!task) {
|
|
845
|
+
return {
|
|
846
|
+
content: JSON.stringify({ error: `Task not found: ${args.taskId}` }),
|
|
847
|
+
result: null
|
|
848
|
+
};
|
|
712
849
|
}
|
|
713
|
-
if (
|
|
714
|
-
|
|
715
|
-
traverse(child);
|
|
716
|
-
}
|
|
850
|
+
if (args.status) {
|
|
851
|
+
task.status = args.status;
|
|
717
852
|
}
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
for (const node of nodes) {
|
|
730
|
-
if (node.path === path) {
|
|
731
|
-
return node;
|
|
853
|
+
if (args.addBlockedBy) {
|
|
854
|
+
for (const blockerId of args.addBlockedBy) {
|
|
855
|
+
if (!task.blockedBy.includes(blockerId)) {
|
|
856
|
+
task.blockedBy.push(blockerId);
|
|
857
|
+
}
|
|
858
|
+
const blockerTask = stateManager.getTask(blockerId);
|
|
859
|
+
if (blockerTask && !blockerTask.blocks.includes(task.id)) {
|
|
860
|
+
blockerTask.blocks.push(task.id);
|
|
861
|
+
stateManager.setTask(blockerTask);
|
|
862
|
+
}
|
|
863
|
+
}
|
|
732
864
|
}
|
|
733
|
-
if (
|
|
734
|
-
const
|
|
735
|
-
|
|
736
|
-
|
|
865
|
+
if (args.addBlocks) {
|
|
866
|
+
for (const blockedId of args.addBlocks) {
|
|
867
|
+
if (!task.blocks.includes(blockedId)) {
|
|
868
|
+
task.blocks.push(blockedId);
|
|
869
|
+
}
|
|
870
|
+
const blockedTask = stateManager.getTask(blockedId);
|
|
871
|
+
if (blockedTask && !blockedTask.blockedBy.includes(task.id)) {
|
|
872
|
+
blockedTask.blockedBy.push(task.id);
|
|
873
|
+
stateManager.setTask(blockedTask);
|
|
874
|
+
}
|
|
737
875
|
}
|
|
738
876
|
}
|
|
739
|
-
|
|
740
|
-
|
|
877
|
+
stateManager.setTask(task);
|
|
878
|
+
return {
|
|
879
|
+
content: JSON.stringify(task, null, 2),
|
|
880
|
+
result: task
|
|
881
|
+
};
|
|
882
|
+
};
|
|
741
883
|
}
|
|
742
884
|
|
|
743
|
-
|
|
744
|
-
exports.askUserQuestionTool = askUserQuestionTool;
|
|
745
|
-
exports.buildFileTreePrompt = buildFileTreePrompt;
|
|
746
|
-
exports.createAgentStateManager = createAgentStateManager;
|
|
747
|
-
exports.createPromptManager = createPromptManager;
|
|
748
|
-
exports.createSession = createSession;
|
|
749
|
-
exports.createTaskHandler = createTaskHandler;
|
|
750
|
-
exports.createTaskTool = createTaskTool;
|
|
751
|
-
exports.createToolRegistry = createToolRegistry;
|
|
752
|
-
exports.createToolRouter = createToolRouter;
|
|
753
|
-
exports.editTool = editTool;
|
|
754
|
-
exports.fileContentToMessageContent = fileContentToMessageContent;
|
|
755
|
-
exports.findNodeByPath = findNodeByPath;
|
|
756
|
-
exports.flattenFileTree = flattenFileTree;
|
|
757
|
-
exports.globTool = globTool;
|
|
758
|
-
exports.grepTool = grepTool;
|
|
759
|
-
exports.hasNoOtherToolCalls = hasNoOtherToolCalls;
|
|
760
|
-
exports.hasTaskTool = hasTaskTool;
|
|
761
|
-
exports.isPathInScope = isPathInScope;
|
|
762
|
-
exports.isTerminalStatus = isTerminalStatus;
|
|
763
|
-
exports.readTool = readTool;
|
|
764
|
-
exports.withSubagentSupport = withSubagentSupport;
|
|
765
|
-
exports.writeTool = writeTool;
|
|
885
|
+
export { AGENT_HANDLER_NAMES, askUserQuestionTool, bashTool, createAgentStateManager, createSession, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskTool, createTaskUpdateHandler, createToolRouter, editTool, globTool, grepTool, hasNoOtherToolCalls, isTerminalStatus, readTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, writeTool };
|
|
766
886
|
//# sourceMappingURL=workflow.js.map
|
|
767
887
|
//# sourceMappingURL=workflow.js.map
|