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
package/src/agent.ts
CHANGED
|
@@ -1,32 +1,23 @@
|
|
|
1
1
|
import { ForegroundTaskManager } from "./managers/foregroundTaskManager.js";
|
|
2
|
-
import {
|
|
3
|
-
MessageManager,
|
|
4
|
-
type MessageManagerCallbacks,
|
|
5
|
-
} from "./managers/messageManager.js";
|
|
2
|
+
import { MessageManager } from "./managers/messageManager.js";
|
|
6
3
|
import { AIManager } from "./managers/aiManager.js";
|
|
7
4
|
import { ToolManager } from "./managers/toolManager.js";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
type SubagentManagerCallbacks,
|
|
11
|
-
} from "./managers/subagentManager.js";
|
|
12
|
-
import { McpManager, type McpManagerCallbacks } from "./managers/mcpManager.js";
|
|
5
|
+
import { SubagentManager } from "./managers/subagentManager.js";
|
|
6
|
+
import { McpManager } from "./managers/mcpManager.js";
|
|
13
7
|
import { LspManager } from "./managers/lspManager.js";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
BackgroundTaskManager,
|
|
17
|
-
type BackgroundTaskManagerCallbacks,
|
|
18
|
-
} from "./managers/backgroundTaskManager.js";
|
|
8
|
+
import { BangManager } from "./managers/bangManager.js";
|
|
9
|
+
import { BackgroundTaskManager } from "./managers/backgroundTaskManager.js";
|
|
19
10
|
import { SlashCommandManager } from "./managers/slashCommandManager.js";
|
|
20
11
|
import { PluginManager } from "./managers/pluginManager.js";
|
|
21
12
|
import { HookManager } from "./managers/hookManager.js";
|
|
22
13
|
import { ReversionManager } from "./managers/reversionManager.js";
|
|
23
14
|
import { PermissionManager } from "./managers/permissionManager.js";
|
|
24
15
|
import { PlanManager } from "./managers/planManager.js";
|
|
25
|
-
import
|
|
16
|
+
import {
|
|
26
17
|
SlashCommand,
|
|
27
18
|
CustomSlashCommand,
|
|
28
19
|
ILspManager,
|
|
29
|
-
|
|
20
|
+
AgentOptions,
|
|
30
21
|
} from "./types/index.js";
|
|
31
22
|
import type {
|
|
32
23
|
Message,
|
|
@@ -36,8 +27,6 @@ import type {
|
|
|
36
27
|
ModelConfig,
|
|
37
28
|
Usage,
|
|
38
29
|
PermissionMode,
|
|
39
|
-
PermissionCallback,
|
|
40
|
-
BackgroundTask,
|
|
41
30
|
ForegroundTask,
|
|
42
31
|
} from "./types/index.js";
|
|
43
32
|
import { MemoryRuleManager } from "./managers/MemoryRuleManager.js";
|
|
@@ -45,90 +34,17 @@ import { LiveConfigManager } from "./managers/liveConfigManager.js";
|
|
|
45
34
|
import { configValidator } from "./utils/configValidator.js";
|
|
46
35
|
import { SkillManager } from "./managers/skillManager.js";
|
|
47
36
|
import { TaskManager } from "./services/taskManager.js";
|
|
48
|
-
import {
|
|
49
|
-
|
|
50
|
-
handleSessionRestoration,
|
|
51
|
-
} from "./services/session.js";
|
|
52
|
-
import { setGlobalLogger } from "./utils/globalLogger.js";
|
|
37
|
+
import { InitializationService } from "./services/initializationService.js";
|
|
38
|
+
import { InteractionService } from "./services/interactionService.js";
|
|
53
39
|
import { ConfigurationService } from "./services/configurationService.js";
|
|
54
|
-
import * as fs from "fs/promises";
|
|
55
|
-
import path from "path";
|
|
56
|
-
import os from "os";
|
|
57
|
-
import { ClientOptions } from "openai";
|
|
58
|
-
|
|
59
40
|
import { Container } from "./utils/container.js";
|
|
60
41
|
import { setupAgentContainer } from "./utils/containerSetup.js";
|
|
61
42
|
|
|
62
|
-
/**
|
|
63
|
-
* Configuration options for Agent instances
|
|
64
|
-
*
|
|
65
|
-
* IMPORTANT: This interface is used by both Agent constructor and Agent.create()
|
|
66
|
-
* Any changes to this interface must be compatible with both methods.
|
|
67
|
-
*/
|
|
68
|
-
export interface AgentOptions {
|
|
69
|
-
// Optional configuration with environment fallbacks
|
|
70
|
-
apiKey?: string;
|
|
71
|
-
baseURL?: string;
|
|
72
|
-
defaultHeaders?: Record<string, string>;
|
|
73
|
-
fetchOptions?: ClientOptions["fetchOptions"];
|
|
74
|
-
fetch?: ClientOptions["fetch"];
|
|
75
|
-
agentModel?: string;
|
|
76
|
-
fastModel?: string;
|
|
77
|
-
maxInputTokens?: number;
|
|
78
|
-
maxTokens?: number;
|
|
79
|
-
/** Preferred language for agent communication */
|
|
80
|
-
language?: string;
|
|
81
|
-
|
|
82
|
-
// Existing options (preserved)
|
|
83
|
-
callbacks?: AgentCallbacks;
|
|
84
|
-
restoreSessionId?: string;
|
|
85
|
-
continueLastSession?: boolean;
|
|
86
|
-
logger?: Logger;
|
|
87
|
-
/**Add optional initial messages parameter for testing convenience */
|
|
88
|
-
messages?: Message[];
|
|
89
|
-
/**Working directory - if not specified, use process.cwd() */
|
|
90
|
-
workdir?: string;
|
|
91
|
-
/**Optional custom system prompt - if provided, replaces default system prompt */
|
|
92
|
-
systemPrompt?: string;
|
|
93
|
-
/**Permission mode - defaults to "default" */
|
|
94
|
-
permissionMode?: PermissionMode;
|
|
95
|
-
/**Custom permission callback */
|
|
96
|
-
canUseTool?: PermissionCallback;
|
|
97
|
-
/**Whether to use streaming mode for AI responses - defaults to true */
|
|
98
|
-
stream?: boolean;
|
|
99
|
-
/**Optional custom LSP manager - if not provided, a standalone one will be created */
|
|
100
|
-
lspManager?: ILspManager;
|
|
101
|
-
/**Optional local plugins to load */
|
|
102
|
-
plugins?: PluginConfig[];
|
|
103
|
-
/**
|
|
104
|
-
* Optional list of tool names to enable.
|
|
105
|
-
* - undefined: Enable all built-in tools and plugins (default).
|
|
106
|
-
* - []: Disable all tools.
|
|
107
|
-
* - string[]: Enable only the tools with the specified names.
|
|
108
|
-
*/
|
|
109
|
-
tools?: string[];
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export interface AgentCallbacks
|
|
113
|
-
extends MessageManagerCallbacks,
|
|
114
|
-
BackgroundTaskManagerCallbacks,
|
|
115
|
-
McpManagerCallbacks,
|
|
116
|
-
SubagentManagerCallbacks {
|
|
117
|
-
onTasksChange?: (tasks: BackgroundTask[]) => void;
|
|
118
|
-
onSessionTasksChange?: (tasks: import("./types/tasks.js").Task[]) => void;
|
|
119
|
-
onPermissionModeChange?: (mode: PermissionMode) => void;
|
|
120
|
-
onSubagentLatestTotalTokensChange?: (
|
|
121
|
-
subagentId: string,
|
|
122
|
-
tokens: number,
|
|
123
|
-
) => void;
|
|
124
|
-
onBackgroundCurrentTask?: () => void;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
43
|
export class Agent {
|
|
128
44
|
private messageManager: MessageManager;
|
|
129
45
|
private aiManager: AIManager;
|
|
130
46
|
|
|
131
|
-
private
|
|
47
|
+
private bangManager: BangManager | null = null;
|
|
132
48
|
private backgroundTaskManager: BackgroundTaskManager;
|
|
133
49
|
private logger?: Logger; // Add optional logger property
|
|
134
50
|
private toolManager: ToolManager; // Add tool registry instance
|
|
@@ -150,7 +66,6 @@ export class Agent {
|
|
|
150
66
|
private configurationService: ConfigurationService; // Add configuration service
|
|
151
67
|
private workdir: string; // Working directory
|
|
152
68
|
private systemPrompt?: string; // Custom system prompt
|
|
153
|
-
private _usages: Usage[] = []; // Usage tracking array
|
|
154
69
|
private stream: boolean; // Streaming mode flag
|
|
155
70
|
|
|
156
71
|
// Configuration options storage for dynamic resolution
|
|
@@ -173,7 +88,7 @@ export class Agent {
|
|
|
173
88
|
|
|
174
89
|
public getModelConfig(): ModelConfig {
|
|
175
90
|
return this.configurationService.resolveModelConfig(
|
|
176
|
-
this.options.
|
|
91
|
+
this.options.model,
|
|
177
92
|
this.options.fastModel,
|
|
178
93
|
this.options.maxTokens,
|
|
179
94
|
this.getPermissionMode(),
|
|
@@ -221,26 +136,23 @@ export class Agent {
|
|
|
221
136
|
configurationService: this.configurationService,
|
|
222
137
|
systemPrompt: this.systemPrompt,
|
|
223
138
|
stream: this.stream,
|
|
224
|
-
onSessionIdChange: () => {
|
|
225
|
-
this.taskManager.setTaskListId(this.messageManager.getRootSessionId());
|
|
226
|
-
},
|
|
227
|
-
onSessionTasksChange: (tasks) => {
|
|
228
|
-
this.options.callbacks?.onSessionTasksChange?.(tasks);
|
|
229
|
-
},
|
|
230
139
|
onTasksChange: (tasks) => {
|
|
231
140
|
this.options.callbacks?.onTasksChange?.(tasks);
|
|
232
141
|
},
|
|
142
|
+
onBackgroundTasksChange: (tasks) => {
|
|
143
|
+
this.options.callbacks?.onBackgroundTasksChange?.(tasks);
|
|
144
|
+
},
|
|
233
145
|
onPermissionModeChange: (mode) => {
|
|
234
146
|
this.options.callbacks?.onPermissionModeChange?.(mode);
|
|
235
147
|
},
|
|
236
148
|
handlePlanModeTransition: (mode) => {
|
|
237
|
-
this.handlePlanModeTransition(mode);
|
|
149
|
+
this.planManager.handlePlanModeTransition(mode);
|
|
238
150
|
},
|
|
239
151
|
setPermissionMode: (mode) => {
|
|
240
152
|
this.setPermissionMode(mode);
|
|
241
153
|
},
|
|
242
154
|
addPermissionRule: (rule) => this.addPermissionRule(rule),
|
|
243
|
-
addUsage: (usage) => this.addUsage(usage),
|
|
155
|
+
addUsage: (usage) => this.messageManager.addUsage(usage),
|
|
244
156
|
getGatewayConfig: () => this.getGatewayConfig(),
|
|
245
157
|
getModelConfig: () => this.getModelConfig(),
|
|
246
158
|
getMaxInputTokens: () => this.getMaxInputTokens(),
|
|
@@ -266,7 +178,7 @@ export class Agent {
|
|
|
266
178
|
this.aiManager = this.container.get("AIManager")!;
|
|
267
179
|
this.slashCommandManager = this.container.get("SlashCommandManager")!;
|
|
268
180
|
this.pluginManager = this.container.get("PluginManager")!;
|
|
269
|
-
this.
|
|
181
|
+
this.bangManager = this.container.get("BangManager")!;
|
|
270
182
|
|
|
271
183
|
// Set initial permission mode if provided
|
|
272
184
|
if (options.permissionMode) {
|
|
@@ -284,37 +196,13 @@ export class Agent {
|
|
|
284
196
|
}
|
|
285
197
|
|
|
286
198
|
public get usages(): Usage[] {
|
|
287
|
-
return
|
|
199
|
+
return this.messageManager.getUsages();
|
|
288
200
|
}
|
|
289
201
|
|
|
290
202
|
public get sessionFilePath(): string {
|
|
291
203
|
return this.messageManager.getTranscriptPath();
|
|
292
204
|
}
|
|
293
205
|
|
|
294
|
-
/**
|
|
295
|
-
* Rebuild usage array from messages containing usage metadata
|
|
296
|
-
* Called during session restoration to reconstruct usage tracking
|
|
297
|
-
*/
|
|
298
|
-
private rebuildUsageFromMessages(messages: Message[]): void {
|
|
299
|
-
this._usages = [];
|
|
300
|
-
messages.forEach((message) => {
|
|
301
|
-
if (message.role === "assistant" && message.usage) {
|
|
302
|
-
this._usages.push(message.usage);
|
|
303
|
-
}
|
|
304
|
-
});
|
|
305
|
-
// Trigger callback after rebuilding usage array
|
|
306
|
-
this.messageManager.triggerUsageChange();
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* Add usage data to the tracking array and trigger callbacks
|
|
311
|
-
* @param usage Usage data from AI operations
|
|
312
|
-
*/
|
|
313
|
-
private addUsage(usage: Usage): void {
|
|
314
|
-
this._usages.push(usage);
|
|
315
|
-
this.messageManager.triggerUsageChange();
|
|
316
|
-
}
|
|
317
|
-
|
|
318
206
|
public get latestTotalTokens(): number {
|
|
319
207
|
return this.messageManager.getlatestTotalTokens();
|
|
320
208
|
}
|
|
@@ -351,7 +239,7 @@ export class Agent {
|
|
|
351
239
|
|
|
352
240
|
/** Get bash command execution status */
|
|
353
241
|
public get isCommandRunning(): boolean {
|
|
354
|
-
return this.
|
|
242
|
+
return this.bangManager?.isCommandRunning ?? false;
|
|
355
243
|
}
|
|
356
244
|
|
|
357
245
|
/** Get background bash shell output */
|
|
@@ -446,7 +334,7 @@ export class Agent {
|
|
|
446
334
|
configValidator.validateGatewayConfig(gatewayConfig);
|
|
447
335
|
configValidator.validateMaxInputTokens(maxInputTokens);
|
|
448
336
|
configValidator.validateModelConfig(
|
|
449
|
-
modelConfig.
|
|
337
|
+
modelConfig.model,
|
|
450
338
|
modelConfig.fastModel,
|
|
451
339
|
);
|
|
452
340
|
}
|
|
@@ -457,160 +345,35 @@ export class Agent {
|
|
|
457
345
|
continueLastSession?: boolean;
|
|
458
346
|
messages?: Message[];
|
|
459
347
|
}): Promise<void> {
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
this.logger?.error("Failed to initialize MCP servers:", error);
|
|
490
|
-
// Don't throw error to prevent app startup failure
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
// Initialize hooks configuration
|
|
494
|
-
try {
|
|
495
|
-
// Load hooks configuration using ConfigurationService
|
|
496
|
-
this.logger?.debug("Loading hooks configuration...");
|
|
497
|
-
const configResult =
|
|
498
|
-
await this.configurationService.loadMergedConfiguration(this.workdir);
|
|
499
|
-
|
|
500
|
-
this.hookManager.loadConfigurationFromWaveConfig(
|
|
501
|
-
configResult.configuration,
|
|
502
|
-
);
|
|
503
|
-
|
|
504
|
-
// Update plugin manager with enabled plugins configuration
|
|
505
|
-
if (configResult.configuration?.enabledPlugins) {
|
|
506
|
-
this.pluginManager.updateEnabledPlugins(
|
|
507
|
-
configResult.configuration.enabledPlugins,
|
|
508
|
-
);
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
this.logger?.debug("Hooks system initialized successfully");
|
|
512
|
-
} catch (error) {
|
|
513
|
-
this.logger?.error("Failed to initialize hooks system:", error);
|
|
514
|
-
// Don't throw error to prevent app startup failure
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
// Resolve and validate configuration after loading settings.json
|
|
518
|
-
this.resolveAndValidateConfig();
|
|
519
|
-
|
|
520
|
-
// Set global logger for SDK-wide access before discovering rules
|
|
521
|
-
setGlobalLogger(this.logger || null);
|
|
522
|
-
|
|
523
|
-
// Discover modular memory rules
|
|
524
|
-
try {
|
|
525
|
-
await this.memoryRuleManager.discoverRules();
|
|
526
|
-
} catch (error) {
|
|
527
|
-
this.logger?.error("Failed to discover memory rules:", error);
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
// Initialize live configuration reload
|
|
531
|
-
try {
|
|
532
|
-
this.logger?.debug("Initializing live configuration reload...");
|
|
533
|
-
await this.liveConfigManager.initialize();
|
|
534
|
-
this.logger?.debug("Live configuration reload initialized successfully");
|
|
535
|
-
} catch (error) {
|
|
536
|
-
this.logger?.error(
|
|
537
|
-
"Failed to initialize live configuration reload:",
|
|
538
|
-
error,
|
|
539
|
-
);
|
|
540
|
-
// Don't throw error to prevent app startup failure - continue without live reload
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
// Load memory files during initialization
|
|
544
|
-
try {
|
|
545
|
-
this.logger?.debug("Loading memory files...");
|
|
546
|
-
|
|
547
|
-
// Load project memory from AGENTS.md (bypass memory store for direct file access)
|
|
548
|
-
try {
|
|
549
|
-
const projectMemoryPath = path.join(this.workdir, "AGENTS.md");
|
|
550
|
-
this._projectMemoryContent = await fs.readFile(
|
|
551
|
-
projectMemoryPath,
|
|
552
|
-
"utf-8",
|
|
553
|
-
);
|
|
554
|
-
this.logger?.debug("Project memory loaded successfully");
|
|
555
|
-
} catch (error) {
|
|
556
|
-
this._projectMemoryContent = "";
|
|
557
|
-
this.logger?.debug(
|
|
558
|
-
"Project memory file not found or unreadable, using empty content:",
|
|
559
|
-
error instanceof Error ? error.message : String(error),
|
|
560
|
-
);
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
// Load user memory (bypass memory store for direct file access)
|
|
564
|
-
try {
|
|
565
|
-
const userMemoryPath = path.join(os.homedir(), ".wave", "AGENTS.md");
|
|
566
|
-
this._userMemoryContent = await fs.readFile(userMemoryPath, "utf-8");
|
|
567
|
-
this.logger?.debug("User memory loaded successfully");
|
|
568
|
-
} catch (error) {
|
|
569
|
-
this._userMemoryContent = "";
|
|
570
|
-
this.logger?.debug(
|
|
571
|
-
"User memory file not found or unreadable, using empty content:",
|
|
572
|
-
error instanceof Error ? error.message : String(error),
|
|
573
|
-
);
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
this.logger?.debug("Memory initialization completed");
|
|
577
|
-
} catch (error) {
|
|
578
|
-
// Ensure memory is always initialized even if loading fails
|
|
579
|
-
this._projectMemoryContent = "";
|
|
580
|
-
this._userMemoryContent = "";
|
|
581
|
-
this.logger?.error("Failed to load memory files:", error);
|
|
582
|
-
// Don't throw error to prevent app startup failure
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
// Handle session restoration or set provided messages
|
|
586
|
-
if (options?.messages) {
|
|
587
|
-
// If messages are provided, use them directly (useful for testing)
|
|
588
|
-
this.messageManager.setMessages(options.messages);
|
|
589
|
-
// Rebuild usage array from restored messages
|
|
590
|
-
this.rebuildUsageFromMessages(options.messages);
|
|
591
|
-
} else {
|
|
592
|
-
// Otherwise, handle session restoration
|
|
593
|
-
const sessionToRestore = await handleSessionRestoration(
|
|
594
|
-
options?.restoreSessionId,
|
|
595
|
-
options?.continueLastSession,
|
|
596
|
-
this.messageManager.getWorkdir(),
|
|
597
|
-
);
|
|
598
|
-
// Rebuild usage array from restored messages
|
|
599
|
-
this.rebuildUsageFromMessages(sessionToRestore?.messages || []);
|
|
600
|
-
|
|
601
|
-
if (sessionToRestore) {
|
|
602
|
-
this.messageManager.initializeFromSession(sessionToRestore);
|
|
603
|
-
|
|
604
|
-
// Update task manager with the root session ID to ensure continuity across compressions
|
|
605
|
-
this.taskManager.setTaskListId(
|
|
606
|
-
sessionToRestore.rootSessionId || sessionToRestore.id,
|
|
607
|
-
);
|
|
608
|
-
|
|
609
|
-
// After session is initialized, load tasks for the session
|
|
610
|
-
const tasks = await this.taskManager.listTasks();
|
|
611
|
-
this.options.callbacks?.onSessionTasksChange?.(tasks);
|
|
612
|
-
}
|
|
613
|
-
}
|
|
348
|
+
await InitializationService.initialize(
|
|
349
|
+
{
|
|
350
|
+
skillManager: this.skillManager,
|
|
351
|
+
subagentManager: this.subagentManager,
|
|
352
|
+
container: this.container,
|
|
353
|
+
toolManager: this.toolManager,
|
|
354
|
+
pluginManager: this.pluginManager,
|
|
355
|
+
options: this.options,
|
|
356
|
+
slashCommandManager: this.slashCommandManager,
|
|
357
|
+
logger: this.logger,
|
|
358
|
+
mcpManager: this.mcpManager,
|
|
359
|
+
workdir: this.workdir,
|
|
360
|
+
lspManager: this.lspManager,
|
|
361
|
+
configurationService: this.configurationService,
|
|
362
|
+
hookManager: this.hookManager,
|
|
363
|
+
messageManager: this.messageManager,
|
|
364
|
+
memoryRuleManager: this.memoryRuleManager,
|
|
365
|
+
liveConfigManager: this.liveConfigManager,
|
|
366
|
+
taskManager: this.taskManager,
|
|
367
|
+
setProjectMemory: (content) => {
|
|
368
|
+
this._projectMemoryContent = content;
|
|
369
|
+
},
|
|
370
|
+
setUserMemory: (content) => {
|
|
371
|
+
this._userMemoryContent = content;
|
|
372
|
+
},
|
|
373
|
+
resolveAndValidateConfig: () => this.resolveAndValidateConfig(),
|
|
374
|
+
},
|
|
375
|
+
options,
|
|
376
|
+
);
|
|
614
377
|
}
|
|
615
378
|
|
|
616
379
|
/**
|
|
@@ -618,47 +381,22 @@ export class Agent {
|
|
|
618
381
|
* @param sessionId - The ID of the session to restore
|
|
619
382
|
*/
|
|
620
383
|
public async restoreSession(sessionId: string): Promise<void> {
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
// 3. Load target session
|
|
638
|
-
const sessionData = await loadSessionFromJsonl(
|
|
384
|
+
await InteractionService.restoreSession(
|
|
385
|
+
{
|
|
386
|
+
messageManager: this.messageManager,
|
|
387
|
+
slashCommandManager: this.slashCommandManager,
|
|
388
|
+
hookManager: this.hookManager,
|
|
389
|
+
workdir: this.workdir,
|
|
390
|
+
configurationService: this.configurationService,
|
|
391
|
+
logger: this.logger,
|
|
392
|
+
aiManager: this.aiManager,
|
|
393
|
+
subagentManager: this.subagentManager,
|
|
394
|
+
taskManager: this.taskManager,
|
|
395
|
+
options: this.options,
|
|
396
|
+
abortMessage: () => this.abortMessage(),
|
|
397
|
+
},
|
|
639
398
|
sessionId,
|
|
640
|
-
this.messageManager.getWorkdir(),
|
|
641
399
|
);
|
|
642
|
-
if (!sessionData) {
|
|
643
|
-
throw new Error(`Session not found: ${sessionId}`);
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
// 4. Clean current state
|
|
647
|
-
this.abortMessage(); // Abort any running operations
|
|
648
|
-
this.subagentManager.cleanup(); // Clean up active subagents
|
|
649
|
-
|
|
650
|
-
// 5. Rebuild usage (in correct order)
|
|
651
|
-
this.rebuildUsageFromMessages(sessionData.messages);
|
|
652
|
-
|
|
653
|
-
// 6. Initialize session state last
|
|
654
|
-
this.messageManager.initializeFromSession(sessionData);
|
|
655
|
-
|
|
656
|
-
// Update task manager with the root session ID to ensure continuity across compressions
|
|
657
|
-
this.taskManager.setTaskListId(sessionData.rootSessionId || sessionData.id);
|
|
658
|
-
|
|
659
|
-
// 7. Load tasks for the restored session
|
|
660
|
-
const tasks = await this.taskManager.listTasks();
|
|
661
|
-
this.options.callbacks?.onSessionTasksChange?.(tasks);
|
|
662
400
|
}
|
|
663
401
|
|
|
664
402
|
public abortAIMessage(): void {
|
|
@@ -667,7 +405,7 @@ export class Agent {
|
|
|
667
405
|
|
|
668
406
|
/** Execute bash command */
|
|
669
407
|
public async executeBashCommand(command: string): Promise<void> {
|
|
670
|
-
await this.
|
|
408
|
+
await this.bangManager?.executeCommand(command);
|
|
671
409
|
}
|
|
672
410
|
|
|
673
411
|
public clearMessages(): void {
|
|
@@ -683,7 +421,7 @@ export class Agent {
|
|
|
683
421
|
|
|
684
422
|
/** Interrupt bash command execution */
|
|
685
423
|
public abortBashCommand(): void {
|
|
686
|
-
this.
|
|
424
|
+
this.bangManager?.abortCommand();
|
|
687
425
|
}
|
|
688
426
|
|
|
689
427
|
/** Interrupt slash command execution */
|
|
@@ -788,82 +526,23 @@ export class Agent {
|
|
|
788
526
|
content: string,
|
|
789
527
|
images?: Array<{ path: string; mimeType: string }>,
|
|
790
528
|
): Promise<void> {
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
// If command doesn't exist, continue as normal message processing
|
|
809
|
-
// Don't add to history, let normal message processing logic below handle it
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
// Handle normal AI message
|
|
813
|
-
// Add user message first, will automatically sync to UI
|
|
814
|
-
this.messageManager.addUserMessage({
|
|
815
|
-
content,
|
|
816
|
-
images: images?.map((img) => ({
|
|
817
|
-
path: img.path,
|
|
818
|
-
mimeType: img.mimeType,
|
|
819
|
-
})),
|
|
820
|
-
});
|
|
821
|
-
|
|
822
|
-
// Execute UserPromptSubmit hooks after adding the user message
|
|
823
|
-
if (this.hookManager) {
|
|
824
|
-
try {
|
|
825
|
-
const hookResults = await this.hookManager.executeHooks(
|
|
826
|
-
"UserPromptSubmit",
|
|
827
|
-
{
|
|
828
|
-
event: "UserPromptSubmit",
|
|
829
|
-
projectDir: this.workdir,
|
|
830
|
-
timestamp: new Date(),
|
|
831
|
-
// UserPromptSubmit doesn't need toolName
|
|
832
|
-
sessionId: this.sessionId,
|
|
833
|
-
transcriptPath: this.messageManager.getTranscriptPath(),
|
|
834
|
-
cwd: this.workdir,
|
|
835
|
-
userPrompt: content,
|
|
836
|
-
env: this.configurationService.getEnvironmentVars(), // Include configuration environment variables
|
|
837
|
-
},
|
|
838
|
-
);
|
|
839
|
-
|
|
840
|
-
// Process hook results and determine if we should continue
|
|
841
|
-
const processResult = this.hookManager.processHookResults(
|
|
842
|
-
"UserPromptSubmit",
|
|
843
|
-
hookResults,
|
|
844
|
-
this.messageManager,
|
|
845
|
-
);
|
|
846
|
-
|
|
847
|
-
// If hook processing indicates we should block (exit code 2), stop here
|
|
848
|
-
if (processResult.shouldBlock) {
|
|
849
|
-
this.logger?.info(
|
|
850
|
-
"UserPromptSubmit hook blocked prompt processing with error:",
|
|
851
|
-
processResult.errorMessage,
|
|
852
|
-
);
|
|
853
|
-
return; // Don't send to AI
|
|
854
|
-
}
|
|
855
|
-
} catch (error) {
|
|
856
|
-
this.logger?.warn("UserPromptSubmit hooks execution failed:", error);
|
|
857
|
-
// Continue processing even if hooks fail
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
// Send AI message
|
|
862
|
-
await this.aiManager.sendAIMessage();
|
|
863
|
-
} catch (error) {
|
|
864
|
-
console.error("Failed to add user message:", error);
|
|
865
|
-
// Loading state will be automatically updated by the useEffect that watches messages
|
|
866
|
-
}
|
|
529
|
+
await InteractionService.sendMessage(
|
|
530
|
+
{
|
|
531
|
+
messageManager: this.messageManager,
|
|
532
|
+
slashCommandManager: this.slashCommandManager,
|
|
533
|
+
hookManager: this.hookManager,
|
|
534
|
+
workdir: this.workdir,
|
|
535
|
+
configurationService: this.configurationService,
|
|
536
|
+
logger: this.logger,
|
|
537
|
+
aiManager: this.aiManager,
|
|
538
|
+
subagentManager: this.subagentManager,
|
|
539
|
+
taskManager: this.taskManager,
|
|
540
|
+
options: this.options,
|
|
541
|
+
abortMessage: () => this.abortMessage(),
|
|
542
|
+
},
|
|
543
|
+
content,
|
|
544
|
+
images,
|
|
545
|
+
);
|
|
867
546
|
}
|
|
868
547
|
|
|
869
548
|
// ========== MCP Management Methods ==========
|
|
@@ -896,8 +575,12 @@ export class Agent {
|
|
|
896
575
|
}
|
|
897
576
|
|
|
898
577
|
/** Reload custom commands */
|
|
899
|
-
public reloadCustomCommands(): void {
|
|
578
|
+
public async reloadCustomCommands(): Promise<void> {
|
|
579
|
+
await this.skillManager.initialize();
|
|
900
580
|
this.slashCommandManager.reloadCustomCommands();
|
|
581
|
+
this.slashCommandManager.registerSkillCommands(
|
|
582
|
+
this.skillManager.getAvailableSkills(),
|
|
583
|
+
);
|
|
901
584
|
}
|
|
902
585
|
|
|
903
586
|
/** Get custom command details */
|
|
@@ -932,7 +615,7 @@ export class Agent {
|
|
|
932
615
|
this.logger?.debug("Setting permission mode", { mode });
|
|
933
616
|
this.toolManager.setPermissionMode(mode);
|
|
934
617
|
|
|
935
|
-
this.handlePlanModeTransition(mode);
|
|
618
|
+
this.planManager.handlePlanModeTransition(mode);
|
|
936
619
|
|
|
937
620
|
this.options.callbacks?.onPermissionModeChange?.(mode);
|
|
938
621
|
}
|
|
@@ -944,7 +627,9 @@ export class Agent {
|
|
|
944
627
|
public async truncateHistory(index: number): Promise<void> {
|
|
945
628
|
await this.messageManager.truncateHistory(index, this.reversionManager);
|
|
946
629
|
// After truncating history, the task list might have changed, so refresh it.
|
|
947
|
-
|
|
630
|
+
// We explicitly load tasks and trigger the callback to ensure UI updates immediately and in order.
|
|
631
|
+
const tasks = await this.taskManager.listTasks();
|
|
632
|
+
this.options.callbacks?.onTasksChange?.(tasks);
|
|
948
633
|
}
|
|
949
634
|
|
|
950
635
|
/**
|
|
@@ -965,9 +650,19 @@ export class Agent {
|
|
|
965
650
|
}
|
|
966
651
|
|
|
967
652
|
/**
|
|
968
|
-
* Get all currently allowed rules (
|
|
653
|
+
* Get all currently allowed rules (user-defined and default)
|
|
969
654
|
*/
|
|
970
655
|
public getAllowedRules(): string[] {
|
|
656
|
+
return [
|
|
657
|
+
...this.permissionManager.getAllowedRules(),
|
|
658
|
+
...this.permissionManager.getDefaultAllowedRules(),
|
|
659
|
+
];
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* Get only user-defined allowed rules
|
|
664
|
+
*/
|
|
665
|
+
public getUserAllowedRules(): string[] {
|
|
971
666
|
return this.permissionManager.getAllowedRules();
|
|
972
667
|
}
|
|
973
668
|
|
|
@@ -985,57 +680,7 @@ export class Agent {
|
|
|
985
680
|
* @param rule - The rule to add (e.g., "Bash(ls)")
|
|
986
681
|
*/
|
|
987
682
|
public async addPermissionRule(rule: string): Promise<void> {
|
|
988
|
-
|
|
989
|
-
let rulesToAdd = [rule];
|
|
990
|
-
const bashMatch = rule.match(/^Bash\((.*)\)$/);
|
|
991
|
-
if (bashMatch) {
|
|
992
|
-
const command = bashMatch[1];
|
|
993
|
-
rulesToAdd = this.permissionManager.expandBashRule(command, this.workdir);
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
for (const ruleToAdd of rulesToAdd) {
|
|
997
|
-
// 2. Update PermissionManager state
|
|
998
|
-
const currentRules = this.permissionManager.getAllowedRules();
|
|
999
|
-
if (!currentRules.includes(ruleToAdd)) {
|
|
1000
|
-
this.permissionManager.updateAllowedRules([...currentRules, ruleToAdd]);
|
|
1001
|
-
|
|
1002
|
-
// 3. Persist to settings.local.json
|
|
1003
|
-
try {
|
|
1004
|
-
await this.configurationService.addAllowedRule(
|
|
1005
|
-
this.workdir,
|
|
1006
|
-
ruleToAdd,
|
|
1007
|
-
);
|
|
1008
|
-
this.logger?.debug("Persistent permission rule added", {
|
|
1009
|
-
rule: ruleToAdd,
|
|
1010
|
-
});
|
|
1011
|
-
} catch (error) {
|
|
1012
|
-
this.logger?.error("Failed to persist permission rule", {
|
|
1013
|
-
rule: ruleToAdd,
|
|
1014
|
-
error: error instanceof Error ? error.message : String(error),
|
|
1015
|
-
});
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
|
-
|
|
1021
|
-
/**
|
|
1022
|
-
* Handle plan mode transition, generating or clearing plan file path
|
|
1023
|
-
* @param mode - The current effective permission mode
|
|
1024
|
-
*/
|
|
1025
|
-
private handlePlanModeTransition(mode: PermissionMode): void {
|
|
1026
|
-
if (mode === "plan") {
|
|
1027
|
-
this.planManager
|
|
1028
|
-
.getOrGeneratePlanFilePath(this.messageManager.getRootSessionId())
|
|
1029
|
-
.then(({ path }) => {
|
|
1030
|
-
this.logger?.debug("Plan file path generated", { path });
|
|
1031
|
-
this.permissionManager.setPlanFilePath(path);
|
|
1032
|
-
})
|
|
1033
|
-
.catch((error) => {
|
|
1034
|
-
this.logger?.error("Failed to generate plan file path", error);
|
|
1035
|
-
});
|
|
1036
|
-
} else {
|
|
1037
|
-
this.permissionManager.setPlanFilePath(undefined);
|
|
1038
|
-
}
|
|
683
|
+
await this.permissionManager.addPermissionRule(rule);
|
|
1039
684
|
}
|
|
1040
685
|
|
|
1041
686
|
/**
|