wave-agent-sdk 0.6.5 → 0.7.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/dist/agent.d.ts +8 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +49 -240
- package/dist/constants/tools.d.ts +0 -2
- package/dist/constants/tools.d.ts.map +1 -1
- package/dist/constants/tools.js +0 -2
- package/dist/core/plugin.d.ts +86 -0
- package/dist/core/plugin.d.ts.map +1 -0
- package/dist/core/plugin.js +164 -0
- package/dist/index.d.ts +1 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -5
- package/dist/managers/MemoryRuleManager.d.ts +3 -1
- package/dist/managers/MemoryRuleManager.d.ts.map +1 -1
- package/dist/managers/MemoryRuleManager.js +2 -1
- package/dist/managers/aiManager.d.ts +13 -23
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +59 -32
- package/dist/managers/backgroundTaskManager.d.ts +3 -1
- package/dist/managers/backgroundTaskManager.d.ts.map +1 -1
- package/dist/managers/backgroundTaskManager.js +2 -1
- package/dist/managers/bashManager.d.ts +4 -4
- package/dist/managers/bashManager.d.ts.map +1 -1
- package/dist/managers/bashManager.js +5 -2
- package/dist/managers/foregroundTaskManager.d.ts +3 -0
- package/dist/managers/foregroundTaskManager.d.ts.map +1 -1
- package/dist/managers/foregroundTaskManager.js +2 -1
- package/dist/managers/hookManager.d.ts +3 -3
- package/dist/managers/hookManager.d.ts.map +1 -1
- package/dist/managers/hookManager.js +20 -19
- package/dist/managers/liveConfigManager.d.ts +6 -13
- package/dist/managers/liveConfigManager.d.ts.map +1 -1
- package/dist/managers/liveConfigManager.js +50 -45
- package/dist/managers/lspManager.d.ts +4 -5
- package/dist/managers/lspManager.d.ts.map +1 -1
- package/dist/managers/lspManager.js +13 -12
- package/dist/managers/mcpManager.d.ts +3 -2
- package/dist/managers/mcpManager.d.ts.map +1 -1
- package/dist/managers/mcpManager.js +16 -15
- package/dist/managers/messageManager.d.ts +5 -7
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +12 -7
- package/dist/managers/permissionManager.d.ts +6 -4
- package/dist/managers/permissionManager.d.ts.map +1 -1
- package/dist/managers/permissionManager.js +39 -63
- package/dist/managers/planManager.d.ts +4 -6
- package/dist/managers/planManager.d.ts.map +1 -1
- package/dist/managers/planManager.js +18 -4
- package/dist/managers/pluginManager.d.ts +10 -22
- package/dist/managers/pluginManager.d.ts.map +1 -1
- package/dist/managers/pluginManager.js +27 -14
- package/dist/managers/reversionManager.d.ts +4 -3
- package/dist/managers/reversionManager.d.ts.map +1 -1
- package/dist/managers/reversionManager.js +5 -2
- package/dist/managers/skillManager.d.ts +3 -2
- package/dist/managers/skillManager.d.ts.map +1 -1
- package/dist/managers/skillManager.js +15 -14
- package/dist/managers/slashCommandManager.d.ts +9 -16
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +21 -10
- package/dist/managers/subagentManager.d.ts +7 -17
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +41 -34
- package/dist/managers/toolManager.d.ts +15 -38
- package/dist/managers/toolManager.d.ts.map +1 -1
- package/dist/managers/toolManager.js +66 -56
- package/dist/prompts/index.d.ts +6 -2
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +8 -4
- package/dist/services/MarketplaceService.d.ts.map +1 -1
- package/dist/services/MarketplaceService.js +13 -0
- package/dist/services/aiService.d.ts +4 -0
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +47 -7
- package/dist/services/configurationService.d.ts.map +1 -1
- package/dist/services/configurationService.js +30 -11
- package/dist/services/taskManager.d.ts +3 -1
- package/dist/services/taskManager.d.ts.map +1 -1
- package/dist/services/taskManager.js +2 -1
- package/dist/tools/bashTool.js +2 -2
- package/dist/tools/editTool.d.ts.map +1 -1
- package/dist/tools/editTool.js +9 -1
- package/dist/tools/readTool.d.ts.map +1 -1
- package/dist/tools/readTool.js +2 -2
- package/dist/tools/skillTool.d.ts +2 -4
- package/dist/tools/skillTool.d.ts.map +1 -1
- package/dist/tools/skillTool.js +61 -61
- package/dist/tools/taskOutputTool.js +1 -1
- package/dist/tools/taskTool.d.ts +2 -4
- package/dist/tools/taskTool.d.ts.map +1 -1
- package/dist/tools/taskTool.js +192 -187
- package/dist/tools/types.d.ts +11 -1
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/writeTool.d.ts.map +1 -1
- package/dist/tools/writeTool.js +4 -2
- package/dist/types/marketplace.d.ts +8 -0
- package/dist/types/marketplace.d.ts.map +1 -1
- package/dist/types/permissions.d.ts +1 -1
- package/dist/types/permissions.d.ts.map +1 -1
- package/dist/types/permissions.js +1 -3
- package/dist/types/skills.d.ts +0 -2
- package/dist/types/skills.d.ts.map +1 -1
- package/dist/types/tools.d.ts +0 -15
- package/dist/types/tools.d.ts.map +1 -1
- package/dist/utils/container.d.ts +31 -0
- package/dist/utils/container.d.ts.map +1 -0
- package/dist/utils/container.js +79 -0
- package/dist/utils/containerSetup.d.ts +26 -0
- package/dist/utils/containerSetup.d.ts.map +1 -0
- package/dist/utils/containerSetup.js +165 -0
- package/dist/utils/editUtils.d.ts +0 -3
- package/dist/utils/editUtils.d.ts.map +1 -1
- package/dist/utils/editUtils.js +4 -3
- package/dist/utils/hookMatcher.d.ts +1 -1
- package/dist/utils/hookMatcher.d.ts.map +1 -1
- package/dist/utils/hookMatcher.js +2 -2
- package/dist/utils/openaiClient.js +2 -2
- package/dist/utils/stringUtils.d.ts +6 -0
- package/dist/utils/stringUtils.d.ts.map +1 -1
- package/dist/utils/stringUtils.js +8 -0
- package/package.json +1 -1
- package/src/agent.ts +60 -282
- package/src/constants/tools.ts +0 -2
- package/src/core/plugin.ts +224 -0
- package/src/index.ts +1 -6
- package/src/managers/MemoryRuleManager.ts +6 -1
- package/src/managers/aiManager.ts +83 -58
- package/src/managers/backgroundTaskManager.ts +5 -1
- package/src/managers/bashManager.ts +9 -4
- package/src/managers/foregroundTaskManager.ts +3 -0
- package/src/managers/hookManager.ts +21 -23
- package/src/managers/liveConfigManager.ts +57 -53
- package/src/managers/lspManager.ts +14 -19
- package/src/managers/mcpManager.ts +20 -20
- package/src/managers/messageManager.ts +19 -12
- package/src/managers/permissionManager.ts +45 -70
- package/src/managers/planManager.ts +26 -7
- package/src/managers/pluginManager.ts +37 -33
- package/src/managers/reversionManager.ts +5 -3
- package/src/managers/skillManager.ts +19 -20
- package/src/managers/slashCommandManager.ts +30 -25
- package/src/managers/subagentManager.ts +53 -53
- package/src/managers/toolManager.ts +91 -90
- package/src/prompts/index.ts +13 -5
- package/src/services/MarketplaceService.ts +13 -0
- package/src/services/aiService.ts +61 -15
- package/src/services/configurationService.ts +34 -13
- package/src/services/taskManager.ts +5 -1
- package/src/tools/bashTool.ts +2 -2
- package/src/tools/editTool.ts +9 -1
- package/src/tools/readTool.ts +2 -2
- package/src/tools/skillTool.ts +75 -71
- package/src/tools/taskOutputTool.ts +1 -1
- package/src/tools/taskTool.ts +224 -225
- package/src/tools/types.ts +12 -1
- package/src/tools/writeTool.ts +4 -2
- package/src/types/marketplace.ts +9 -0
- package/src/types/permissions.ts +0 -4
- package/src/types/skills.ts +0 -3
- package/src/types/tools.ts +0 -17
- package/src/utils/container.ts +92 -0
- package/src/utils/containerSetup.ts +256 -0
- package/src/utils/editUtils.ts +4 -3
- package/src/utils/hookMatcher.ts +2 -2
- package/src/utils/openaiClient.ts +2 -2
- package/src/utils/stringUtils.ts +9 -0
- package/dist/tools/deleteFileTool.d.ts +0 -6
- package/dist/tools/deleteFileTool.d.ts.map +0 -1
- package/dist/tools/deleteFileTool.js +0 -100
- package/dist/tools/multiEditTool.d.ts +0 -6
- package/dist/tools/multiEditTool.d.ts.map +0 -1
- package/dist/tools/multiEditTool.js +0 -246
- package/src/tools/deleteFileTool.ts +0 -127
- package/src/tools/multiEditTool.ts +0 -306
package/src/tools/readTool.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { extname } from "path";
|
|
|
3
3
|
import { logger } from "../utils/globalLogger.js";
|
|
4
4
|
import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
|
|
5
5
|
import { resolvePath, getDisplayPath } from "../utils/path.js";
|
|
6
|
+
import { formatLineNumberPrefix } from "../utils/stringUtils.js";
|
|
6
7
|
import {
|
|
7
8
|
isBinaryDocument,
|
|
8
9
|
getBinaryDocumentError,
|
|
@@ -142,7 +143,6 @@ Usage:
|
|
|
142
143
|
- Any lines longer than 2000 characters will be truncated
|
|
143
144
|
- Results are returned using cat -n format, with line numbers starting at 1
|
|
144
145
|
- This tool allows Agent to read images (eg PNG, JPG, etc). When reading an image file the contents are presented visually as Agent is a multimodal LLM.
|
|
145
|
-
- This tool can read Jupyter notebooks (.ipynb files) and returns all cells with their outputs, combining code, text, and visualizations.
|
|
146
146
|
- You have the capability to call multiple tools in a single response. It is always better to speculatively read multiple files as a batch that are potentially useful.
|
|
147
147
|
- You will regularly be asked to read screenshots. If the user provides a path to a screenshot ALWAYS use this tool to view the file at the path. This tool will work with all temporary file paths like /var/folders/123/abc/T/TemporaryItems/NSIRD_screencaptureui_ZfB1tD/Screenshot.png
|
|
148
148
|
- If you read a file that exists but has empty contents you will receive a system reminder warning in place of file contents.
|
|
@@ -294,7 +294,7 @@ Usage:
|
|
|
294
294
|
// Truncate overly long lines
|
|
295
295
|
const truncatedLine =
|
|
296
296
|
line.length > 2000 ? line.substring(0, 2000) + "..." : line;
|
|
297
|
-
return `${lineNumber
|
|
297
|
+
return `${formatLineNumberPrefix(lineNumber)}${truncatedLine}`;
|
|
298
298
|
})
|
|
299
299
|
.join("\n");
|
|
300
300
|
|
package/src/tools/skillTool.ts
CHANGED
|
@@ -1,87 +1,91 @@
|
|
|
1
|
-
import type { ToolPlugin, ToolResult } from "./types.js";
|
|
2
|
-
import type { SkillManager } from "../managers/skillManager.js";
|
|
1
|
+
import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
|
|
3
2
|
import { SKILL_TOOL_NAME } from "../constants/tools.js";
|
|
3
|
+
import type { SkillMetadata } from "../types/skills.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
* Note: SkillManager should be initialized before calling this function
|
|
6
|
+
* Skill tool plugin for invoking Wave skills
|
|
8
7
|
*/
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const skillList = availableSkills
|
|
24
|
-
.map(
|
|
25
|
-
(skill) =>
|
|
26
|
-
`• **${skill.name}** (${skill.type}): ${skill.description}`,
|
|
27
|
-
)
|
|
28
|
-
.join("\n");
|
|
29
|
-
|
|
30
|
-
return `Invoke a Wave skill by name. Skills are user-defined automation templates that can be personal or project-specific.\n\nAvailable skills:\n${skillList}`;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
return {
|
|
34
|
-
type: "function" as const,
|
|
35
|
-
function: {
|
|
36
|
-
name: SKILL_TOOL_NAME,
|
|
37
|
-
description: getToolDescription(),
|
|
38
|
-
parameters: {
|
|
39
|
-
type: "object",
|
|
40
|
-
properties: {
|
|
41
|
-
skill_name: {
|
|
42
|
-
type: "string",
|
|
43
|
-
description: "Name of the skill to invoke",
|
|
44
|
-
enum: availableSkills.map((skill) => skill.name),
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
required: ["skill_name"],
|
|
8
|
+
export const skillTool: ToolPlugin = {
|
|
9
|
+
name: SKILL_TOOL_NAME,
|
|
10
|
+
config: {
|
|
11
|
+
type: "function" as const,
|
|
12
|
+
function: {
|
|
13
|
+
name: SKILL_TOOL_NAME,
|
|
14
|
+
description:
|
|
15
|
+
"Invoke a Wave skill by name. Skills are user-defined automation templates that can be personal or project-specific.",
|
|
16
|
+
parameters: {
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
skill_name: {
|
|
20
|
+
type: "string",
|
|
21
|
+
description: "Name of the skill to invoke",
|
|
48
22
|
},
|
|
49
23
|
},
|
|
50
|
-
|
|
24
|
+
required: ["skill_name"],
|
|
25
|
+
},
|
|
51
26
|
},
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
content: "",
|
|
60
|
-
error: "skill_name parameter is required and must be a string",
|
|
61
|
-
};
|
|
62
|
-
}
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
prompt: (args?: { availableSkills?: SkillMetadata[] }) => {
|
|
30
|
+
const availableSkills = args?.availableSkills;
|
|
31
|
+
if (!availableSkills || availableSkills.length === 0) {
|
|
32
|
+
return "Invoke a Wave skill by name. Skills are user-defined automation templates that can be personal or project-specific. No skills are currently available.";
|
|
33
|
+
}
|
|
63
34
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
35
|
+
const skillList = availableSkills
|
|
36
|
+
.map(
|
|
37
|
+
(skill) => `• **${skill.name}** (${skill.type}): ${skill.description}`,
|
|
38
|
+
)
|
|
39
|
+
.join("\n");
|
|
68
40
|
|
|
41
|
+
return `Invoke a Wave skill by name. Skills are user-defined automation templates that can be personal or project-specific.\n\nAvailable skills:\n${skillList}`;
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
execute: async (
|
|
45
|
+
args: Record<string, unknown>,
|
|
46
|
+
context: ToolContext,
|
|
47
|
+
): Promise<ToolResult> => {
|
|
48
|
+
try {
|
|
49
|
+
const skillManager = context.skillManager;
|
|
50
|
+
if (!skillManager) {
|
|
69
51
|
return {
|
|
70
|
-
success:
|
|
71
|
-
content:
|
|
72
|
-
|
|
52
|
+
success: false,
|
|
53
|
+
content: "",
|
|
54
|
+
error: "Skill manager not available in tool context",
|
|
73
55
|
};
|
|
74
|
-
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Validate arguments
|
|
59
|
+
const skillName = args.skill_name as string;
|
|
60
|
+
if (!skillName || typeof skillName !== "string") {
|
|
75
61
|
return {
|
|
76
62
|
success: false,
|
|
77
63
|
content: "",
|
|
78
|
-
error:
|
|
64
|
+
error: "skill_name parameter is required and must be a string",
|
|
79
65
|
};
|
|
80
66
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
67
|
+
|
|
68
|
+
// Execute the skill
|
|
69
|
+
const result = await skillManager.executeSkill({
|
|
70
|
+
skill_name: skillName,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
success: true,
|
|
75
|
+
content: result.content,
|
|
76
|
+
shortResult: `Invoked skill: ${skillName}`,
|
|
77
|
+
};
|
|
78
|
+
} catch (error) {
|
|
79
|
+
return {
|
|
80
|
+
success: false,
|
|
81
|
+
content: "",
|
|
82
|
+
error: error instanceof Error ? error.message : String(error),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
formatCompactParams: (params: Record<string, unknown>) => {
|
|
88
|
+
const skillName = params.skill_name as string;
|
|
89
|
+
return skillName || "unknown-skill";
|
|
90
|
+
},
|
|
91
|
+
};
|
|
@@ -190,7 +190,7 @@ export const taskOutputTool: ToolPlugin = {
|
|
|
190
190
|
},
|
|
191
191
|
formatCompactParams: (params: Record<string, unknown>) => {
|
|
192
192
|
const taskId = params.task_id as string;
|
|
193
|
-
const block = params.block as boolean;
|
|
193
|
+
const block = (params.block as boolean | undefined) ?? true;
|
|
194
194
|
return `${taskId}${block ? " (blocking)" : ""}`;
|
|
195
195
|
},
|
|
196
196
|
};
|
package/src/tools/taskTool.ts
CHANGED
|
@@ -1,245 +1,244 @@
|
|
|
1
1
|
import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
|
|
2
|
-
import type { SubagentManager } from "../managers/subagentManager.js";
|
|
3
2
|
import { EXPLORE_SUBAGENT_TYPE } from "../constants/subagents.js";
|
|
4
3
|
import { TASK_TOOL_NAME } from "../constants/tools.js";
|
|
4
|
+
import type { SubagentConfiguration } from "../utils/subagentParser.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
* Note: SubagentManager should be initialized before calling this function
|
|
7
|
+
* Task tool plugin for delegating tasks to specialized subagents
|
|
9
8
|
*/
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
type: "
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
type: "string",
|
|
38
|
-
description:
|
|
39
|
-
"A clear, concise description of what needs to be accomplished",
|
|
40
|
-
},
|
|
41
|
-
prompt: {
|
|
42
|
-
type: "string",
|
|
43
|
-
description:
|
|
44
|
-
"The specific instructions or prompt to send to the subagent",
|
|
45
|
-
},
|
|
46
|
-
subagent_type: {
|
|
47
|
-
type: "string",
|
|
48
|
-
description: `The type or name of subagent to use. Available options: ${availableSubagents.map((c) => c.name).join(", ") || "none"}`,
|
|
49
|
-
},
|
|
50
|
-
run_in_background: {
|
|
51
|
-
type: "boolean",
|
|
52
|
-
description:
|
|
53
|
-
"Set to true to run this command in the background. Use TaskOutput to read the output later.",
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
required: ["description", "prompt", "subagent_type"],
|
|
9
|
+
export const taskTool: ToolPlugin = {
|
|
10
|
+
name: TASK_TOOL_NAME,
|
|
11
|
+
config: {
|
|
12
|
+
type: "function" as const,
|
|
13
|
+
function: {
|
|
14
|
+
name: TASK_TOOL_NAME,
|
|
15
|
+
description:
|
|
16
|
+
"Delegate a task to a specialized subagent. Use this when you need specialized expertise or want to break down complex work into focused subtasks.",
|
|
17
|
+
parameters: {
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: {
|
|
20
|
+
description: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "A short (3-5 word) description of the task",
|
|
23
|
+
},
|
|
24
|
+
prompt: {
|
|
25
|
+
type: "string",
|
|
26
|
+
description: "The task for the agent to perform",
|
|
27
|
+
},
|
|
28
|
+
subagent_type: {
|
|
29
|
+
type: "string",
|
|
30
|
+
description: "The type of specialized agent to use for this task",
|
|
31
|
+
},
|
|
32
|
+
run_in_background: {
|
|
33
|
+
type: "boolean",
|
|
34
|
+
description:
|
|
35
|
+
"Set to true to run this command in the background. Use TaskOutput to read the output later.",
|
|
57
36
|
},
|
|
58
37
|
},
|
|
59
|
-
|
|
38
|
+
required: ["description", "prompt", "subagent_type"],
|
|
39
|
+
},
|
|
60
40
|
},
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
prompt: (args?: { availableSubagents?: SubagentConfiguration[] }) => {
|
|
44
|
+
const subagentList = args?.availableSubagents
|
|
45
|
+
? args.availableSubagents
|
|
46
|
+
.map((config) => `- ${config.name}: ${config.description}`)
|
|
47
|
+
.join("\n")
|
|
48
|
+
: "";
|
|
49
|
+
|
|
50
|
+
return `
|
|
51
|
+
Delegate a task to a specialized subagent. Use this when you need specialized expertise or want to break down complex work into focused subtasks.
|
|
52
|
+
|
|
53
|
+
Available subagents:
|
|
54
|
+
${subagentList || "No subagents configured"}
|
|
61
55
|
|
|
62
|
-
prompt: () => `
|
|
63
56
|
- When doing file search, prefer to use the ${TASK_TOOL_NAME} tool in order to reduce context usage.
|
|
64
57
|
- You should proactively use the ${TASK_TOOL_NAME} tool with specialized agents when the task at hand matches the agent's description.
|
|
65
|
-
- VERY IMPORTANT: When exploring the codebase to gather context or to answer a question that is not a needle query for a specific file/class/function, it is CRITICAL that you use the ${TASK_TOOL_NAME} tool with subagent_type=${EXPLORE_SUBAGENT_TYPE} instead of running search commands directly
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
success: false,
|
|
82
|
-
content: "",
|
|
83
|
-
error: "description parameter is required and must be a string",
|
|
84
|
-
shortResult: "Task delegation failed",
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (!prompt || typeof prompt !== "string") {
|
|
89
|
-
return resolve({
|
|
90
|
-
success: false,
|
|
91
|
-
content: "",
|
|
92
|
-
error: "prompt parameter is required and must be a string",
|
|
93
|
-
shortResult: "Task delegation failed",
|
|
94
|
-
});
|
|
95
|
-
}
|
|
58
|
+
- VERY IMPORTANT: When exploring the codebase to gather context or to answer a question that is not a needle query for a specific file/class/function, it is CRITICAL that you use the ${TASK_TOOL_NAME} tool with subagent_type=${EXPLORE_SUBAGENT_TYPE} instead of running search commands directly.`;
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
execute: async (
|
|
62
|
+
args: Record<string, unknown>,
|
|
63
|
+
context: ToolContext,
|
|
64
|
+
): Promise<ToolResult> => {
|
|
65
|
+
const subagentManager = context.subagentManager;
|
|
66
|
+
if (!subagentManager) {
|
|
67
|
+
return {
|
|
68
|
+
success: false,
|
|
69
|
+
content: "",
|
|
70
|
+
error: "Subagent manager not available in tool context",
|
|
71
|
+
shortResult: "Task delegation failed",
|
|
72
|
+
};
|
|
73
|
+
}
|
|
96
74
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
shortResult: "Task delegation failed",
|
|
103
|
-
});
|
|
104
|
-
}
|
|
75
|
+
// Input validation
|
|
76
|
+
const description = args.description as string;
|
|
77
|
+
const prompt = args.prompt as string;
|
|
78
|
+
const subagent_type = args.subagent_type as string;
|
|
79
|
+
const run_in_background = args.run_in_background as boolean;
|
|
105
80
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const availableNames = allConfigs.map((c) => c.name).join(", ");
|
|
115
|
-
|
|
116
|
-
return resolve({
|
|
117
|
-
success: false,
|
|
118
|
-
content: "",
|
|
119
|
-
error: `No subagent found matching "${subagent_type}". Available subagents: ${availableNames || "none"}`,
|
|
120
|
-
shortResult: "Subagent not found",
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Set up callback to update shortResult with tool names, tool count and tokens
|
|
125
|
-
const updateShortResult = () => {
|
|
126
|
-
const messages = instance.messageManager.getMessages();
|
|
127
|
-
const tokens = instance.messageManager.getlatestTotalTokens();
|
|
128
|
-
const lastTools = instance.lastTools;
|
|
129
|
-
|
|
130
|
-
// Count tool blocks in messages
|
|
131
|
-
let toolCount = 0;
|
|
132
|
-
messages.forEach((msg) => {
|
|
133
|
-
msg.blocks.forEach((block) => {
|
|
134
|
-
if (block.type === "tool") {
|
|
135
|
-
toolCount++;
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
let shortResult = "";
|
|
141
|
-
if (toolCount > 2) {
|
|
142
|
-
shortResult += "... ";
|
|
143
|
-
}
|
|
144
|
-
if (lastTools.length > 0) {
|
|
145
|
-
shortResult += `${lastTools.join(", ")} `;
|
|
146
|
-
}
|
|
81
|
+
if (!description || typeof description !== "string") {
|
|
82
|
+
return {
|
|
83
|
+
success: false,
|
|
84
|
+
content: "",
|
|
85
|
+
error: "description parameter is required and must be a string",
|
|
86
|
+
shortResult: "Task delegation failed",
|
|
87
|
+
};
|
|
88
|
+
}
|
|
147
89
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
// Create subagent instance and execute task
|
|
158
|
-
const instance = await subagentManager.createInstance(
|
|
159
|
-
configuration,
|
|
160
|
-
{
|
|
161
|
-
description,
|
|
162
|
-
prompt,
|
|
163
|
-
subagent_type,
|
|
164
|
-
},
|
|
165
|
-
run_in_background,
|
|
166
|
-
updateShortResult,
|
|
167
|
-
);
|
|
168
|
-
|
|
169
|
-
// Initial update
|
|
170
|
-
updateShortResult();
|
|
171
|
-
|
|
172
|
-
let isBackgrounded = false;
|
|
173
|
-
|
|
174
|
-
// Register for backgrounding if not already in background
|
|
175
|
-
if (!run_in_background && context.foregroundTaskManager) {
|
|
176
|
-
context.foregroundTaskManager.registerForegroundTask({
|
|
177
|
-
id: instance.subagentId,
|
|
178
|
-
backgroundHandler: async () => {
|
|
179
|
-
isBackgrounded = true;
|
|
180
|
-
const taskId = await subagentManager.backgroundInstance(
|
|
181
|
-
instance.subagentId,
|
|
182
|
-
);
|
|
183
|
-
// Resolve the tool execution early so the main agent can continue
|
|
184
|
-
resolve({
|
|
185
|
-
success: true,
|
|
186
|
-
content: `Task moved to background with ID: ${taskId}.`,
|
|
187
|
-
shortResult: "Task backgrounded",
|
|
188
|
-
isManuallyBackgrounded: true,
|
|
189
|
-
});
|
|
190
|
-
},
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
try {
|
|
195
|
-
const result = await subagentManager.executeTask(
|
|
196
|
-
instance,
|
|
197
|
-
prompt,
|
|
198
|
-
context.abortSignal,
|
|
199
|
-
run_in_background,
|
|
200
|
-
);
|
|
201
|
-
|
|
202
|
-
if (isBackgrounded) return;
|
|
203
|
-
|
|
204
|
-
if (run_in_background) {
|
|
205
|
-
return resolve({
|
|
206
|
-
success: true,
|
|
207
|
-
content: `Task started in background with ID: ${result}`,
|
|
208
|
-
shortResult: `Task started in background: ${result}`,
|
|
209
|
-
});
|
|
210
|
-
}
|
|
90
|
+
if (!prompt || typeof prompt !== "string") {
|
|
91
|
+
return {
|
|
92
|
+
success: false,
|
|
93
|
+
content: "",
|
|
94
|
+
error: "prompt parameter is required and must be a string",
|
|
95
|
+
shortResult: "Task delegation failed",
|
|
96
|
+
};
|
|
97
|
+
}
|
|
211
98
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
99
|
+
if (!subagent_type || typeof subagent_type !== "string") {
|
|
100
|
+
return {
|
|
101
|
+
success: false,
|
|
102
|
+
content: "",
|
|
103
|
+
error: "subagent_type parameter is required and must be a string",
|
|
104
|
+
shortResult: "Task delegation failed",
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
// Subagent selection logic with explicit name matching only
|
|
110
|
+
const configuration = await subagentManager.findSubagent(subagent_type);
|
|
111
|
+
|
|
112
|
+
if (!configuration) {
|
|
113
|
+
// Error handling for nonexistent subagents with available subagents listing
|
|
114
|
+
const allConfigs = subagentManager.getConfigurations();
|
|
115
|
+
const availableNames = allConfigs.map((c) => c.name).join(", ");
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
success: false,
|
|
119
|
+
content: "",
|
|
120
|
+
error: `No subagent found matching "${subagent_type}". Available subagents: ${availableNames || "none"}`,
|
|
121
|
+
shortResult: "Subagent not found",
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
let isBackgrounded = false;
|
|
126
|
+
|
|
127
|
+
// Create subagent instance and execute task
|
|
128
|
+
const instance = await subagentManager.createInstance(
|
|
129
|
+
configuration,
|
|
130
|
+
{
|
|
131
|
+
description,
|
|
132
|
+
prompt,
|
|
133
|
+
subagent_type,
|
|
134
|
+
},
|
|
135
|
+
run_in_background,
|
|
136
|
+
() => {
|
|
137
|
+
// Do not update shortResult if it is running in background
|
|
138
|
+
if (run_in_background || isBackgrounded) return;
|
|
139
|
+
|
|
140
|
+
const messages = instance.messageManager.getMessages();
|
|
141
|
+
const tokens = instance.messageManager.getlatestTotalTokens();
|
|
142
|
+
const lastTools = instance.lastTools;
|
|
143
|
+
|
|
144
|
+
// Count tool blocks in messages
|
|
145
|
+
let toolCount = 0;
|
|
146
|
+
messages.forEach((msg) => {
|
|
147
|
+
msg.blocks.forEach((block) => {
|
|
148
|
+
if (block.type === "tool") {
|
|
149
|
+
toolCount++;
|
|
225
150
|
}
|
|
226
|
-
}
|
|
227
|
-
} catch (error) {
|
|
228
|
-
return resolve({
|
|
229
|
-
success: false,
|
|
230
|
-
content: "",
|
|
231
|
-
error: `Task delegation failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
232
|
-
shortResult: "Delegation error",
|
|
233
151
|
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
let shortResult = "";
|
|
155
|
+
if (toolCount > 2) {
|
|
156
|
+
shortResult += "... ";
|
|
157
|
+
}
|
|
158
|
+
if (lastTools.length > 0) {
|
|
159
|
+
shortResult += `${lastTools.join(", ")} `;
|
|
234
160
|
}
|
|
235
|
-
})();
|
|
236
|
-
});
|
|
237
|
-
},
|
|
238
161
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
162
|
+
shortResult += `(${toolCount} tools`;
|
|
163
|
+
if (tokens > 0) {
|
|
164
|
+
shortResult += ` | ${tokens.toLocaleString()} tokens`;
|
|
165
|
+
}
|
|
166
|
+
shortResult += ")";
|
|
167
|
+
|
|
168
|
+
context.onShortResultUpdate?.(shortResult);
|
|
169
|
+
},
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
// Register for backgrounding if not already in background
|
|
173
|
+
if (!run_in_background && context.foregroundTaskManager) {
|
|
174
|
+
context.foregroundTaskManager.registerForegroundTask({
|
|
175
|
+
id: instance.subagentId,
|
|
176
|
+
backgroundHandler: async () => {
|
|
177
|
+
isBackgrounded = true;
|
|
178
|
+
await subagentManager.backgroundInstance(instance.subagentId);
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
try {
|
|
184
|
+
const result = await subagentManager.executeTask(
|
|
185
|
+
instance,
|
|
186
|
+
prompt,
|
|
187
|
+
context.abortSignal,
|
|
188
|
+
run_in_background,
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
if (isBackgrounded) {
|
|
192
|
+
// If it was backgrounded during execution, the backgroundHandler already returned/will return
|
|
193
|
+
// But wait, the backgroundHandler is async and returns a ToolResult.
|
|
194
|
+
// In the current ToolManager/AIManager implementation, the backgroundHandler's return value
|
|
195
|
+
// is what's used when backgrounding happens.
|
|
196
|
+
// However, executeTask might still be running.
|
|
197
|
+
// We should return a special value or just let it be.
|
|
198
|
+
return {
|
|
199
|
+
success: true,
|
|
200
|
+
content: "Task backgrounded",
|
|
201
|
+
shortResult: "Task backgrounded",
|
|
202
|
+
isManuallyBackgrounded: true,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (run_in_background) {
|
|
207
|
+
return {
|
|
208
|
+
success: true,
|
|
209
|
+
content: `Task started in background with ID: ${result}`,
|
|
210
|
+
shortResult: `Task started in background: ${result}`,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Cleanup subagent instance after task completion
|
|
215
|
+
subagentManager.cleanupInstance(instance.subagentId);
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
success: true,
|
|
219
|
+
content: result,
|
|
220
|
+
shortResult: `Task completed by ${configuration.name}`,
|
|
221
|
+
};
|
|
222
|
+
} finally {
|
|
223
|
+
if (!run_in_background && context.foregroundTaskManager) {
|
|
224
|
+
context.foregroundTaskManager.unregisterForegroundTask(
|
|
225
|
+
instance.subagentId,
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
} catch (error) {
|
|
230
|
+
return {
|
|
231
|
+
success: false,
|
|
232
|
+
content: "",
|
|
233
|
+
error: `Task delegation failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
234
|
+
shortResult: "Delegation error",
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
|
|
239
|
+
formatCompactParams: (params: Record<string, unknown>) => {
|
|
240
|
+
const subagent_type = params.subagent_type as string;
|
|
241
|
+
const description = params.description as string;
|
|
242
|
+
return `${subagent_type || "unknown"}: ${description || "no description"}`;
|
|
243
|
+
},
|
|
244
|
+
};
|