wave-agent-sdk 0.8.3 → 0.8.4
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.js +2 -2
- package/dist/constants/tools.d.ts +1 -2
- package/dist/constants/tools.d.ts.map +1 -1
- package/dist/constants/tools.js +1 -2
- package/dist/managers/permissionManager.d.ts.map +1 -1
- package/dist/managers/permissionManager.js +2 -7
- package/dist/managers/subagentManager.d.ts +3 -3
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +13 -12
- package/dist/managers/toolManager.d.ts +2 -2
- package/dist/managers/toolManager.d.ts.map +1 -1
- package/dist/managers/toolManager.js +4 -6
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +3 -3
- package/dist/tools/agentTool.d.ts +6 -0
- package/dist/tools/agentTool.d.ts.map +1 -0
- package/dist/tools/{taskTool.js → agentTool.js} +42 -30
- package/dist/tools/grepTool.js +2 -2
- package/dist/tools/skillTool.js +2 -2
- package/dist/tools/types.d.ts +1 -1
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/utils/builtinSubagents.d.ts.map +1 -1
- package/dist/utils/builtinSubagents.js +1 -3
- package/dist/utils/gitUtils.d.ts.map +1 -1
- package/dist/utils/gitUtils.js +47 -1
- package/dist/utils/path.d.ts +0 -10
- package/dist/utils/path.d.ts.map +1 -1
- package/dist/utils/path.js +0 -61
- package/package.json +1 -1
- package/src/agent.ts +2 -2
- package/src/constants/tools.ts +1 -2
- package/src/managers/permissionManager.ts +1 -7
- package/src/managers/subagentManager.ts +13 -12
- package/src/managers/toolManager.ts +4 -6
- package/src/prompts/index.ts +3 -2
- package/src/tools/{taskTool.ts → agentTool.ts} +42 -30
- package/src/tools/grepTool.ts +2 -2
- package/src/tools/skillTool.ts +2 -2
- package/src/tools/types.ts +1 -1
- package/src/utils/builtinSubagents.ts +0 -3
- package/src/utils/gitUtils.ts +48 -1
- package/src/utils/path.ts +0 -62
- package/dist/tools/lsTool.d.ts +0 -6
- package/dist/tools/lsTool.d.ts.map +0 -1
- package/dist/tools/lsTool.js +0 -175
- package/dist/tools/taskTool.d.ts +0 -6
- package/dist/tools/taskTool.d.ts.map +0 -1
- package/src/tools/lsTool.ts +0 -212
package/dist/utils/gitUtils.js
CHANGED
|
@@ -46,6 +46,7 @@ export function getGitRepoRoot(cwd) {
|
|
|
46
46
|
* @returns Default remote branch name
|
|
47
47
|
*/
|
|
48
48
|
export function getDefaultRemoteBranch(cwd) {
|
|
49
|
+
// 1. Try git symbolic-ref refs/remotes/origin/HEAD
|
|
49
50
|
try {
|
|
50
51
|
const head = execSync("git symbolic-ref refs/remotes/origin/HEAD", {
|
|
51
52
|
cwd,
|
|
@@ -55,9 +56,54 @@ export function getDefaultRemoteBranch(cwd) {
|
|
|
55
56
|
return head.replace("refs/remotes/", "");
|
|
56
57
|
}
|
|
57
58
|
catch {
|
|
58
|
-
//
|
|
59
|
+
// Ignore error and proceed to next step
|
|
60
|
+
}
|
|
61
|
+
// 2. Check if origin/main exists
|
|
62
|
+
try {
|
|
63
|
+
execSync("git rev-parse --verify origin/main", {
|
|
64
|
+
cwd,
|
|
65
|
+
stdio: "ignore",
|
|
66
|
+
});
|
|
59
67
|
return "origin/main";
|
|
60
68
|
}
|
|
69
|
+
catch {
|
|
70
|
+
// Ignore error and proceed to next step
|
|
71
|
+
}
|
|
72
|
+
// 3. Check if origin/master exists
|
|
73
|
+
try {
|
|
74
|
+
execSync("git rev-parse --verify origin/master", {
|
|
75
|
+
cwd,
|
|
76
|
+
stdio: "ignore",
|
|
77
|
+
});
|
|
78
|
+
return "origin/master";
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// Ignore error and proceed to next step
|
|
82
|
+
}
|
|
83
|
+
// 4. Try to get the current branch's upstream
|
|
84
|
+
try {
|
|
85
|
+
return execSync("git rev-parse --abbrev-ref --symbolic-full-name @{u}", {
|
|
86
|
+
cwd,
|
|
87
|
+
encoding: "utf8",
|
|
88
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
89
|
+
}).trim();
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// Ignore error and proceed to next step
|
|
93
|
+
}
|
|
94
|
+
// 5. Try to get the current branch name
|
|
95
|
+
try {
|
|
96
|
+
return execSync("git rev-parse --abbrev-ref HEAD", {
|
|
97
|
+
cwd,
|
|
98
|
+
encoding: "utf8",
|
|
99
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
100
|
+
}).trim();
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// Ignore error and proceed to next step
|
|
104
|
+
}
|
|
105
|
+
// 6. Fallback to origin/main
|
|
106
|
+
return "origin/main";
|
|
61
107
|
}
|
|
62
108
|
/**
|
|
63
109
|
* Check if there are uncommitted changes in the working directory
|
package/dist/utils/path.d.ts
CHANGED
|
@@ -5,16 +5,6 @@
|
|
|
5
5
|
* @returns Resolved absolute path
|
|
6
6
|
*/
|
|
7
7
|
export declare function resolvePath(filePath: string, workdir: string): string;
|
|
8
|
-
/**
|
|
9
|
-
* Binary file extension list
|
|
10
|
-
*/
|
|
11
|
-
export declare const binaryExtensions: readonly ["png", "jpg", "jpeg", "gif", "bmp", "ico", "webp", "svg", "sketch", "mp3", "wav", "ogg", "aac", "mp4", "webm", "avi", "mov", "pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "zip", "rar", "7z", "tar", "gz", "ttf", "otf", "woff", "woff2", "eot", "exe", "dll", "so", "dylib", "bin"];
|
|
12
|
-
/**
|
|
13
|
-
* Check if a file is a binary file
|
|
14
|
-
* @param filename File name
|
|
15
|
-
* @returns Whether it is a binary file
|
|
16
|
-
*/
|
|
17
|
-
export declare const isBinary: (filename: string) => boolean;
|
|
18
8
|
/**
|
|
19
9
|
* Get relative path for display, use relative path if shorter and not in parent directory
|
|
20
10
|
* @param filePath Absolute path
|
package/dist/utils/path.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAarE;AAED
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAarE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAwBxE"}
|
package/dist/utils/path.js
CHANGED
|
@@ -19,67 +19,6 @@ export function resolvePath(filePath, workdir) {
|
|
|
19
19
|
// For other paths, resolve using the specified working directory
|
|
20
20
|
return resolve(workdir, filePath);
|
|
21
21
|
}
|
|
22
|
-
/**
|
|
23
|
-
* Binary file extension list
|
|
24
|
-
*/
|
|
25
|
-
export const binaryExtensions = [
|
|
26
|
-
// Image files
|
|
27
|
-
"png",
|
|
28
|
-
"jpg",
|
|
29
|
-
"jpeg",
|
|
30
|
-
"gif",
|
|
31
|
-
"bmp",
|
|
32
|
-
"ico",
|
|
33
|
-
"webp",
|
|
34
|
-
"svg",
|
|
35
|
-
"sketch",
|
|
36
|
-
// Audio files
|
|
37
|
-
"mp3",
|
|
38
|
-
"wav",
|
|
39
|
-
"ogg",
|
|
40
|
-
"aac",
|
|
41
|
-
// Video files
|
|
42
|
-
"mp4",
|
|
43
|
-
"webm",
|
|
44
|
-
"avi",
|
|
45
|
-
"mov",
|
|
46
|
-
// Document files
|
|
47
|
-
"pdf",
|
|
48
|
-
"doc",
|
|
49
|
-
"docx",
|
|
50
|
-
"xls",
|
|
51
|
-
"xlsx",
|
|
52
|
-
"ppt",
|
|
53
|
-
"pptx",
|
|
54
|
-
// Compressed files
|
|
55
|
-
"zip",
|
|
56
|
-
"rar",
|
|
57
|
-
"7z",
|
|
58
|
-
"tar",
|
|
59
|
-
"gz",
|
|
60
|
-
// Font files
|
|
61
|
-
"ttf",
|
|
62
|
-
"otf",
|
|
63
|
-
"woff",
|
|
64
|
-
"woff2",
|
|
65
|
-
"eot",
|
|
66
|
-
// Other binary files
|
|
67
|
-
"exe",
|
|
68
|
-
"dll",
|
|
69
|
-
"so",
|
|
70
|
-
"dylib",
|
|
71
|
-
"bin",
|
|
72
|
-
];
|
|
73
|
-
/**
|
|
74
|
-
* Check if a file is a binary file
|
|
75
|
-
* @param filename File name
|
|
76
|
-
* @returns Whether it is a binary file
|
|
77
|
-
*/
|
|
78
|
-
export const isBinary = (filename) => {
|
|
79
|
-
const parts = filename.split(".");
|
|
80
|
-
const ext = parts.length > 1 ? parts.pop()?.toLowerCase() || "" : "";
|
|
81
|
-
return binaryExtensions.includes(ext);
|
|
82
|
-
};
|
|
83
22
|
/**
|
|
84
23
|
* Get relative path for display, use relative path if shorter and not in parent directory
|
|
85
24
|
* @param filePath Absolute path
|
package/package.json
CHANGED
package/src/agent.ts
CHANGED
|
@@ -414,7 +414,7 @@ export class Agent {
|
|
|
414
414
|
|
|
415
415
|
/** Unified interrupt method, interrupts both AI messages and command execution */
|
|
416
416
|
public abortMessage(): void {
|
|
417
|
-
this.abortAIMessage(); // This will abort tools including
|
|
417
|
+
this.abortAIMessage(); // This will abort tools including Agent tool (subagents)
|
|
418
418
|
this.abortBashCommand();
|
|
419
419
|
this.abortSlashCommand();
|
|
420
420
|
}
|
|
@@ -454,7 +454,7 @@ export class Agent {
|
|
|
454
454
|
/** Destroy managers, clean up resources */
|
|
455
455
|
public async destroy(): Promise<void> {
|
|
456
456
|
await this.messageManager.saveSession();
|
|
457
|
-
this.abortAIMessage(); // This will abort tools including
|
|
457
|
+
this.abortAIMessage(); // This will abort tools including Agent tool (subagents)
|
|
458
458
|
this.abortBashCommand();
|
|
459
459
|
this.abortSlashCommand();
|
|
460
460
|
// Cleanup background task manager
|
package/src/constants/tools.ts
CHANGED
|
@@ -7,10 +7,9 @@ export const EXIT_PLAN_MODE_TOOL_NAME = "ExitPlanMode";
|
|
|
7
7
|
export const GLOB_TOOL_NAME = "Glob";
|
|
8
8
|
export const GREP_TOOL_NAME = "Grep";
|
|
9
9
|
export const LSP_TOOL_NAME = "LSP";
|
|
10
|
-
export const LS_TOOL_NAME = "LS";
|
|
11
10
|
export const READ_TOOL_NAME = "Read";
|
|
12
11
|
export const SKILL_TOOL_NAME = "Skill";
|
|
13
|
-
export const
|
|
12
|
+
export const AGENT_TOOL_NAME = "Agent";
|
|
14
13
|
export const TASK_CREATE_TOOL_NAME = "TaskCreate";
|
|
15
14
|
export const TASK_GET_TOOL_NAME = "TaskGet";
|
|
16
15
|
export const TASK_UPDATE_TOOL_NAME = "TaskUpdate";
|
|
@@ -30,7 +30,6 @@ import {
|
|
|
30
30
|
EDIT_TOOL_NAME,
|
|
31
31
|
WRITE_TOOL_NAME,
|
|
32
32
|
READ_TOOL_NAME,
|
|
33
|
-
LS_TOOL_NAME,
|
|
34
33
|
} from "../constants/tools.js";
|
|
35
34
|
import { Container } from "../utils/container.js";
|
|
36
35
|
import { ConfigurationService } from "../services/configurationService.js";
|
|
@@ -550,12 +549,7 @@ export class PermissionManager {
|
|
|
550
549
|
}
|
|
551
550
|
|
|
552
551
|
// Handle path-based rules (e.g., "Read(**/*.env)")
|
|
553
|
-
const pathTools = [
|
|
554
|
-
READ_TOOL_NAME,
|
|
555
|
-
WRITE_TOOL_NAME,
|
|
556
|
-
EDIT_TOOL_NAME,
|
|
557
|
-
LS_TOOL_NAME,
|
|
558
|
-
];
|
|
552
|
+
const pathTools = [READ_TOOL_NAME, WRITE_TOOL_NAME, EDIT_TOOL_NAME];
|
|
559
553
|
if (pathTools.includes(toolName)) {
|
|
560
554
|
const targetPath = (context.toolInput?.file_path ||
|
|
561
555
|
context.toolInput?.path) as string | undefined;
|
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
import { AIManager } from "./aiManager.js";
|
|
10
10
|
import { MessageManager } from "./messageManager.js";
|
|
11
11
|
import { ToolManager } from "./toolManager.js";
|
|
12
|
+
import { AGENT_TOOL_NAME } from "../constants/tools.js";
|
|
12
13
|
import {
|
|
13
14
|
addConsolidatedAbortListener,
|
|
14
15
|
createAbortPromise,
|
|
@@ -287,12 +288,12 @@ export class SubagentManager {
|
|
|
287
288
|
}
|
|
288
289
|
|
|
289
290
|
/**
|
|
290
|
-
* Execute
|
|
291
|
+
* Execute agent using subagent instance
|
|
291
292
|
*
|
|
292
|
-
* IMPORTANT: This method automatically filters out the
|
|
293
|
+
* IMPORTANT: This method automatically filters out the Agent tool from allowedTools
|
|
293
294
|
* to prevent subagents from spawning other subagents (infinite recursion protection)
|
|
294
295
|
*/
|
|
295
|
-
async
|
|
296
|
+
async executeAgent(
|
|
296
297
|
instance: SubagentInstance,
|
|
297
298
|
prompt: string,
|
|
298
299
|
abortSignal?: AbortSignal,
|
|
@@ -301,7 +302,7 @@ export class SubagentManager {
|
|
|
301
302
|
try {
|
|
302
303
|
// Check if already aborted before starting
|
|
303
304
|
if (abortSignal?.aborted) {
|
|
304
|
-
throw new Error("
|
|
305
|
+
throw new Error("Agent was aborted before execution started");
|
|
305
306
|
}
|
|
306
307
|
|
|
307
308
|
// Set status to active and update parent
|
|
@@ -433,17 +434,17 @@ export class SubagentManager {
|
|
|
433
434
|
// Add the user's prompt as a message
|
|
434
435
|
instance.messageManager.addUserMessage({ content: prompt });
|
|
435
436
|
|
|
436
|
-
// Create enabled tools list - always exclude
|
|
437
|
+
// Create enabled tools list - always exclude Agent tool to prevent subagent recursion
|
|
437
438
|
// Use instance.configuration.tools if provided, otherwise fallback to all tools
|
|
438
439
|
let enabledTools = instance.configuration.tools;
|
|
439
440
|
|
|
440
|
-
// Always filter out the
|
|
441
|
+
// Always filter out the Agent tool to prevent subagents from creating sub-subagents
|
|
441
442
|
if (enabledTools) {
|
|
442
|
-
enabledTools = enabledTools.filter((tool) => tool !==
|
|
443
|
+
enabledTools = enabledTools.filter((tool) => tool !== AGENT_TOOL_NAME);
|
|
443
444
|
} else {
|
|
444
|
-
// If no tools specified, get all tools except
|
|
445
|
+
// If no tools specified, get all tools except Agent
|
|
445
446
|
const allTools = instance.toolManager.list().map((tool) => tool.name);
|
|
446
|
-
enabledTools = allTools.filter((tool) => tool !==
|
|
447
|
+
enabledTools = allTools.filter((tool) => tool !== AGENT_TOOL_NAME);
|
|
447
448
|
}
|
|
448
449
|
|
|
449
450
|
// Execute the AI request with tool restrictions
|
|
@@ -476,7 +477,7 @@ export class SubagentManager {
|
|
|
476
477
|
if (abortSignal && !instance.backgroundTaskId) {
|
|
477
478
|
await Promise.race([
|
|
478
479
|
executeAI,
|
|
479
|
-
createAbortPromise(abortSignal, "
|
|
480
|
+
createAbortPromise(abortSignal, "Agent was aborted"),
|
|
480
481
|
]);
|
|
481
482
|
} else {
|
|
482
483
|
await executeAI;
|
|
@@ -510,7 +511,7 @@ export class SubagentManager {
|
|
|
510
511
|
const task = backgroundTaskManager.getTask(instance.backgroundTaskId);
|
|
511
512
|
if (task) {
|
|
512
513
|
task.status = "completed";
|
|
513
|
-
task.stdout = response || "
|
|
514
|
+
task.stdout = response || "Agent completed with no text response";
|
|
514
515
|
task.endTime = Date.now();
|
|
515
516
|
if (task.startTime) {
|
|
516
517
|
task.runtime = task.endTime - task.startTime;
|
|
@@ -518,7 +519,7 @@ export class SubagentManager {
|
|
|
518
519
|
}
|
|
519
520
|
}
|
|
520
521
|
|
|
521
|
-
return response || "
|
|
522
|
+
return response || "Agent completed with no text response";
|
|
522
523
|
} catch (error) {
|
|
523
524
|
const backgroundTaskManager = this.container.has("BackgroundTaskManager")
|
|
524
525
|
? this.container.get<BackgroundTaskManager>("BackgroundTaskManager")
|
|
@@ -9,10 +9,9 @@ import { askUserQuestionTool } from "../tools/askUserQuestion.js";
|
|
|
9
9
|
// New tools
|
|
10
10
|
import { globTool } from "../tools/globTool.js";
|
|
11
11
|
import { grepTool } from "../tools/grepTool.js";
|
|
12
|
-
import { lsTool } from "../tools/lsTool.js";
|
|
13
12
|
import { readTool } from "../tools/readTool.js";
|
|
14
13
|
import { lspTool } from "../tools/lspTool.js";
|
|
15
|
-
import {
|
|
14
|
+
import { agentTool } from "../tools/agentTool.js";
|
|
16
15
|
import { skillTool } from "../tools/skillTool.js";
|
|
17
16
|
import {
|
|
18
17
|
taskCreateTool,
|
|
@@ -78,10 +77,10 @@ class ToolManager {
|
|
|
78
77
|
*
|
|
79
78
|
* This method can be called multiple times safely. When called without dependencies,
|
|
80
79
|
* it registers basic tools (Bash, Read, Write, TaskCreate, etc.). When called with
|
|
81
|
-
* dependencies, it also registers tools that require managers (
|
|
80
|
+
* dependencies, it also registers tools that require managers (Agent, Skill).
|
|
82
81
|
*
|
|
83
82
|
* @param deps Optional dependencies for advanced tools
|
|
84
|
-
* @param deps.subagentManager SubagentManager instance for
|
|
83
|
+
* @param deps.subagentManager SubagentManager instance for Agent tool
|
|
85
84
|
* @param deps.skillManager SkillManager instance for Skill tool
|
|
86
85
|
*
|
|
87
86
|
* @example
|
|
@@ -107,10 +106,9 @@ class ToolManager {
|
|
|
107
106
|
askUserQuestionTool,
|
|
108
107
|
globTool,
|
|
109
108
|
grepTool,
|
|
110
|
-
lsTool,
|
|
111
109
|
readTool,
|
|
112
110
|
lspTool,
|
|
113
|
-
|
|
111
|
+
agentTool,
|
|
114
112
|
skillTool,
|
|
115
113
|
taskCreateTool,
|
|
116
114
|
taskGetTool,
|
package/src/prompts/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
READ_TOOL_NAME,
|
|
15
15
|
WRITE_TOOL_NAME,
|
|
16
16
|
EXIT_PLAN_MODE_TOOL_NAME,
|
|
17
|
+
AGENT_TOOL_NAME,
|
|
17
18
|
} from "../constants/tools.js";
|
|
18
19
|
|
|
19
20
|
export const BASE_SYSTEM_PROMPT = `You are an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.
|
|
@@ -61,7 +62,7 @@ You should build your plan incrementally by writing to or editing this file. NOT
|
|
|
61
62
|
## Plan Workflow
|
|
62
63
|
|
|
63
64
|
### Phase 1: Initial Understanding
|
|
64
|
-
Goal: Gain a comprehensive understanding of the user's request by reading through code and asking them questions. Critical: In this phase you should only use the
|
|
65
|
+
Goal: Gain a comprehensive understanding of the user's request by reading through code and asking them questions. Critical: In this phase you should only use the ${AGENT_TOOL_NAME} tool with subagent_type=${EXPLORE_SUBAGENT_TYPE}.
|
|
65
66
|
|
|
66
67
|
1. Focus on understanding the user's request and the code associated with their request. Actively search for existing functions, utilities, and patterns that can be reused — avoid proposing new code when suitable implementations already exist.
|
|
67
68
|
|
|
@@ -74,7 +75,7 @@ Goal: Gain a comprehensive understanding of the user's request by reading throug
|
|
|
74
75
|
### Phase 2: Design
|
|
75
76
|
Goal: Design an implementation approach.
|
|
76
77
|
|
|
77
|
-
Launch
|
|
78
|
+
Launch agent(s) with subagent_type=${PLAN_SUBAGENT_TYPE} to design the implementation based on the user's intent and your exploration results from Phase 1.
|
|
78
79
|
|
|
79
80
|
You can launch up to 3 agent(s) in parallel.
|
|
80
81
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
|
|
2
2
|
import { EXPLORE_SUBAGENT_TYPE } from "../constants/subagents.js";
|
|
3
|
-
import {
|
|
3
|
+
import { AGENT_TOOL_NAME } from "../constants/tools.js";
|
|
4
4
|
import type { SubagentConfiguration } from "../utils/subagentParser.js";
|
|
5
5
|
import {
|
|
6
6
|
countToolBlocks,
|
|
@@ -8,16 +8,16 @@ import {
|
|
|
8
8
|
} from "../utils/messageOperations.js";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* Agent tool plugin for launching specialized agents to handle complex tasks
|
|
12
12
|
*/
|
|
13
|
-
export const
|
|
14
|
-
name:
|
|
13
|
+
export const agentTool: ToolPlugin = {
|
|
14
|
+
name: AGENT_TOOL_NAME,
|
|
15
15
|
config: {
|
|
16
16
|
type: "function" as const,
|
|
17
17
|
function: {
|
|
18
|
-
name:
|
|
18
|
+
name: AGENT_TOOL_NAME,
|
|
19
19
|
description:
|
|
20
|
-
"
|
|
20
|
+
"Launch a new agent to handle complex, multi-step tasks autonomously.",
|
|
21
21
|
parameters: {
|
|
22
22
|
type: "object",
|
|
23
23
|
properties: {
|
|
@@ -47,19 +47,31 @@ export const taskTool: ToolPlugin = {
|
|
|
47
47
|
prompt: (args?: { availableSubagents?: SubagentConfiguration[] }) => {
|
|
48
48
|
const subagentList = args?.availableSubagents
|
|
49
49
|
? args.availableSubagents
|
|
50
|
-
.map((config) =>
|
|
50
|
+
.map((config) => {
|
|
51
|
+
let toolsStr = "";
|
|
52
|
+
if (config.tools && config.tools.length > 0) {
|
|
53
|
+
toolsStr = ` (Tools: ${config.tools.join(", ")})`;
|
|
54
|
+
} else {
|
|
55
|
+
toolsStr = " (Tools: *)";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return `- ${config.name}: ${config.description}${toolsStr}`;
|
|
59
|
+
})
|
|
51
60
|
.join("\n")
|
|
52
61
|
: "";
|
|
53
62
|
|
|
54
|
-
return `
|
|
55
|
-
|
|
63
|
+
return `Launch a new agent to handle complex, multi-step tasks autonomously.
|
|
64
|
+
|
|
65
|
+
The Agent tool launches specialized agents (subprocesses) that autonomously handle complex tasks. Each agent type has specific capabilities and tools available to it.
|
|
66
|
+
|
|
67
|
+
Available agent types and the tools they have access to:
|
|
68
|
+
${subagentList || "No agents configured"}
|
|
56
69
|
|
|
57
|
-
|
|
58
|
-
${subagentList || "No subagents configured"}
|
|
70
|
+
When using the Agent tool, you must specify a subagent_type parameter to select which agent type to use.
|
|
59
71
|
|
|
60
|
-
- When doing file search, prefer to use the ${
|
|
61
|
-
- You should proactively use the ${
|
|
62
|
-
- 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 ${
|
|
72
|
+
- When doing file search, prefer to use the ${AGENT_TOOL_NAME} tool in order to reduce context usage.
|
|
73
|
+
- You should proactively use the ${AGENT_TOOL_NAME} tool with specialized agents when the task at hand matches the agent's description.
|
|
74
|
+
- 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 ${AGENT_TOOL_NAME} tool with subagent_type=${EXPLORE_SUBAGENT_TYPE} instead of running search commands directly.`;
|
|
63
75
|
},
|
|
64
76
|
|
|
65
77
|
execute: async (
|
|
@@ -72,7 +84,7 @@ ${subagentList || "No subagents configured"}
|
|
|
72
84
|
success: false,
|
|
73
85
|
content: "",
|
|
74
86
|
error: "Subagent manager not available in tool context",
|
|
75
|
-
shortResult: "
|
|
87
|
+
shortResult: "Agent delegation failed",
|
|
76
88
|
};
|
|
77
89
|
}
|
|
78
90
|
|
|
@@ -87,7 +99,7 @@ ${subagentList || "No subagents configured"}
|
|
|
87
99
|
success: false,
|
|
88
100
|
content: "",
|
|
89
101
|
error: "description parameter is required and must be a string",
|
|
90
|
-
shortResult: "
|
|
102
|
+
shortResult: "Agent delegation failed",
|
|
91
103
|
};
|
|
92
104
|
}
|
|
93
105
|
|
|
@@ -96,7 +108,7 @@ ${subagentList || "No subagents configured"}
|
|
|
96
108
|
success: false,
|
|
97
109
|
content: "",
|
|
98
110
|
error: "prompt parameter is required and must be a string",
|
|
99
|
-
shortResult: "
|
|
111
|
+
shortResult: "Agent delegation failed",
|
|
100
112
|
};
|
|
101
113
|
}
|
|
102
114
|
|
|
@@ -105,7 +117,7 @@ ${subagentList || "No subagents configured"}
|
|
|
105
117
|
success: false,
|
|
106
118
|
content: "",
|
|
107
119
|
error: "subagent_type parameter is required and must be a string",
|
|
108
|
-
shortResult: "
|
|
120
|
+
shortResult: "Agent delegation failed",
|
|
109
121
|
};
|
|
110
122
|
}
|
|
111
123
|
|
|
@@ -121,14 +133,14 @@ ${subagentList || "No subagents configured"}
|
|
|
121
133
|
return {
|
|
122
134
|
success: false,
|
|
123
135
|
content: "",
|
|
124
|
-
error: `No
|
|
125
|
-
shortResult: "
|
|
136
|
+
error: `No agent found matching "${subagent_type}". Available agents: ${availableNames || "none"}`,
|
|
137
|
+
shortResult: "Agent not found",
|
|
126
138
|
};
|
|
127
139
|
}
|
|
128
140
|
|
|
129
141
|
let isBackgrounded = false;
|
|
130
142
|
|
|
131
|
-
// Create subagent instance and execute
|
|
143
|
+
// Create subagent instance and execute agent
|
|
132
144
|
const instance = await subagentManager.createInstance(
|
|
133
145
|
configuration,
|
|
134
146
|
{
|
|
@@ -173,8 +185,8 @@ ${subagentList || "No subagents configured"}
|
|
|
173
185
|
await subagentManager.backgroundInstance(instance.subagentId);
|
|
174
186
|
resolve({
|
|
175
187
|
success: true,
|
|
176
|
-
content: "
|
|
177
|
-
shortResult: "
|
|
188
|
+
content: "Agent backgrounded",
|
|
189
|
+
shortResult: "Agent backgrounded",
|
|
178
190
|
isManuallyBackgrounded: true,
|
|
179
191
|
});
|
|
180
192
|
},
|
|
@@ -182,7 +194,7 @@ ${subagentList || "No subagents configured"}
|
|
|
182
194
|
}
|
|
183
195
|
|
|
184
196
|
try {
|
|
185
|
-
const result = await subagentManager.
|
|
197
|
+
const result = await subagentManager.executeAgent(
|
|
186
198
|
instance,
|
|
187
199
|
prompt,
|
|
188
200
|
context.abortSignal,
|
|
@@ -196,13 +208,13 @@ ${subagentList || "No subagents configured"}
|
|
|
196
208
|
if (run_in_background) {
|
|
197
209
|
resolve({
|
|
198
210
|
success: true,
|
|
199
|
-
content: `
|
|
200
|
-
shortResult: `
|
|
211
|
+
content: `Agent started in background with ID: ${result}`,
|
|
212
|
+
shortResult: `Agent started in background: ${result}`,
|
|
201
213
|
});
|
|
202
214
|
return;
|
|
203
215
|
}
|
|
204
216
|
|
|
205
|
-
// Cleanup subagent instance after
|
|
217
|
+
// Cleanup subagent instance after agent completion
|
|
206
218
|
subagentManager.cleanupInstance(instance.subagentId);
|
|
207
219
|
|
|
208
220
|
const messages = instance.messageManager.getMessages();
|
|
@@ -213,14 +225,14 @@ ${subagentList || "No subagents configured"}
|
|
|
213
225
|
resolve({
|
|
214
226
|
success: true,
|
|
215
227
|
content: result,
|
|
216
|
-
shortResult: `
|
|
228
|
+
shortResult: `Agent completed${summary ? ` ${summary}` : ""}`,
|
|
217
229
|
});
|
|
218
230
|
} catch (error) {
|
|
219
231
|
if (!isBackgrounded) {
|
|
220
232
|
resolve({
|
|
221
233
|
success: false,
|
|
222
234
|
content: "",
|
|
223
|
-
error: `
|
|
235
|
+
error: `Agent delegation failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
224
236
|
shortResult: "Delegation error",
|
|
225
237
|
});
|
|
226
238
|
}
|
|
@@ -237,7 +249,7 @@ ${subagentList || "No subagents configured"}
|
|
|
237
249
|
return {
|
|
238
250
|
success: false,
|
|
239
251
|
content: "",
|
|
240
|
-
error: `
|
|
252
|
+
error: `Agent delegation failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
241
253
|
shortResult: "Delegation error",
|
|
242
254
|
};
|
|
243
255
|
}
|
package/src/tools/grepTool.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { getDisplayPath } from "../utils/path.js";
|
|
|
6
6
|
import {
|
|
7
7
|
GREP_TOOL_NAME,
|
|
8
8
|
BASH_TOOL_NAME,
|
|
9
|
-
|
|
9
|
+
AGENT_TOOL_NAME,
|
|
10
10
|
} from "../constants/tools.js";
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -94,7 +94,7 @@ export const grepTool: ToolPlugin = {
|
|
|
94
94
|
- Supports full regex syntax (e.g., "log.*Error", "function\\s+\\w+")
|
|
95
95
|
- Filter files with glob parameter (e.g., "*.js", "**/*.tsx") or type parameter (e.g., "js", "py", "rust")
|
|
96
96
|
- Output modes: "content" shows matching lines, "files_with_matches" shows only file paths (default), "count" shows match counts
|
|
97
|
-
- Use ${
|
|
97
|
+
- Use ${AGENT_TOOL_NAME} tool for open-ended searches requiring multiple rounds
|
|
98
98
|
- Pattern syntax: Uses ripgrep (not grep) - literal braces need escaping (use \`interface\\{\\}\` to find \`interface{}\` in Go code)
|
|
99
99
|
- Multiline matching: By default patterns match within single lines only. For cross-line patterns like \`struct \\{[\\s\\S]*?field\`, use \`multiline: true\`
|
|
100
100
|
`,
|
package/src/tools/skillTool.ts
CHANGED
|
@@ -155,14 +155,14 @@ export const skillTool: ToolPlugin = {
|
|
|
155
155
|
);
|
|
156
156
|
|
|
157
157
|
try {
|
|
158
|
-
const result = await subagentManager.
|
|
158
|
+
const result = await subagentManager.executeAgent(
|
|
159
159
|
instance,
|
|
160
160
|
skillResult.content,
|
|
161
161
|
context.abortSignal,
|
|
162
162
|
false,
|
|
163
163
|
);
|
|
164
164
|
|
|
165
|
-
// Cleanup subagent instance after
|
|
165
|
+
// Cleanup subagent instance after agent completion
|
|
166
166
|
subagentManager.cleanupInstance(instance.subagentId);
|
|
167
167
|
|
|
168
168
|
const messages = instance.messageManager.getMessages();
|
package/src/tools/types.ts
CHANGED
|
@@ -73,7 +73,7 @@ export interface ToolContext {
|
|
|
73
73
|
foregroundTaskManager?: import("../types/processes.js").IForegroundTaskManager;
|
|
74
74
|
/** Task manager instance for task management */
|
|
75
75
|
taskManager: import("../services/taskManager.js").TaskManager;
|
|
76
|
-
/** Subagent manager instance for
|
|
76
|
+
/** Subagent manager instance for agent delegation */
|
|
77
77
|
subagentManager?: import("../managers/subagentManager.js").SubagentManager;
|
|
78
78
|
/** Skill manager instance for skill invocation */
|
|
79
79
|
skillManager?: import("../managers/skillManager.js").SkillManager;
|
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
GLOB_TOOL_NAME,
|
|
16
16
|
GREP_TOOL_NAME,
|
|
17
17
|
READ_TOOL_NAME,
|
|
18
|
-
LS_TOOL_NAME,
|
|
19
18
|
LSP_TOOL_NAME,
|
|
20
19
|
} from "../constants/tools.js";
|
|
21
20
|
import type { SubagentConfiguration } from "./subagentParser.js";
|
|
@@ -79,7 +78,6 @@ function createExploreSubagent(): SubagentConfiguration {
|
|
|
79
78
|
GREP_TOOL_NAME,
|
|
80
79
|
READ_TOOL_NAME,
|
|
81
80
|
BASH_TOOL_NAME,
|
|
82
|
-
LS_TOOL_NAME,
|
|
83
81
|
LSP_TOOL_NAME,
|
|
84
82
|
];
|
|
85
83
|
|
|
@@ -107,7 +105,6 @@ function createPlanSubagent(): SubagentConfiguration {
|
|
|
107
105
|
GREP_TOOL_NAME,
|
|
108
106
|
READ_TOOL_NAME,
|
|
109
107
|
BASH_TOOL_NAME,
|
|
110
|
-
LS_TOOL_NAME,
|
|
111
108
|
LSP_TOOL_NAME,
|
|
112
109
|
];
|
|
113
110
|
|