wave-agent-sdk 0.6.5 → 0.7.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 +8 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +49 -240
- package/dist/constants/tools.d.ts +0 -2
- package/dist/constants/tools.d.ts.map +1 -1
- package/dist/constants/tools.js +0 -2
- package/dist/core/plugin.d.ts +86 -0
- package/dist/core/plugin.d.ts.map +1 -0
- package/dist/core/plugin.js +164 -0
- package/dist/core/session.d.ts +3 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +1 -0
- package/dist/index.d.ts +2 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -10
- package/dist/managers/MemoryRuleManager.d.ts +3 -1
- package/dist/managers/MemoryRuleManager.d.ts.map +1 -1
- package/dist/managers/MemoryRuleManager.js +2 -1
- package/dist/managers/aiManager.d.ts +13 -23
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +60 -32
- package/dist/managers/backgroundTaskManager.d.ts +3 -1
- package/dist/managers/backgroundTaskManager.d.ts.map +1 -1
- package/dist/managers/backgroundTaskManager.js +2 -1
- package/dist/managers/bashManager.d.ts +4 -4
- package/dist/managers/bashManager.d.ts.map +1 -1
- package/dist/managers/bashManager.js +5 -2
- package/dist/managers/foregroundTaskManager.d.ts +3 -0
- package/dist/managers/foregroundTaskManager.d.ts.map +1 -1
- package/dist/managers/foregroundTaskManager.js +2 -1
- package/dist/managers/hookManager.d.ts +3 -3
- package/dist/managers/hookManager.d.ts.map +1 -1
- package/dist/managers/hookManager.js +20 -19
- package/dist/managers/liveConfigManager.d.ts +6 -13
- package/dist/managers/liveConfigManager.d.ts.map +1 -1
- package/dist/managers/liveConfigManager.js +50 -45
- package/dist/managers/lspManager.d.ts +4 -5
- package/dist/managers/lspManager.d.ts.map +1 -1
- package/dist/managers/lspManager.js +13 -12
- package/dist/managers/mcpManager.d.ts +3 -2
- package/dist/managers/mcpManager.d.ts.map +1 -1
- package/dist/managers/mcpManager.js +16 -15
- package/dist/managers/messageManager.d.ts +5 -7
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +12 -7
- package/dist/managers/permissionManager.d.ts +6 -4
- package/dist/managers/permissionManager.d.ts.map +1 -1
- package/dist/managers/permissionManager.js +39 -63
- package/dist/managers/planManager.d.ts +4 -6
- package/dist/managers/planManager.d.ts.map +1 -1
- package/dist/managers/planManager.js +18 -4
- package/dist/managers/pluginManager.d.ts +10 -22
- package/dist/managers/pluginManager.d.ts.map +1 -1
- package/dist/managers/pluginManager.js +27 -14
- package/dist/managers/reversionManager.d.ts +4 -3
- package/dist/managers/reversionManager.d.ts.map +1 -1
- package/dist/managers/reversionManager.js +5 -2
- package/dist/managers/skillManager.d.ts +3 -2
- package/dist/managers/skillManager.d.ts.map +1 -1
- package/dist/managers/skillManager.js +15 -14
- package/dist/managers/slashCommandManager.d.ts +9 -16
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +21 -10
- package/dist/managers/subagentManager.d.ts +7 -17
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +41 -34
- package/dist/managers/toolManager.d.ts +15 -38
- package/dist/managers/toolManager.d.ts.map +1 -1
- package/dist/managers/toolManager.js +67 -56
- package/dist/prompts/index.d.ts +6 -2
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +8 -4
- package/dist/services/MarketplaceService.d.ts.map +1 -1
- package/dist/services/MarketplaceService.js +13 -0
- package/dist/services/aiService.d.ts +4 -0
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +47 -7
- package/dist/services/configurationService.d.ts.map +1 -1
- package/dist/services/configurationService.js +30 -11
- package/dist/services/taskManager.d.ts +3 -1
- package/dist/services/taskManager.d.ts.map +1 -1
- package/dist/services/taskManager.js +3 -2
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +19 -4
- package/dist/tools/editTool.d.ts.map +1 -1
- package/dist/tools/editTool.js +16 -4
- package/dist/tools/readTool.d.ts.map +1 -1
- package/dist/tools/readTool.js +2 -2
- package/dist/tools/skillTool.d.ts +2 -4
- package/dist/tools/skillTool.d.ts.map +1 -1
- package/dist/tools/skillTool.js +61 -61
- package/dist/tools/taskOutputTool.d.ts.map +1 -1
- package/dist/tools/taskOutputTool.js +3 -2
- package/dist/tools/taskTool.d.ts +2 -4
- package/dist/tools/taskTool.d.ts.map +1 -1
- package/dist/tools/taskTool.js +192 -187
- package/dist/tools/types.d.ts +12 -1
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/writeTool.d.ts.map +1 -1
- package/dist/tools/writeTool.js +5 -2
- package/dist/types/core.d.ts +2 -0
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/marketplace.d.ts +8 -0
- package/dist/types/marketplace.d.ts.map +1 -1
- package/dist/types/messaging.d.ts +1 -0
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/types/permissions.d.ts +3 -1
- package/dist/types/permissions.d.ts.map +1 -1
- package/dist/types/permissions.js +1 -3
- package/dist/types/skills.d.ts +0 -2
- package/dist/types/skills.d.ts.map +1 -1
- package/dist/types/tools.d.ts +0 -15
- package/dist/types/tools.d.ts.map +1 -1
- package/dist/utils/container.d.ts +31 -0
- package/dist/utils/container.d.ts.map +1 -0
- package/dist/utils/container.js +79 -0
- package/dist/utils/containerSetup.d.ts +26 -0
- package/dist/utils/containerSetup.d.ts.map +1 -0
- package/dist/utils/containerSetup.js +187 -0
- package/dist/utils/editUtils.d.ts +0 -3
- package/dist/utils/editUtils.d.ts.map +1 -1
- package/dist/utils/editUtils.js +4 -3
- package/dist/utils/hookMatcher.d.ts +1 -1
- package/dist/utils/hookMatcher.d.ts.map +1 -1
- package/dist/utils/hookMatcher.js +2 -2
- package/dist/utils/messageOperations.d.ts +2 -1
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +4 -1
- package/dist/utils/openaiClient.js +2 -2
- package/dist/utils/stringUtils.d.ts +6 -0
- package/dist/utils/stringUtils.d.ts.map +1 -1
- package/dist/utils/stringUtils.js +8 -0
- package/package.json +1 -1
- package/src/agent.ts +60 -282
- package/src/constants/tools.ts +0 -2
- package/src/core/plugin.ts +224 -0
- package/src/core/session.ts +6 -0
- package/src/index.ts +2 -11
- package/src/managers/MemoryRuleManager.ts +6 -1
- package/src/managers/aiManager.ts +84 -58
- package/src/managers/backgroundTaskManager.ts +5 -1
- package/src/managers/bashManager.ts +9 -4
- package/src/managers/foregroundTaskManager.ts +3 -0
- package/src/managers/hookManager.ts +21 -23
- package/src/managers/liveConfigManager.ts +57 -53
- package/src/managers/lspManager.ts +14 -19
- package/src/managers/mcpManager.ts +20 -20
- package/src/managers/messageManager.ts +19 -12
- package/src/managers/permissionManager.ts +45 -70
- package/src/managers/planManager.ts +26 -7
- package/src/managers/pluginManager.ts +37 -33
- package/src/managers/reversionManager.ts +5 -3
- package/src/managers/skillManager.ts +19 -20
- package/src/managers/slashCommandManager.ts +30 -25
- package/src/managers/subagentManager.ts +53 -53
- package/src/managers/toolManager.ts +93 -90
- package/src/prompts/index.ts +13 -5
- package/src/services/MarketplaceService.ts +13 -0
- package/src/services/aiService.ts +61 -15
- package/src/services/configurationService.ts +34 -13
- package/src/services/taskManager.ts +6 -2
- package/src/tools/bashTool.ts +19 -4
- package/src/tools/editTool.ts +17 -4
- package/src/tools/readTool.ts +2 -2
- package/src/tools/skillTool.ts +75 -71
- package/src/tools/taskOutputTool.ts +3 -2
- package/src/tools/taskTool.ts +224 -225
- package/src/tools/types.ts +14 -1
- package/src/tools/writeTool.ts +5 -2
- package/src/types/core.ts +2 -0
- package/src/types/marketplace.ts +9 -0
- package/src/types/messaging.ts +1 -0
- package/src/types/permissions.ts +2 -4
- package/src/types/skills.ts +0 -3
- package/src/types/tools.ts +0 -17
- package/src/utils/container.ts +92 -0
- package/src/utils/containerSetup.ts +279 -0
- package/src/utils/editUtils.ts +4 -3
- package/src/utils/hookMatcher.ts +2 -2
- package/src/utils/messageOperations.ts +5 -0
- package/src/utils/openaiClient.ts +2 -2
- package/src/utils/stringUtils.ts +9 -0
- package/dist/tools/deleteFileTool.d.ts +0 -6
- package/dist/tools/deleteFileTool.d.ts.map +0 -1
- package/dist/tools/deleteFileTool.js +0 -100
- package/dist/tools/multiEditTool.d.ts +0 -6
- package/dist/tools/multiEditTool.d.ts.map +0 -1
- package/dist/tools/multiEditTool.js +0 -246
- package/src/tools/deleteFileTool.ts +0 -127
- package/src/tools/multiEditTool.ts +0 -306
|
@@ -2,9 +2,7 @@ import type { ToolContext, ToolPlugin, ToolResult } from "../tools/types.js";
|
|
|
2
2
|
import { bashTool } from "../tools/bashTool.js";
|
|
3
3
|
import { taskOutputTool } from "../tools/taskOutputTool.js";
|
|
4
4
|
import { taskStopTool } from "../tools/taskStopTool.js";
|
|
5
|
-
import { deleteFileTool } from "../tools/deleteFileTool.js";
|
|
6
5
|
import { editTool } from "../tools/editTool.js";
|
|
7
|
-
import { multiEditTool } from "../tools/multiEditTool.js";
|
|
8
6
|
import { writeTool } from "../tools/writeTool.js";
|
|
9
7
|
import { exitPlanModeTool } from "../tools/exitPlanMode.js";
|
|
10
8
|
import { askUserQuestionTool } from "../tools/askUserQuestion.js";
|
|
@@ -14,8 +12,8 @@ import { grepTool } from "../tools/grepTool.js";
|
|
|
14
12
|
import { lsTool } from "../tools/lsTool.js";
|
|
15
13
|
import { readTool } from "../tools/readTool.js";
|
|
16
14
|
import { lspTool } from "../tools/lspTool.js";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
15
|
+
import { taskTool } from "../tools/taskTool.js";
|
|
16
|
+
import { skillTool } from "../tools/skillTool.js";
|
|
19
17
|
import {
|
|
20
18
|
taskCreateTool,
|
|
21
19
|
taskGetTool,
|
|
@@ -26,7 +24,6 @@ import { McpManager } from "./mcpManager.js";
|
|
|
26
24
|
import { PermissionManager } from "./permissionManager.js";
|
|
27
25
|
import { ChatCompletionFunctionTool } from "openai/resources.js";
|
|
28
26
|
import type {
|
|
29
|
-
Logger,
|
|
30
27
|
PermissionMode,
|
|
31
28
|
PermissionCallback,
|
|
32
29
|
ILspManager,
|
|
@@ -36,24 +33,14 @@ import type { SkillManager } from "./skillManager.js";
|
|
|
36
33
|
|
|
37
34
|
import { ReversionManager } from "./reversionManager.js";
|
|
38
35
|
|
|
36
|
+
import { Container } from "../utils/container.js";
|
|
37
|
+
|
|
38
|
+
import { logger } from "../utils/globalLogger.js";
|
|
39
|
+
|
|
39
40
|
export interface ToolManagerOptions {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
/** Permission manager for handling tool permission checks */
|
|
44
|
-
permissionManager?: PermissionManager;
|
|
45
|
-
/** Foreground task manager for backgrounding tasks */
|
|
46
|
-
foregroundTaskManager?: import("../types/processes.js").IForegroundTaskManager;
|
|
47
|
-
/** Task manager for task management */
|
|
48
|
-
taskManager?: import("../services/taskManager.js").TaskManager;
|
|
49
|
-
/** Reversion manager for file snapshots */
|
|
50
|
-
reversionManager?: ReversionManager;
|
|
51
|
-
/** Background task manager for background execution */
|
|
52
|
-
backgroundTaskManager?: import("./backgroundTaskManager.js").BackgroundTaskManager;
|
|
53
|
-
/** Permission mode for tool execution (defaults to "default") */
|
|
54
|
-
permissionMode?: PermissionMode;
|
|
55
|
-
/** Custom permission callback for tool usage */
|
|
56
|
-
canUseToolCallback?: PermissionCallback;
|
|
41
|
+
container: Container;
|
|
42
|
+
/** Optional list of tool names to enable */
|
|
43
|
+
tools?: string[];
|
|
57
44
|
}
|
|
58
45
|
|
|
59
46
|
/**
|
|
@@ -63,44 +50,31 @@ export interface ToolManagerOptions {
|
|
|
63
50
|
* Supports both built-in tools and MCP (Model Context Protocol) tools.
|
|
64
51
|
*/
|
|
65
52
|
class ToolManager {
|
|
66
|
-
private
|
|
67
|
-
private
|
|
68
|
-
private
|
|
69
|
-
private logger?: Logger;
|
|
70
|
-
private permissionManager?: PermissionManager;
|
|
71
|
-
private foregroundTaskManager?: import("../types/processes.js").IForegroundTaskManager;
|
|
72
|
-
private reversionManager?: ReversionManager;
|
|
73
|
-
private taskManager?: import("../services/taskManager.js").TaskManager;
|
|
74
|
-
private backgroundTaskManager?: import("./backgroundTaskManager.js").BackgroundTaskManager;
|
|
75
|
-
private permissionMode?: PermissionMode;
|
|
76
|
-
private canUseToolCallback?: PermissionCallback;
|
|
53
|
+
private toolsRegistry = new Map<string, ToolPlugin>();
|
|
54
|
+
private tools?: string[];
|
|
55
|
+
private container: Container;
|
|
77
56
|
|
|
78
57
|
constructor(options: ToolManagerOptions) {
|
|
79
|
-
this.
|
|
80
|
-
this.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
this.
|
|
85
|
-
this.reversionManager = options.reversionManager;
|
|
86
|
-
this.backgroundTaskManager = options.backgroundTaskManager;
|
|
87
|
-
// Store CLI permission mode, let PermissionManager resolve effective mode
|
|
88
|
-
this.permissionMode = options.permissionMode;
|
|
89
|
-
this.canUseToolCallback = options.canUseToolCallback;
|
|
58
|
+
this.container = options.container;
|
|
59
|
+
this.tools = options.tools;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private get mcpManager(): McpManager {
|
|
63
|
+
return this.container.get<McpManager>("McpManager")!;
|
|
90
64
|
}
|
|
91
65
|
|
|
92
66
|
/**
|
|
93
67
|
* Register a new tool
|
|
94
68
|
*/
|
|
95
69
|
public register(tool: ToolPlugin): void {
|
|
96
|
-
this.
|
|
70
|
+
this.toolsRegistry.set(tool.name, tool);
|
|
97
71
|
}
|
|
98
72
|
|
|
99
73
|
/**
|
|
100
74
|
* Initialize built-in tools. Can be called with dependencies for tools that require them.
|
|
101
75
|
*
|
|
102
76
|
* This method can be called multiple times safely. When called without dependencies,
|
|
103
|
-
* it registers basic tools (Bash, Read, Write,
|
|
77
|
+
* it registers basic tools (Bash, Read, Write, TaskCreate, etc.). When called with
|
|
104
78
|
* dependencies, it also registers tools that require managers (Task, Skill).
|
|
105
79
|
*
|
|
106
80
|
* @param deps Optional dependencies for advanced tools
|
|
@@ -119,17 +93,12 @@ class ToolManager {
|
|
|
119
93
|
* });
|
|
120
94
|
* ```
|
|
121
95
|
*/
|
|
122
|
-
public initializeBuiltInTools(
|
|
123
|
-
subagentManager?: SubagentManager;
|
|
124
|
-
skillManager?: SkillManager;
|
|
125
|
-
}): void {
|
|
96
|
+
public initializeBuiltInTools(): void {
|
|
126
97
|
const builtInTools = [
|
|
127
98
|
bashTool,
|
|
128
99
|
taskOutputTool,
|
|
129
100
|
taskStopTool,
|
|
130
|
-
deleteFileTool,
|
|
131
101
|
editTool,
|
|
132
|
-
multiEditTool,
|
|
133
102
|
writeTool,
|
|
134
103
|
exitPlanModeTool,
|
|
135
104
|
askUserQuestionTool,
|
|
@@ -138,6 +107,8 @@ class ToolManager {
|
|
|
138
107
|
lsTool,
|
|
139
108
|
readTool,
|
|
140
109
|
lspTool,
|
|
110
|
+
taskTool,
|
|
111
|
+
skillTool,
|
|
141
112
|
taskCreateTool,
|
|
142
113
|
taskGetTool,
|
|
143
114
|
taskUpdateTool,
|
|
@@ -145,19 +116,22 @@ class ToolManager {
|
|
|
145
116
|
];
|
|
146
117
|
|
|
147
118
|
for (const tool of builtInTools) {
|
|
148
|
-
this.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
// Register tools that require dependencies
|
|
152
|
-
if (deps?.subagentManager) {
|
|
153
|
-
const taskTool = createTaskTool(deps.subagentManager);
|
|
154
|
-
this.tools.set(taskTool.name, taskTool);
|
|
119
|
+
if (this.shouldEnableTool(tool.name)) {
|
|
120
|
+
this.toolsRegistry.set(tool.name, tool);
|
|
121
|
+
}
|
|
155
122
|
}
|
|
123
|
+
}
|
|
156
124
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
125
|
+
/**
|
|
126
|
+
* Check if a tool should be enabled based on tools configuration
|
|
127
|
+
*/
|
|
128
|
+
private shouldEnableTool(name: string): boolean {
|
|
129
|
+
if (!this.tools) {
|
|
130
|
+
return true;
|
|
160
131
|
}
|
|
132
|
+
return this.tools.some(
|
|
133
|
+
(toolName) => toolName.toLowerCase() === name.toLowerCase(),
|
|
134
|
+
);
|
|
161
135
|
}
|
|
162
136
|
|
|
163
137
|
/**
|
|
@@ -178,32 +152,55 @@ class ToolManager {
|
|
|
178
152
|
args: Record<string, unknown>,
|
|
179
153
|
context: ToolContext,
|
|
180
154
|
): Promise<ToolResult> {
|
|
155
|
+
const permissionManager =
|
|
156
|
+
this.container.get<PermissionManager>("PermissionManager");
|
|
157
|
+
const permissionMode = this.container.has("PermissionMode")
|
|
158
|
+
? this.container.get<PermissionMode>("PermissionMode")
|
|
159
|
+
: undefined;
|
|
160
|
+
|
|
181
161
|
// Resolve effective permission mode (CLI override > configuration > default)
|
|
182
|
-
const effectivePermissionMode =
|
|
183
|
-
?
|
|
184
|
-
:
|
|
162
|
+
const effectivePermissionMode = permissionManager
|
|
163
|
+
? permissionManager.getCurrentEffectiveMode(permissionMode)
|
|
164
|
+
: permissionMode || "default";
|
|
185
165
|
|
|
186
166
|
// Enhance context with permission-related fields
|
|
167
|
+
const canUseToolCallback = this.container.has("CanUseToolCallback")
|
|
168
|
+
? this.container.get<PermissionCallback>("CanUseToolCallback")
|
|
169
|
+
: undefined;
|
|
170
|
+
|
|
187
171
|
const enhancedContext: ToolContext = {
|
|
188
172
|
...context,
|
|
189
173
|
permissionMode: effectivePermissionMode,
|
|
190
|
-
canUseToolCallback
|
|
191
|
-
permissionManager
|
|
192
|
-
taskManager:
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
174
|
+
canUseToolCallback,
|
|
175
|
+
permissionManager,
|
|
176
|
+
taskManager:
|
|
177
|
+
this.container.get<import("../services/taskManager.js").TaskManager>(
|
|
178
|
+
"TaskManager",
|
|
179
|
+
)!,
|
|
180
|
+
reversionManager:
|
|
181
|
+
this.container.get<ReversionManager>("ReversionManager")!,
|
|
182
|
+
backgroundTaskManager: this.container.get<
|
|
183
|
+
import("./backgroundTaskManager.js").BackgroundTaskManager
|
|
184
|
+
>("BackgroundTaskManager")!,
|
|
185
|
+
foregroundTaskManager: this.container.get<
|
|
186
|
+
import("../types/processes.js").IForegroundTaskManager
|
|
187
|
+
>("ForegroundTaskManager")!,
|
|
196
188
|
mcpManager: this.mcpManager,
|
|
197
|
-
lspManager: this.
|
|
189
|
+
lspManager: this.container.get<ILspManager>("LspManager")!,
|
|
190
|
+
subagentManager: this.container.has("SubagentManager")
|
|
191
|
+
? this.container.get<SubagentManager>("SubagentManager")
|
|
192
|
+
: undefined,
|
|
193
|
+
skillManager: this.container.has("SkillManager")
|
|
194
|
+
? this.container.get<SkillManager>("SkillManager")
|
|
195
|
+
: undefined,
|
|
198
196
|
sessionId: context.sessionId,
|
|
199
197
|
};
|
|
200
198
|
|
|
201
|
-
|
|
199
|
+
logger?.debug("Executing tool with enhanced context", {
|
|
202
200
|
toolName: name,
|
|
203
|
-
|
|
201
|
+
permissionMode,
|
|
204
202
|
effectivePermissionMode,
|
|
205
|
-
hasPermissionManager: !!
|
|
206
|
-
hasPermissionCallback: !!this.canUseToolCallback,
|
|
203
|
+
hasPermissionManager: !!permissionManager,
|
|
207
204
|
});
|
|
208
205
|
|
|
209
206
|
// Check if it's an MCP tool first
|
|
@@ -216,12 +213,12 @@ class ToolManager {
|
|
|
216
213
|
}
|
|
217
214
|
|
|
218
215
|
// Check built-in tools
|
|
219
|
-
const plugin = this.
|
|
216
|
+
const plugin = this.toolsRegistry.get(name);
|
|
220
217
|
if (plugin) {
|
|
221
218
|
try {
|
|
222
219
|
return await plugin.execute(args, enhancedContext);
|
|
223
220
|
} catch (error) {
|
|
224
|
-
|
|
221
|
+
logger?.error("Tool execution failed", {
|
|
225
222
|
toolName: name,
|
|
226
223
|
error: error instanceof Error ? error.message : String(error),
|
|
227
224
|
});
|
|
@@ -233,7 +230,7 @@ class ToolManager {
|
|
|
233
230
|
}
|
|
234
231
|
}
|
|
235
232
|
|
|
236
|
-
|
|
233
|
+
logger?.warn("Tool not found", { toolName: name });
|
|
237
234
|
return {
|
|
238
235
|
success: false,
|
|
239
236
|
content: "",
|
|
@@ -242,14 +239,14 @@ class ToolManager {
|
|
|
242
239
|
}
|
|
243
240
|
|
|
244
241
|
list(): ToolPlugin[] {
|
|
245
|
-
const builtInTools = Array.from(this.
|
|
242
|
+
const builtInTools = Array.from(this.toolsRegistry.values());
|
|
246
243
|
const mcpTools = this.mcpManager.getMcpToolPlugins();
|
|
247
244
|
return [...builtInTools, ...mcpTools];
|
|
248
245
|
}
|
|
249
246
|
|
|
250
247
|
getToolsConfig(): ChatCompletionFunctionTool[] {
|
|
251
248
|
const effectivePermissionMode = this.getPermissionMode();
|
|
252
|
-
const builtInToolsConfig = Array.from(this.
|
|
249
|
+
const builtInToolsConfig = Array.from(this.toolsRegistry.values())
|
|
253
250
|
.filter((tool) => {
|
|
254
251
|
if (effectivePermissionMode === "bypassPermissions") {
|
|
255
252
|
if (tool.name === "ExitPlanMode" || tool.name === "AskUserQuestion") {
|
|
@@ -270,19 +267,23 @@ class ToolManager {
|
|
|
270
267
|
* Get the list of registered tool plugins
|
|
271
268
|
*/
|
|
272
269
|
public getTools(): ToolPlugin[] {
|
|
273
|
-
return Array.from(this.
|
|
270
|
+
return Array.from(this.toolsRegistry.values());
|
|
274
271
|
}
|
|
275
272
|
|
|
276
273
|
/**
|
|
277
274
|
* Get the current permission mode
|
|
278
275
|
*/
|
|
279
276
|
public getPermissionMode(): PermissionMode {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
)
|
|
277
|
+
const permissionManager =
|
|
278
|
+
this.container.get<PermissionManager>("PermissionManager");
|
|
279
|
+
const permissionMode = this.container.has("PermissionMode")
|
|
280
|
+
? this.container.get<PermissionMode>("PermissionMode")
|
|
281
|
+
: undefined;
|
|
282
|
+
|
|
283
|
+
if (permissionManager) {
|
|
284
|
+
return permissionManager.getCurrentEffectiveMode(permissionMode);
|
|
284
285
|
}
|
|
285
|
-
return
|
|
286
|
+
return permissionMode || "default";
|
|
286
287
|
}
|
|
287
288
|
|
|
288
289
|
/**
|
|
@@ -290,14 +291,14 @@ class ToolManager {
|
|
|
290
291
|
* @param mode - The new permission mode
|
|
291
292
|
*/
|
|
292
293
|
public setPermissionMode(mode: PermissionMode): void {
|
|
293
|
-
this.
|
|
294
|
+
this.container.register("PermissionMode", mode);
|
|
294
295
|
}
|
|
295
296
|
|
|
296
297
|
/**
|
|
297
298
|
* Get the permission manager
|
|
298
299
|
*/
|
|
299
300
|
public getPermissionManager(): PermissionManager | undefined {
|
|
300
|
-
return this.
|
|
301
|
+
return this.container.get<PermissionManager>("PermissionManager");
|
|
301
302
|
}
|
|
302
303
|
|
|
303
304
|
/**
|
|
@@ -306,7 +307,9 @@ class ToolManager {
|
|
|
306
307
|
public getTaskManager():
|
|
307
308
|
| import("../services/taskManager.js").TaskManager
|
|
308
309
|
| undefined {
|
|
309
|
-
return this.taskManager
|
|
310
|
+
return this.container.get<import("../services/taskManager.js").TaskManager>(
|
|
311
|
+
"TaskManager",
|
|
312
|
+
);
|
|
310
313
|
}
|
|
311
314
|
}
|
|
312
315
|
|
package/src/prompts/index.ts
CHANGED
|
@@ -161,7 +161,6 @@ export const EXPLORE_SUBAGENT_SYSTEM_PROMPT = `You are a file search specialist.
|
|
|
161
161
|
This is a READ-ONLY exploration task. You are STRICTLY PROHIBITED from:
|
|
162
162
|
- Creating new files (no Write, touch, or file creation of any kind)
|
|
163
163
|
- Modifying existing files (no Edit operations)
|
|
164
|
-
- Deleting files (no rm or deletion)
|
|
165
164
|
- Moving or copying files (no mv or cp)
|
|
166
165
|
- Creating temporary files anywhere, including /tmp
|
|
167
166
|
- Using redirect operators (>, >>, |) or heredocs to write to files
|
|
@@ -199,7 +198,6 @@ export const PLAN_SUBAGENT_SYSTEM_PROMPT = `You are a software architect and pla
|
|
|
199
198
|
This is a READ-ONLY planning task. You are STRICTLY PROHIBITED from:
|
|
200
199
|
- Creating new files (no Write, touch, or file creation of any kind)
|
|
201
200
|
- Modifying existing files (no Edit operations)
|
|
202
|
-
- Deleting files (no rm or deletion)
|
|
203
201
|
- Moving or copying files (no mv or cp)
|
|
204
202
|
- Creating temporary files anywhere, including /tmp
|
|
205
203
|
- Using redirect operators (>, >>, |) or heredocs to write to files
|
|
@@ -290,6 +288,9 @@ Any promises made to the user
|
|
|
290
288
|
Be concise but complete—err on the side of including information that would prevent duplicate work or repeated mistakes. Write in a way that enables immediate resumption of the task.
|
|
291
289
|
Wrap your summary in <summary></summary> tags.`;
|
|
292
290
|
|
|
291
|
+
import type { SubagentConfiguration } from "../utils/subagentParser.js";
|
|
292
|
+
import type { SkillMetadata } from "../types/skills.js";
|
|
293
|
+
|
|
293
294
|
export function buildSystemPrompt(
|
|
294
295
|
basePrompt: string | undefined,
|
|
295
296
|
tools: ToolPlugin[],
|
|
@@ -302,15 +303,22 @@ export function buildSystemPrompt(
|
|
|
302
303
|
planFilePath: string;
|
|
303
304
|
planExists: boolean;
|
|
304
305
|
};
|
|
306
|
+
availableSubagents?: SubagentConfiguration[];
|
|
307
|
+
availableSkills?: SkillMetadata[];
|
|
305
308
|
} = {},
|
|
306
309
|
): string {
|
|
307
310
|
let prompt = basePrompt || DEFAULT_SYSTEM_PROMPT;
|
|
308
|
-
|
|
309
|
-
|
|
311
|
+
if (tools.length > 0) {
|
|
312
|
+
prompt += `\n\n${TOOL_POLICY}`;
|
|
313
|
+
}
|
|
310
314
|
|
|
311
315
|
for (const tool of tools) {
|
|
312
316
|
if (tool.prompt) {
|
|
313
|
-
prompt += tool.prompt(
|
|
317
|
+
prompt += tool.prompt({
|
|
318
|
+
availableSubagents: options.availableSubagents,
|
|
319
|
+
availableSkills: options.availableSkills,
|
|
320
|
+
workdir: options.workdir,
|
|
321
|
+
});
|
|
314
322
|
}
|
|
315
323
|
}
|
|
316
324
|
|
|
@@ -80,6 +80,16 @@ export class MarketplaceService {
|
|
|
80
80
|
}
|
|
81
81
|
try {
|
|
82
82
|
const content = await fs.readFile(this.knownMarketplacesPath, "utf-8");
|
|
83
|
+
if (!content.trim()) {
|
|
84
|
+
return {
|
|
85
|
+
marketplaces: [
|
|
86
|
+
{
|
|
87
|
+
...MarketplaceService.BUILTIN_MARKETPLACE,
|
|
88
|
+
isBuiltin: true,
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
83
93
|
return JSON.parse(content);
|
|
84
94
|
} catch (error) {
|
|
85
95
|
console.error("Failed to load known marketplaces:", error);
|
|
@@ -96,6 +106,9 @@ export class MarketplaceService {
|
|
|
96
106
|
}
|
|
97
107
|
try {
|
|
98
108
|
const content = await fs.readFile(this.installedPluginsPath, "utf-8");
|
|
109
|
+
if (!content.trim()) {
|
|
110
|
+
return { plugins: [] };
|
|
111
|
+
}
|
|
99
112
|
return JSON.parse(content);
|
|
100
113
|
} catch (error) {
|
|
101
114
|
console.error("Failed to load installed plugins:", error);
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
} from "openai/resources.js";
|
|
9
9
|
import { OpenAIClient } from "../utils/openaiClient.js";
|
|
10
10
|
import { logger } from "../utils/globalLogger.js";
|
|
11
|
+
import { addOnceAbortListener } from "../utils/abortUtils.js";
|
|
11
12
|
import type { GatewayConfig, ModelConfig } from "../types/index.js";
|
|
12
13
|
import {
|
|
13
14
|
transformMessagesForClaudeCache,
|
|
@@ -69,13 +70,50 @@ interface ErrorData {
|
|
|
69
70
|
type OpenAIModelConfig = Omit<
|
|
70
71
|
ChatCompletionCreateParamsNonStreaming,
|
|
71
72
|
"messages"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
>;
|
|
74
|
+
|
|
75
|
+
// Global rate limiter state for 1 QPS
|
|
76
|
+
let nextAllowedTime = 0;
|
|
77
|
+
const MIN_INTERVAL = 1000; // 1 second for 1 QPS
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Resets the rate limiter state. Primarily used for testing.
|
|
81
|
+
*/
|
|
82
|
+
export function resetRateLimiter(): void {
|
|
83
|
+
nextAllowedTime = 0;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Acquires a slot for an AI request, ensuring 1 QPS limit.
|
|
88
|
+
* @param abortSignal Optional abort signal to cancel waiting
|
|
89
|
+
*/
|
|
90
|
+
async function acquireSlot(abortSignal?: AbortSignal): Promise<void> {
|
|
91
|
+
if (abortSignal?.aborted) {
|
|
92
|
+
throw new Error("Request was aborted");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const now = Date.now();
|
|
96
|
+
const waitTime = Math.max(0, nextAllowedTime - now);
|
|
97
|
+
|
|
98
|
+
// Reserve the slot synchronously to ensure global ordering
|
|
99
|
+
nextAllowedTime = Math.max(now, nextAllowedTime) + MIN_INTERVAL;
|
|
100
|
+
|
|
101
|
+
if (waitTime > 0) {
|
|
102
|
+
await new Promise<void>((resolve, reject) => {
|
|
103
|
+
const timeout = setTimeout(() => {
|
|
104
|
+
cleanup();
|
|
105
|
+
resolve();
|
|
106
|
+
}, waitTime);
|
|
107
|
+
|
|
108
|
+
const cleanup = abortSignal
|
|
109
|
+
? addOnceAbortListener(abortSignal, () => {
|
|
110
|
+
clearTimeout(timeout);
|
|
111
|
+
reject(new Error("Request was aborted"));
|
|
112
|
+
})
|
|
113
|
+
: () => {};
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
79
117
|
|
|
80
118
|
/**
|
|
81
119
|
* Get specific configuration parameters based on model name
|
|
@@ -99,14 +137,6 @@ function getModelConfig(
|
|
|
99
137
|
config.temperature = undefined;
|
|
100
138
|
}
|
|
101
139
|
|
|
102
|
-
if (modelName.startsWith("gemini-3-flash")) {
|
|
103
|
-
config.vertexai = {
|
|
104
|
-
thinking_config: {
|
|
105
|
-
thinking_level: "minimal",
|
|
106
|
-
},
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
|
|
110
140
|
return config;
|
|
111
141
|
}
|
|
112
142
|
|
|
@@ -170,6 +200,14 @@ export async function callAgent(
|
|
|
170
200
|
onReasoningUpdate,
|
|
171
201
|
} = options;
|
|
172
202
|
|
|
203
|
+
// Apply global 1 QPS rate limit
|
|
204
|
+
if (
|
|
205
|
+
process.env.NODE_ENV !== "test" ||
|
|
206
|
+
modelConfig.agentModel === "rate-limit-test"
|
|
207
|
+
) {
|
|
208
|
+
await acquireSlot(abortSignal);
|
|
209
|
+
}
|
|
210
|
+
|
|
173
211
|
// Declare variables outside try block for error handling access
|
|
174
212
|
let openaiMessages: ChatCompletionMessageParam[] | undefined;
|
|
175
213
|
let createParams:
|
|
@@ -719,6 +757,14 @@ export async function compressMessages(
|
|
|
719
757
|
): Promise<CompressMessagesResult> {
|
|
720
758
|
const { gatewayConfig, modelConfig, messages, abortSignal } = options;
|
|
721
759
|
|
|
760
|
+
// Apply global 1 QPS rate limit
|
|
761
|
+
if (
|
|
762
|
+
process.env.NODE_ENV !== "test" ||
|
|
763
|
+
modelConfig.agentModel === "rate-limit-test"
|
|
764
|
+
) {
|
|
765
|
+
await acquireSlot(abortSignal);
|
|
766
|
+
}
|
|
767
|
+
|
|
722
768
|
// Create OpenAI client with injected configuration
|
|
723
769
|
const openai = new OpenAIClient({
|
|
724
770
|
apiKey: gatewayConfig.apiKey,
|
|
@@ -374,7 +374,7 @@ export class ConfigurationService {
|
|
|
374
374
|
if (apiKey !== undefined) {
|
|
375
375
|
resolvedApiKey = apiKey;
|
|
376
376
|
} else {
|
|
377
|
-
resolvedApiKey = this.env.WAVE_API_KEY
|
|
377
|
+
resolvedApiKey = this.env.WAVE_API_KEY;
|
|
378
378
|
}
|
|
379
379
|
|
|
380
380
|
// Resolve base URL: constructor > env (settings.json) > process.env
|
|
@@ -383,8 +383,25 @@ export class ConfigurationService {
|
|
|
383
383
|
if (baseURL !== undefined) {
|
|
384
384
|
resolvedBaseURL = baseURL;
|
|
385
385
|
} else {
|
|
386
|
-
resolvedBaseURL =
|
|
387
|
-
|
|
386
|
+
resolvedBaseURL = this.env.WAVE_BASE_URL || "";
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// If we have a parent configuration, use it as a fallback for API key and base URL
|
|
390
|
+
if (this.currentConfiguration?.env) {
|
|
391
|
+
if (resolvedApiKey === undefined) {
|
|
392
|
+
resolvedApiKey = this.currentConfiguration.env.WAVE_API_KEY;
|
|
393
|
+
}
|
|
394
|
+
if (!resolvedBaseURL) {
|
|
395
|
+
resolvedBaseURL = this.currentConfiguration.env.WAVE_BASE_URL || "";
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Fallback to process.env if still not resolved (for dynamic updates in tests)
|
|
400
|
+
if (resolvedApiKey === undefined) {
|
|
401
|
+
resolvedApiKey = process.env.WAVE_API_KEY;
|
|
402
|
+
}
|
|
403
|
+
if (!resolvedBaseURL) {
|
|
404
|
+
resolvedBaseURL = process.env.WAVE_BASE_URL || "";
|
|
388
405
|
}
|
|
389
406
|
|
|
390
407
|
if (!resolvedBaseURL && baseURL === undefined) {
|
|
@@ -443,18 +460,22 @@ export class ConfigurationService {
|
|
|
443
460
|
const DEFAULT_FAST_MODEL = "gemini-2.5-flash";
|
|
444
461
|
|
|
445
462
|
// Resolve agent model: constructor > env (settings.json) > process.env > default
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
463
|
+
let resolvedAgentModel = agentModel || this.env.WAVE_MODEL;
|
|
464
|
+
|
|
465
|
+
if (!resolvedAgentModel && this.currentConfiguration?.env?.WAVE_MODEL) {
|
|
466
|
+
resolvedAgentModel = this.currentConfiguration.env.WAVE_MODEL;
|
|
467
|
+
}
|
|
468
|
+
resolvedAgentModel =
|
|
469
|
+
resolvedAgentModel || process.env.WAVE_MODEL || DEFAULT_AGENT_MODEL;
|
|
451
470
|
|
|
452
471
|
// Resolve fast model: constructor > env (settings.json) > process.env > default
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
472
|
+
let resolvedFastModel = fastModel || this.env.WAVE_FAST_MODEL;
|
|
473
|
+
|
|
474
|
+
if (!resolvedFastModel && this.currentConfiguration?.env?.WAVE_FAST_MODEL) {
|
|
475
|
+
resolvedFastModel = this.currentConfiguration.env.WAVE_FAST_MODEL;
|
|
476
|
+
}
|
|
477
|
+
resolvedFastModel =
|
|
478
|
+
resolvedFastModel || process.env.WAVE_FAST_MODEL || DEFAULT_FAST_MODEL;
|
|
458
479
|
|
|
459
480
|
// Resolve max output tokens
|
|
460
481
|
const resolvedMaxTokens = this.resolveMaxOutputTokens(maxTokens);
|
|
@@ -4,12 +4,16 @@ import { homedir } from "os";
|
|
|
4
4
|
import { EventEmitter } from "events";
|
|
5
5
|
import { Task } from "../types/tasks.js";
|
|
6
6
|
import { logger } from "../utils/globalLogger.js";
|
|
7
|
+
import { Container } from "../utils/container.js";
|
|
7
8
|
|
|
8
9
|
export class TaskManager extends EventEmitter {
|
|
9
10
|
private readonly baseDir: string;
|
|
10
11
|
private taskListId: string;
|
|
11
12
|
|
|
12
|
-
constructor(
|
|
13
|
+
constructor(
|
|
14
|
+
private container: Container,
|
|
15
|
+
taskListId: string,
|
|
16
|
+
) {
|
|
13
17
|
super();
|
|
14
18
|
this.taskListId = taskListId;
|
|
15
19
|
this.baseDir = join(homedir(), ".wave", "tasks");
|
|
@@ -43,7 +47,7 @@ export class TaskManager extends EventEmitter {
|
|
|
43
47
|
const lockPath = this.getLockPath();
|
|
44
48
|
let lockHandle;
|
|
45
49
|
const maxRetries = 100;
|
|
46
|
-
const retryDelay = process.env.NODE_ENV === "test" ?
|
|
50
|
+
const retryDelay = process.env.NODE_ENV === "test" ? 1 : 100;
|
|
47
51
|
|
|
48
52
|
await this.ensureSessionDir();
|
|
49
53
|
|
package/src/tools/bashTool.ts
CHANGED
|
@@ -197,9 +197,24 @@ Usage notes:
|
|
|
197
197
|
|
|
198
198
|
let outputBuffer = "";
|
|
199
199
|
let errorBuffer = "";
|
|
200
|
+
let shortResultBuffer = "";
|
|
200
201
|
let isAborted = false;
|
|
201
202
|
let isBackgrounded = false;
|
|
202
203
|
|
|
204
|
+
const updateShortResult = (chunk: string) => {
|
|
205
|
+
if (!chunk) return;
|
|
206
|
+
shortResultBuffer += chunk;
|
|
207
|
+
if (shortResultBuffer.length > MAX_OUTPUT_LENGTH) {
|
|
208
|
+
shortResultBuffer = shortResultBuffer.slice(-MAX_OUTPUT_LENGTH);
|
|
209
|
+
}
|
|
210
|
+
const lastLines = shortResultBuffer
|
|
211
|
+
.trim()
|
|
212
|
+
.split("\n")
|
|
213
|
+
.slice(-3)
|
|
214
|
+
.join("\n");
|
|
215
|
+
context.onShortResultUpdate?.(lastLines || "");
|
|
216
|
+
};
|
|
217
|
+
|
|
203
218
|
const foregroundTaskId = `bash_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
204
219
|
|
|
205
220
|
// Register as foreground task
|
|
@@ -306,18 +321,18 @@ Usage notes:
|
|
|
306
321
|
}
|
|
307
322
|
|
|
308
323
|
child.stdout?.on("data", (data) => {
|
|
309
|
-
if (!isAborted && !isBackgrounded) {
|
|
324
|
+
if (!isAborted && !isBackgrounded && !runInBackground) {
|
|
310
325
|
const chunk = stripAnsiColors(data.toString());
|
|
311
326
|
outputBuffer += chunk;
|
|
312
|
-
|
|
327
|
+
updateShortResult(chunk);
|
|
313
328
|
}
|
|
314
329
|
});
|
|
315
330
|
|
|
316
331
|
child.stderr?.on("data", (data) => {
|
|
317
|
-
if (!isAborted && !isBackgrounded) {
|
|
332
|
+
if (!isAborted && !isBackgrounded && !runInBackground) {
|
|
318
333
|
const chunk = stripAnsiColors(data.toString());
|
|
319
334
|
errorBuffer += chunk;
|
|
320
|
-
|
|
335
|
+
updateShortResult(chunk);
|
|
321
336
|
}
|
|
322
337
|
});
|
|
323
338
|
|