wave-agent-sdk 0.0.8 → 0.0.10
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 +92 -23
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +340 -137
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/managers/aiManager.d.ts +14 -36
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +74 -77
- package/dist/managers/backgroundBashManager.d.ts.map +1 -1
- package/dist/managers/backgroundBashManager.js +4 -3
- package/dist/managers/hookManager.d.ts +3 -8
- package/dist/managers/hookManager.d.ts.map +1 -1
- package/dist/managers/hookManager.js +39 -29
- package/dist/managers/liveConfigManager.d.ts +55 -18
- package/dist/managers/liveConfigManager.d.ts.map +1 -1
- package/dist/managers/liveConfigManager.js +372 -90
- package/dist/managers/lspManager.d.ts +43 -0
- package/dist/managers/lspManager.d.ts.map +1 -0
- package/dist/managers/lspManager.js +326 -0
- package/dist/managers/messageManager.d.ts +8 -16
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +52 -74
- package/dist/managers/permissionManager.d.ts +66 -0
- package/dist/managers/permissionManager.d.ts.map +1 -0
- package/dist/managers/permissionManager.js +208 -0
- package/dist/managers/skillManager.d.ts +1 -0
- package/dist/managers/skillManager.d.ts.map +1 -1
- package/dist/managers/skillManager.js +2 -1
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +0 -1
- package/dist/managers/subagentManager.d.ts +8 -23
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +97 -117
- package/dist/managers/toolManager.d.ts +38 -1
- package/dist/managers/toolManager.d.ts.map +1 -1
- package/dist/managers/toolManager.js +66 -2
- package/dist/services/aiService.d.ts +3 -1
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +123 -30
- package/dist/services/configurationService.d.ts +116 -0
- package/dist/services/configurationService.d.ts.map +1 -0
- package/dist/services/configurationService.js +585 -0
- package/dist/services/fileWatcher.d.ts.map +1 -1
- package/dist/services/fileWatcher.js +5 -6
- package/dist/services/hook.d.ts +7 -124
- package/dist/services/hook.d.ts.map +1 -1
- package/dist/services/hook.js +46 -458
- package/dist/services/jsonlHandler.d.ts +24 -15
- package/dist/services/jsonlHandler.d.ts.map +1 -1
- package/dist/services/jsonlHandler.js +67 -88
- package/dist/services/memory.d.ts +0 -9
- package/dist/services/memory.d.ts.map +1 -1
- package/dist/services/memory.js +2 -49
- package/dist/services/session.d.ts +82 -33
- package/dist/services/session.d.ts.map +1 -1
- package/dist/services/session.js +275 -181
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +72 -13
- package/dist/tools/deleteFileTool.d.ts.map +1 -1
- package/dist/tools/deleteFileTool.js +25 -0
- package/dist/tools/editTool.d.ts.map +1 -1
- package/dist/tools/editTool.js +30 -6
- package/dist/tools/lspTool.d.ts +6 -0
- package/dist/tools/lspTool.d.ts.map +1 -0
- package/dist/tools/lspTool.js +589 -0
- package/dist/tools/multiEditTool.d.ts.map +1 -1
- package/dist/tools/multiEditTool.js +26 -7
- package/dist/tools/readTool.d.ts.map +1 -1
- package/dist/tools/readTool.js +111 -2
- package/dist/tools/skillTool.js +2 -2
- package/dist/tools/todoWriteTool.d.ts.map +1 -1
- package/dist/tools/todoWriteTool.js +23 -0
- package/dist/tools/types.d.ts +11 -8
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/writeTool.d.ts.map +1 -1
- package/dist/tools/writeTool.js +25 -9
- package/dist/types/commands.d.ts +0 -1
- package/dist/types/commands.d.ts.map +1 -1
- package/dist/types/config.d.ts +4 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/configuration.d.ts +69 -0
- package/dist/types/configuration.d.ts.map +1 -0
- package/dist/types/configuration.js +8 -0
- package/dist/types/core.d.ts +10 -0
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/environment.d.ts +41 -0
- package/dist/types/environment.d.ts.map +1 -1
- package/dist/types/fileSearch.d.ts +5 -0
- package/dist/types/fileSearch.d.ts.map +1 -0
- package/dist/types/fileSearch.js +1 -0
- package/dist/types/hooks.d.ts +11 -2
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/hooks.js +1 -7
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +5 -0
- package/dist/types/lsp.d.ts +90 -0
- package/dist/types/lsp.d.ts.map +1 -0
- package/dist/types/lsp.js +4 -0
- package/dist/types/messaging.d.ts +6 -11
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/types/permissions.d.ts +35 -0
- package/dist/types/permissions.d.ts.map +1 -0
- package/dist/types/permissions.js +12 -0
- package/dist/types/session.d.ts +1 -6
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/skills.d.ts +1 -0
- package/dist/types/skills.d.ts.map +1 -1
- package/dist/types/tools.d.ts +35 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +4 -0
- package/dist/utils/abortUtils.d.ts +34 -0
- package/dist/utils/abortUtils.d.ts.map +1 -0
- package/dist/utils/abortUtils.js +92 -0
- package/dist/utils/bashHistory.d.ts +4 -0
- package/dist/utils/bashHistory.d.ts.map +1 -1
- package/dist/utils/bashHistory.js +21 -4
- package/dist/utils/builtinSubagents.d.ts +7 -0
- package/dist/utils/builtinSubagents.d.ts.map +1 -0
- package/dist/utils/builtinSubagents.js +65 -0
- package/dist/utils/cacheControlUtils.d.ts +8 -33
- package/dist/utils/cacheControlUtils.d.ts.map +1 -1
- package/dist/utils/cacheControlUtils.js +83 -126
- package/dist/utils/constants.d.ts +0 -12
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/constants.js +1 -13
- package/dist/utils/convertMessagesForAPI.d.ts +2 -1
- package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
- package/dist/utils/convertMessagesForAPI.js +33 -14
- package/dist/utils/fileSearch.d.ts +14 -0
- package/dist/utils/fileSearch.d.ts.map +1 -0
- package/dist/utils/fileSearch.js +88 -0
- package/dist/utils/fileUtils.d.ts +14 -2
- package/dist/utils/fileUtils.d.ts.map +1 -1
- package/dist/utils/fileUtils.js +101 -17
- package/dist/utils/globalLogger.d.ts +0 -14
- package/dist/utils/globalLogger.d.ts.map +1 -1
- package/dist/utils/globalLogger.js +0 -16
- package/dist/utils/largeOutputHandler.d.ts +15 -0
- package/dist/utils/largeOutputHandler.d.ts.map +1 -0
- package/dist/utils/largeOutputHandler.js +40 -0
- package/dist/utils/markdownParser.d.ts.map +1 -1
- package/dist/utils/markdownParser.js +1 -17
- package/dist/utils/messageOperations.d.ts +1 -11
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +7 -24
- package/dist/utils/pathEncoder.d.ts +4 -0
- package/dist/utils/pathEncoder.d.ts.map +1 -1
- package/dist/utils/pathEncoder.js +16 -9
- package/dist/utils/subagentParser.d.ts +2 -2
- package/dist/utils/subagentParser.d.ts.map +1 -1
- package/dist/utils/subagentParser.js +10 -7
- package/dist/utils/tokenEstimator.d.ts +39 -0
- package/dist/utils/tokenEstimator.d.ts.map +1 -0
- package/dist/utils/tokenEstimator.js +55 -0
- package/package.json +5 -8
- package/src/agent.ts +460 -216
- package/src/index.ts +2 -0
- package/src/managers/aiManager.ts +107 -111
- package/src/managers/backgroundBashManager.ts +4 -3
- package/src/managers/hookManager.ts +44 -39
- package/src/managers/liveConfigManager.ts +524 -138
- package/src/managers/lspManager.ts +434 -0
- package/src/managers/messageManager.ts +73 -103
- package/src/managers/permissionManager.ts +276 -0
- package/src/managers/skillManager.ts +3 -1
- package/src/managers/slashCommandManager.ts +1 -2
- package/src/managers/subagentManager.ts +116 -159
- package/src/managers/toolManager.ts +95 -3
- package/src/services/aiService.ts +207 -26
- package/src/services/configurationService.ts +762 -0
- package/src/services/fileWatcher.ts +5 -6
- package/src/services/hook.ts +50 -631
- package/src/services/jsonlHandler.ts +84 -100
- package/src/services/memory.ts +2 -59
- package/src/services/session.ts +338 -213
- package/src/tools/bashTool.ts +89 -16
- package/src/tools/deleteFileTool.ts +36 -0
- package/src/tools/editTool.ts +41 -7
- package/src/tools/lspTool.ts +760 -0
- package/src/tools/multiEditTool.ts +37 -8
- package/src/tools/readTool.ts +125 -2
- package/src/tools/skillTool.ts +2 -2
- package/src/tools/todoWriteTool.ts +33 -1
- package/src/tools/types.ts +15 -9
- package/src/tools/writeTool.ts +36 -10
- package/src/types/commands.ts +0 -1
- package/src/types/config.ts +5 -0
- package/src/types/configuration.ts +73 -0
- package/src/types/core.ts +11 -0
- package/src/types/environment.ts +44 -0
- package/src/types/fileSearch.ts +4 -0
- package/src/types/hooks.ts +14 -11
- package/src/types/index.ts +5 -0
- package/src/types/lsp.ts +96 -0
- package/src/types/messaging.ts +8 -13
- package/src/types/permissions.ts +48 -0
- package/src/types/session.ts +3 -8
- package/src/types/skills.ts +1 -0
- package/src/types/tools.ts +38 -0
- package/src/utils/abortUtils.ts +118 -0
- package/src/utils/bashHistory.ts +28 -4
- package/src/utils/builtinSubagents.ts +71 -0
- package/src/utils/cacheControlUtils.ts +106 -171
- package/src/utils/constants.ts +1 -16
- package/src/utils/convertMessagesForAPI.ts +38 -14
- package/src/utils/fileSearch.ts +107 -0
- package/src/utils/fileUtils.ts +114 -19
- package/src/utils/globalLogger.ts +0 -17
- package/src/utils/largeOutputHandler.ts +55 -0
- package/src/utils/markdownParser.ts +1 -19
- package/src/utils/messageOperations.ts +7 -35
- package/src/utils/pathEncoder.ts +24 -9
- package/src/utils/subagentParser.ts +11 -8
- package/src/utils/tokenEstimator.ts +68 -0
- package/dist/constants/events.d.ts +0 -28
- package/dist/constants/events.d.ts.map +0 -1
- package/dist/constants/events.js +0 -27
- package/dist/services/configurationWatcher.d.ts +0 -120
- package/dist/services/configurationWatcher.d.ts.map +0 -1
- package/dist/services/configurationWatcher.js +0 -439
- package/dist/services/memoryStore.d.ts +0 -81
- package/dist/services/memoryStore.d.ts.map +0 -1
- package/dist/services/memoryStore.js +0 -200
- package/dist/types/memoryStore.d.ts +0 -82
- package/dist/types/memoryStore.d.ts.map +0 -1
- package/dist/types/memoryStore.js +0 -7
- package/dist/utils/configResolver.d.ts +0 -65
- package/dist/utils/configResolver.d.ts.map +0 -1
- package/dist/utils/configResolver.js +0 -210
- package/src/constants/events.ts +0 -38
- package/src/services/configurationWatcher.ts +0 -622
- package/src/services/memoryStore.ts +0 -279
- package/src/types/memoryStore.ts +0 -94
- package/src/utils/configResolver.ts +0 -302
|
@@ -16,6 +16,10 @@ import {
|
|
|
16
16
|
UserMessageParams,
|
|
17
17
|
type AgentToolBlockUpdateParams,
|
|
18
18
|
} from "../utils/messageOperations.js";
|
|
19
|
+
import {
|
|
20
|
+
addConsolidatedAbortListener,
|
|
21
|
+
createAbortPromise,
|
|
22
|
+
} from "../utils/abortUtils.js";
|
|
19
23
|
|
|
20
24
|
export interface SubagentManagerCallbacks {
|
|
21
25
|
// Granular subagent message callbacks (015-subagent-message-callbacks)
|
|
@@ -32,6 +36,12 @@ export interface SubagentManagerCallbacks {
|
|
|
32
36
|
chunk: string,
|
|
33
37
|
accumulated: string,
|
|
34
38
|
) => void;
|
|
39
|
+
/** Triggered during subagent reasoning streaming updates */
|
|
40
|
+
onSubagentAssistantReasoningUpdated?: (
|
|
41
|
+
subagentId: string,
|
|
42
|
+
chunk: string,
|
|
43
|
+
accumulated: string,
|
|
44
|
+
) => void;
|
|
35
45
|
/** Triggered when subagent tool block is updated */
|
|
36
46
|
onSubagentToolBlockUpdated?: (
|
|
37
47
|
subagentId: string,
|
|
@@ -58,9 +68,9 @@ export interface SubagentManagerOptions {
|
|
|
58
68
|
parentMessageManager: MessageManager;
|
|
59
69
|
callbacks?: SubagentManagerCallbacks; // Use SubagentManagerCallbacks instead of parentCallbacks
|
|
60
70
|
logger?: Logger;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
71
|
+
getGatewayConfig: () => GatewayConfig;
|
|
72
|
+
getModelConfig: () => ModelConfig;
|
|
73
|
+
getTokenLimit: () => number;
|
|
64
74
|
hookManager?: HookManager;
|
|
65
75
|
onUsageAdded?: (usage: Usage) => void;
|
|
66
76
|
}
|
|
@@ -74,9 +84,9 @@ export class SubagentManager {
|
|
|
74
84
|
private parentMessageManager: MessageManager;
|
|
75
85
|
private callbacks?: SubagentManagerCallbacks; // Use SubagentManagerCallbacks instead of parentCallbacks
|
|
76
86
|
private logger?: Logger;
|
|
77
|
-
private
|
|
78
|
-
private
|
|
79
|
-
private
|
|
87
|
+
private getGatewayConfig: () => GatewayConfig;
|
|
88
|
+
private getModelConfig: () => ModelConfig;
|
|
89
|
+
private getTokenLimit: () => number;
|
|
80
90
|
private hookManager?: HookManager;
|
|
81
91
|
private onUsageAdded?: (usage: Usage) => void;
|
|
82
92
|
|
|
@@ -86,9 +96,9 @@ export class SubagentManager {
|
|
|
86
96
|
this.parentMessageManager = options.parentMessageManager;
|
|
87
97
|
this.callbacks = options.callbacks; // Store SubagentManagerCallbacks
|
|
88
98
|
this.logger = options.logger;
|
|
89
|
-
this.
|
|
90
|
-
this.
|
|
91
|
-
this.
|
|
99
|
+
this.getGatewayConfig = options.getGatewayConfig;
|
|
100
|
+
this.getModelConfig = options.getModelConfig;
|
|
101
|
+
this.getTokenLimit = options.getTokenLimit;
|
|
92
102
|
this.hookManager = options.hookManager;
|
|
93
103
|
this.onUsageAdded = options.onUsageAdded;
|
|
94
104
|
}
|
|
@@ -146,12 +156,7 @@ export class SubagentManager {
|
|
|
146
156
|
subagent_type: string;
|
|
147
157
|
},
|
|
148
158
|
): Promise<SubagentInstance> {
|
|
149
|
-
if (
|
|
150
|
-
!this.parentToolManager ||
|
|
151
|
-
!this.gatewayConfig ||
|
|
152
|
-
!this.modelConfig ||
|
|
153
|
-
!this.tokenLimit
|
|
154
|
-
) {
|
|
159
|
+
if (!this.parentToolManager) {
|
|
155
160
|
throw new Error(
|
|
156
161
|
"SubagentManager not properly initialized - call initialize() first",
|
|
157
162
|
);
|
|
@@ -167,19 +172,12 @@ export class SubagentManager {
|
|
|
167
172
|
workdir: this.workdir,
|
|
168
173
|
logger: this.logger,
|
|
169
174
|
sessionType: "subagent",
|
|
170
|
-
parentSessionId: this.parentMessageManager.getSessionId(),
|
|
171
175
|
subagentType: parameters.subagent_type,
|
|
172
176
|
});
|
|
173
177
|
|
|
174
178
|
// Use the parent tool manager directly - tool restrictions will be handled by allowedTools parameter
|
|
175
179
|
const toolManager = this.parentToolManager;
|
|
176
180
|
|
|
177
|
-
// Determine model to use
|
|
178
|
-
const modelToUse =
|
|
179
|
-
configuration.model && configuration.model !== "inherit"
|
|
180
|
-
? configuration.model
|
|
181
|
-
: this.modelConfig.agentModel;
|
|
182
|
-
|
|
183
181
|
// Create isolated AIManager for the subagent
|
|
184
182
|
const aiManager = new AIManager({
|
|
185
183
|
messageManager,
|
|
@@ -189,12 +187,29 @@ export class SubagentManager {
|
|
|
189
187
|
systemPrompt: configuration.systemPrompt,
|
|
190
188
|
subagentType: parameters.subagent_type, // Pass subagent type for hook context
|
|
191
189
|
hookManager: this.hookManager,
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
190
|
+
getGatewayConfig: this.getGatewayConfig,
|
|
191
|
+
getModelConfig: () => {
|
|
192
|
+
// Determine model dynamically each time
|
|
193
|
+
const parentModelConfig = this.getModelConfig();
|
|
194
|
+
let modelToUse: string;
|
|
195
|
+
|
|
196
|
+
if (!configuration.model || configuration.model === "inherit") {
|
|
197
|
+
// Use parent's agentModel for "inherit" or undefined
|
|
198
|
+
modelToUse = parentModelConfig.agentModel;
|
|
199
|
+
} else if (configuration.model === "fastModel") {
|
|
200
|
+
// Use parent's fastModel for special "fastModel" value
|
|
201
|
+
modelToUse = parentModelConfig.fastModel;
|
|
202
|
+
} else {
|
|
203
|
+
// Use specific model name
|
|
204
|
+
modelToUse = configuration.model;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return {
|
|
208
|
+
...parentModelConfig,
|
|
209
|
+
agentModel: modelToUse,
|
|
210
|
+
};
|
|
196
211
|
},
|
|
197
|
-
|
|
212
|
+
getTokenLimit: this.getTokenLimit,
|
|
198
213
|
callbacks: {
|
|
199
214
|
onUsageAdded: this.onUsageAdded,
|
|
200
215
|
},
|
|
@@ -249,14 +264,22 @@ export class SubagentManager {
|
|
|
249
264
|
status: "active",
|
|
250
265
|
});
|
|
251
266
|
|
|
252
|
-
// Set up abort handler
|
|
267
|
+
// Set up consolidated abort handler to prevent listener accumulation
|
|
268
|
+
let abortCleanup: (() => void) | undefined;
|
|
253
269
|
if (abortSignal) {
|
|
254
|
-
abortSignal
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
270
|
+
abortCleanup = addConsolidatedAbortListener(abortSignal, [
|
|
271
|
+
() => {
|
|
272
|
+
// Update status to aborted
|
|
273
|
+
this.updateInstanceStatus(instance.subagentId, "aborted");
|
|
274
|
+
this.parentMessageManager.updateSubagentBlock(instance.subagentId, {
|
|
275
|
+
status: "aborted",
|
|
276
|
+
});
|
|
277
|
+
},
|
|
278
|
+
() => {
|
|
279
|
+
// Abort the AI execution
|
|
280
|
+
instance.aiManager.abortAIMessage();
|
|
281
|
+
},
|
|
282
|
+
]);
|
|
260
283
|
}
|
|
261
284
|
|
|
262
285
|
// Add the user's prompt as a message
|
|
@@ -276,32 +299,43 @@ export class SubagentManager {
|
|
|
276
299
|
|
|
277
300
|
// Execute the AI request with tool restrictions
|
|
278
301
|
// The AIManager will handle abort signals through its own abort controllers
|
|
279
|
-
//
|
|
302
|
+
// Resolve model name for sendAIMessage
|
|
303
|
+
let resolvedModel: string | undefined;
|
|
304
|
+
if (
|
|
305
|
+
instance.configuration.model &&
|
|
306
|
+
instance.configuration.model !== "inherit"
|
|
307
|
+
) {
|
|
308
|
+
if (instance.configuration.model === "fastModel") {
|
|
309
|
+
// Use parent's fastModel for special "fastModel" value
|
|
310
|
+
const parentModelConfig = this.getModelConfig();
|
|
311
|
+
resolvedModel = parentModelConfig.fastModel;
|
|
312
|
+
} else {
|
|
313
|
+
// Use specific model name
|
|
314
|
+
resolvedModel = instance.configuration.model;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
// For "inherit" or undefined, resolvedModel remains undefined (uses AIManager default)
|
|
318
|
+
|
|
280
319
|
const executeAI = instance.aiManager.sendAIMessage({
|
|
281
320
|
allowedTools,
|
|
282
|
-
model:
|
|
283
|
-
instance.configuration.model !== "inherit"
|
|
284
|
-
? instance.configuration.model
|
|
285
|
-
: undefined,
|
|
321
|
+
model: resolvedModel,
|
|
286
322
|
});
|
|
287
323
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
} else {
|
|
304
|
-
await executeAI;
|
|
324
|
+
try {
|
|
325
|
+
// If we have an abort signal, race against it using utilities to prevent listener accumulation
|
|
326
|
+
if (abortSignal) {
|
|
327
|
+
await Promise.race([
|
|
328
|
+
executeAI,
|
|
329
|
+
createAbortPromise(abortSignal, "Task was aborted"),
|
|
330
|
+
]);
|
|
331
|
+
} else {
|
|
332
|
+
await executeAI;
|
|
333
|
+
}
|
|
334
|
+
} finally {
|
|
335
|
+
// Clean up abort listeners to prevent memory leaks
|
|
336
|
+
if (abortCleanup) {
|
|
337
|
+
abortCleanup();
|
|
338
|
+
}
|
|
305
339
|
}
|
|
306
340
|
|
|
307
341
|
// Get the latest messages to extract the response
|
|
@@ -422,7 +456,6 @@ export class SubagentManager {
|
|
|
422
456
|
workdir: this.workdir,
|
|
423
457
|
logger: this.logger,
|
|
424
458
|
sessionType: "subagent",
|
|
425
|
-
parentSessionId: this.parentMessageManager.getSessionId(),
|
|
426
459
|
subagentType: configuration.name, // Use configuration name for restored sessions
|
|
427
460
|
});
|
|
428
461
|
|
|
@@ -430,10 +463,16 @@ export class SubagentManager {
|
|
|
430
463
|
const toolManager = this.parentToolManager;
|
|
431
464
|
|
|
432
465
|
// Determine model to use
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
466
|
+
let modelToUse: string;
|
|
467
|
+
const parentModelConfig = this.getModelConfig();
|
|
468
|
+
|
|
469
|
+
if (!configuration.model || configuration.model === "inherit") {
|
|
470
|
+
modelToUse = parentModelConfig.agentModel;
|
|
471
|
+
} else if (configuration.model === "fastModel") {
|
|
472
|
+
modelToUse = parentModelConfig.fastModel;
|
|
473
|
+
} else {
|
|
474
|
+
modelToUse = configuration.model;
|
|
475
|
+
}
|
|
437
476
|
|
|
438
477
|
// Create AIManager for the restored subagent
|
|
439
478
|
const aiManager = new AIManager({
|
|
@@ -444,12 +483,12 @@ export class SubagentManager {
|
|
|
444
483
|
systemPrompt: configuration.systemPrompt,
|
|
445
484
|
subagentType: configuration.name, // Use configuration name as subagent type for restored instances
|
|
446
485
|
hookManager: this.hookManager,
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
...
|
|
486
|
+
getGatewayConfig: this.getGatewayConfig,
|
|
487
|
+
getModelConfig: () => ({
|
|
488
|
+
...parentModelConfig,
|
|
450
489
|
agentModel: modelToUse,
|
|
451
|
-
},
|
|
452
|
-
|
|
490
|
+
}),
|
|
491
|
+
getTokenLimit: this.getTokenLimit,
|
|
453
492
|
callbacks: {
|
|
454
493
|
onUsageAdded: this.onUsageAdded,
|
|
455
494
|
},
|
|
@@ -471,19 +510,7 @@ export class SubagentManager {
|
|
|
471
510
|
// This ensures the callback can find the instance
|
|
472
511
|
this.instances.set(subagentId, instance);
|
|
473
512
|
|
|
474
|
-
|
|
475
|
-
const sessionDataObj = {
|
|
476
|
-
id: sessionData.id,
|
|
477
|
-
messages: sessionData.messages,
|
|
478
|
-
version: "1.0.0",
|
|
479
|
-
metadata: {
|
|
480
|
-
workdir: this.workdir,
|
|
481
|
-
startedAt: new Date().toISOString(),
|
|
482
|
-
lastActiveAt: new Date().toISOString(),
|
|
483
|
-
latestTotalTokens: 0,
|
|
484
|
-
},
|
|
485
|
-
};
|
|
486
|
-
messageManager.initializeFromSession(sessionDataObj);
|
|
513
|
+
messageManager.initializeFromSession(sessionData);
|
|
487
514
|
} catch (error) {
|
|
488
515
|
this.logger?.warn(
|
|
489
516
|
`Failed to restore subagent session ${subagentId}:`,
|
|
@@ -524,6 +551,16 @@ export class SubagentManager {
|
|
|
524
551
|
);
|
|
525
552
|
}
|
|
526
553
|
},
|
|
554
|
+
onAssistantReasoningUpdated: (chunk: string, accumulated: string) => {
|
|
555
|
+
// Forward assistant reasoning updates to parent via SubagentManager callbacks
|
|
556
|
+
if (this.callbacks?.onSubagentAssistantReasoningUpdated) {
|
|
557
|
+
this.callbacks.onSubagentAssistantReasoningUpdated(
|
|
558
|
+
subagentId,
|
|
559
|
+
chunk,
|
|
560
|
+
accumulated,
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
},
|
|
527
564
|
|
|
528
565
|
onToolBlockUpdated: (params: AgentToolBlockUpdateParams) => {
|
|
529
566
|
// Forward tool block updates to parent via SubagentManager callbacks
|
|
@@ -552,84 +589,4 @@ export class SubagentManager {
|
|
|
552
589
|
},
|
|
553
590
|
};
|
|
554
591
|
}
|
|
555
|
-
|
|
556
|
-
/**
|
|
557
|
-
* Update configuration for SubagentManager and all active subagents
|
|
558
|
-
* This method updates configuration for live config reload support
|
|
559
|
-
* @param newGatewayConfig - New gateway configuration
|
|
560
|
-
* @param newModelConfig - New model configuration
|
|
561
|
-
* @param newTokenLimit - New token limit
|
|
562
|
-
*/
|
|
563
|
-
updateConfiguration(
|
|
564
|
-
newGatewayConfig: GatewayConfig,
|
|
565
|
-
newModelConfig: ModelConfig,
|
|
566
|
-
newTokenLimit: number,
|
|
567
|
-
): void {
|
|
568
|
-
this.logger?.info("Live Config: Updating SubagentManager configuration");
|
|
569
|
-
|
|
570
|
-
// Update stored configuration
|
|
571
|
-
this.gatewayConfig = newGatewayConfig;
|
|
572
|
-
this.modelConfig = newModelConfig;
|
|
573
|
-
this.tokenLimit = newTokenLimit;
|
|
574
|
-
|
|
575
|
-
// Update all active subagent AIManager instances
|
|
576
|
-
let updatedCount = 0;
|
|
577
|
-
for (const [subagentId, instance] of this.instances.entries()) {
|
|
578
|
-
if (instance.status === "active" || instance.status === "initializing") {
|
|
579
|
-
try {
|
|
580
|
-
// For subagents, we need to preserve their model if it was explicitly set
|
|
581
|
-
const subagentModelConfig = {
|
|
582
|
-
...newModelConfig,
|
|
583
|
-
// If subagent has its own model configured, preserve it
|
|
584
|
-
agentModel:
|
|
585
|
-
instance.configuration.model &&
|
|
586
|
-
instance.configuration.model !== "inherit"
|
|
587
|
-
? instance.configuration.model
|
|
588
|
-
: newModelConfig.agentModel,
|
|
589
|
-
};
|
|
590
|
-
|
|
591
|
-
instance.aiManager.updateConfiguration(
|
|
592
|
-
newGatewayConfig,
|
|
593
|
-
subagentModelConfig,
|
|
594
|
-
newTokenLimit,
|
|
595
|
-
);
|
|
596
|
-
updatedCount++;
|
|
597
|
-
|
|
598
|
-
this.logger?.debug(
|
|
599
|
-
`Live Config: Updated configuration for subagent ${subagentId}`,
|
|
600
|
-
);
|
|
601
|
-
} catch (error) {
|
|
602
|
-
this.logger?.error(
|
|
603
|
-
`Live Config: Failed to update configuration for subagent ${subagentId}: ${(error as Error).message}`,
|
|
604
|
-
);
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
this.logger?.info(
|
|
610
|
-
`Live Config: SubagentManager configuration updated - ${updatedCount} active subagents updated`,
|
|
611
|
-
);
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
/**
|
|
615
|
-
* Get current configuration for debugging
|
|
616
|
-
*/
|
|
617
|
-
getCurrentConfiguration(): {
|
|
618
|
-
gatewayConfig: GatewayConfig;
|
|
619
|
-
modelConfig: ModelConfig;
|
|
620
|
-
tokenLimit: number;
|
|
621
|
-
activeSubagents: number;
|
|
622
|
-
} {
|
|
623
|
-
const activeSubagents = Array.from(this.instances.values()).filter(
|
|
624
|
-
(instance) =>
|
|
625
|
-
instance.status === "active" || instance.status === "initializing",
|
|
626
|
-
).length;
|
|
627
|
-
|
|
628
|
-
return {
|
|
629
|
-
gatewayConfig: { ...this.gatewayConfig },
|
|
630
|
-
modelConfig: { ...this.modelConfig },
|
|
631
|
-
tokenLimit: this.tokenLimit,
|
|
632
|
-
activeSubagents,
|
|
633
|
-
};
|
|
634
|
-
}
|
|
635
592
|
}
|
|
@@ -10,30 +10,56 @@ import { grepTool } from "../tools/grepTool.js";
|
|
|
10
10
|
import { lsTool } from "../tools/lsTool.js";
|
|
11
11
|
import { readTool } from "../tools/readTool.js";
|
|
12
12
|
import { todoWriteTool } from "../tools/todoWriteTool.js";
|
|
13
|
+
import { lspTool } from "../tools/lspTool.js";
|
|
13
14
|
import { createTaskTool } from "../tools/taskTool.js";
|
|
14
15
|
import { createSkillTool } from "../tools/skillTool.js";
|
|
15
16
|
import { McpManager } from "./mcpManager.js";
|
|
17
|
+
import { PermissionManager } from "./permissionManager.js";
|
|
16
18
|
import { ChatCompletionFunctionTool } from "openai/resources.js";
|
|
17
|
-
import type {
|
|
19
|
+
import type {
|
|
20
|
+
Logger,
|
|
21
|
+
PermissionMode,
|
|
22
|
+
PermissionCallback,
|
|
23
|
+
ILspManager,
|
|
24
|
+
} from "../types/index.js";
|
|
18
25
|
import type { SubagentManager } from "./subagentManager.js";
|
|
19
26
|
import type { SkillManager } from "./skillManager.js";
|
|
20
27
|
|
|
21
28
|
export interface ToolManagerOptions {
|
|
22
29
|
mcpManager: McpManager;
|
|
30
|
+
lspManager?: ILspManager;
|
|
23
31
|
logger?: Logger;
|
|
32
|
+
/** Optional permission manager for handling tool permission checks */
|
|
33
|
+
permissionManager?: PermissionManager;
|
|
34
|
+
/** Permission mode for tool execution (defaults to "default") */
|
|
35
|
+
permissionMode?: PermissionMode;
|
|
36
|
+
/** Custom permission callback for tool usage */
|
|
37
|
+
canUseToolCallback?: PermissionCallback;
|
|
24
38
|
}
|
|
25
39
|
|
|
26
40
|
/**
|
|
27
41
|
* Tool Manager
|
|
42
|
+
*
|
|
43
|
+
* Manages tool registration and execution with optional permission system integration.
|
|
44
|
+
* Supports both built-in tools and MCP (Model Context Protocol) tools.
|
|
28
45
|
*/
|
|
29
46
|
class ToolManager {
|
|
30
47
|
private tools = new Map<string, ToolPlugin>();
|
|
31
48
|
private mcpManager: McpManager;
|
|
49
|
+
private lspManager?: ILspManager;
|
|
32
50
|
private logger?: Logger;
|
|
51
|
+
private permissionManager?: PermissionManager;
|
|
52
|
+
private permissionMode?: PermissionMode;
|
|
53
|
+
private canUseToolCallback?: PermissionCallback;
|
|
33
54
|
|
|
34
55
|
constructor(options: ToolManagerOptions) {
|
|
35
56
|
this.mcpManager = options.mcpManager;
|
|
57
|
+
this.lspManager = options.lspManager;
|
|
36
58
|
this.logger = options.logger;
|
|
59
|
+
this.permissionManager = options.permissionManager;
|
|
60
|
+
// Store CLI permission mode, let PermissionManager resolve effective mode
|
|
61
|
+
this.permissionMode = options.permissionMode;
|
|
62
|
+
this.canUseToolCallback = options.canUseToolCallback;
|
|
37
63
|
}
|
|
38
64
|
|
|
39
65
|
/**
|
|
@@ -83,6 +109,7 @@ class ToolManager {
|
|
|
83
109
|
lsTool,
|
|
84
110
|
readTool,
|
|
85
111
|
todoWriteTool,
|
|
112
|
+
lspTool,
|
|
86
113
|
];
|
|
87
114
|
|
|
88
115
|
for (const tool of builtInTools) {
|
|
@@ -101,22 +128,66 @@ class ToolManager {
|
|
|
101
128
|
}
|
|
102
129
|
}
|
|
103
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Execute a tool by name with the provided arguments and context
|
|
133
|
+
*
|
|
134
|
+
* Enhances the context with permission-related fields before execution:
|
|
135
|
+
* - permissionMode: The current permission mode (default or bypassPermissions)
|
|
136
|
+
* - canUseToolCallback: Custom permission callback if provided
|
|
137
|
+
* - permissionManager: The PermissionManager instance for permission checks
|
|
138
|
+
*
|
|
139
|
+
* @param name - Name of the tool to execute
|
|
140
|
+
* @param args - Arguments to pass to the tool
|
|
141
|
+
* @param context - Execution context for the tool
|
|
142
|
+
* @returns Promise resolving to the tool execution result
|
|
143
|
+
*/
|
|
104
144
|
async execute(
|
|
105
145
|
name: string,
|
|
106
146
|
args: Record<string, unknown>,
|
|
107
147
|
context: ToolContext,
|
|
108
148
|
): Promise<ToolResult> {
|
|
149
|
+
// Resolve effective permission mode (CLI override > configuration > default)
|
|
150
|
+
const effectivePermissionMode = this.permissionManager
|
|
151
|
+
? this.permissionManager.getCurrentEffectiveMode(this.permissionMode)
|
|
152
|
+
: this.permissionMode || "default";
|
|
153
|
+
|
|
154
|
+
// Enhance context with permission-related fields
|
|
155
|
+
const enhancedContext: ToolContext = {
|
|
156
|
+
...context,
|
|
157
|
+
permissionMode: effectivePermissionMode,
|
|
158
|
+
canUseToolCallback: this.canUseToolCallback,
|
|
159
|
+
permissionManager: this.permissionManager,
|
|
160
|
+
mcpManager: this.mcpManager,
|
|
161
|
+
lspManager: this.lspManager,
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
this.logger?.debug("Executing tool with enhanced context", {
|
|
165
|
+
toolName: name,
|
|
166
|
+
cliPermissionMode: this.permissionMode,
|
|
167
|
+
effectivePermissionMode,
|
|
168
|
+
hasPermissionManager: !!this.permissionManager,
|
|
169
|
+
hasPermissionCallback: !!this.canUseToolCallback,
|
|
170
|
+
});
|
|
171
|
+
|
|
109
172
|
// Check if it's an MCP tool first
|
|
110
173
|
if (this.mcpManager.isMcpTool(name)) {
|
|
111
|
-
return this.mcpManager.executeMcpToolByRegistry(
|
|
174
|
+
return this.mcpManager.executeMcpToolByRegistry(
|
|
175
|
+
name,
|
|
176
|
+
args,
|
|
177
|
+
enhancedContext,
|
|
178
|
+
);
|
|
112
179
|
}
|
|
113
180
|
|
|
114
181
|
// Check built-in tools
|
|
115
182
|
const plugin = this.tools.get(name);
|
|
116
183
|
if (plugin) {
|
|
117
184
|
try {
|
|
118
|
-
return await plugin.execute(args,
|
|
185
|
+
return await plugin.execute(args, enhancedContext);
|
|
119
186
|
} catch (error) {
|
|
187
|
+
this.logger?.error("Tool execution failed", {
|
|
188
|
+
toolName: name,
|
|
189
|
+
error: error instanceof Error ? error.message : String(error),
|
|
190
|
+
});
|
|
120
191
|
return {
|
|
121
192
|
success: false,
|
|
122
193
|
content: "",
|
|
@@ -125,6 +196,7 @@ class ToolManager {
|
|
|
125
196
|
}
|
|
126
197
|
}
|
|
127
198
|
|
|
199
|
+
this.logger?.warn("Tool not found", { toolName: name });
|
|
128
200
|
return {
|
|
129
201
|
success: false,
|
|
130
202
|
content: "",
|
|
@@ -145,6 +217,26 @@ class ToolManager {
|
|
|
145
217
|
const mcpToolsConfig = this.mcpManager.getMcpToolsConfig();
|
|
146
218
|
return [...builtInToolsConfig, ...mcpToolsConfig];
|
|
147
219
|
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Get the current permission mode
|
|
223
|
+
*/
|
|
224
|
+
public getPermissionMode(): PermissionMode {
|
|
225
|
+
if (this.permissionManager) {
|
|
226
|
+
return this.permissionManager.getCurrentEffectiveMode(
|
|
227
|
+
this.permissionMode,
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
return this.permissionMode || "default";
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Set the permission mode
|
|
235
|
+
* @param mode - The new permission mode
|
|
236
|
+
*/
|
|
237
|
+
public setPermissionMode(mode: PermissionMode): void {
|
|
238
|
+
this.permissionMode = mode;
|
|
239
|
+
}
|
|
148
240
|
}
|
|
149
241
|
|
|
150
242
|
// Export tool registry class and types
|