wave-agent-sdk 0.7.2 → 0.8.1
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 +9 -79
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +85 -302
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +20 -13
- package/dist/managers/backgroundTaskManager.d.ts +1 -1
- package/dist/managers/backgroundTaskManager.d.ts.map +1 -1
- package/dist/managers/backgroundTaskManager.js +1 -1
- package/dist/managers/{bashManager.d.ts → bangManager.d.ts} +4 -4
- package/dist/managers/{bashManager.d.ts.map → bangManager.d.ts.map} +1 -1
- package/dist/managers/{bashManager.js → bangManager.js} +5 -6
- package/dist/managers/hookManager.d.ts.map +1 -1
- package/dist/managers/hookManager.js +12 -3
- package/dist/managers/messageManager.d.ts +18 -6
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +42 -20
- package/dist/managers/permissionManager.d.ts +22 -1
- package/dist/managers/permissionManager.d.ts.map +1 -1
- package/dist/managers/permissionManager.js +106 -85
- package/dist/managers/planManager.d.ts +6 -0
- package/dist/managers/planManager.d.ts.map +1 -1
- package/dist/managers/planManager.js +21 -0
- package/dist/managers/skillManager.d.ts +7 -2
- package/dist/managers/skillManager.d.ts.map +1 -1
- package/dist/managers/skillManager.js +30 -10
- package/dist/managers/slashCommandManager.d.ts +7 -0
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +59 -59
- package/dist/managers/subagentManager.d.ts +4 -0
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +47 -13
- package/dist/managers/toolManager.d.ts +7 -1
- package/dist/managers/toolManager.d.ts.map +1 -1
- package/dist/managers/toolManager.js +15 -2
- package/dist/prompts/index.d.ts +0 -4
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +0 -9
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +9 -9
- package/dist/services/configurationService.d.ts +2 -2
- package/dist/services/configurationService.d.ts.map +1 -1
- package/dist/services/configurationService.js +4 -4
- package/dist/services/hook.d.ts.map +1 -1
- package/dist/services/hook.js +6 -0
- package/dist/services/initializationService.d.ts +44 -0
- package/dist/services/initializationService.d.ts.map +1 -0
- package/dist/services/initializationService.js +170 -0
- package/dist/services/interactionService.d.ts +29 -0
- package/dist/services/interactionService.d.ts.map +1 -0
- package/dist/services/interactionService.js +97 -0
- package/dist/services/session.js +1 -1
- package/dist/services/taskManager.d.ts +5 -0
- package/dist/services/taskManager.d.ts.map +1 -1
- package/dist/services/taskManager.js +16 -2
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +7 -18
- package/dist/tools/editTool.js +1 -1
- package/dist/tools/exitPlanMode.js +1 -1
- package/dist/tools/globTool.d.ts.map +1 -1
- package/dist/tools/globTool.js +12 -2
- package/dist/tools/lspTool.d.ts +2 -0
- package/dist/tools/lspTool.d.ts.map +1 -1
- package/dist/tools/lspTool.js +144 -52
- package/dist/tools/skillTool.d.ts.map +1 -1
- package/dist/tools/skillTool.js +97 -2
- package/dist/tools/taskManagementTools.d.ts.map +1 -1
- package/dist/tools/taskManagementTools.js +23 -2
- package/dist/tools/taskTool.d.ts.map +1 -1
- package/dist/tools/taskTool.js +9 -15
- package/dist/tools/types.d.ts +1 -2
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/writeTool.js +1 -1
- package/dist/types/agent.d.ts +64 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +1 -0
- package/dist/types/commands.d.ts +0 -4
- package/dist/types/commands.d.ts.map +1 -1
- package/dist/types/config.d.ts +1 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/hooks.d.ts +3 -1
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/hooks.js +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/messaging.d.ts +3 -3
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/types/skills.d.ts +13 -0
- package/dist/types/skills.d.ts.map +1 -1
- package/dist/utils/commandArgumentParser.d.ts.map +1 -1
- package/dist/utils/commandArgumentParser.js +7 -0
- package/dist/utils/commandPathResolver.d.ts +3 -36
- package/dist/utils/commandPathResolver.d.ts.map +1 -1
- package/dist/utils/commandPathResolver.js +16 -93
- package/dist/utils/configValidator.d.ts +2 -2
- package/dist/utils/configValidator.d.ts.map +1 -1
- package/dist/utils/configValidator.js +4 -6
- package/dist/utils/containerSetup.d.ts +3 -4
- package/dist/utils/containerSetup.d.ts.map +1 -1
- package/dist/utils/containerSetup.js +14 -9
- package/dist/utils/customCommands.d.ts +2 -3
- package/dist/utils/customCommands.d.ts.map +1 -1
- package/dist/utils/customCommands.js +20 -60
- package/dist/utils/gitUtils.d.ts +25 -0
- package/dist/utils/gitUtils.d.ts.map +1 -1
- package/dist/utils/gitUtils.js +75 -0
- package/dist/utils/markdownParser.d.ts +4 -0
- package/dist/utils/markdownParser.d.ts.map +1 -1
- package/dist/utils/markdownParser.js +33 -0
- package/dist/utils/messageOperations.d.ts +16 -7
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +45 -20
- package/dist/utils/nameGenerator.d.ts +1 -1
- package/dist/utils/nameGenerator.d.ts.map +1 -1
- package/dist/utils/nameGenerator.js +10 -6
- package/dist/utils/skillParser.d.ts.map +1 -1
- package/dist/utils/skillParser.js +48 -0
- package/package.json +1 -1
- package/src/agent.ts +103 -458
- package/src/index.ts +2 -2
- package/src/managers/aiManager.ts +23 -17
- package/src/managers/backgroundTaskManager.ts +2 -2
- package/src/managers/{bashManager.ts → bangManager.ts} +11 -8
- package/src/managers/hookManager.ts +13 -3
- package/src/managers/messageManager.ts +55 -26
- package/src/managers/permissionManager.ts +121 -98
- package/src/managers/planManager.ts +26 -0
- package/src/managers/skillManager.ts +51 -14
- package/src/managers/slashCommandManager.ts +83 -73
- package/src/managers/subagentManager.ts +57 -13
- package/src/managers/toolManager.ts +22 -2
- package/src/prompts/index.ts +0 -15
- package/src/services/aiService.ts +12 -15
- package/src/services/configurationService.ts +4 -4
- package/src/services/hook.ts +7 -0
- package/src/services/initializationService.ts +291 -0
- package/src/services/interactionService.ts +171 -0
- package/src/services/session.ts +1 -1
- package/src/services/taskManager.ts +18 -2
- package/src/tools/bashTool.ts +8 -18
- package/src/tools/editTool.ts +1 -1
- package/src/tools/exitPlanMode.ts +1 -1
- package/src/tools/globTool.ts +15 -2
- package/src/tools/lsTool.ts +1 -1
- package/src/tools/lspTool.ts +184 -52
- package/src/tools/skillTool.ts +127 -2
- package/src/tools/taskManagementTools.ts +32 -2
- package/src/tools/taskTool.ts +13 -15
- package/src/tools/types.ts +1 -2
- package/src/tools/writeTool.ts +1 -1
- package/src/types/agent.ts +83 -0
- package/src/types/commands.ts +0 -6
- package/src/types/config.ts +1 -1
- package/src/types/hooks.ts +5 -1
- package/src/types/index.ts +1 -0
- package/src/types/messaging.ts +3 -3
- package/src/types/skills.ts +13 -0
- package/src/utils/commandArgumentParser.ts +8 -0
- package/src/utils/commandPathResolver.ts +14 -117
- package/src/utils/configValidator.ts +5 -9
- package/src/utils/containerSetup.ts +17 -14
- package/src/utils/customCommands.ts +20 -83
- package/src/utils/gitUtils.ts +75 -0
- package/src/utils/markdownParser.ts +47 -0
- package/src/utils/messageOperations.ts +58 -28
- package/src/utils/nameGenerator.ts +10 -6
- package/src/utils/skillParser.ts +52 -0
- package/dist/managers/backgroundBashManager.d.ts +0 -27
- package/dist/managers/backgroundBashManager.d.ts.map +0 -1
- package/dist/managers/backgroundBashManager.js +0 -169
- package/src/managers/backgroundBashManager.ts +0 -206
|
@@ -12,15 +12,13 @@ import {
|
|
|
12
12
|
} from "../utils/commandArgumentParser.js";
|
|
13
13
|
import { Container } from "../utils/container.js";
|
|
14
14
|
import {
|
|
15
|
-
BashCommandResult,
|
|
16
15
|
parseBashCommands,
|
|
17
16
|
replaceBashCommandsWithOutput,
|
|
17
|
+
executeBashCommands,
|
|
18
18
|
} from "../utils/markdownParser.js";
|
|
19
|
-
import { exec } from "child_process";
|
|
20
|
-
import { promisify } from "util";
|
|
21
19
|
import { INIT_PROMPT } from "../prompts/index.js";
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
import type { SkillManager } from "./skillManager.js";
|
|
21
|
+
import type { SkillMetadata } from "../types/skills.js";
|
|
24
22
|
|
|
25
23
|
import { logger } from "../utils/globalLogger.js";
|
|
26
24
|
|
|
@@ -31,6 +29,7 @@ export interface SlashCommandManagerOptions {
|
|
|
31
29
|
export class SlashCommandManager {
|
|
32
30
|
private commands = new Map<string, SlashCommand>();
|
|
33
31
|
private customCommands = new Map<string, CustomSlashCommand>();
|
|
32
|
+
private skillCommandIds = new Set<string>();
|
|
34
33
|
private workdir: string;
|
|
35
34
|
|
|
36
35
|
constructor(
|
|
@@ -61,25 +60,11 @@ export class SlashCommandManager {
|
|
|
61
60
|
return this.container.get<TaskManager>("TaskManager")!;
|
|
62
61
|
}
|
|
63
62
|
|
|
64
|
-
private
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
id: "clear",
|
|
68
|
-
name: "clear",
|
|
69
|
-
description: "Clear the chat session and terminal",
|
|
70
|
-
handler: () => {
|
|
71
|
-
// Clear chat messages
|
|
72
|
-
this.messageManager.clearMessages();
|
|
73
|
-
|
|
74
|
-
// Reset task list if WAVE_TASK_LIST_ID is not set
|
|
75
|
-
if (!process.env.WAVE_TASK_LIST_ID) {
|
|
76
|
-
const newTaskListId = this.messageManager.getRootSessionId();
|
|
77
|
-
this.taskManager.setTaskListId(newTaskListId);
|
|
78
|
-
this.taskManager.emit("tasksChange", newTaskListId);
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
});
|
|
63
|
+
private get skillManager(): SkillManager {
|
|
64
|
+
return this.container.get<SkillManager>("SkillManager")!;
|
|
65
|
+
}
|
|
82
66
|
|
|
67
|
+
private initializeBuiltinCommands(): void {
|
|
83
68
|
// Register built-in init command
|
|
84
69
|
this.registerCommand({
|
|
85
70
|
id: "init",
|
|
@@ -132,15 +117,10 @@ export class SlashCommandManager {
|
|
|
132
117
|
}
|
|
133
118
|
|
|
134
119
|
if (args) {
|
|
135
|
-
|
|
136
|
-
processedContent
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
);
|
|
140
|
-
} else {
|
|
141
|
-
// If no placeholders, append arguments to the content
|
|
142
|
-
processedContent = `${processedContent.trim()} ${args}`;
|
|
143
|
-
}
|
|
120
|
+
processedContent = substituteCommandParameters(
|
|
121
|
+
processedContent,
|
|
122
|
+
args,
|
|
123
|
+
);
|
|
144
124
|
}
|
|
145
125
|
|
|
146
126
|
await this.executeCustomCommandInMainAgent(
|
|
@@ -159,6 +139,66 @@ export class SlashCommandManager {
|
|
|
159
139
|
}
|
|
160
140
|
}
|
|
161
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Register skills as slash commands
|
|
144
|
+
*/
|
|
145
|
+
public registerSkillCommands(skills: SkillMetadata[]): void {
|
|
146
|
+
// Clear existing skill commands
|
|
147
|
+
for (const commandId of this.skillCommandIds) {
|
|
148
|
+
this.unregisterCommand(commandId);
|
|
149
|
+
}
|
|
150
|
+
this.skillCommandIds.clear();
|
|
151
|
+
|
|
152
|
+
for (const skill of skills) {
|
|
153
|
+
if (skill.userInvocable === false) {
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
const commandId = skill.name;
|
|
157
|
+
this.skillCommandIds.add(commandId);
|
|
158
|
+
|
|
159
|
+
this.registerCommand({
|
|
160
|
+
id: commandId,
|
|
161
|
+
name: skill.name,
|
|
162
|
+
description: `Skill: ${skill.description}`,
|
|
163
|
+
handler: async (args?: string) => {
|
|
164
|
+
try {
|
|
165
|
+
const result = await this.skillManager.executeSkill({
|
|
166
|
+
skill_name: skill.name,
|
|
167
|
+
args,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Add user message with skill content
|
|
171
|
+
const originalInput = args
|
|
172
|
+
? `/${skill.name} ${args}`
|
|
173
|
+
: `/${skill.name}`;
|
|
174
|
+
this.messageManager.addUserMessage({
|
|
175
|
+
content: originalInput,
|
|
176
|
+
customCommandContent: result.content,
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Trigger AI response
|
|
180
|
+
await this.aiManager.sendAIMessage({
|
|
181
|
+
model: skill.model,
|
|
182
|
+
allowedRules: result.allowedTools,
|
|
183
|
+
});
|
|
184
|
+
} catch (error) {
|
|
185
|
+
logger?.error(
|
|
186
|
+
`Failed to execute skill command '${skill.name}':`,
|
|
187
|
+
error,
|
|
188
|
+
);
|
|
189
|
+
this.messageManager.addErrorBlock(
|
|
190
|
+
`Failed to execute skill command '${skill.name}': ${
|
|
191
|
+
error instanceof Error ? error.message : String(error)
|
|
192
|
+
}`,
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
logger?.debug(`Registered ${skills.length} skill commands`);
|
|
200
|
+
}
|
|
201
|
+
|
|
162
202
|
/**
|
|
163
203
|
* Register commands from a plugin with namespacing
|
|
164
204
|
*/
|
|
@@ -195,15 +235,10 @@ export class SlashCommandManager {
|
|
|
195
235
|
}
|
|
196
236
|
|
|
197
237
|
if (args) {
|
|
198
|
-
|
|
199
|
-
processedContent
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
);
|
|
203
|
-
} else {
|
|
204
|
-
// If no placeholders, append arguments to the content
|
|
205
|
-
processedContent = `${processedContent.trim()} ${args}`;
|
|
206
|
-
}
|
|
238
|
+
processedContent = substituteCommandParameters(
|
|
239
|
+
processedContent,
|
|
240
|
+
args,
|
|
241
|
+
);
|
|
207
242
|
}
|
|
208
243
|
|
|
209
244
|
await this.executeCustomCommandInMainAgent(
|
|
@@ -343,40 +378,15 @@ export class SlashCommandManager {
|
|
|
343
378
|
const { commands, processedContent } = parseBashCommands(content);
|
|
344
379
|
|
|
345
380
|
// Execute bash commands if any
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
bashResults.push({
|
|
354
|
-
command,
|
|
355
|
-
output: stdout || stderr || "",
|
|
356
|
-
exitCode: 0,
|
|
357
|
-
});
|
|
358
|
-
} catch (error) {
|
|
359
|
-
const execError = error as {
|
|
360
|
-
stdout?: string;
|
|
361
|
-
stderr?: string;
|
|
362
|
-
message?: string;
|
|
363
|
-
code?: number;
|
|
364
|
-
};
|
|
365
|
-
bashResults.push({
|
|
366
|
-
command,
|
|
367
|
-
output:
|
|
368
|
-
execError.stdout || execError.stderr || execError.message || "",
|
|
369
|
-
exitCode: execError.code || 1,
|
|
370
|
-
});
|
|
371
|
-
}
|
|
381
|
+
let finalContent = processedContent;
|
|
382
|
+
if (commands.length > 0) {
|
|
383
|
+
const bashResults = await executeBashCommands(commands, this.workdir);
|
|
384
|
+
finalContent = replaceBashCommandsWithOutput(
|
|
385
|
+
processedContent,
|
|
386
|
+
bashResults,
|
|
387
|
+
);
|
|
372
388
|
}
|
|
373
389
|
|
|
374
|
-
// Replace bash command placeholders with their outputs
|
|
375
|
-
const finalContent =
|
|
376
|
-
bashResults.length > 0
|
|
377
|
-
? replaceBashCommandsWithOutput(processedContent, bashResults)
|
|
378
|
-
: processedContent;
|
|
379
|
-
|
|
380
390
|
// Add custom command message to show the command being executed
|
|
381
391
|
const originalInput = args
|
|
382
392
|
? `/${commandName} ${args}`
|
|
@@ -14,12 +14,14 @@ import {
|
|
|
14
14
|
createAbortPromise,
|
|
15
15
|
} from "../utils/abortUtils.js";
|
|
16
16
|
import { BackgroundTaskManager } from "./backgroundTaskManager.js";
|
|
17
|
+
import { logger } from "../utils/globalLogger.js";
|
|
17
18
|
import {
|
|
18
19
|
UserMessageParams,
|
|
19
20
|
type AgentToolBlockUpdateParams,
|
|
20
21
|
} from "../utils/messageOperations.js";
|
|
21
22
|
|
|
22
23
|
import { Container } from "../utils/container.js";
|
|
24
|
+
import type { PermissionManager } from "./permissionManager.js";
|
|
23
25
|
|
|
24
26
|
export interface SubagentManagerCallbacks {
|
|
25
27
|
// Granular subagent message callbacks (015-subagent-message-callbacks)
|
|
@@ -67,8 +69,10 @@ export interface SubagentInstance {
|
|
|
67
69
|
lastTools: string[]; // Track last two tool names
|
|
68
70
|
subagentType: string; // Store the subagent type for hook context
|
|
69
71
|
description: string; // Store the AI-generated description
|
|
72
|
+
allowedTools?: string[]; // Optional permission rules (e.g. git:*)
|
|
70
73
|
backgroundTaskId?: string; // ID of the background task if transitioned
|
|
71
74
|
onUpdate?: () => void; // Optional callback for real-time updates
|
|
75
|
+
model?: string; // Optional model override
|
|
72
76
|
}
|
|
73
77
|
|
|
74
78
|
export interface SubagentManagerOptions {
|
|
@@ -159,6 +163,8 @@ export class SubagentManager {
|
|
|
159
163
|
description: string;
|
|
160
164
|
prompt: string;
|
|
161
165
|
subagent_type: string;
|
|
166
|
+
allowedTools?: string[];
|
|
167
|
+
model?: string;
|
|
162
168
|
},
|
|
163
169
|
runInBackground?: boolean,
|
|
164
170
|
onUpdate?: () => void,
|
|
@@ -176,6 +182,31 @@ export class SubagentManager {
|
|
|
176
182
|
// Create a child container for the subagent to isolate its managers
|
|
177
183
|
const subagentContainer = this.container.createChild();
|
|
178
184
|
|
|
185
|
+
// Create isolated PermissionManager for the subagent
|
|
186
|
+
const { PermissionManager } = await import("./permissionManager.js");
|
|
187
|
+
const parentPermissionManager =
|
|
188
|
+
this.container.get<PermissionManager>("PermissionManager");
|
|
189
|
+
const subagentPermissionManager = new PermissionManager(subagentContainer, {
|
|
190
|
+
workdir: this.workdir,
|
|
191
|
+
configuredDefaultMode:
|
|
192
|
+
parentPermissionManager?.getConfiguredDefaultMode(),
|
|
193
|
+
allowedRules: parentPermissionManager?.getAllowedRules(),
|
|
194
|
+
deniedRules: parentPermissionManager?.getDeniedRules(),
|
|
195
|
+
additionalDirectories:
|
|
196
|
+
parentPermissionManager?.getAdditionalDirectories(),
|
|
197
|
+
planFilePath: parentPermissionManager?.getPlanFilePath(),
|
|
198
|
+
});
|
|
199
|
+
subagentContainer.register("PermissionManager", subagentPermissionManager);
|
|
200
|
+
|
|
201
|
+
// Add temporary permission rules if provided
|
|
202
|
+
if (parameters.allowedTools) {
|
|
203
|
+
logger.debug(
|
|
204
|
+
`Adding ${parameters.allowedTools.length} temporary permission rules to subagent ${subagentId}`,
|
|
205
|
+
{ rules: parameters.allowedTools },
|
|
206
|
+
);
|
|
207
|
+
subagentPermissionManager.addTemporaryRules(parameters.allowedTools);
|
|
208
|
+
}
|
|
209
|
+
|
|
179
210
|
// Create isolated MessageManager for the subagent
|
|
180
211
|
const subagentCallbacks = this.createSubagentCallbacks(subagentId);
|
|
181
212
|
|
|
@@ -187,8 +218,13 @@ export class SubagentManager {
|
|
|
187
218
|
});
|
|
188
219
|
subagentContainer.register("MessageManager", messageManager);
|
|
189
220
|
|
|
190
|
-
//
|
|
191
|
-
const toolManager =
|
|
221
|
+
// Create isolated ToolManager for the subagent to ensure it uses the subagent's PermissionManager
|
|
222
|
+
const toolManager = new ToolManager({
|
|
223
|
+
container: subagentContainer,
|
|
224
|
+
tools: configuration.tools,
|
|
225
|
+
});
|
|
226
|
+
toolManager.initializeBuiltInTools();
|
|
227
|
+
subagentContainer.register("ToolManager", toolManager);
|
|
192
228
|
|
|
193
229
|
// Create isolated AIManager for the subagent
|
|
194
230
|
const aiManager = new AIManager(subagentContainer, {
|
|
@@ -201,9 +237,12 @@ export class SubagentManager {
|
|
|
201
237
|
const parentModelConfig = this.getModelConfig();
|
|
202
238
|
let modelToUse: string;
|
|
203
239
|
|
|
204
|
-
if (
|
|
205
|
-
// Use
|
|
206
|
-
modelToUse =
|
|
240
|
+
if (parameters.model) {
|
|
241
|
+
// Use model override from parameters if provided
|
|
242
|
+
modelToUse = parameters.model;
|
|
243
|
+
} else if (!configuration.model || configuration.model === "inherit") {
|
|
244
|
+
// Use parent's model for "inherit" or undefined
|
|
245
|
+
modelToUse = parentModelConfig.model;
|
|
207
246
|
} else if (configuration.model === "fastModel") {
|
|
208
247
|
// Use parent's fastModel for special "fastModel" value
|
|
209
248
|
modelToUse = parentModelConfig.fastModel;
|
|
@@ -214,7 +253,7 @@ export class SubagentManager {
|
|
|
214
253
|
|
|
215
254
|
return {
|
|
216
255
|
...parentModelConfig,
|
|
217
|
-
|
|
256
|
+
model: modelToUse,
|
|
218
257
|
};
|
|
219
258
|
},
|
|
220
259
|
getMaxInputTokens: this.getMaxInputTokens,
|
|
@@ -237,6 +276,8 @@ export class SubagentManager {
|
|
|
237
276
|
lastTools: [], // Initialize lastTools
|
|
238
277
|
subagentType: parameters.subagent_type, // Store the subagent type
|
|
239
278
|
description: parameters.description, // Store the AI-generated description
|
|
279
|
+
allowedTools: parameters.allowedTools, // Store optional permission rules
|
|
280
|
+
model: parameters.model, // Store optional model override
|
|
240
281
|
onUpdate,
|
|
241
282
|
};
|
|
242
283
|
|
|
@@ -392,23 +433,26 @@ export class SubagentManager {
|
|
|
392
433
|
// Add the user's prompt as a message
|
|
393
434
|
instance.messageManager.addUserMessage({ content: prompt });
|
|
394
435
|
|
|
395
|
-
// Create
|
|
396
|
-
|
|
436
|
+
// Create enabled tools list - always exclude Task tool to prevent subagent recursion
|
|
437
|
+
// Use instance.configuration.tools if provided, otherwise fallback to all tools
|
|
438
|
+
let enabledTools = instance.configuration.tools;
|
|
397
439
|
|
|
398
440
|
// Always filter out the Task tool to prevent subagents from creating sub-subagents
|
|
399
|
-
if (
|
|
400
|
-
|
|
441
|
+
if (enabledTools) {
|
|
442
|
+
enabledTools = enabledTools.filter((tool) => tool !== "Task");
|
|
401
443
|
} else {
|
|
402
444
|
// If no tools specified, get all tools except Task
|
|
403
445
|
const allTools = instance.toolManager.list().map((tool) => tool.name);
|
|
404
|
-
|
|
446
|
+
enabledTools = allTools.filter((tool) => tool !== "Task");
|
|
405
447
|
}
|
|
406
448
|
|
|
407
449
|
// Execute the AI request with tool restrictions
|
|
408
450
|
// The AIManager will handle abort signals through its own abort controllers
|
|
409
451
|
// Resolve model name for sendAIMessage
|
|
410
452
|
let resolvedModel: string | undefined;
|
|
411
|
-
if (
|
|
453
|
+
if (instance.model) {
|
|
454
|
+
resolvedModel = instance.model;
|
|
455
|
+
} else if (
|
|
412
456
|
instance.configuration.model &&
|
|
413
457
|
instance.configuration.model !== "inherit"
|
|
414
458
|
) {
|
|
@@ -424,7 +468,7 @@ export class SubagentManager {
|
|
|
424
468
|
// For "inherit" or undefined, resolvedModel remains undefined (uses AIManager default)
|
|
425
469
|
|
|
426
470
|
const executeAI = instance.aiManager.sendAIMessage({
|
|
427
|
-
tools:
|
|
471
|
+
tools: enabledTools,
|
|
428
472
|
model: resolvedModel,
|
|
429
473
|
});
|
|
430
474
|
|
|
@@ -37,6 +37,9 @@ import { Container } from "../utils/container.js";
|
|
|
37
37
|
|
|
38
38
|
import { logger } from "../utils/globalLogger.js";
|
|
39
39
|
|
|
40
|
+
import type { SubagentConfiguration } from "../utils/subagentParser.js";
|
|
41
|
+
import type { SkillMetadata } from "../types/skills.js";
|
|
42
|
+
|
|
40
43
|
export interface ToolManagerOptions {
|
|
41
44
|
container: Container;
|
|
42
45
|
/** Optional list of tool names to enable */
|
|
@@ -244,7 +247,11 @@ class ToolManager {
|
|
|
244
247
|
return [...builtInTools, ...mcpTools];
|
|
245
248
|
}
|
|
246
249
|
|
|
247
|
-
getToolsConfig(
|
|
250
|
+
getToolsConfig(options?: {
|
|
251
|
+
availableSubagents?: SubagentConfiguration[];
|
|
252
|
+
availableSkills?: SkillMetadata[];
|
|
253
|
+
workdir?: string;
|
|
254
|
+
}): ChatCompletionFunctionTool[] {
|
|
248
255
|
const effectivePermissionMode = this.getPermissionMode();
|
|
249
256
|
const builtInToolsConfig = Array.from(this.toolsRegistry.values())
|
|
250
257
|
.filter((tool) => {
|
|
@@ -258,7 +265,20 @@ class ToolManager {
|
|
|
258
265
|
}
|
|
259
266
|
return true;
|
|
260
267
|
})
|
|
261
|
-
.map((tool) =>
|
|
268
|
+
.map((tool) => {
|
|
269
|
+
// Create a copy of the tool config to avoid modifying the original
|
|
270
|
+
const config = {
|
|
271
|
+
...tool.config,
|
|
272
|
+
function: {
|
|
273
|
+
...tool.config.function,
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
// Override description with prompt if available
|
|
277
|
+
if (tool.prompt) {
|
|
278
|
+
config.function.description = tool.prompt(options);
|
|
279
|
+
}
|
|
280
|
+
return config;
|
|
281
|
+
});
|
|
262
282
|
const mcpToolsConfig = this.mcpManager.getMcpToolsConfig();
|
|
263
283
|
return [...builtInToolsConfig, ...mcpToolsConfig];
|
|
264
284
|
}
|
package/src/prompts/index.ts
CHANGED
|
@@ -288,9 +288,6 @@ Any promises made to the user
|
|
|
288
288
|
Be concise but complete—err on the side of including information that would prevent duplicate work or repeated mistakes. Write in a way that enables immediate resumption of the task.
|
|
289
289
|
Wrap your summary in <summary></summary> tags.`;
|
|
290
290
|
|
|
291
|
-
import type { SubagentConfiguration } from "../utils/subagentParser.js";
|
|
292
|
-
import type { SkillMetadata } from "../types/skills.js";
|
|
293
|
-
|
|
294
291
|
export function buildSystemPrompt(
|
|
295
292
|
basePrompt: string | undefined,
|
|
296
293
|
tools: ToolPlugin[],
|
|
@@ -303,8 +300,6 @@ export function buildSystemPrompt(
|
|
|
303
300
|
planFilePath: string;
|
|
304
301
|
planExists: boolean;
|
|
305
302
|
};
|
|
306
|
-
availableSubagents?: SubagentConfiguration[];
|
|
307
|
-
availableSkills?: SkillMetadata[];
|
|
308
303
|
} = {},
|
|
309
304
|
): string {
|
|
310
305
|
let prompt = basePrompt || DEFAULT_SYSTEM_PROMPT;
|
|
@@ -312,16 +307,6 @@ export function buildSystemPrompt(
|
|
|
312
307
|
prompt += `\n\n${TOOL_POLICY}`;
|
|
313
308
|
}
|
|
314
309
|
|
|
315
|
-
for (const tool of tools) {
|
|
316
|
-
if (tool.prompt) {
|
|
317
|
-
prompt += tool.prompt({
|
|
318
|
-
availableSubagents: options.availableSubagents,
|
|
319
|
-
availableSkills: options.availableSkills,
|
|
320
|
-
workdir: options.workdir,
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
|
|
325
310
|
if (options.language) {
|
|
326
311
|
prompt += `\n\n# Language\nAlways respond in ${options.language}. Technical terms (e.g., code, tool names, file paths) should remain in their original language or English where appropriate.`;
|
|
327
312
|
}
|
|
@@ -132,9 +132,9 @@ function getModelConfig(
|
|
|
132
132
|
};
|
|
133
133
|
|
|
134
134
|
// Configuration rules for specific models
|
|
135
|
-
if (modelName.includes("gpt-5
|
|
136
|
-
// gpt-5
|
|
137
|
-
config.temperature
|
|
135
|
+
if (modelName.includes("gpt-5")) {
|
|
136
|
+
// gpt-5 models should not have temperature field
|
|
137
|
+
delete config.temperature;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
return config;
|
|
@@ -203,7 +203,7 @@ export async function callAgent(
|
|
|
203
203
|
// Apply global 1 QPS rate limit
|
|
204
204
|
if (
|
|
205
205
|
process.env.NODE_ENV !== "test" ||
|
|
206
|
-
modelConfig.
|
|
206
|
+
modelConfig.model === "rate-limit-test"
|
|
207
207
|
) {
|
|
208
208
|
await acquireSlot(abortSignal);
|
|
209
209
|
}
|
|
@@ -239,7 +239,7 @@ export async function callAgent(
|
|
|
239
239
|
openaiMessages = [systemMessage, ...messages];
|
|
240
240
|
|
|
241
241
|
// Apply cache control for Claude models
|
|
242
|
-
const currentModel = model || modelConfig.
|
|
242
|
+
const currentModel = model || modelConfig.model;
|
|
243
243
|
const resolvedMaxTokens = options.maxTokens ?? modelConfig.maxTokens;
|
|
244
244
|
|
|
245
245
|
processedTools = tools;
|
|
@@ -257,7 +257,7 @@ export async function callAgent(
|
|
|
257
257
|
}
|
|
258
258
|
|
|
259
259
|
// Get model configuration - use injected modelConfig with optional override
|
|
260
|
-
const openaiModelConfig = getModelConfig(model || modelConfig.
|
|
260
|
+
const openaiModelConfig = getModelConfig(model || modelConfig.model, {
|
|
261
261
|
temperature: 0,
|
|
262
262
|
max_tokens: resolvedMaxTokens,
|
|
263
263
|
});
|
|
@@ -421,7 +421,7 @@ export async function callAgent(
|
|
|
421
421
|
const debugData: DebugData = {
|
|
422
422
|
originalMessages: messages,
|
|
423
423
|
timestamp: new Date().toISOString(),
|
|
424
|
-
model: model || modelConfig.
|
|
424
|
+
model: model || modelConfig.model,
|
|
425
425
|
workdir,
|
|
426
426
|
sessionId: options.sessionId,
|
|
427
427
|
gatewayConfig: {
|
|
@@ -760,7 +760,7 @@ export async function compressMessages(
|
|
|
760
760
|
// Apply global 1 QPS rate limit
|
|
761
761
|
if (
|
|
762
762
|
process.env.NODE_ENV !== "test" ||
|
|
763
|
-
modelConfig.
|
|
763
|
+
modelConfig.model === "rate-limit-test"
|
|
764
764
|
) {
|
|
765
765
|
await acquireSlot(abortSignal);
|
|
766
766
|
}
|
|
@@ -775,13 +775,10 @@ export async function compressMessages(
|
|
|
775
775
|
});
|
|
776
776
|
|
|
777
777
|
// Get model configuration - use injected agent model
|
|
778
|
-
const openaiModelConfig = getModelConfig(
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
max_tokens: 2048,
|
|
783
|
-
},
|
|
784
|
-
);
|
|
778
|
+
const openaiModelConfig = getModelConfig(options.model || modelConfig.model, {
|
|
779
|
+
temperature: 0.1,
|
|
780
|
+
max_tokens: 2048,
|
|
781
|
+
});
|
|
785
782
|
|
|
786
783
|
try {
|
|
787
784
|
const response = await openai.chat.completions.create(
|
|
@@ -444,13 +444,13 @@ export class ConfigurationService {
|
|
|
444
444
|
/**
|
|
445
445
|
* Resolves model configuration with fallbacks
|
|
446
446
|
* Resolution priority: options > env (from settings.json) > process.env > default
|
|
447
|
-
* @param
|
|
447
|
+
* @param model - Agent model from constructor (optional)
|
|
448
448
|
* @param fastModel - Fast model from constructor (optional)
|
|
449
449
|
* @param maxTokens - Max output tokens from constructor (optional)
|
|
450
450
|
* @returns Resolved model configuration with defaults
|
|
451
451
|
*/
|
|
452
452
|
resolveModelConfig(
|
|
453
|
-
|
|
453
|
+
model?: string,
|
|
454
454
|
fastModel?: string,
|
|
455
455
|
maxTokens?: number,
|
|
456
456
|
permissionMode?: PermissionMode,
|
|
@@ -460,7 +460,7 @@ export class ConfigurationService {
|
|
|
460
460
|
const DEFAULT_FAST_MODEL = "gemini-2.5-flash";
|
|
461
461
|
|
|
462
462
|
// Resolve agent model: constructor > env (settings.json) > process.env > default
|
|
463
|
-
let resolvedAgentModel =
|
|
463
|
+
let resolvedAgentModel = model || this.env.WAVE_MODEL;
|
|
464
464
|
|
|
465
465
|
if (!resolvedAgentModel && this.currentConfiguration?.env?.WAVE_MODEL) {
|
|
466
466
|
resolvedAgentModel = this.currentConfiguration.env.WAVE_MODEL;
|
|
@@ -481,7 +481,7 @@ export class ConfigurationService {
|
|
|
481
481
|
const resolvedMaxTokens = this.resolveMaxOutputTokens(maxTokens);
|
|
482
482
|
|
|
483
483
|
return {
|
|
484
|
-
|
|
484
|
+
model: resolvedAgentModel,
|
|
485
485
|
fastModel: resolvedFastModel,
|
|
486
486
|
maxTokens: resolvedMaxTokens,
|
|
487
487
|
permissionMode,
|
package/src/services/hook.ts
CHANGED
|
@@ -83,6 +83,13 @@ async function buildHookJsonInput(
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
// Add name field for WorktreeCreate events
|
|
87
|
+
if (context.event === "WorktreeCreate") {
|
|
88
|
+
if (context.worktreeName !== undefined) {
|
|
89
|
+
jsonInput.name = context.worktreeName;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
86
93
|
return jsonInput;
|
|
87
94
|
}
|
|
88
95
|
|