wave-agent-sdk 0.0.7 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.d.ts +105 -24
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +438 -53
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/managers/aiManager.d.ts +18 -7
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +254 -142
- package/dist/managers/backgroundBashManager.d.ts.map +1 -1
- package/dist/managers/backgroundBashManager.js +11 -9
- package/dist/managers/hookManager.d.ts +6 -6
- package/dist/managers/hookManager.d.ts.map +1 -1
- package/dist/managers/hookManager.js +81 -39
- package/dist/managers/liveConfigManager.d.ts +95 -0
- package/dist/managers/liveConfigManager.d.ts.map +1 -0
- package/dist/managers/liveConfigManager.js +442 -0
- package/dist/managers/lspManager.d.ts +43 -0
- package/dist/managers/lspManager.d.ts.map +1 -0
- package/dist/managers/lspManager.js +326 -0
- package/dist/managers/messageManager.d.ts +41 -24
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +184 -73
- package/dist/managers/permissionManager.d.ts +66 -0
- package/dist/managers/permissionManager.d.ts.map +1 -0
- package/dist/managers/permissionManager.js +208 -0
- package/dist/managers/skillManager.d.ts +1 -0
- package/dist/managers/skillManager.d.ts.map +1 -1
- package/dist/managers/skillManager.js +2 -1
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +4 -2
- package/dist/managers/subagentManager.d.ts +42 -6
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +213 -62
- package/dist/managers/toolManager.d.ts +38 -1
- package/dist/managers/toolManager.d.ts.map +1 -1
- package/dist/managers/toolManager.js +66 -2
- package/dist/services/aiService.d.ts +15 -5
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +446 -77
- package/dist/services/configurationService.d.ts +116 -0
- package/dist/services/configurationService.d.ts.map +1 -0
- package/dist/services/configurationService.js +585 -0
- package/dist/services/fileWatcher.d.ts +69 -0
- package/dist/services/fileWatcher.d.ts.map +1 -0
- package/dist/services/fileWatcher.js +212 -0
- package/dist/services/hook.d.ts +5 -40
- package/dist/services/hook.d.ts.map +1 -1
- package/dist/services/hook.js +47 -109
- package/dist/services/jsonlHandler.d.ts +71 -0
- package/dist/services/jsonlHandler.d.ts.map +1 -0
- package/dist/services/jsonlHandler.js +236 -0
- package/dist/services/memory.d.ts.map +1 -1
- package/dist/services/memory.js +33 -11
- package/dist/services/session.d.ts +116 -52
- package/dist/services/session.d.ts.map +1 -1
- package/dist/services/session.js +415 -143
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +77 -17
- package/dist/tools/deleteFileTool.d.ts.map +1 -1
- package/dist/tools/deleteFileTool.js +27 -1
- package/dist/tools/editTool.d.ts.map +1 -1
- package/dist/tools/editTool.js +33 -8
- package/dist/tools/lspTool.d.ts +6 -0
- package/dist/tools/lspTool.d.ts.map +1 -0
- package/dist/tools/lspTool.js +589 -0
- package/dist/tools/multiEditTool.d.ts.map +1 -1
- package/dist/tools/multiEditTool.js +30 -10
- package/dist/tools/readTool.d.ts.map +1 -1
- package/dist/tools/readTool.js +113 -3
- package/dist/tools/skillTool.js +2 -2
- package/dist/tools/todoWriteTool.d.ts.map +1 -1
- package/dist/tools/todoWriteTool.js +23 -0
- package/dist/tools/types.d.ts +11 -8
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/writeTool.d.ts.map +1 -1
- package/dist/tools/writeTool.js +30 -15
- package/dist/types/commands.d.ts +4 -1
- package/dist/types/commands.d.ts.map +1 -1
- package/dist/types/config.d.ts +4 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/configuration.d.ts +69 -0
- package/dist/types/configuration.d.ts.map +1 -0
- package/dist/types/configuration.js +8 -0
- package/dist/types/core.d.ts +45 -0
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/environment.d.ts +83 -0
- package/dist/types/environment.d.ts.map +1 -0
- package/dist/types/environment.js +21 -0
- package/dist/types/fileSearch.d.ts +5 -0
- package/dist/types/fileSearch.d.ts.map +1 -0
- package/dist/types/fileSearch.js +1 -0
- package/dist/types/hooks.d.ts +18 -3
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/hooks.js +8 -8
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +7 -0
- package/dist/types/lsp.d.ts +90 -0
- package/dist/types/lsp.d.ts.map +1 -0
- package/dist/types/lsp.js +4 -0
- package/dist/types/messaging.d.ts +19 -12
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/types/permissions.d.ts +35 -0
- package/dist/types/permissions.d.ts.map +1 -0
- package/dist/types/permissions.js +12 -0
- package/dist/types/session.d.ts +15 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +7 -0
- package/dist/types/skills.d.ts +1 -0
- package/dist/types/skills.d.ts.map +1 -1
- package/dist/types/tools.d.ts +35 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +4 -0
- package/dist/utils/abortUtils.d.ts +34 -0
- package/dist/utils/abortUtils.d.ts.map +1 -0
- package/dist/utils/abortUtils.js +92 -0
- package/dist/utils/bashHistory.d.ts +4 -0
- package/dist/utils/bashHistory.d.ts.map +1 -1
- package/dist/utils/bashHistory.js +48 -30
- package/dist/utils/builtinSubagents.d.ts +7 -0
- package/dist/utils/builtinSubagents.d.ts.map +1 -0
- package/dist/utils/builtinSubagents.js +65 -0
- package/dist/utils/cacheControlUtils.d.ts +96 -0
- package/dist/utils/cacheControlUtils.d.ts.map +1 -0
- package/dist/utils/cacheControlUtils.js +324 -0
- package/dist/utils/commandPathResolver.d.ts +52 -0
- package/dist/utils/commandPathResolver.d.ts.map +1 -0
- package/dist/utils/commandPathResolver.js +145 -0
- package/dist/utils/configPaths.d.ts +85 -0
- package/dist/utils/configPaths.d.ts.map +1 -0
- package/dist/utils/configPaths.js +121 -0
- package/dist/utils/constants.d.ts +1 -13
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/constants.js +2 -14
- package/dist/utils/convertMessagesForAPI.d.ts +2 -1
- package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
- package/dist/utils/convertMessagesForAPI.js +39 -18
- package/dist/utils/customCommands.d.ts.map +1 -1
- package/dist/utils/customCommands.js +66 -21
- package/dist/utils/fileSearch.d.ts +14 -0
- package/dist/utils/fileSearch.d.ts.map +1 -0
- package/dist/utils/fileSearch.js +88 -0
- package/dist/utils/fileUtils.d.ts +27 -0
- package/dist/utils/fileUtils.d.ts.map +1 -0
- package/dist/utils/fileUtils.js +145 -0
- package/dist/utils/globalLogger.d.ts +88 -0
- package/dist/utils/globalLogger.d.ts.map +1 -0
- package/dist/utils/globalLogger.js +120 -0
- package/dist/utils/largeOutputHandler.d.ts +15 -0
- package/dist/utils/largeOutputHandler.d.ts.map +1 -0
- package/dist/utils/largeOutputHandler.js +40 -0
- package/dist/utils/markdownParser.d.ts.map +1 -1
- package/dist/utils/markdownParser.js +1 -17
- package/dist/utils/mcpUtils.d.ts.map +1 -1
- package/dist/utils/mcpUtils.js +25 -3
- package/dist/utils/messageOperations.d.ts +20 -18
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +30 -38
- package/dist/utils/pathEncoder.d.ts +108 -0
- package/dist/utils/pathEncoder.d.ts.map +1 -0
- package/dist/utils/pathEncoder.js +279 -0
- package/dist/utils/subagentParser.d.ts +2 -2
- package/dist/utils/subagentParser.d.ts.map +1 -1
- package/dist/utils/subagentParser.js +12 -8
- package/dist/utils/tokenCalculation.d.ts +26 -0
- package/dist/utils/tokenCalculation.d.ts.map +1 -0
- package/dist/utils/tokenCalculation.js +36 -0
- package/dist/utils/tokenEstimator.d.ts +39 -0
- package/dist/utils/tokenEstimator.d.ts.map +1 -0
- package/dist/utils/tokenEstimator.js +55 -0
- package/package.json +6 -6
- package/src/agent.ts +586 -78
- package/src/index.ts +4 -0
- package/src/managers/aiManager.ts +341 -192
- package/src/managers/backgroundBashManager.ts +11 -9
- package/src/managers/hookManager.ts +102 -54
- package/src/managers/liveConfigManager.ts +634 -0
- package/src/managers/lspManager.ts +434 -0
- package/src/managers/messageManager.ts +258 -121
- package/src/managers/permissionManager.ts +276 -0
- package/src/managers/skillManager.ts +3 -1
- package/src/managers/slashCommandManager.ts +5 -3
- package/src/managers/subagentManager.ts +295 -76
- package/src/managers/toolManager.ts +95 -3
- package/src/services/aiService.ts +656 -84
- package/src/services/configurationService.ts +762 -0
- package/src/services/fileWatcher.ts +300 -0
- package/src/services/hook.ts +54 -144
- package/src/services/jsonlHandler.ts +303 -0
- package/src/services/memory.ts +34 -11
- package/src/services/session.ts +522 -173
- package/src/tools/bashTool.ts +94 -20
- package/src/tools/deleteFileTool.ts +38 -1
- package/src/tools/editTool.ts +44 -9
- package/src/tools/lspTool.ts +760 -0
- package/src/tools/multiEditTool.ts +41 -11
- package/src/tools/readTool.ts +127 -3
- package/src/tools/skillTool.ts +2 -2
- package/src/tools/todoWriteTool.ts +33 -1
- package/src/tools/types.ts +15 -9
- package/src/tools/writeTool.ts +43 -16
- package/src/types/commands.ts +6 -1
- package/src/types/config.ts +5 -0
- package/src/types/configuration.ts +73 -0
- package/src/types/core.ts +55 -0
- package/src/types/environment.ts +104 -0
- package/src/types/fileSearch.ts +4 -0
- package/src/types/hooks.ts +32 -16
- package/src/types/index.ts +7 -0
- package/src/types/lsp.ts +96 -0
- package/src/types/messaging.ts +21 -14
- package/src/types/permissions.ts +48 -0
- package/src/types/session.ts +20 -0
- package/src/types/skills.ts +1 -0
- package/src/types/tools.ts +38 -0
- package/src/utils/abortUtils.ts +118 -0
- package/src/utils/bashHistory.ts +55 -31
- package/src/utils/builtinSubagents.ts +71 -0
- package/src/utils/cacheControlUtils.ts +475 -0
- package/src/utils/commandPathResolver.ts +189 -0
- package/src/utils/configPaths.ts +163 -0
- package/src/utils/constants.ts +2 -17
- package/src/utils/convertMessagesForAPI.ts +44 -18
- package/src/utils/customCommands.ts +90 -22
- package/src/utils/fileSearch.ts +107 -0
- package/src/utils/fileUtils.ts +160 -0
- package/src/utils/globalLogger.ts +128 -0
- package/src/utils/largeOutputHandler.ts +55 -0
- package/src/utils/markdownParser.ts +1 -19
- package/src/utils/mcpUtils.ts +34 -3
- package/src/utils/messageOperations.ts +47 -53
- package/src/utils/pathEncoder.ts +394 -0
- package/src/utils/subagentParser.ts +13 -9
- package/src/utils/tokenCalculation.ts +43 -0
- package/src/utils/tokenEstimator.ts +68 -0
- package/dist/utils/configResolver.d.ts +0 -38
- package/dist/utils/configResolver.d.ts.map +0 -1
- package/dist/utils/configResolver.js +0 -106
- package/src/utils/configResolver.ts +0 -142
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { callAgent, compressMessages } from "../services/aiService.js";
|
|
1
|
+
import { callAgent, compressMessages, } from "../services/aiService.js";
|
|
2
2
|
import { getMessagesToCompress } from "../utils/messageOperations.js";
|
|
3
3
|
import { convertMessagesForAPI } from "../utils/convertMessagesForAPI.js";
|
|
4
|
+
import { calculateComprehensiveTotalTokens } from "../utils/tokenCalculation.js";
|
|
4
5
|
import * as memory from "../services/memory.js";
|
|
5
6
|
export class AIManager {
|
|
6
7
|
constructor(options) {
|
|
@@ -15,11 +16,24 @@ export class AIManager {
|
|
|
15
16
|
this.logger = options.logger;
|
|
16
17
|
this.workdir = options.workdir;
|
|
17
18
|
this.systemPrompt = options.systemPrompt;
|
|
19
|
+
this.subagentType = options.subagentType; // Store subagent type
|
|
20
|
+
this.stream = options.stream ?? true; // Default to true if not specified
|
|
18
21
|
this.callbacks = options.callbacks ?? {};
|
|
19
|
-
// Store
|
|
20
|
-
this.
|
|
21
|
-
this.
|
|
22
|
-
this.
|
|
22
|
+
// Store configuration getter functions for dynamic resolution
|
|
23
|
+
this.getGatewayConfigFn = options.getGatewayConfig;
|
|
24
|
+
this.getModelConfigFn = options.getModelConfig;
|
|
25
|
+
this.getTokenLimitFn = options.getTokenLimit;
|
|
26
|
+
this.getEnvironmentVarsFn = options.getEnvironmentVars;
|
|
27
|
+
}
|
|
28
|
+
// Getter methods for accessing dynamic configuration
|
|
29
|
+
getGatewayConfig() {
|
|
30
|
+
return this.getGatewayConfigFn();
|
|
31
|
+
}
|
|
32
|
+
getModelConfig() {
|
|
33
|
+
return this.getModelConfigFn();
|
|
34
|
+
}
|
|
35
|
+
getTokenLimit() {
|
|
36
|
+
return this.getTokenLimitFn();
|
|
23
37
|
}
|
|
24
38
|
/**
|
|
25
39
|
* Get filtered tool configuration
|
|
@@ -73,45 +87,52 @@ export class AIManager {
|
|
|
73
87
|
catch (error) {
|
|
74
88
|
this.logger?.warn("Failed to generate compactParams", error);
|
|
75
89
|
}
|
|
76
|
-
return
|
|
90
|
+
return "";
|
|
77
91
|
}
|
|
78
92
|
// Private method to handle token statistics and message compression
|
|
79
93
|
async handleTokenUsageAndCompression(usage, abortController) {
|
|
80
94
|
if (!usage)
|
|
81
95
|
return;
|
|
82
|
-
// Update token statistics - display
|
|
83
|
-
|
|
96
|
+
// Update token statistics - display comprehensive token usage including cache tokens
|
|
97
|
+
const comprehensiveTotalTokens = calculateComprehensiveTotalTokens(usage);
|
|
98
|
+
this.messageManager.setlatestTotalTokens(comprehensiveTotalTokens);
|
|
84
99
|
// Check if token limit exceeded - use injected configuration
|
|
85
|
-
if (usage.total_tokens
|
|
86
|
-
|
|
100
|
+
if (usage.total_tokens +
|
|
101
|
+
(usage.cache_read_input_tokens || 0) +
|
|
102
|
+
(usage.cache_creation_input_tokens || 0) >
|
|
103
|
+
this.getTokenLimit()) {
|
|
104
|
+
this.logger?.debug(`Token usage exceeded ${this.getTokenLimit()}, compressing messages...`);
|
|
87
105
|
// Check if messages need compression
|
|
88
106
|
const { messagesToCompress, insertIndex } = getMessagesToCompress(this.messageManager.getMessages(), 7);
|
|
89
107
|
// If there are messages to compress, perform compression
|
|
90
108
|
if (messagesToCompress.length > 0) {
|
|
91
109
|
const recentChatMessages = convertMessagesForAPI(messagesToCompress);
|
|
110
|
+
// Save session before compression to preserve original messages
|
|
111
|
+
await this.messageManager.saveSession();
|
|
92
112
|
this.setIsCompressing(true);
|
|
93
113
|
try {
|
|
94
114
|
const compressionResult = await compressMessages({
|
|
95
|
-
gatewayConfig: this.
|
|
96
|
-
modelConfig: this.
|
|
115
|
+
gatewayConfig: this.getGatewayConfig(),
|
|
116
|
+
modelConfig: this.getModelConfig(),
|
|
97
117
|
messages: recentChatMessages,
|
|
98
118
|
abortSignal: abortController.signal,
|
|
99
119
|
});
|
|
100
|
-
// Execute message reconstruction and sessionId update after compression
|
|
101
|
-
this.messageManager.compressMessagesAndUpdateSession(insertIndex, compressionResult.content);
|
|
102
120
|
// Handle usage tracking for compression operations
|
|
121
|
+
let compressionUsage;
|
|
103
122
|
if (compressionResult.usage) {
|
|
104
|
-
|
|
123
|
+
compressionUsage = {
|
|
105
124
|
prompt_tokens: compressionResult.usage.prompt_tokens,
|
|
106
125
|
completion_tokens: compressionResult.usage.completion_tokens,
|
|
107
126
|
total_tokens: compressionResult.usage.total_tokens,
|
|
108
|
-
model: this.
|
|
127
|
+
model: this.getModelConfig().fastModel,
|
|
109
128
|
operation_type: "compress",
|
|
110
129
|
};
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
130
|
+
}
|
|
131
|
+
// Execute message reconstruction and sessionId update after compression
|
|
132
|
+
this.messageManager.compressMessagesAndUpdateSession(insertIndex, compressionResult.content, compressionUsage);
|
|
133
|
+
// Notify Agent to add to usage tracking
|
|
134
|
+
if (compressionUsage && this.callbacks?.onUsageAdded) {
|
|
135
|
+
this.callbacks.onUsageAdded(compressionUsage);
|
|
115
136
|
}
|
|
116
137
|
this.logger?.debug(`Successfully compressed ${messagesToCompress.length} messages and updated session`);
|
|
117
138
|
}
|
|
@@ -139,6 +160,8 @@ export class AIManager {
|
|
|
139
160
|
if (recursionDepth === 0 && this.isLoading) {
|
|
140
161
|
return;
|
|
141
162
|
}
|
|
163
|
+
// Save session in each recursion to ensure message persistence
|
|
164
|
+
await this.messageManager.saveSession();
|
|
142
165
|
// Only create new AbortControllers for the initial call (recursionDepth === 0)
|
|
143
166
|
// For recursive calls, reuse existing controllers to maintain abort signal
|
|
144
167
|
let abortController;
|
|
@@ -164,10 +187,13 @@ export class AIManager {
|
|
|
164
187
|
try {
|
|
165
188
|
// Get combined memory content
|
|
166
189
|
const combinedMemory = await memory.getCombinedMemoryContent(this.workdir);
|
|
167
|
-
//
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
190
|
+
// Track if assistant message has been created
|
|
191
|
+
let assistantMessageCreated = false;
|
|
192
|
+
this.logger?.debug("modelConfig in sendAIMessage", this.getModelConfig());
|
|
193
|
+
// Call AI service with streaming callbacks if enabled
|
|
194
|
+
const callAgentOptions = {
|
|
195
|
+
gatewayConfig: this.getGatewayConfig(),
|
|
196
|
+
modelConfig: this.getModelConfig(),
|
|
171
197
|
messages: recentMessages,
|
|
172
198
|
sessionId: this.messageManager.getSessionId(),
|
|
173
199
|
abortSignal: abortController.signal,
|
|
@@ -176,17 +202,73 @@ export class AIManager {
|
|
|
176
202
|
tools: this.getFilteredToolsConfig(allowedTools), // Pass filtered tool configuration
|
|
177
203
|
model: model, // Use passed model
|
|
178
204
|
systemPrompt: this.systemPrompt, // Pass custom system prompt
|
|
179
|
-
}
|
|
180
|
-
//
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
toolCalls.push(toolCall);
|
|
205
|
+
};
|
|
206
|
+
// Add streaming callbacks only if streaming is enabled
|
|
207
|
+
if (this.stream) {
|
|
208
|
+
callAgentOptions.onContentUpdate = (content) => {
|
|
209
|
+
// Create assistant message on first chunk if not already created
|
|
210
|
+
if (!assistantMessageCreated) {
|
|
211
|
+
this.messageManager.addAssistantMessage();
|
|
212
|
+
assistantMessageCreated = true;
|
|
188
213
|
}
|
|
189
|
-
|
|
214
|
+
this.messageManager.updateCurrentMessageContent(content);
|
|
215
|
+
};
|
|
216
|
+
callAgentOptions.onToolUpdate = (toolCall) => {
|
|
217
|
+
// Create assistant message on first tool update if not already created
|
|
218
|
+
if (!assistantMessageCreated) {
|
|
219
|
+
this.messageManager.addAssistantMessage();
|
|
220
|
+
assistantMessageCreated = true;
|
|
221
|
+
}
|
|
222
|
+
// Use parametersChunk as compact param for better performance
|
|
223
|
+
// No need to extract params or generate compact params during streaming
|
|
224
|
+
// Update tool block with streaming parameters using parametersChunk as compact param
|
|
225
|
+
this.messageManager.updateToolBlock({
|
|
226
|
+
id: toolCall.id,
|
|
227
|
+
name: toolCall.name,
|
|
228
|
+
parameters: toolCall.parameters,
|
|
229
|
+
parametersChunk: toolCall.parametersChunk,
|
|
230
|
+
compactParams: toolCall.parameters?.split("\n").pop()?.slice(-30),
|
|
231
|
+
stage: toolCall.stage || "streaming", // Default to streaming if stage not provided
|
|
232
|
+
});
|
|
233
|
+
};
|
|
234
|
+
callAgentOptions.onReasoningUpdate = (reasoning) => {
|
|
235
|
+
// Create assistant message on first reasoning update if not already created
|
|
236
|
+
if (!assistantMessageCreated) {
|
|
237
|
+
this.messageManager.addAssistantMessage();
|
|
238
|
+
assistantMessageCreated = true;
|
|
239
|
+
}
|
|
240
|
+
this.messageManager.updateCurrentMessageReasoning(reasoning);
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
const result = await callAgent(callAgentOptions);
|
|
244
|
+
const createdByStreaming = assistantMessageCreated;
|
|
245
|
+
// For non-streaming mode, create assistant message after callAgent returns
|
|
246
|
+
// Also create if streaming mode but no streaming callbacks were called (e.g., when content comes directly in result)
|
|
247
|
+
if (!this.stream ||
|
|
248
|
+
(!assistantMessageCreated &&
|
|
249
|
+
(result.content || result.tool_calls || result.reasoning_content))) {
|
|
250
|
+
this.messageManager.addAssistantMessage();
|
|
251
|
+
assistantMessageCreated = true;
|
|
252
|
+
}
|
|
253
|
+
// Log finish reason and response headers if available
|
|
254
|
+
if (result.finish_reason) {
|
|
255
|
+
this.logger?.debug(`AI response finished with reason: ${result.finish_reason}`);
|
|
256
|
+
}
|
|
257
|
+
if (result.response_headers &&
|
|
258
|
+
Object.keys(result.response_headers).length > 0) {
|
|
259
|
+
this.logger?.debug("AI response headers:", result.response_headers);
|
|
260
|
+
}
|
|
261
|
+
if (result.additionalFields &&
|
|
262
|
+
Object.keys(result.additionalFields).length > 0) {
|
|
263
|
+
this.messageManager.mergeAssistantAdditionalFields(result.additionalFields);
|
|
264
|
+
}
|
|
265
|
+
// Handle result reasoning content from non-streaming mode
|
|
266
|
+
if (result.reasoning_content && !createdByStreaming) {
|
|
267
|
+
this.messageManager.updateCurrentMessageReasoning(result.reasoning_content);
|
|
268
|
+
}
|
|
269
|
+
// Handle result content from non-streaming mode
|
|
270
|
+
if (result.content && !createdByStreaming) {
|
|
271
|
+
this.messageManager.updateCurrentMessageContent(result.content);
|
|
190
272
|
}
|
|
191
273
|
// Handle usage tracking for agent operations
|
|
192
274
|
let usage;
|
|
@@ -195,115 +277,136 @@ export class AIManager {
|
|
|
195
277
|
prompt_tokens: result.usage.prompt_tokens,
|
|
196
278
|
completion_tokens: result.usage.completion_tokens,
|
|
197
279
|
total_tokens: result.usage.total_tokens,
|
|
198
|
-
model: model || this.
|
|
280
|
+
model: model || this.getModelConfig().agentModel,
|
|
199
281
|
operation_type: "agent",
|
|
282
|
+
// Preserve cache fields if present
|
|
283
|
+
...(result.usage.cache_read_input_tokens !== undefined && {
|
|
284
|
+
cache_read_input_tokens: result.usage.cache_read_input_tokens,
|
|
285
|
+
}),
|
|
286
|
+
...(result.usage.cache_creation_input_tokens !== undefined && {
|
|
287
|
+
cache_creation_input_tokens: result.usage.cache_creation_input_tokens,
|
|
288
|
+
}),
|
|
289
|
+
...(result.usage.cache_creation && {
|
|
290
|
+
cache_creation: result.usage.cache_creation,
|
|
291
|
+
}),
|
|
200
292
|
};
|
|
201
293
|
}
|
|
202
|
-
//
|
|
203
|
-
this.messageManager.addAssistantMessage(content, toolCalls, usage);
|
|
204
|
-
// Notify Agent to add to usage tracking
|
|
294
|
+
// Set usage on the assistant message if available
|
|
205
295
|
if (usage) {
|
|
296
|
+
const messages = this.messageManager.getMessages();
|
|
297
|
+
const lastMessage = messages[messages.length - 1];
|
|
298
|
+
if (lastMessage && lastMessage.role === "assistant") {
|
|
299
|
+
lastMessage.usage = usage;
|
|
300
|
+
this.messageManager.setMessages(messages);
|
|
301
|
+
}
|
|
302
|
+
// Notify Agent to add to usage tracking
|
|
206
303
|
if (this.callbacks?.onUsageAdded) {
|
|
207
304
|
this.callbacks.onUsageAdded(usage);
|
|
208
305
|
}
|
|
209
306
|
}
|
|
307
|
+
// Collect tool calls for processing
|
|
308
|
+
const toolCalls = [];
|
|
309
|
+
if (result.tool_calls) {
|
|
310
|
+
for (const toolCall of result.tool_calls) {
|
|
311
|
+
if (toolCall.type === "function") {
|
|
312
|
+
toolCalls.push(toolCall);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
210
316
|
if (toolCalls.length > 0) {
|
|
211
317
|
// Execute all tools in parallel using Promise.all
|
|
212
318
|
const toolExecutionPromises = toolCalls.map(async (functionToolCall) => {
|
|
213
319
|
const toolId = functionToolCall.id || "";
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
try {
|
|
229
|
-
toolArgs = JSON.parse(argsString);
|
|
230
|
-
}
|
|
231
|
-
catch (parseError) {
|
|
232
|
-
// For non-empty but malformed JSON, still throw exception
|
|
233
|
-
const errorMessage = `Failed to parse tool arguments: ${argsString}`;
|
|
234
|
-
this.logger?.error(errorMessage, parseError);
|
|
235
|
-
throw new Error(errorMessage);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
// Set tool start execution state
|
|
239
|
-
const toolName = functionToolCall.function?.name || "";
|
|
240
|
-
const compactParams = this.generateCompactParams(toolName, toolArgs);
|
|
241
|
-
this.messageManager.updateToolBlock({
|
|
242
|
-
id: toolId,
|
|
243
|
-
parameters: JSON.stringify(toolArgs, null, 2),
|
|
244
|
-
isRunning: true, // isRunning: true
|
|
245
|
-
name: toolName,
|
|
246
|
-
compactParams,
|
|
247
|
-
});
|
|
320
|
+
// Check if already interrupted, skip tool execution if so
|
|
321
|
+
if (abortController.signal.aborted ||
|
|
322
|
+
toolAbortController.signal.aborted) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
const toolName = functionToolCall.function?.name || "";
|
|
326
|
+
// Safely parse tool parameters, handle tools without parameters
|
|
327
|
+
let toolArgs = {};
|
|
328
|
+
const argsString = functionToolCall.function?.arguments?.trim();
|
|
329
|
+
if (!argsString || argsString === "") {
|
|
330
|
+
// Tool without parameters, use empty object
|
|
331
|
+
toolArgs = {};
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
248
334
|
try {
|
|
249
|
-
|
|
250
|
-
const shouldExecuteTool = await this.executePreToolUseHooks(toolName, toolArgs, toolId);
|
|
251
|
-
// If PreToolUse hooks blocked execution, skip tool execution
|
|
252
|
-
if (!shouldExecuteTool) {
|
|
253
|
-
this.logger?.info(`Tool ${toolName} execution blocked by PreToolUse hooks`);
|
|
254
|
-
return; // Skip this tool and return from this map function
|
|
255
|
-
}
|
|
256
|
-
// Create tool execution context
|
|
257
|
-
const context = {
|
|
258
|
-
abortSignal: toolAbortController.signal,
|
|
259
|
-
backgroundBashManager: this.backgroundBashManager,
|
|
260
|
-
workdir: this.workdir,
|
|
261
|
-
};
|
|
262
|
-
// Execute tool
|
|
263
|
-
const toolResult = await this.toolManager.execute(functionToolCall.function?.name || "", toolArgs, context);
|
|
264
|
-
// Update message state - tool execution completed
|
|
265
|
-
this.messageManager.updateToolBlock({
|
|
266
|
-
id: toolId,
|
|
267
|
-
parameters: JSON.stringify(toolArgs, null, 2),
|
|
268
|
-
result: toolResult.content ||
|
|
269
|
-
(toolResult.error ? `Error: ${toolResult.error}` : ""),
|
|
270
|
-
success: toolResult.success,
|
|
271
|
-
error: toolResult.error,
|
|
272
|
-
isRunning: false, // isRunning: false
|
|
273
|
-
name: toolName,
|
|
274
|
-
shortResult: toolResult.shortResult,
|
|
275
|
-
compactParams,
|
|
276
|
-
});
|
|
277
|
-
// If tool returns diff information, add diff block
|
|
278
|
-
if (toolResult.success &&
|
|
279
|
-
toolResult.diffResult &&
|
|
280
|
-
toolResult.filePath) {
|
|
281
|
-
this.messageManager.addDiffBlock(toolResult.filePath, toolResult.diffResult);
|
|
282
|
-
}
|
|
283
|
-
// Execute PostToolUse hooks after successful tool completion
|
|
284
|
-
await this.executePostToolUseHooks(toolId, toolName, toolArgs, toolResult);
|
|
335
|
+
toolArgs = JSON.parse(argsString);
|
|
285
336
|
}
|
|
286
|
-
catch (
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
337
|
+
catch (parseError) {
|
|
338
|
+
// For non-empty but malformed JSON, still throw exception
|
|
339
|
+
const errorMessage = `Failed to parse tool arguments, finish_reason: ${result.finish_reason}`;
|
|
340
|
+
const fullErrorMessage = `${errorMessage}\nAI response headers:, ${JSON.stringify(result.response_headers)}`;
|
|
341
|
+
this.logger?.error(fullErrorMessage, parseError);
|
|
290
342
|
this.messageManager.updateToolBlock({
|
|
291
343
|
id: toolId,
|
|
292
|
-
parameters:
|
|
293
|
-
result:
|
|
344
|
+
parameters: argsString,
|
|
345
|
+
result: errorMessage,
|
|
294
346
|
success: false,
|
|
295
|
-
error:
|
|
296
|
-
|
|
347
|
+
error: fullErrorMessage,
|
|
348
|
+
stage: "end",
|
|
297
349
|
name: toolName,
|
|
298
|
-
compactParams,
|
|
350
|
+
compactParams: "",
|
|
299
351
|
});
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
const compactParams = this.generateCompactParams(toolName, toolArgs);
|
|
356
|
+
// Emit running stage for non-streaming tool calls (tool execution about to start)
|
|
357
|
+
this.messageManager.updateToolBlock({
|
|
358
|
+
id: toolId,
|
|
359
|
+
stage: "running",
|
|
360
|
+
name: toolName,
|
|
361
|
+
compactParams,
|
|
362
|
+
parameters: argsString,
|
|
363
|
+
parametersChunk: "",
|
|
364
|
+
});
|
|
365
|
+
try {
|
|
366
|
+
// Execute PreToolUse hooks before tool execution
|
|
367
|
+
const shouldExecuteTool = await this.executePreToolUseHooks(toolName, toolArgs, toolId);
|
|
368
|
+
// If PreToolUse hooks blocked execution, skip tool execution
|
|
369
|
+
if (!shouldExecuteTool) {
|
|
370
|
+
this.logger?.info(`Tool ${toolName} execution blocked by PreToolUse hooks`);
|
|
371
|
+
return; // Skip this tool and return from this map function
|
|
300
372
|
}
|
|
373
|
+
// Create tool execution context
|
|
374
|
+
const context = {
|
|
375
|
+
abortSignal: toolAbortController.signal,
|
|
376
|
+
backgroundBashManager: this.backgroundBashManager,
|
|
377
|
+
workdir: this.workdir,
|
|
378
|
+
};
|
|
379
|
+
// Execute tool
|
|
380
|
+
const toolResult = await this.toolManager.execute(functionToolCall.function?.name || "", toolArgs, context);
|
|
381
|
+
// Update message state - tool execution completed
|
|
382
|
+
this.messageManager.updateToolBlock({
|
|
383
|
+
id: toolId,
|
|
384
|
+
parameters: argsString,
|
|
385
|
+
result: toolResult.content ||
|
|
386
|
+
(toolResult.error ? `Error: ${toolResult.error}` : ""),
|
|
387
|
+
success: toolResult.success,
|
|
388
|
+
error: toolResult.error,
|
|
389
|
+
stage: "end",
|
|
390
|
+
name: toolName,
|
|
391
|
+
shortResult: toolResult.shortResult,
|
|
392
|
+
});
|
|
393
|
+
// Execute PostToolUse hooks after successful tool completion
|
|
394
|
+
await this.executePostToolUseHooks(toolId, toolName, toolArgs, toolResult);
|
|
301
395
|
}
|
|
302
|
-
catch (
|
|
303
|
-
const errorMessage =
|
|
304
|
-
?
|
|
305
|
-
: String(
|
|
306
|
-
this.messageManager.
|
|
396
|
+
catch (toolError) {
|
|
397
|
+
const errorMessage = toolError instanceof Error
|
|
398
|
+
? toolError.message
|
|
399
|
+
: String(toolError);
|
|
400
|
+
this.messageManager.updateToolBlock({
|
|
401
|
+
id: toolId,
|
|
402
|
+
parameters: JSON.stringify(toolArgs, null, 2),
|
|
403
|
+
result: `Tool execution failed: ${errorMessage}`,
|
|
404
|
+
success: false,
|
|
405
|
+
error: errorMessage,
|
|
406
|
+
stage: "end",
|
|
407
|
+
name: toolName,
|
|
408
|
+
compactParams,
|
|
409
|
+
});
|
|
307
410
|
}
|
|
308
411
|
});
|
|
309
412
|
// Wait for all tools to complete execution in parallel
|
|
@@ -329,66 +432,71 @@ export class AIManager {
|
|
|
329
432
|
this.messageManager.addErrorBlock(error instanceof Error ? error.message : "Unknown error occurred");
|
|
330
433
|
}
|
|
331
434
|
finally {
|
|
332
|
-
// Only execute
|
|
435
|
+
// Only execute cleanup and hooks for the initial call
|
|
333
436
|
if (recursionDepth === 0) {
|
|
334
|
-
//
|
|
437
|
+
// Save session in each recursion to ensure message persistence
|
|
438
|
+
await this.messageManager.saveSession();
|
|
439
|
+
// Set loading to false first
|
|
440
|
+
this.setIsLoading(false);
|
|
441
|
+
// Clear abort controllers
|
|
442
|
+
this.abortController = null;
|
|
443
|
+
this.toolAbortController = null;
|
|
444
|
+
// Execute Stop/SubagentStop hooks only if the operation was not aborted
|
|
335
445
|
const isCurrentlyAborted = abortController.signal.aborted || toolAbortController.signal.aborted;
|
|
336
446
|
if (!isCurrentlyAborted) {
|
|
337
447
|
const shouldContinue = await this.executeStopHooks();
|
|
338
|
-
// If Stop hooks indicate we should continue (due to blocking errors),
|
|
448
|
+
// If Stop/SubagentStop hooks indicate we should continue (due to blocking errors),
|
|
339
449
|
// restart the AI conversation cycle
|
|
340
450
|
if (shouldContinue) {
|
|
341
|
-
this.logger?.info("Stop hooks indicate issues need fixing, continuing conversation
|
|
451
|
+
this.logger?.info(`${this.subagentType ? "SubagentStop" : "Stop"} hooks indicate issues need fixing, continuing conversation...`);
|
|
342
452
|
// Restart the conversation to let AI fix the issues
|
|
343
|
-
// Use recursionDepth =
|
|
453
|
+
// Use recursionDepth = 0 to set loading false again for continuation
|
|
344
454
|
await this.sendAIMessage({
|
|
345
|
-
recursionDepth:
|
|
455
|
+
recursionDepth: 0,
|
|
346
456
|
model,
|
|
347
457
|
allowedTools,
|
|
348
458
|
});
|
|
349
459
|
}
|
|
350
460
|
}
|
|
351
|
-
// Save session after all operations (including continuation) are complete
|
|
352
|
-
await this.messageManager.saveSession();
|
|
353
|
-
// Clear abort controllers and loading state after all operations are complete
|
|
354
|
-
this.abortController = null;
|
|
355
|
-
this.toolAbortController = null;
|
|
356
|
-
// Set loading to false at the very end, after all operations including continuation
|
|
357
|
-
this.setIsLoading(false);
|
|
358
461
|
}
|
|
359
462
|
}
|
|
360
463
|
}
|
|
361
464
|
/**
|
|
362
|
-
* Execute Stop hooks when AI response cycle completes
|
|
465
|
+
* Execute Stop or SubagentStop hooks when AI response cycle completes
|
|
466
|
+
* Uses "SubagentStop" hook name when triggered by a subagent, otherwise uses "Stop"
|
|
363
467
|
* @returns Promise<boolean> - true if should continue conversation, false if should stop
|
|
364
468
|
*/
|
|
365
469
|
async executeStopHooks() {
|
|
366
470
|
if (!this.hookManager)
|
|
367
471
|
return false;
|
|
368
472
|
try {
|
|
473
|
+
// Use "SubagentStop" hook name when triggered by a subagent, otherwise use "Stop"
|
|
474
|
+
const hookName = this.subagentType ? "SubagentStop" : "Stop";
|
|
369
475
|
const context = {
|
|
370
|
-
event:
|
|
476
|
+
event: hookName,
|
|
371
477
|
projectDir: this.workdir,
|
|
372
478
|
timestamp: new Date(),
|
|
373
479
|
sessionId: this.messageManager.getSessionId(),
|
|
374
480
|
transcriptPath: this.messageManager.getTranscriptPath(),
|
|
375
481
|
cwd: this.workdir,
|
|
482
|
+
subagentType: this.subagentType, // Include subagent type in hook context
|
|
376
483
|
// Stop hooks don't need toolName, toolInput, toolResponse, or userPrompt
|
|
484
|
+
env: this.getEnvironmentVarsFn?.() || {}, // Include configuration environment variables
|
|
377
485
|
};
|
|
378
|
-
const results = await this.hookManager.executeHooks(
|
|
486
|
+
const results = await this.hookManager.executeHooks(hookName, context);
|
|
379
487
|
// Process hook results to handle exit codes and appropriate responses
|
|
380
488
|
let shouldContinue = false;
|
|
381
489
|
if (results.length > 0) {
|
|
382
|
-
const processResult = this.hookManager.processHookResults(
|
|
490
|
+
const processResult = this.hookManager.processHookResults(hookName, results, this.messageManager);
|
|
383
491
|
// If hook processing indicates we should block (exit code 2), continue conversation
|
|
384
492
|
if (processResult.shouldBlock) {
|
|
385
|
-
this.logger?.info(
|
|
493
|
+
this.logger?.info(`${hookName} hook blocked stopping with error:`, processResult.errorMessage);
|
|
386
494
|
shouldContinue = true;
|
|
387
495
|
}
|
|
388
496
|
}
|
|
389
497
|
// Log hook execution results for debugging
|
|
390
498
|
if (results.length > 0) {
|
|
391
|
-
this.logger?.debug(`Executed ${results.length}
|
|
499
|
+
this.logger?.debug(`Executed ${results.length} ${hookName} hook(s):`, results.map((r) => ({
|
|
392
500
|
success: r.success,
|
|
393
501
|
duration: r.duration,
|
|
394
502
|
exitCode: r.exitCode,
|
|
@@ -400,7 +508,7 @@ export class AIManager {
|
|
|
400
508
|
}
|
|
401
509
|
catch (error) {
|
|
402
510
|
// Hook execution errors should not interrupt the main workflow
|
|
403
|
-
this.logger?.error("Stop hook execution failed
|
|
511
|
+
this.logger?.error(`${this.subagentType ? "SubagentStop" : "Stop"} hook execution failed:`, error);
|
|
404
512
|
return false;
|
|
405
513
|
}
|
|
406
514
|
}
|
|
@@ -421,6 +529,8 @@ export class AIManager {
|
|
|
421
529
|
transcriptPath: this.messageManager.getTranscriptPath(),
|
|
422
530
|
cwd: this.workdir,
|
|
423
531
|
toolInput,
|
|
532
|
+
subagentType: this.subagentType, // Include subagent type in hook context
|
|
533
|
+
env: this.getEnvironmentVarsFn?.() || {}, // Include configuration environment variables
|
|
424
534
|
};
|
|
425
535
|
const results = await this.hookManager.executeHooks("PreToolUse", context);
|
|
426
536
|
// Process hook results to handle exit codes and determine if tool should be blocked
|
|
@@ -465,6 +575,8 @@ export class AIManager {
|
|
|
465
575
|
cwd: this.workdir,
|
|
466
576
|
toolInput,
|
|
467
577
|
toolResponse,
|
|
578
|
+
subagentType: this.subagentType, // Include subagent type in hook context
|
|
579
|
+
env: this.getEnvironmentVarsFn?.() || {}, // Include configuration environment variables
|
|
468
580
|
};
|
|
469
581
|
const results = await this.hookManager.executeHooks("PostToolUse", context);
|
|
470
582
|
// Process hook results to handle exit codes and update tool results
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backgroundBashManager.d.ts","sourceRoot":"","sources":["../../src/managers/backgroundBashManager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"backgroundBashManager.d.ts","sourceRoot":"","sources":["../../src/managers/backgroundBashManager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,MAAM,WAAW,8BAA8B;IAC7C,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,CAAC,EAAE,8BAA8B,CAAC;IAC3C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAsC;IACpD,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,4BAA4B;IAKjD,OAAO,CAAC,kBAAkB;IAInB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM;IAsErD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAIjD,YAAY,IAAI,eAAe,EAAE;IAIjC,SAAS,CACd,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,MAAM,GACd;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAiCrD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAmD9B,OAAO,IAAI,IAAI;CAUvB"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { spawn } from "child_process";
|
|
2
|
+
import { logger } from "../utils/globalLogger.js";
|
|
3
|
+
import { stripAnsiColors } from "../utils/stringUtils.js";
|
|
2
4
|
export class BackgroundBashManager {
|
|
3
5
|
constructor(options) {
|
|
4
6
|
this.shells = new Map();
|
|
@@ -41,11 +43,11 @@ export class BackgroundBashManager {
|
|
|
41
43
|
}, timeout);
|
|
42
44
|
}
|
|
43
45
|
child.stdout?.on("data", (data) => {
|
|
44
|
-
shell.stdout += data.toString();
|
|
46
|
+
shell.stdout += stripAnsiColors(data.toString());
|
|
45
47
|
this.notifyShellsChange();
|
|
46
48
|
});
|
|
47
49
|
child.stderr?.on("data", (data) => {
|
|
48
|
-
shell.stderr += data.toString();
|
|
50
|
+
shell.stderr += stripAnsiColors(data.toString());
|
|
49
51
|
this.notifyShellsChange();
|
|
50
52
|
});
|
|
51
53
|
child.on("exit", (code) => {
|
|
@@ -62,7 +64,7 @@ export class BackgroundBashManager {
|
|
|
62
64
|
clearTimeout(timeoutHandle);
|
|
63
65
|
}
|
|
64
66
|
shell.status = "completed";
|
|
65
|
-
shell.stderr += `\nProcess error: ${error.message}`;
|
|
67
|
+
shell.stderr += `\nProcess error: ${stripAnsiColors(error.message)}`;
|
|
66
68
|
shell.exitCode = 1;
|
|
67
69
|
shell.runtime = Date.now() - startTime;
|
|
68
70
|
this.notifyShellsChange();
|
|
@@ -95,8 +97,8 @@ export class BackgroundBashManager {
|
|
|
95
97
|
.filter((line) => regex.test(line))
|
|
96
98
|
.join("\n");
|
|
97
99
|
}
|
|
98
|
-
catch {
|
|
99
|
-
|
|
100
|
+
catch (error) {
|
|
101
|
+
logger.warn(`Invalid filter regex: ${filter}`, error);
|
|
100
102
|
}
|
|
101
103
|
}
|
|
102
104
|
return {
|
|
@@ -122,8 +124,8 @@ export class BackgroundBashManager {
|
|
|
122
124
|
try {
|
|
123
125
|
process.kill(-shell.process.pid, "SIGKILL");
|
|
124
126
|
}
|
|
125
|
-
catch {
|
|
126
|
-
|
|
127
|
+
catch (error) {
|
|
128
|
+
logger.error("Failed to force kill process:", error);
|
|
127
129
|
}
|
|
128
130
|
}
|
|
129
131
|
}, 1000);
|
|
@@ -147,8 +149,8 @@ export class BackgroundBashManager {
|
|
|
147
149
|
this.notifyShellsChange();
|
|
148
150
|
return true;
|
|
149
151
|
}
|
|
150
|
-
catch {
|
|
151
|
-
|
|
152
|
+
catch (directKillError) {
|
|
153
|
+
logger.error("Failed to kill child process:", directKillError);
|
|
152
154
|
return false;
|
|
153
155
|
}
|
|
154
156
|
}
|