wave-agent-sdk 0.2.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.d.ts +66 -20
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +156 -83
- package/dist/constants/prompts.d.ts +7 -2
- package/dist/constants/prompts.d.ts.map +1 -1
- package/dist/constants/prompts.js +41 -5
- package/dist/constants/tools.d.ts +2 -2
- package/dist/constants/tools.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/managers/MemoryRuleManager.d.ts.map +1 -1
- package/dist/managers/MemoryRuleManager.js +16 -2
- package/dist/managers/aiManager.d.ts +14 -4
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +61 -9
- package/dist/managers/backgroundBashManager.d.ts.map +1 -1
- package/dist/managers/backgroundBashManager.js +1 -0
- package/dist/managers/backgroundTaskManager.d.ts +35 -0
- package/dist/managers/backgroundTaskManager.d.ts.map +1 -0
- package/dist/managers/backgroundTaskManager.js +249 -0
- package/dist/managers/bashManager.d.ts.map +1 -1
- package/dist/managers/bashManager.js +0 -3
- package/dist/managers/foregroundTaskManager.d.ts +9 -0
- package/dist/managers/foregroundTaskManager.d.ts.map +1 -0
- package/dist/managers/foregroundTaskManager.js +20 -0
- package/dist/managers/liveConfigManager.d.ts +1 -1
- package/dist/managers/liveConfigManager.d.ts.map +1 -1
- package/dist/managers/lspManager.d.ts.map +1 -1
- package/dist/managers/lspManager.js +3 -1
- package/dist/managers/messageManager.d.ts +34 -4
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +104 -13
- package/dist/managers/permissionManager.d.ts.map +1 -1
- package/dist/managers/permissionManager.js +11 -13
- package/dist/managers/pluginManager.d.ts.map +1 -1
- package/dist/managers/pluginManager.js +3 -2
- package/dist/managers/pluginScopeManager.d.ts +13 -2
- package/dist/managers/pluginScopeManager.d.ts.map +1 -1
- package/dist/managers/pluginScopeManager.js +38 -0
- package/dist/managers/reversionManager.d.ts +39 -0
- package/dist/managers/reversionManager.d.ts.map +1 -0
- package/dist/managers/reversionManager.js +118 -0
- package/dist/managers/slashCommandManager.d.ts +4 -1
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +16 -6
- package/dist/managers/subagentManager.d.ts +13 -2
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +144 -35
- package/dist/managers/toolManager.d.ts +11 -1
- package/dist/managers/toolManager.d.ts.map +1 -1
- package/dist/managers/toolManager.js +11 -3
- package/dist/services/GitService.d.ts.map +1 -1
- package/dist/services/GitService.js +6 -2
- package/dist/services/MarketplaceService.d.ts +14 -1
- package/dist/services/MarketplaceService.d.ts.map +1 -1
- package/dist/services/MarketplaceService.js +72 -4
- package/dist/services/MemoryRuleService.d.ts +1 -1
- package/dist/services/MemoryRuleService.d.ts.map +1 -1
- package/dist/services/MemoryRuleService.js +13 -2
- package/dist/services/aiService.js +1 -1
- package/dist/services/configurationService.d.ts +18 -2
- package/dist/services/configurationService.d.ts.map +1 -1
- package/dist/services/configurationService.js +62 -0
- package/dist/services/fileWatcher.d.ts +0 -5
- package/dist/services/fileWatcher.d.ts.map +1 -1
- package/dist/services/fileWatcher.js +0 -11
- package/dist/services/memory.js +1 -1
- package/dist/services/pluginLoader.d.ts.map +1 -1
- package/dist/services/pluginLoader.js +6 -1
- package/dist/services/reversionService.d.ts +24 -0
- package/dist/services/reversionService.d.ts.map +1 -0
- package/dist/services/reversionService.js +76 -0
- package/dist/services/session.d.ts +7 -0
- package/dist/services/session.d.ts.map +1 -1
- package/dist/services/session.js +126 -3
- package/dist/tools/bashTool.d.ts +0 -8
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +52 -174
- package/dist/tools/deleteFileTool.d.ts.map +1 -1
- package/dist/tools/deleteFileTool.js +9 -0
- package/dist/tools/editTool.d.ts.map +1 -1
- package/dist/tools/editTool.js +15 -4
- package/dist/tools/multiEditTool.d.ts.map +1 -1
- package/dist/tools/multiEditTool.js +16 -5
- package/dist/tools/taskOutputTool.d.ts +3 -0
- package/dist/tools/taskOutputTool.d.ts.map +1 -0
- package/dist/tools/taskOutputTool.js +149 -0
- package/dist/tools/taskStopTool.d.ts +3 -0
- package/dist/tools/taskStopTool.d.ts.map +1 -0
- package/dist/tools/taskStopTool.js +65 -0
- package/dist/tools/taskTool.d.ts.map +1 -1
- package/dist/tools/taskTool.js +105 -63
- package/dist/tools/types.d.ts +7 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/writeTool.d.ts.map +1 -1
- package/dist/tools/writeTool.js +9 -0
- package/dist/types/commands.d.ts +1 -0
- package/dist/types/commands.d.ts.map +1 -1
- package/dist/types/configuration.d.ts +3 -0
- package/dist/types/configuration.d.ts.map +1 -1
- package/dist/types/environment.d.ts +2 -1
- package/dist/types/environment.d.ts.map +1 -1
- package/dist/types/environment.js +0 -6
- package/dist/types/history.d.ts +5 -0
- package/dist/types/history.d.ts.map +1 -0
- package/dist/types/history.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/marketplace.d.ts +4 -0
- package/dist/types/marketplace.d.ts.map +1 -1
- package/dist/types/messaging.d.ts +7 -1
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/types/processes.d.ts +24 -4
- package/dist/types/processes.d.ts.map +1 -1
- package/dist/types/reversion.d.ts +29 -0
- package/dist/types/reversion.d.ts.map +1 -0
- package/dist/types/reversion.js +1 -0
- package/dist/utils/builtinSubagents.d.ts.map +1 -1
- package/dist/utils/builtinSubagents.js +16 -0
- package/dist/utils/constants.d.ts +2 -2
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/constants.js +2 -2
- package/dist/utils/editUtils.d.ts +4 -9
- package/dist/utils/editUtils.d.ts.map +1 -1
- package/dist/utils/editUtils.js +54 -55
- package/dist/utils/messageOperations.d.ts +3 -1
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +8 -1
- package/dist/utils/openaiClient.d.ts.map +1 -1
- package/dist/utils/openaiClient.js +56 -26
- package/dist/utils/promptHistory.d.ts +20 -0
- package/dist/utils/promptHistory.d.ts.map +1 -0
- package/dist/utils/promptHistory.js +117 -0
- package/package.json +5 -3
- package/src/agent.ts +193 -109
- package/src/constants/prompts.ts +45 -5
- package/src/constants/tools.ts +2 -2
- package/src/index.ts +1 -1
- package/src/managers/MemoryRuleManager.ts +18 -2
- package/src/managers/aiManager.ts +87 -18
- package/src/managers/backgroundBashManager.ts +1 -0
- package/src/managers/backgroundTaskManager.ts +306 -0
- package/src/managers/bashManager.ts +0 -4
- package/src/managers/foregroundTaskManager.ts +26 -0
- package/src/managers/liveConfigManager.ts +2 -1
- package/src/managers/lspManager.ts +3 -1
- package/src/managers/messageManager.ts +136 -18
- package/src/managers/permissionManager.ts +11 -13
- package/src/managers/pluginManager.ts +4 -3
- package/src/managers/pluginScopeManager.ts +57 -8
- package/src/managers/reversionManager.ts +152 -0
- package/src/managers/slashCommandManager.ts +30 -7
- package/src/managers/subagentManager.ts +176 -31
- package/src/managers/toolManager.ts +23 -4
- package/src/services/GitService.ts +6 -2
- package/src/services/MarketplaceService.ts +100 -4
- package/src/services/MemoryRuleService.ts +18 -6
- package/src/services/aiService.ts +1 -1
- package/src/services/configurationService.ts +79 -1
- package/src/services/fileWatcher.ts +0 -13
- package/src/services/memory.ts +1 -1
- package/src/services/pluginLoader.ts +7 -1
- package/src/services/reversionService.ts +94 -0
- package/src/services/session.ts +161 -3
- package/src/tools/bashTool.ts +73 -200
- package/src/tools/deleteFileTool.ts +15 -0
- package/src/tools/editTool.ts +20 -10
- package/src/tools/multiEditTool.ts +21 -11
- package/src/tools/taskOutputTool.ts +174 -0
- package/src/tools/taskStopTool.ts +72 -0
- package/src/tools/taskTool.ts +130 -74
- package/src/tools/types.ts +7 -0
- package/src/tools/writeTool.ts +14 -0
- package/src/types/commands.ts +3 -0
- package/src/types/configuration.ts +4 -0
- package/src/types/environment.ts +3 -1
- package/src/types/history.ts +4 -0
- package/src/types/index.ts +1 -0
- package/src/types/marketplace.ts +5 -0
- package/src/types/messaging.ts +9 -1
- package/src/types/processes.ts +33 -4
- package/src/types/reversion.ts +29 -0
- package/src/utils/builtinSubagents.ts +18 -0
- package/src/utils/constants.ts +2 -2
- package/src/utils/editUtils.ts +66 -58
- package/src/utils/messageOperations.ts +10 -0
- package/src/utils/openaiClient.ts +69 -35
- package/src/utils/promptHistory.ts +133 -0
- package/dist/utils/bashHistory.d.ts +0 -50
- package/dist/utils/bashHistory.d.ts.map +0 -1
- package/dist/utils/bashHistory.js +0 -256
- package/src/utils/bashHistory.ts +0 -320
package/src/agent.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ForegroundTaskManager } from "./managers/foregroundTaskManager.js";
|
|
1
2
|
import {
|
|
2
3
|
MessageManager,
|
|
3
4
|
type MessageManagerCallbacks,
|
|
@@ -13,12 +14,14 @@ import { McpManager, type McpManagerCallbacks } from "./managers/mcpManager.js";
|
|
|
13
14
|
import { LspManager } from "./managers/lspManager.js";
|
|
14
15
|
import { BashManager } from "./managers/bashManager.js";
|
|
15
16
|
import {
|
|
16
|
-
|
|
17
|
-
type
|
|
18
|
-
} from "./managers/
|
|
17
|
+
BackgroundTaskManager,
|
|
18
|
+
type BackgroundTaskManagerCallbacks,
|
|
19
|
+
} from "./managers/backgroundTaskManager.js";
|
|
19
20
|
import { SlashCommandManager } from "./managers/slashCommandManager.js";
|
|
20
21
|
import { PluginManager } from "./managers/pluginManager.js";
|
|
21
22
|
import { HookManager } from "./managers/hookManager.js";
|
|
23
|
+
import { ReversionManager } from "./managers/reversionManager.js";
|
|
24
|
+
import { ReversionService } from "./services/reversionService.js";
|
|
22
25
|
import { PermissionManager } from "./managers/permissionManager.js";
|
|
23
26
|
import { PlanManager } from "./managers/planManager.js";
|
|
24
27
|
import type {
|
|
@@ -36,6 +39,8 @@ import type {
|
|
|
36
39
|
Usage,
|
|
37
40
|
PermissionMode,
|
|
38
41
|
PermissionCallback,
|
|
42
|
+
BackgroundTask,
|
|
43
|
+
ForegroundTask,
|
|
39
44
|
} from "./types/index.js";
|
|
40
45
|
import { MemoryRuleManager } from "./managers/MemoryRuleManager.js";
|
|
41
46
|
import { LiveConfigManager } from "./managers/liveConfigManager.js";
|
|
@@ -70,6 +75,8 @@ export interface AgentOptions {
|
|
|
70
75
|
fastModel?: string;
|
|
71
76
|
maxInputTokens?: number;
|
|
72
77
|
maxTokens?: number;
|
|
78
|
+
/** Preferred language for agent communication */
|
|
79
|
+
language?: string;
|
|
73
80
|
|
|
74
81
|
// Existing options (preserved)
|
|
75
82
|
callbacks?: AgentCallbacks;
|
|
@@ -96,10 +103,12 @@ export interface AgentOptions {
|
|
|
96
103
|
|
|
97
104
|
export interface AgentCallbacks
|
|
98
105
|
extends MessageManagerCallbacks,
|
|
99
|
-
|
|
106
|
+
BackgroundTaskManagerCallbacks,
|
|
100
107
|
McpManagerCallbacks,
|
|
101
108
|
SubagentManagerCallbacks {
|
|
109
|
+
onTasksChange?: (tasks: BackgroundTask[]) => void;
|
|
102
110
|
onPermissionModeChange?: (mode: PermissionMode) => void;
|
|
111
|
+
onBackgroundCurrentTask?: () => void;
|
|
103
112
|
}
|
|
104
113
|
|
|
105
114
|
export class Agent {
|
|
@@ -107,7 +116,7 @@ export class Agent {
|
|
|
107
116
|
private aiManager: AIManager;
|
|
108
117
|
|
|
109
118
|
private bashManager: BashManager | null = null;
|
|
110
|
-
private
|
|
119
|
+
private backgroundTaskManager: BackgroundTaskManager;
|
|
111
120
|
private logger?: Logger; // Add optional logger property
|
|
112
121
|
private toolManager: ToolManager; // Add tool registry instance
|
|
113
122
|
private mcpManager: McpManager; // Add MCP manager instance
|
|
@@ -119,8 +128,10 @@ export class Agent {
|
|
|
119
128
|
private pluginManager: PluginManager; // Add plugin manager instance
|
|
120
129
|
private skillManager: SkillManager; // Add skill manager instance
|
|
121
130
|
private hookManager: HookManager; // Add hooks manager instance
|
|
131
|
+
private reversionManager: ReversionManager;
|
|
122
132
|
private memoryRuleManager: MemoryRuleManager; // Add memory rule manager instance
|
|
123
133
|
private liveConfigManager: LiveConfigManager; // Add live configuration manager
|
|
134
|
+
private foregroundTaskManager: ForegroundTaskManager;
|
|
124
135
|
private configurationService: ConfigurationService; // Add configuration service
|
|
125
136
|
private workdir: string; // Working directory
|
|
126
137
|
private systemPrompt?: string; // Custom system prompt
|
|
@@ -160,44 +171,8 @@ export class Agent {
|
|
|
160
171
|
);
|
|
161
172
|
}
|
|
162
173
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
*
|
|
166
|
-
* @param config - Configuration updates for gateway, model, and token limit
|
|
167
|
-
*/
|
|
168
|
-
public updateConfig(config: {
|
|
169
|
-
gateway?: Partial<GatewayConfig>;
|
|
170
|
-
model?: Partial<ModelConfig>;
|
|
171
|
-
maxInputTokens?: number;
|
|
172
|
-
maxTokens?: number;
|
|
173
|
-
}): void {
|
|
174
|
-
if (config.gateway) {
|
|
175
|
-
this.options.apiKey = config.gateway.apiKey ?? this.options.apiKey;
|
|
176
|
-
this.options.baseURL = config.gateway.baseURL ?? this.options.baseURL;
|
|
177
|
-
this.options.defaultHeaders =
|
|
178
|
-
config.gateway.defaultHeaders ?? this.options.defaultHeaders;
|
|
179
|
-
this.options.fetchOptions =
|
|
180
|
-
config.gateway.fetchOptions ?? this.options.fetchOptions;
|
|
181
|
-
this.options.fetch = config.gateway.fetch ?? this.options.fetch;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
if (config.model) {
|
|
185
|
-
this.options.agentModel =
|
|
186
|
-
config.model.agentModel ?? this.options.agentModel;
|
|
187
|
-
this.options.fastModel = config.model.fastModel ?? this.options.fastModel;
|
|
188
|
-
this.options.maxTokens = config.model.maxTokens ?? this.options.maxTokens;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (config.maxInputTokens !== undefined) {
|
|
192
|
-
this.options.maxInputTokens = config.maxInputTokens;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
if (config.maxTokens !== undefined) {
|
|
196
|
-
this.options.maxTokens = config.maxTokens;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Re-validate configuration after update
|
|
200
|
-
this.resolveAndValidateConfig();
|
|
174
|
+
public getLanguage(): string | undefined {
|
|
175
|
+
return this.configurationService.resolveLanguage(this.options.language);
|
|
201
176
|
}
|
|
202
177
|
|
|
203
178
|
/**
|
|
@@ -231,8 +206,15 @@ export class Agent {
|
|
|
231
206
|
// Store options for dynamic configuration resolution
|
|
232
207
|
this.options = options;
|
|
233
208
|
|
|
234
|
-
this.
|
|
235
|
-
|
|
209
|
+
this.foregroundTaskManager = new ForegroundTaskManager();
|
|
210
|
+
|
|
211
|
+
this.backgroundTaskManager = new BackgroundTaskManager({
|
|
212
|
+
callbacks: {
|
|
213
|
+
...callbacks,
|
|
214
|
+
onTasksChange: (tasks) => {
|
|
215
|
+
callbacks.onTasksChange?.(tasks);
|
|
216
|
+
},
|
|
217
|
+
},
|
|
236
218
|
workdir: this.workdir,
|
|
237
219
|
});
|
|
238
220
|
this.mcpManager = new McpManager({ callbacks, logger: this.logger }); // Initialize MCP manager
|
|
@@ -261,17 +243,23 @@ export class Agent {
|
|
|
261
243
|
workdir: this.workdir,
|
|
262
244
|
});
|
|
263
245
|
|
|
246
|
+
// Initialize memory rule manager
|
|
247
|
+
this.memoryRuleManager = new MemoryRuleManager({
|
|
248
|
+
workdir: this.workdir,
|
|
249
|
+
});
|
|
250
|
+
|
|
264
251
|
// Initialize MessageManager
|
|
265
252
|
this.messageManager = new MessageManager({
|
|
266
253
|
callbacks,
|
|
267
254
|
workdir: this.workdir,
|
|
268
255
|
logger: this.logger,
|
|
256
|
+
memoryRuleManager: this.memoryRuleManager,
|
|
269
257
|
});
|
|
270
258
|
|
|
271
|
-
// Initialize
|
|
272
|
-
this.
|
|
273
|
-
|
|
274
|
-
|
|
259
|
+
// Initialize ReversionManager
|
|
260
|
+
this.reversionManager = new ReversionManager(
|
|
261
|
+
new ReversionService(this.messageManager.getTranscriptPath()),
|
|
262
|
+
);
|
|
275
263
|
|
|
276
264
|
// Create a wrapper for canUseTool that triggers notification hooks
|
|
277
265
|
const canUseToolWithNotification: PermissionCallback | undefined =
|
|
@@ -321,8 +309,11 @@ export class Agent {
|
|
|
321
309
|
lspManager: this.lspManager,
|
|
322
310
|
logger: this.logger,
|
|
323
311
|
permissionManager: this.permissionManager,
|
|
312
|
+
reversionManager: this.reversionManager,
|
|
324
313
|
permissionMode: options.permissionMode, // Let PermissionManager handle defaultMode resolution
|
|
325
314
|
canUseToolCallback: canUseToolWithNotification,
|
|
315
|
+
backgroundTaskManager: this.backgroundTaskManager,
|
|
316
|
+
foregroundTaskManager: this.foregroundTaskManager,
|
|
326
317
|
}); // Initialize tool registry with permission support
|
|
327
318
|
this.liveConfigManager = new LiveConfigManager({
|
|
328
319
|
workdir: this.workdir,
|
|
@@ -353,8 +344,11 @@ export class Agent {
|
|
|
353
344
|
getGatewayConfig: () => this.getGatewayConfig(),
|
|
354
345
|
getModelConfig: () => this.getModelConfig(),
|
|
355
346
|
getMaxInputTokens: () => this.getMaxInputTokens(),
|
|
347
|
+
getLanguage: () => this.getLanguage(),
|
|
356
348
|
hookManager: this.hookManager,
|
|
357
349
|
onUsageAdded: (usage) => this.addUsage(usage),
|
|
350
|
+
backgroundTaskManager: this.backgroundTaskManager,
|
|
351
|
+
memoryRuleManager: this.memoryRuleManager,
|
|
358
352
|
});
|
|
359
353
|
|
|
360
354
|
// Initialize AI manager with resolved configuration
|
|
@@ -362,7 +356,7 @@ export class Agent {
|
|
|
362
356
|
messageManager: this.messageManager,
|
|
363
357
|
toolManager: this.toolManager,
|
|
364
358
|
logger: this.logger,
|
|
365
|
-
|
|
359
|
+
backgroundTaskManager: this.backgroundTaskManager,
|
|
366
360
|
hookManager: this.hookManager,
|
|
367
361
|
permissionManager: this.permissionManager,
|
|
368
362
|
callbacks: {
|
|
@@ -374,9 +368,11 @@ export class Agent {
|
|
|
374
368
|
workdir: this.workdir,
|
|
375
369
|
systemPrompt: this.systemPrompt,
|
|
376
370
|
stream: this.stream, // Pass streaming mode flag
|
|
371
|
+
reversionManager: this.reversionManager,
|
|
377
372
|
getGatewayConfig: () => this.getGatewayConfig(),
|
|
378
373
|
getModelConfig: () => this.getModelConfig(),
|
|
379
374
|
getMaxInputTokens: () => this.getMaxInputTokens(),
|
|
375
|
+
getLanguage: () => this.getLanguage(),
|
|
380
376
|
getEnvironmentVars: () => this.configurationService.getEnvironmentVars(), // Provide access to configuration environment variables
|
|
381
377
|
});
|
|
382
378
|
|
|
@@ -384,6 +380,7 @@ export class Agent {
|
|
|
384
380
|
this.slashCommandManager = new SlashCommandManager({
|
|
385
381
|
messageManager: this.messageManager,
|
|
386
382
|
aiManager: this.aiManager,
|
|
383
|
+
backgroundTaskManager: this.backgroundTaskManager,
|
|
387
384
|
workdir: this.workdir,
|
|
388
385
|
logger: this.logger,
|
|
389
386
|
});
|
|
@@ -478,29 +475,8 @@ export class Agent {
|
|
|
478
475
|
}
|
|
479
476
|
|
|
480
477
|
/** Get combined memory content (project + user + modular rules) */
|
|
481
|
-
public
|
|
482
|
-
|
|
483
|
-
if (this._projectMemoryContent.trim()) {
|
|
484
|
-
combined += this._projectMemoryContent;
|
|
485
|
-
}
|
|
486
|
-
if (this._userMemoryContent.trim()) {
|
|
487
|
-
if (combined) {
|
|
488
|
-
combined += "\n\n";
|
|
489
|
-
}
|
|
490
|
-
combined += this._userMemoryContent;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
// Add modular memory rules
|
|
494
|
-
const filesInContext = this.messageManager.getFilesInContext();
|
|
495
|
-
const activeRules = this.memoryRuleManager.getActiveRules(filesInContext);
|
|
496
|
-
if (activeRules.length > 0) {
|
|
497
|
-
if (combined) {
|
|
498
|
-
combined += "\n\n";
|
|
499
|
-
}
|
|
500
|
-
combined += activeRules.map((r) => r.content).join("\n\n");
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
return combined;
|
|
478
|
+
public async getCombinedMemory(): Promise<string> {
|
|
479
|
+
return this.messageManager.getCombinedMemory();
|
|
504
480
|
}
|
|
505
481
|
|
|
506
482
|
/** Get AI loading status */
|
|
@@ -523,12 +499,25 @@ export class Agent {
|
|
|
523
499
|
id: string,
|
|
524
500
|
filter?: string,
|
|
525
501
|
): { stdout: string; stderr: string; status: string } | null {
|
|
526
|
-
return this.
|
|
502
|
+
return this.backgroundTaskManager.getOutput(id, filter);
|
|
527
503
|
}
|
|
528
504
|
|
|
529
505
|
/** Kill background bash shell */
|
|
530
506
|
public killBackgroundShell(id: string): boolean {
|
|
531
|
-
return this.
|
|
507
|
+
return this.backgroundTaskManager.stopTask(id);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/** Get background task output */
|
|
511
|
+
public getBackgroundTaskOutput(
|
|
512
|
+
id: string,
|
|
513
|
+
filter?: string,
|
|
514
|
+
): { stdout: string; stderr: string; status: string } | null {
|
|
515
|
+
return this.backgroundTaskManager.getOutput(id, filter);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/** Stop background task */
|
|
519
|
+
public stopBackgroundTask(id: string): boolean {
|
|
520
|
+
return this.backgroundTaskManager.stopTask(id);
|
|
532
521
|
}
|
|
533
522
|
|
|
534
523
|
/**
|
|
@@ -667,6 +656,9 @@ export class Agent {
|
|
|
667
656
|
// Resolve and validate configuration after loading settings.json
|
|
668
657
|
this.resolveAndValidateConfig();
|
|
669
658
|
|
|
659
|
+
// Set global logger for SDK-wide access before discovering rules
|
|
660
|
+
setGlobalLogger(this.logger || null);
|
|
661
|
+
|
|
670
662
|
// Discover modular memory rules
|
|
671
663
|
try {
|
|
672
664
|
await this.memoryRuleManager.discoverRules();
|
|
@@ -674,9 +666,6 @@ export class Agent {
|
|
|
674
666
|
this.logger?.error("Failed to discover memory rules:", error);
|
|
675
667
|
}
|
|
676
668
|
|
|
677
|
-
// Set global logger for SDK-wide access after validation
|
|
678
|
-
setGlobalLogger(this.logger || null);
|
|
679
|
-
|
|
680
669
|
// Initialize live configuration reload
|
|
681
670
|
try {
|
|
682
671
|
this.logger?.debug("Initializing live configuration reload...");
|
|
@@ -955,14 +944,42 @@ export class Agent {
|
|
|
955
944
|
this.slashCommandManager.abortCurrentCommand();
|
|
956
945
|
}
|
|
957
946
|
|
|
947
|
+
/**
|
|
948
|
+
* Register a foreground task that can be backgrounded
|
|
949
|
+
*/
|
|
950
|
+
public registerForegroundTask(task: ForegroundTask): void {
|
|
951
|
+
this.foregroundTaskManager.registerForegroundTask(task);
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
/**
|
|
955
|
+
* Unregister a foreground task
|
|
956
|
+
*/
|
|
957
|
+
public unregisterForegroundTask(id: string): void {
|
|
958
|
+
this.foregroundTaskManager.unregisterForegroundTask(id);
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
/**
|
|
962
|
+
* Background the current foreground task
|
|
963
|
+
*/
|
|
964
|
+
public async backgroundCurrentTask(): Promise<void> {
|
|
965
|
+
await this.foregroundTaskManager.backgroundCurrentTask();
|
|
966
|
+
this.options.callbacks?.onBackgroundCurrentTask?.();
|
|
967
|
+
|
|
968
|
+
// If there was no foreground task (e.g. a tool that doesn't register one),
|
|
969
|
+
// or even if there was, we should stop the AI recursion loop.
|
|
970
|
+
if (!this.foregroundTaskManager.hasActiveTasks()) {
|
|
971
|
+
this.aiManager.abortRecursion();
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
|
|
958
975
|
/** Destroy managers, clean up resources */
|
|
959
976
|
public async destroy(): Promise<void> {
|
|
960
977
|
await this.messageManager.saveSession();
|
|
961
978
|
this.abortAIMessage(); // This will abort tools including Task tool (subagents)
|
|
962
979
|
this.abortBashCommand();
|
|
963
980
|
this.abortSlashCommand();
|
|
964
|
-
// Cleanup background
|
|
965
|
-
this.
|
|
981
|
+
// Cleanup background task manager
|
|
982
|
+
this.backgroundTaskManager.cleanup();
|
|
966
983
|
// Cleanup MCP connections
|
|
967
984
|
await this.mcpManager.cleanup();
|
|
968
985
|
// Cleanup LSP connections
|
|
@@ -983,6 +1000,23 @@ export class Agent {
|
|
|
983
1000
|
// Cleanup memory store
|
|
984
1001
|
}
|
|
985
1002
|
|
|
1003
|
+
/**
|
|
1004
|
+
* Get a subagent instance by its ID
|
|
1005
|
+
* @param subagentId - The ID of the subagent instance
|
|
1006
|
+
*/
|
|
1007
|
+
public getSubagentInstance(
|
|
1008
|
+
subagentId: string,
|
|
1009
|
+
): import("./managers/subagentManager.js").SubagentInstance | null {
|
|
1010
|
+
return this.subagentManager.getInstance(subagentId);
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
/**
|
|
1014
|
+
* Trigger the rewind UI callback
|
|
1015
|
+
*/
|
|
1016
|
+
public triggerShowRewind(): void {
|
|
1017
|
+
this.messageManager.triggerShowRewind();
|
|
1018
|
+
}
|
|
1019
|
+
|
|
986
1020
|
/**
|
|
987
1021
|
* Send a message to the AI agent with optional images
|
|
988
1022
|
*
|
|
@@ -1122,12 +1156,18 @@ export class Agent {
|
|
|
1122
1156
|
const typeLabel = type === "project" ? "Project Memory" : "User Memory";
|
|
1123
1157
|
const storagePath = "AGENTS.md";
|
|
1124
1158
|
|
|
1125
|
-
this.messageManager.
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1159
|
+
const messages = this.messageManager.getMessages();
|
|
1160
|
+
const lastMessage = messages[messages.length - 1];
|
|
1161
|
+
if (lastMessage && lastMessage.role === "assistant") {
|
|
1162
|
+
lastMessage.blocks.push({
|
|
1163
|
+
type: "memory",
|
|
1164
|
+
content: `${typeLabel}: ${memoryText}`,
|
|
1165
|
+
isSuccess: true,
|
|
1166
|
+
memoryType: type,
|
|
1167
|
+
storagePath,
|
|
1168
|
+
});
|
|
1169
|
+
this.messageManager.setMessages(messages);
|
|
1170
|
+
}
|
|
1131
1171
|
} catch (error) {
|
|
1132
1172
|
// Add failed MemoryBlock to the last assistant message
|
|
1133
1173
|
const memoryText = message.substring(1).trim();
|
|
@@ -1136,12 +1176,18 @@ export class Agent {
|
|
|
1136
1176
|
const errorMessage =
|
|
1137
1177
|
error instanceof Error ? error.message : String(error);
|
|
1138
1178
|
|
|
1139
|
-
this.messageManager.
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1179
|
+
const messages = this.messageManager.getMessages();
|
|
1180
|
+
const lastMessage = messages[messages.length - 1];
|
|
1181
|
+
if (lastMessage && lastMessage.role === "assistant") {
|
|
1182
|
+
lastMessage.blocks.push({
|
|
1183
|
+
type: "memory",
|
|
1184
|
+
content: `${typeLabel}: ${memoryText} - Error: ${errorMessage}`,
|
|
1185
|
+
isSuccess: false,
|
|
1186
|
+
memoryType: type,
|
|
1187
|
+
storagePath,
|
|
1188
|
+
});
|
|
1189
|
+
this.messageManager.setMessages(messages);
|
|
1190
|
+
}
|
|
1145
1191
|
}
|
|
1146
1192
|
}
|
|
1147
1193
|
|
|
@@ -1189,6 +1235,13 @@ export class Agent {
|
|
|
1189
1235
|
return this.slashCommandManager.getCustomCommands();
|
|
1190
1236
|
}
|
|
1191
1237
|
|
|
1238
|
+
/**
|
|
1239
|
+
* Register a custom slash command
|
|
1240
|
+
*/
|
|
1241
|
+
public registerSlashCommand(command: SlashCommand): void {
|
|
1242
|
+
this.slashCommandManager.registerCommand(command);
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1192
1245
|
/**
|
|
1193
1246
|
* Get the current permission mode
|
|
1194
1247
|
*/
|
|
@@ -1210,30 +1263,41 @@ export class Agent {
|
|
|
1210
1263
|
}
|
|
1211
1264
|
|
|
1212
1265
|
/**
|
|
1213
|
-
*
|
|
1214
|
-
* @param
|
|
1266
|
+
* Truncate history to a specific index and revert file changes.
|
|
1267
|
+
* @param index - The index of the user message to truncate to.
|
|
1215
1268
|
*/
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1269
|
+
public async truncateHistory(index: number): Promise<void> {
|
|
1270
|
+
await this.messageManager.truncateHistory(index, this.reversionManager);
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
/**
|
|
1274
|
+
* Get the current plan file path (for testing and UI)
|
|
1275
|
+
*/
|
|
1276
|
+
public getPlanFilePath(): string | undefined {
|
|
1277
|
+
return this.permissionManager.getPlanFilePath();
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
/**
|
|
1281
|
+
* Get all currently allowed rules (for testing and UI)
|
|
1282
|
+
*/
|
|
1283
|
+
public getAllowedRules(): string[] {
|
|
1284
|
+
return this.permissionManager.getAllowedRules();
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
/**
|
|
1288
|
+
* Check permission for a tool call (for testing)
|
|
1289
|
+
*/
|
|
1290
|
+
public async checkPermission(
|
|
1291
|
+
context: import("./types/permissions.js").ToolPermissionContext,
|
|
1292
|
+
): Promise<import("./types/permissions.js").PermissionDecision> {
|
|
1293
|
+
return this.permissionManager.checkPermission(context);
|
|
1230
1294
|
}
|
|
1231
1295
|
|
|
1232
1296
|
/**
|
|
1233
1297
|
* Add a persistent permission rule
|
|
1234
1298
|
* @param rule - The rule to add (e.g., "Bash(ls)")
|
|
1235
1299
|
*/
|
|
1236
|
-
|
|
1300
|
+
public async addPermissionRule(rule: string): Promise<void> {
|
|
1237
1301
|
// 1. Expand rule if it's a Bash command
|
|
1238
1302
|
let rulesToAdd = [rule];
|
|
1239
1303
|
const bashMatch = rule.match(/^Bash\((.*)\)$/);
|
|
@@ -1266,4 +1330,24 @@ export class Agent {
|
|
|
1266
1330
|
}
|
|
1267
1331
|
}
|
|
1268
1332
|
}
|
|
1333
|
+
|
|
1334
|
+
/**
|
|
1335
|
+
* Handle plan mode transition, generating or clearing plan file path
|
|
1336
|
+
* @param mode - The current effective permission mode
|
|
1337
|
+
*/
|
|
1338
|
+
private handlePlanModeTransition(mode: PermissionMode): void {
|
|
1339
|
+
if (mode === "plan") {
|
|
1340
|
+
this.planManager
|
|
1341
|
+
.getOrGeneratePlanFilePath()
|
|
1342
|
+
.then(({ path }) => {
|
|
1343
|
+
this.logger?.debug("Plan file path generated", { path });
|
|
1344
|
+
this.permissionManager.setPlanFilePath(path);
|
|
1345
|
+
})
|
|
1346
|
+
.catch((error) => {
|
|
1347
|
+
this.logger?.error("Failed to generate plan file path", error);
|
|
1348
|
+
});
|
|
1349
|
+
} else {
|
|
1350
|
+
this.permissionManager.setPlanFilePath(undefined);
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1269
1353
|
}
|
package/src/constants/prompts.ts
CHANGED
|
@@ -44,8 +44,11 @@ export const SUBAGENT_POLICY = `
|
|
|
44
44
|
- You should proactively use the ${TASK_TOOL_NAME} tool with specialized agents when the task at hand matches the agent's description.
|
|
45
45
|
- VERY IMPORTANT: When exploring the codebase to gather context or to answer a question that is not a needle query for a specific file/class/function, it is CRITICAL that you use the ${TASK_TOOL_NAME} tool with subagent_type=Explore instead of running search commands directly.`;
|
|
46
46
|
|
|
47
|
-
export const
|
|
48
|
-
|
|
47
|
+
export const FILE_TOOL_POLICY_PREFIX = `\n- Use specialized tools instead of bash commands when possible, as this provides a better user experience. For file operations, use dedicated tools:`;
|
|
48
|
+
export const READ_FILE_POLICY = ` ${READ_TOOL_NAME} for reading files instead of cat/head/tail`;
|
|
49
|
+
export const EDIT_FILE_POLICY = ` ${EDIT_TOOL_NAME}/${MULTI_EDIT_TOOL_NAME} for editing instead of sed/awk`;
|
|
50
|
+
export const WRITE_FILE_POLICY = ` ${WRITE_TOOL_NAME} for creating files instead of cat with heredoc or echo redirection`;
|
|
51
|
+
export const SEARCH_FILE_POLICY = ` ${LS_TOOL_NAME}/${GLOB_TOOL_NAME}/${GREP_TOOL_NAME} for searching and listing files instead of find/ls/grep`;
|
|
49
52
|
|
|
50
53
|
export const BASH_POLICY = `
|
|
51
54
|
- Reserve bash tools exclusively for actual system commands and terminal operations that require shell execution. NEVER use bash echo or other command-line tools to communicate thoughts, explanations, or instructions to the user. Output all communication directly in your response text instead.
|
|
@@ -53,7 +56,24 @@ export const BASH_POLICY = `
|
|
|
53
56
|
|
|
54
57
|
export const DEFAULT_SYSTEM_PROMPT = BASE_SYSTEM_PROMPT;
|
|
55
58
|
|
|
56
|
-
export const
|
|
59
|
+
export const GENERAL_PURPOSE_SYSTEM_PROMPT = `You are an agent. Given the user's message, you should use the tools available to complete the task. Do what has been asked; nothing more, nothing less. When you complete the task simply respond with a detailed writeup.
|
|
60
|
+
|
|
61
|
+
Your strengths:
|
|
62
|
+
- Searching for code, configurations, and patterns across large codebases
|
|
63
|
+
- Analyzing multiple files to understand system architecture
|
|
64
|
+
- Investigating complex questions that require exploring many files
|
|
65
|
+
- Performing multi-step research tasks
|
|
66
|
+
|
|
67
|
+
Guidelines:
|
|
68
|
+
- For file searches: Use Grep or Glob when you need to search broadly. Use Read when you know the specific file path.
|
|
69
|
+
- For analysis: Start broad and narrow down. Use multiple search strategies if the first doesn't yield results.
|
|
70
|
+
- Be thorough: Check multiple locations, consider different naming conventions, look for related files.
|
|
71
|
+
- NEVER create files unless they're absolutely necessary for achieving your goal. ALWAYS prefer editing an existing file to creating a new one.
|
|
72
|
+
- NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested.
|
|
73
|
+
- In your final response always share relevant file names and code snippets. Any file paths you return in your response MUST be absolute. Do NOT use relative paths.
|
|
74
|
+
- For clear communication, avoid using emojis.`;
|
|
75
|
+
|
|
76
|
+
export const INIT_PROMPT = `Please analyze this codebase and create a AGENTS.md file, which will be given to future instances of Agent to operate in this repository.
|
|
57
77
|
|
|
58
78
|
What to add:
|
|
59
79
|
1. Commands that will be commonly used, such as how to build, lint, and run tests. Include the necessary commands to develop in this codebase, such as how to run a single test.
|
|
@@ -72,7 +92,7 @@ Usage notes:
|
|
|
72
92
|
\`\`\`
|
|
73
93
|
# AGENTS.md
|
|
74
94
|
|
|
75
|
-
This file provides guidance to
|
|
95
|
+
This file provides guidance to Agent when working with code in this repository.
|
|
76
96
|
\`\`\``;
|
|
77
97
|
|
|
78
98
|
export function buildSystemPrompt(
|
|
@@ -104,7 +124,27 @@ export function buildSystemPrompt(
|
|
|
104
124
|
toolNames.has(GLOB_TOOL_NAME) ||
|
|
105
125
|
toolNames.has(GREP_TOOL_NAME)
|
|
106
126
|
) {
|
|
107
|
-
|
|
127
|
+
const parts: string[] = [];
|
|
128
|
+
if (toolNames.has(READ_TOOL_NAME)) {
|
|
129
|
+
parts.push(READ_FILE_POLICY);
|
|
130
|
+
}
|
|
131
|
+
if (toolNames.has(EDIT_TOOL_NAME) || toolNames.has(MULTI_EDIT_TOOL_NAME)) {
|
|
132
|
+
parts.push(EDIT_FILE_POLICY);
|
|
133
|
+
}
|
|
134
|
+
if (toolNames.has(WRITE_TOOL_NAME)) {
|
|
135
|
+
parts.push(WRITE_FILE_POLICY);
|
|
136
|
+
}
|
|
137
|
+
if (
|
|
138
|
+
toolNames.has(LS_TOOL_NAME) ||
|
|
139
|
+
toolNames.has(GLOB_TOOL_NAME) ||
|
|
140
|
+
toolNames.has(GREP_TOOL_NAME)
|
|
141
|
+
) {
|
|
142
|
+
parts.push(SEARCH_FILE_POLICY);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (parts.length > 0) {
|
|
146
|
+
prompt += FILE_TOOL_POLICY_PREFIX + parts.join(",") + ".";
|
|
147
|
+
}
|
|
108
148
|
}
|
|
109
149
|
|
|
110
150
|
if (toolNames.has(BASH_TOOL_NAME)) {
|
package/src/constants/tools.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion";
|
|
2
2
|
export const BASH_TOOL_NAME = "Bash";
|
|
3
|
-
export const
|
|
4
|
-
export const
|
|
3
|
+
export const TASK_OUTPUT_TOOL_NAME = "TaskOutput";
|
|
4
|
+
export const TASK_STOP_TOOL_NAME = "TaskStop";
|
|
5
5
|
export const DELETE_FILE_TOOL_NAME = "Delete";
|
|
6
6
|
export const EDIT_TOOL_NAME = "Edit";
|
|
7
7
|
export const EXIT_PLAN_MODE_TOOL_NAME = "ExitPlanMode";
|
package/src/index.ts
CHANGED
|
@@ -18,7 +18,6 @@ export * from "./managers/pluginScopeManager.js";
|
|
|
18
18
|
export * from "./agent.js";
|
|
19
19
|
|
|
20
20
|
// Export all utilities
|
|
21
|
-
export * from "./utils/bashHistory.js";
|
|
22
21
|
export * from "./utils/bashParser.js";
|
|
23
22
|
export * from "./utils/convertMessagesForAPI.js";
|
|
24
23
|
export * from "./utils/fileFilter.js";
|
|
@@ -27,6 +26,7 @@ export * from "./utils/globalLogger.js";
|
|
|
27
26
|
export * from "./utils/mcpUtils.js";
|
|
28
27
|
export * from "./utils/messageOperations.js";
|
|
29
28
|
export * from "./utils/path.js";
|
|
29
|
+
export * from "./utils/promptHistory.js";
|
|
30
30
|
export * from "./utils/stringUtils.js";
|
|
31
31
|
export * from "./utils/customCommands.js";
|
|
32
32
|
export * from "./utils/hookMatcher.js";
|
|
@@ -37,6 +37,10 @@ export class MemoryRuleManager {
|
|
|
37
37
|
const projectRulesDir = path.join(this.workdir, ".wave", "rules");
|
|
38
38
|
const userRulesDir = path.join(os.homedir(), ".wave", "rules");
|
|
39
39
|
|
|
40
|
+
logger.debug(`Scanning for modular memory rules...`);
|
|
41
|
+
logger.debug(` User rules directory: ${userRulesDir}`);
|
|
42
|
+
logger.debug(` Project rules directory: ${projectRulesDir}`);
|
|
43
|
+
|
|
40
44
|
const newRules: Record<string, MemoryRule> = {};
|
|
41
45
|
|
|
42
46
|
// Discover user rules first, then project rules so project rules can override if needed
|
|
@@ -45,7 +49,18 @@ export class MemoryRuleManager {
|
|
|
45
49
|
await this.scanDirectory(projectRulesDir, "project", newRules);
|
|
46
50
|
|
|
47
51
|
this.state.rules = newRules;
|
|
48
|
-
|
|
52
|
+
const ruleCount = Object.keys(newRules).length;
|
|
53
|
+
logger.debug(`Discovered ${ruleCount} modular memory rules`);
|
|
54
|
+
|
|
55
|
+
if (ruleCount > 0) {
|
|
56
|
+
logger.debug("Loaded memory rules:");
|
|
57
|
+
for (const [id, rule] of Object.entries(newRules)) {
|
|
58
|
+
const pathInfo = rule.metadata.paths
|
|
59
|
+
? `paths: ${JSON.stringify(rule.metadata.paths)}`
|
|
60
|
+
: "global (no path restriction)";
|
|
61
|
+
logger.debug(` - ${id} (${rule.source}): ${pathInfo}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
49
64
|
}
|
|
50
65
|
|
|
51
66
|
private async scanDirectory(
|
|
@@ -121,6 +136,7 @@ export class MemoryRuleManager {
|
|
|
121
136
|
const relativeId = path.relative(rulesRoot, filePath);
|
|
122
137
|
rule.id = relativeId;
|
|
123
138
|
registry[rule.id] = rule;
|
|
139
|
+
logger.debug(`Loaded memory rule: ${relativeId} from ${filePath}`);
|
|
124
140
|
} catch (error) {
|
|
125
141
|
logger.error(`Failed to parse memory rule at ${filePath}:`, error);
|
|
126
142
|
}
|
|
@@ -132,7 +148,7 @@ export class MemoryRuleManager {
|
|
|
132
148
|
getActiveRules(filesInContext: string[]): MemoryRule[] {
|
|
133
149
|
const activeRules: MemoryRule[] = [];
|
|
134
150
|
for (const rule of Object.values(this.state.rules)) {
|
|
135
|
-
if (this.service.isRuleActive(rule, filesInContext)) {
|
|
151
|
+
if (this.service.isRuleActive(rule, filesInContext, this.workdir)) {
|
|
136
152
|
activeRules.push(rule);
|
|
137
153
|
}
|
|
138
154
|
}
|