wave-agent-sdk 0.0.7 → 0.0.8
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 +32 -20
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +202 -20
- package/dist/constants/events.d.ts +28 -0
- package/dist/constants/events.d.ts.map +1 -0
- package/dist/constants/events.js +27 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/managers/aiManager.d.ts +34 -1
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +243 -128
- package/dist/managers/backgroundBashManager.d.ts.map +1 -1
- package/dist/managers/backgroundBashManager.js +7 -6
- package/dist/managers/hookManager.d.ts +9 -4
- package/dist/managers/hookManager.d.ts.map +1 -1
- package/dist/managers/hookManager.js +62 -30
- package/dist/managers/liveConfigManager.d.ts +58 -0
- package/dist/managers/liveConfigManager.d.ts.map +1 -0
- package/dist/managers/liveConfigManager.js +160 -0
- package/dist/managers/messageManager.d.ts +38 -13
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +163 -30
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +4 -1
- package/dist/managers/subagentManager.d.ts +51 -0
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +189 -18
- package/dist/services/aiService.d.ts +13 -5
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +350 -74
- package/dist/services/configurationWatcher.d.ts +120 -0
- package/dist/services/configurationWatcher.d.ts.map +1 -0
- package/dist/services/configurationWatcher.js +439 -0
- package/dist/services/fileWatcher.d.ts +69 -0
- package/dist/services/fileWatcher.d.ts.map +1 -0
- package/dist/services/fileWatcher.js +213 -0
- package/dist/services/hook.d.ts +91 -9
- package/dist/services/hook.d.ts.map +1 -1
- package/dist/services/hook.js +393 -43
- package/dist/services/jsonlHandler.d.ts +62 -0
- package/dist/services/jsonlHandler.d.ts.map +1 -0
- package/dist/services/jsonlHandler.js +257 -0
- package/dist/services/memory.d.ts +9 -0
- package/dist/services/memory.d.ts.map +1 -1
- package/dist/services/memory.js +81 -12
- package/dist/services/memoryStore.d.ts +81 -0
- package/dist/services/memoryStore.d.ts.map +1 -0
- package/dist/services/memoryStore.js +200 -0
- package/dist/services/session.d.ts +64 -49
- package/dist/services/session.d.ts.map +1 -1
- package/dist/services/session.js +310 -132
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +5 -4
- package/dist/tools/deleteFileTool.d.ts.map +1 -1
- package/dist/tools/deleteFileTool.js +2 -1
- package/dist/tools/editTool.d.ts.map +1 -1
- package/dist/tools/editTool.js +3 -2
- package/dist/tools/multiEditTool.d.ts.map +1 -1
- package/dist/tools/multiEditTool.js +4 -3
- package/dist/tools/readTool.d.ts.map +1 -1
- package/dist/tools/readTool.js +2 -1
- package/dist/tools/writeTool.d.ts.map +1 -1
- package/dist/tools/writeTool.js +5 -6
- package/dist/types/commands.d.ts +4 -0
- package/dist/types/commands.d.ts.map +1 -1
- package/dist/types/core.d.ts +35 -0
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/environment.d.ts +42 -0
- package/dist/types/environment.d.ts.map +1 -0
- package/dist/types/environment.js +21 -0
- package/dist/types/hooks.d.ts +8 -2
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/hooks.js +8 -2
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/memoryStore.d.ts +82 -0
- package/dist/types/memoryStore.d.ts.map +1 -0
- package/dist/types/memoryStore.js +7 -0
- package/dist/types/messaging.d.ts +14 -2
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/types/session.d.ts +20 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +7 -0
- package/dist/utils/bashHistory.d.ts.map +1 -1
- package/dist/utils/bashHistory.js +27 -26
- package/dist/utils/cacheControlUtils.d.ts +121 -0
- package/dist/utils/cacheControlUtils.d.ts.map +1 -0
- package/dist/utils/cacheControlUtils.js +367 -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/configResolver.d.ts +37 -10
- package/dist/utils/configResolver.d.ts.map +1 -1
- package/dist/utils/configResolver.js +127 -23
- package/dist/utils/constants.d.ts +1 -1
- package/dist/utils/constants.js +1 -1
- package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
- package/dist/utils/convertMessagesForAPI.js +7 -5
- package/dist/utils/customCommands.d.ts.map +1 -1
- package/dist/utils/customCommands.js +66 -21
- package/dist/utils/fileUtils.d.ts +15 -0
- package/dist/utils/fileUtils.d.ts.map +1 -0
- package/dist/utils/fileUtils.js +61 -0
- package/dist/utils/globalLogger.d.ts +102 -0
- package/dist/utils/globalLogger.d.ts.map +1 -0
- package/dist/utils/globalLogger.js +136 -0
- package/dist/utils/mcpUtils.d.ts.map +1 -1
- package/dist/utils/mcpUtils.js +25 -3
- package/dist/utils/messageOperations.d.ts +20 -8
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +25 -16
- package/dist/utils/pathEncoder.d.ts +104 -0
- package/dist/utils/pathEncoder.d.ts.map +1 -0
- package/dist/utils/pathEncoder.js +272 -0
- package/dist/utils/subagentParser.d.ts.map +1 -1
- package/dist/utils/subagentParser.js +2 -1
- 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/package.json +6 -3
- package/src/agent.ts +298 -34
- package/src/constants/events.ts +38 -0
- package/src/index.ts +2 -0
- package/src/managers/aiManager.ts +323 -170
- package/src/managers/backgroundBashManager.ts +7 -6
- package/src/managers/hookManager.ts +83 -40
- package/src/managers/liveConfigManager.ts +248 -0
- package/src/managers/messageManager.ts +230 -63
- package/src/managers/slashCommandManager.ts +4 -1
- package/src/managers/subagentManager.ts +283 -21
- package/src/services/aiService.ts +474 -83
- package/src/services/configurationWatcher.ts +622 -0
- package/src/services/fileWatcher.ts +301 -0
- package/src/services/hook.ts +538 -47
- package/src/services/jsonlHandler.ts +319 -0
- package/src/services/memory.ts +92 -12
- package/src/services/memoryStore.ts +279 -0
- package/src/services/session.ts +381 -157
- package/src/tools/bashTool.ts +5 -4
- package/src/tools/deleteFileTool.ts +2 -1
- package/src/tools/editTool.ts +3 -2
- package/src/tools/multiEditTool.ts +4 -3
- package/src/tools/readTool.ts +2 -1
- package/src/tools/writeTool.ts +7 -6
- package/src/types/commands.ts +6 -0
- package/src/types/core.ts +44 -0
- package/src/types/environment.ts +60 -0
- package/src/types/hooks.ts +21 -8
- package/src/types/index.ts +2 -0
- package/src/types/memoryStore.ts +94 -0
- package/src/types/messaging.ts +14 -2
- package/src/types/session.ts +25 -0
- package/src/utils/bashHistory.ts +27 -27
- package/src/utils/cacheControlUtils.ts +540 -0
- package/src/utils/commandPathResolver.ts +189 -0
- package/src/utils/configPaths.ts +163 -0
- package/src/utils/configResolver.ts +182 -22
- package/src/utils/constants.ts +1 -1
- package/src/utils/convertMessagesForAPI.ts +7 -5
- package/src/utils/customCommands.ts +90 -22
- package/src/utils/fileUtils.ts +65 -0
- package/src/utils/globalLogger.ts +145 -0
- package/src/utils/mcpUtils.ts +34 -3
- package/src/utils/messageOperations.ts +42 -20
- package/src/utils/pathEncoder.ts +379 -0
- package/src/utils/subagentParser.ts +2 -1
- package/src/utils/tokenCalculation.ts +43 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
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,12 +16,60 @@ 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
|
|
18
20
|
this.callbacks = options.callbacks ?? {};
|
|
19
21
|
// Store resolved configuration
|
|
20
22
|
this.gatewayConfig = options.gatewayConfig;
|
|
21
23
|
this.modelConfig = options.modelConfig;
|
|
22
24
|
this.tokenLimit = options.tokenLimit;
|
|
23
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Update gateway configuration at runtime for live config reload
|
|
28
|
+
* @param newConfig - New gateway configuration
|
|
29
|
+
*/
|
|
30
|
+
updateGatewayConfig(newConfig) {
|
|
31
|
+
this.logger?.info(`Live Config: Updating AIManager gateway config - baseURL: ${newConfig.baseURL}`);
|
|
32
|
+
this.gatewayConfig = newConfig;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Update model configuration at runtime for live config reload
|
|
36
|
+
* @param newConfig - New model configuration
|
|
37
|
+
*/
|
|
38
|
+
updateModelConfig(newConfig) {
|
|
39
|
+
this.logger?.info(`Live Config: Updating AIManager model config - agent: ${newConfig.agentModel}, fast: ${newConfig.fastModel}`);
|
|
40
|
+
this.modelConfig = newConfig;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Update token limit at runtime for live config reload
|
|
44
|
+
* @param newLimit - New token limit
|
|
45
|
+
*/
|
|
46
|
+
updateTokenLimit(newLimit) {
|
|
47
|
+
this.logger?.info(`Live Config: Updating AIManager token limit: ${newLimit}`);
|
|
48
|
+
this.tokenLimit = newLimit;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Update all configurations at once for live config reload
|
|
52
|
+
* @param newGatewayConfig - New gateway configuration
|
|
53
|
+
* @param newModelConfig - New model configuration
|
|
54
|
+
* @param newTokenLimit - New token limit
|
|
55
|
+
*/
|
|
56
|
+
updateConfiguration(newGatewayConfig, newModelConfig, newTokenLimit) {
|
|
57
|
+
this.logger?.info("Live Config: Updating all AIManager configuration");
|
|
58
|
+
this.gatewayConfig = newGatewayConfig;
|
|
59
|
+
this.modelConfig = newModelConfig;
|
|
60
|
+
this.tokenLimit = newTokenLimit;
|
|
61
|
+
this.logger?.info(`Live Config: Configuration updated - model: ${newModelConfig.agentModel}, tokenLimit: ${newTokenLimit}`);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get current configuration for debugging
|
|
65
|
+
*/
|
|
66
|
+
getCurrentConfiguration() {
|
|
67
|
+
return {
|
|
68
|
+
gatewayConfig: { ...this.gatewayConfig },
|
|
69
|
+
modelConfig: { ...this.modelConfig },
|
|
70
|
+
tokenLimit: this.tokenLimit,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
24
73
|
/**
|
|
25
74
|
* Get filtered tool configuration
|
|
26
75
|
*/
|
|
@@ -73,22 +122,28 @@ export class AIManager {
|
|
|
73
122
|
catch (error) {
|
|
74
123
|
this.logger?.warn("Failed to generate compactParams", error);
|
|
75
124
|
}
|
|
76
|
-
return
|
|
125
|
+
return "";
|
|
77
126
|
}
|
|
78
127
|
// Private method to handle token statistics and message compression
|
|
79
128
|
async handleTokenUsageAndCompression(usage, abortController) {
|
|
80
129
|
if (!usage)
|
|
81
130
|
return;
|
|
82
|
-
// Update token statistics - display
|
|
83
|
-
|
|
131
|
+
// Update token statistics - display comprehensive token usage including cache tokens
|
|
132
|
+
const comprehensiveTotalTokens = calculateComprehensiveTotalTokens(usage);
|
|
133
|
+
this.messageManager.setlatestTotalTokens(comprehensiveTotalTokens);
|
|
84
134
|
// Check if token limit exceeded - use injected configuration
|
|
85
|
-
if (usage.total_tokens
|
|
135
|
+
if (usage.total_tokens +
|
|
136
|
+
(usage.cache_read_input_tokens || 0) +
|
|
137
|
+
(usage.cache_creation_input_tokens || 0) >
|
|
138
|
+
this.tokenLimit) {
|
|
86
139
|
this.logger?.debug(`Token usage exceeded ${this.tokenLimit}, compressing messages...`);
|
|
87
140
|
// Check if messages need compression
|
|
88
141
|
const { messagesToCompress, insertIndex } = getMessagesToCompress(this.messageManager.getMessages(), 7);
|
|
89
142
|
// If there are messages to compress, perform compression
|
|
90
143
|
if (messagesToCompress.length > 0) {
|
|
91
144
|
const recentChatMessages = convertMessagesForAPI(messagesToCompress);
|
|
145
|
+
// Save session before compression to preserve original messages
|
|
146
|
+
await this.messageManager.saveSession();
|
|
92
147
|
this.setIsCompressing(true);
|
|
93
148
|
try {
|
|
94
149
|
const compressionResult = await compressMessages({
|
|
@@ -97,21 +152,22 @@ export class AIManager {
|
|
|
97
152
|
messages: recentChatMessages,
|
|
98
153
|
abortSignal: abortController.signal,
|
|
99
154
|
});
|
|
100
|
-
// Execute message reconstruction and sessionId update after compression
|
|
101
|
-
this.messageManager.compressMessagesAndUpdateSession(insertIndex, compressionResult.content);
|
|
102
155
|
// Handle usage tracking for compression operations
|
|
156
|
+
let compressionUsage;
|
|
103
157
|
if (compressionResult.usage) {
|
|
104
|
-
|
|
158
|
+
compressionUsage = {
|
|
105
159
|
prompt_tokens: compressionResult.usage.prompt_tokens,
|
|
106
160
|
completion_tokens: compressionResult.usage.completion_tokens,
|
|
107
161
|
total_tokens: compressionResult.usage.total_tokens,
|
|
108
162
|
model: this.modelConfig.fastModel,
|
|
109
163
|
operation_type: "compress",
|
|
110
164
|
};
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
165
|
+
}
|
|
166
|
+
// Execute message reconstruction and sessionId update after compression
|
|
167
|
+
this.messageManager.compressMessagesAndUpdateSession(insertIndex, compressionResult.content, compressionUsage);
|
|
168
|
+
// Notify Agent to add to usage tracking
|
|
169
|
+
if (compressionUsage && this.callbacks?.onUsageAdded) {
|
|
170
|
+
this.callbacks.onUsageAdded(compressionUsage);
|
|
115
171
|
}
|
|
116
172
|
this.logger?.debug(`Successfully compressed ${messagesToCompress.length} messages and updated session`);
|
|
117
173
|
}
|
|
@@ -139,6 +195,8 @@ export class AIManager {
|
|
|
139
195
|
if (recursionDepth === 0 && this.isLoading) {
|
|
140
196
|
return;
|
|
141
197
|
}
|
|
198
|
+
// Save session in each recursion to ensure message persistence
|
|
199
|
+
await this.messageManager.saveSession();
|
|
142
200
|
// Only create new AbortControllers for the initial call (recursionDepth === 0)
|
|
143
201
|
// For recursive calls, reuse existing controllers to maintain abort signal
|
|
144
202
|
let abortController;
|
|
@@ -164,7 +222,9 @@ export class AIManager {
|
|
|
164
222
|
try {
|
|
165
223
|
// Get combined memory content
|
|
166
224
|
const combinedMemory = await memory.getCombinedMemoryContent(this.workdir);
|
|
167
|
-
//
|
|
225
|
+
// Add assistant message first (for streaming updates)
|
|
226
|
+
this.messageManager.addAssistantMessage();
|
|
227
|
+
// Call AI service with streaming callbacks
|
|
168
228
|
const result = await callAgent({
|
|
169
229
|
gatewayConfig: this.gatewayConfig,
|
|
170
230
|
modelConfig: this.modelConfig,
|
|
@@ -176,17 +236,39 @@ export class AIManager {
|
|
|
176
236
|
tools: this.getFilteredToolsConfig(allowedTools), // Pass filtered tool configuration
|
|
177
237
|
model: model, // Use passed model
|
|
178
238
|
systemPrompt: this.systemPrompt, // Pass custom system prompt
|
|
239
|
+
// Streaming callbacks
|
|
240
|
+
onContentUpdate: (content) => {
|
|
241
|
+
this.messageManager.updateCurrentMessageContent(content);
|
|
242
|
+
},
|
|
243
|
+
onToolUpdate: (toolCall) => {
|
|
244
|
+
// Use parametersChunk as compact param for better performance
|
|
245
|
+
// No need to extract params or generate compact params during streaming
|
|
246
|
+
this.logger?.debug("Tool streaming update:", toolCall);
|
|
247
|
+
// Update tool block with streaming parameters using parametersChunk as compact param
|
|
248
|
+
this.messageManager.updateToolBlock({
|
|
249
|
+
id: toolCall.id,
|
|
250
|
+
name: toolCall.name,
|
|
251
|
+
parameters: toolCall.parameters,
|
|
252
|
+
parametersChunk: toolCall.parametersChunk,
|
|
253
|
+
compactParams: toolCall.parameters?.split("\n").pop()?.slice(-30),
|
|
254
|
+
stage: toolCall.stage || "streaming", // Default to streaming if stage not provided
|
|
255
|
+
});
|
|
256
|
+
},
|
|
179
257
|
});
|
|
180
|
-
//
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
258
|
+
// Log finish reason and response headers if available
|
|
259
|
+
if (result.finish_reason) {
|
|
260
|
+
this.logger?.debug(`AI response finished with reason: ${result.finish_reason}`);
|
|
261
|
+
}
|
|
262
|
+
if (result.response_headers &&
|
|
263
|
+
Object.keys(result.response_headers).length > 0) {
|
|
264
|
+
this.logger?.debug("AI response headers:", result.response_headers);
|
|
265
|
+
}
|
|
266
|
+
if (result.metadata && Object.keys(result.metadata).length > 0) {
|
|
267
|
+
this.messageManager.mergeAssistantMetadata(result.metadata);
|
|
268
|
+
}
|
|
269
|
+
// Handle result content from non-streaming mode
|
|
270
|
+
if (result.content) {
|
|
271
|
+
this.messageManager.updateCurrentMessageContent(result.content);
|
|
190
272
|
}
|
|
191
273
|
// Handle usage tracking for agent operations
|
|
192
274
|
let usage;
|
|
@@ -197,113 +279,140 @@ export class AIManager {
|
|
|
197
279
|
total_tokens: result.usage.total_tokens,
|
|
198
280
|
model: model || this.modelConfig.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
|
-
|
|
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 {
|
|
334
|
+
try {
|
|
335
|
+
toolArgs = JSON.parse(argsString);
|
|
336
|
+
}
|
|
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);
|
|
342
|
+
this.messageManager.updateToolBlock({
|
|
343
|
+
id: toolId,
|
|
344
|
+
parameters: argsString,
|
|
345
|
+
result: errorMessage,
|
|
346
|
+
success: false,
|
|
347
|
+
error: fullErrorMessage,
|
|
348
|
+
stage: "end",
|
|
349
|
+
name: toolName,
|
|
350
|
+
compactParams: "",
|
|
351
|
+
});
|
|
218
352
|
return;
|
|
219
353
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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
|
|
226
372
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
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
|
+
// If tool returns diff information, add diff block
|
|
394
|
+
if (toolResult.success &&
|
|
395
|
+
toolResult.diffResult &&
|
|
396
|
+
toolResult.filePath) {
|
|
397
|
+
this.messageManager.addDiffBlock(toolResult.filePath, toolResult.diffResult);
|
|
237
398
|
}
|
|
238
|
-
//
|
|
239
|
-
|
|
240
|
-
|
|
399
|
+
// Execute PostToolUse hooks after successful tool completion
|
|
400
|
+
await this.executePostToolUseHooks(toolId, toolName, toolArgs, toolResult);
|
|
401
|
+
}
|
|
402
|
+
catch (toolError) {
|
|
403
|
+
const errorMessage = toolError instanceof Error
|
|
404
|
+
? toolError.message
|
|
405
|
+
: String(toolError);
|
|
241
406
|
this.messageManager.updateToolBlock({
|
|
242
407
|
id: toolId,
|
|
243
408
|
parameters: JSON.stringify(toolArgs, null, 2),
|
|
244
|
-
|
|
409
|
+
result: `Tool execution failed: ${errorMessage}`,
|
|
410
|
+
success: false,
|
|
411
|
+
error: errorMessage,
|
|
412
|
+
stage: "end",
|
|
245
413
|
name: toolName,
|
|
246
414
|
compactParams,
|
|
247
415
|
});
|
|
248
|
-
try {
|
|
249
|
-
// Execute PreToolUse hooks before tool execution
|
|
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);
|
|
285
|
-
}
|
|
286
|
-
catch (toolError) {
|
|
287
|
-
const errorMessage = toolError instanceof Error
|
|
288
|
-
? toolError.message
|
|
289
|
-
: String(toolError);
|
|
290
|
-
this.messageManager.updateToolBlock({
|
|
291
|
-
id: toolId,
|
|
292
|
-
parameters: JSON.stringify(toolArgs, null, 2),
|
|
293
|
-
result: `Tool execution failed: ${errorMessage}`,
|
|
294
|
-
success: false,
|
|
295
|
-
error: errorMessage,
|
|
296
|
-
isRunning: false,
|
|
297
|
-
name: toolName,
|
|
298
|
-
compactParams,
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
catch (parseError) {
|
|
303
|
-
const errorMessage = parseError instanceof Error
|
|
304
|
-
? parseError.message
|
|
305
|
-
: String(parseError);
|
|
306
|
-
this.messageManager.addErrorBlock(`Failed to parse tool arguments for ${functionToolCall.function?.name}: ${errorMessage}`);
|
|
307
416
|
}
|
|
308
417
|
});
|
|
309
418
|
// Wait for all tools to complete execution in parallel
|
|
@@ -329,66 +438,70 @@ export class AIManager {
|
|
|
329
438
|
this.messageManager.addErrorBlock(error instanceof Error ? error.message : "Unknown error occurred");
|
|
330
439
|
}
|
|
331
440
|
finally {
|
|
332
|
-
// Only execute
|
|
441
|
+
// Only execute cleanup and hooks for the initial call
|
|
333
442
|
if (recursionDepth === 0) {
|
|
334
|
-
//
|
|
443
|
+
// Save session in each recursion to ensure message persistence
|
|
444
|
+
await this.messageManager.saveSession();
|
|
445
|
+
// Set loading to false first
|
|
446
|
+
this.setIsLoading(false);
|
|
447
|
+
// Clear abort controllers
|
|
448
|
+
this.abortController = null;
|
|
449
|
+
this.toolAbortController = null;
|
|
450
|
+
// Execute Stop/SubagentStop hooks only if the operation was not aborted
|
|
335
451
|
const isCurrentlyAborted = abortController.signal.aborted || toolAbortController.signal.aborted;
|
|
336
452
|
if (!isCurrentlyAborted) {
|
|
337
453
|
const shouldContinue = await this.executeStopHooks();
|
|
338
|
-
// If Stop hooks indicate we should continue (due to blocking errors),
|
|
454
|
+
// If Stop/SubagentStop hooks indicate we should continue (due to blocking errors),
|
|
339
455
|
// restart the AI conversation cycle
|
|
340
456
|
if (shouldContinue) {
|
|
341
|
-
this.logger?.info("Stop hooks indicate issues need fixing, continuing conversation
|
|
457
|
+
this.logger?.info(`${this.subagentType ? "SubagentStop" : "Stop"} hooks indicate issues need fixing, continuing conversation...`);
|
|
342
458
|
// Restart the conversation to let AI fix the issues
|
|
343
|
-
// Use recursionDepth =
|
|
459
|
+
// Use recursionDepth = 0 to set loading false again for continuation
|
|
344
460
|
await this.sendAIMessage({
|
|
345
|
-
recursionDepth:
|
|
461
|
+
recursionDepth: 0,
|
|
346
462
|
model,
|
|
347
463
|
allowedTools,
|
|
348
464
|
});
|
|
349
465
|
}
|
|
350
466
|
}
|
|
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
467
|
}
|
|
359
468
|
}
|
|
360
469
|
}
|
|
361
470
|
/**
|
|
362
|
-
* Execute Stop hooks when AI response cycle completes
|
|
471
|
+
* Execute Stop or SubagentStop hooks when AI response cycle completes
|
|
472
|
+
* Uses "SubagentStop" hook name when triggered by a subagent, otherwise uses "Stop"
|
|
363
473
|
* @returns Promise<boolean> - true if should continue conversation, false if should stop
|
|
364
474
|
*/
|
|
365
475
|
async executeStopHooks() {
|
|
366
476
|
if (!this.hookManager)
|
|
367
477
|
return false;
|
|
368
478
|
try {
|
|
479
|
+
// Use "SubagentStop" hook name when triggered by a subagent, otherwise use "Stop"
|
|
480
|
+
const hookName = this.subagentType ? "SubagentStop" : "Stop";
|
|
369
481
|
const context = {
|
|
370
|
-
event:
|
|
482
|
+
event: hookName,
|
|
371
483
|
projectDir: this.workdir,
|
|
372
484
|
timestamp: new Date(),
|
|
373
485
|
sessionId: this.messageManager.getSessionId(),
|
|
374
486
|
transcriptPath: this.messageManager.getTranscriptPath(),
|
|
375
487
|
cwd: this.workdir,
|
|
488
|
+
subagentType: this.subagentType, // Include subagent type in hook context
|
|
376
489
|
// Stop hooks don't need toolName, toolInput, toolResponse, or userPrompt
|
|
377
490
|
};
|
|
378
|
-
const results = await this.hookManager.executeHooks(
|
|
491
|
+
const results = await this.hookManager.executeHooks(hookName, context);
|
|
379
492
|
// Process hook results to handle exit codes and appropriate responses
|
|
380
493
|
let shouldContinue = false;
|
|
381
494
|
if (results.length > 0) {
|
|
382
|
-
const processResult = this.hookManager.processHookResults(
|
|
495
|
+
const processResult = this.hookManager.processHookResults(hookName, results, this.messageManager);
|
|
383
496
|
// If hook processing indicates we should block (exit code 2), continue conversation
|
|
384
497
|
if (processResult.shouldBlock) {
|
|
385
|
-
this.logger?.info(
|
|
498
|
+
this.logger?.info(`${hookName} hook blocked stopping with error:`, processResult.errorMessage);
|
|
386
499
|
shouldContinue = true;
|
|
387
500
|
}
|
|
388
501
|
}
|
|
389
502
|
// Log hook execution results for debugging
|
|
390
503
|
if (results.length > 0) {
|
|
391
|
-
this.logger?.debug(`Executed ${results.length}
|
|
504
|
+
this.logger?.debug(`Executed ${results.length} ${hookName} hook(s):`, results.map((r) => ({
|
|
392
505
|
success: r.success,
|
|
393
506
|
duration: r.duration,
|
|
394
507
|
exitCode: r.exitCode,
|
|
@@ -400,7 +513,7 @@ export class AIManager {
|
|
|
400
513
|
}
|
|
401
514
|
catch (error) {
|
|
402
515
|
// Hook execution errors should not interrupt the main workflow
|
|
403
|
-
this.logger?.error("Stop hook execution failed
|
|
516
|
+
this.logger?.error(`${this.subagentType ? "SubagentStop" : "Stop"} hook execution failed:`, error);
|
|
404
517
|
return false;
|
|
405
518
|
}
|
|
406
519
|
}
|
|
@@ -421,6 +534,7 @@ export class AIManager {
|
|
|
421
534
|
transcriptPath: this.messageManager.getTranscriptPath(),
|
|
422
535
|
cwd: this.workdir,
|
|
423
536
|
toolInput,
|
|
537
|
+
subagentType: this.subagentType, // Include subagent type in hook context
|
|
424
538
|
};
|
|
425
539
|
const results = await this.hookManager.executeHooks("PreToolUse", context);
|
|
426
540
|
// Process hook results to handle exit codes and determine if tool should be blocked
|
|
@@ -465,6 +579,7 @@ export class AIManager {
|
|
|
465
579
|
cwd: this.workdir,
|
|
466
580
|
toolInput,
|
|
467
581
|
toolResponse,
|
|
582
|
+
subagentType: this.subagentType, // Include subagent type in hook context
|
|
468
583
|
};
|
|
469
584
|
const results = await this.hookManager.executeHooks("PostToolUse", context);
|
|
470
585
|
// 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":"AAEA,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,5 @@
|
|
|
1
1
|
import { spawn } from "child_process";
|
|
2
|
+
import { logger } from "../utils/globalLogger.js";
|
|
2
3
|
export class BackgroundBashManager {
|
|
3
4
|
constructor(options) {
|
|
4
5
|
this.shells = new Map();
|
|
@@ -95,8 +96,8 @@ export class BackgroundBashManager {
|
|
|
95
96
|
.filter((line) => regex.test(line))
|
|
96
97
|
.join("\n");
|
|
97
98
|
}
|
|
98
|
-
catch {
|
|
99
|
-
|
|
99
|
+
catch (error) {
|
|
100
|
+
logger.warn(`Invalid filter regex: ${filter}`, error);
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
return {
|
|
@@ -122,8 +123,8 @@ export class BackgroundBashManager {
|
|
|
122
123
|
try {
|
|
123
124
|
process.kill(-shell.process.pid, "SIGKILL");
|
|
124
125
|
}
|
|
125
|
-
catch {
|
|
126
|
-
|
|
126
|
+
catch (error) {
|
|
127
|
+
logger.error("Failed to force kill process:", error);
|
|
127
128
|
}
|
|
128
129
|
}
|
|
129
130
|
}, 1000);
|
|
@@ -147,8 +148,8 @@ export class BackgroundBashManager {
|
|
|
147
148
|
this.notifyShellsChange();
|
|
148
149
|
return true;
|
|
149
150
|
}
|
|
150
|
-
catch {
|
|
151
|
-
|
|
151
|
+
catch (directKillError) {
|
|
152
|
+
logger.error("Failed to kill child process:", directKillError);
|
|
152
153
|
return false;
|
|
153
154
|
}
|
|
154
155
|
}
|
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
* Central orchestrator for the hooks system. Handles configuration loading,
|
|
5
5
|
* validation, and hook execution across all supported events.
|
|
6
6
|
*/
|
|
7
|
-
import { type HookEvent, type
|
|
7
|
+
import { type HookEvent, type WaveConfiguration, type PartialHookConfiguration, type HookExecutionContext, type ExtendedHookExecutionContext, type HookExecutionResult, type ValidationResult } from "../types/hooks.js";
|
|
8
8
|
import { HookMatcher } from "../utils/hookMatcher.js";
|
|
9
9
|
import type { Logger } from "../types/index.js";
|
|
10
10
|
import type { MessageManager } from "./messageManager.js";
|
|
11
11
|
export declare class HookManager {
|
|
12
12
|
private configuration;
|
|
13
|
+
private environmentVars;
|
|
13
14
|
private readonly matcher;
|
|
14
15
|
private readonly logger?;
|
|
15
16
|
private readonly workdir;
|
|
@@ -21,7 +22,7 @@ export declare class HookManager {
|
|
|
21
22
|
loadConfiguration(userHooks?: PartialHookConfiguration, projectHooks?: PartialHookConfiguration): void;
|
|
22
23
|
/**
|
|
23
24
|
* Load configuration from filesystem settings
|
|
24
|
-
* Automatically loads and merges user and project hooks
|
|
25
|
+
* Automatically loads and merges user and project Wave configuration (hooks + environment)
|
|
25
26
|
*/
|
|
26
27
|
loadConfigurationFromSettings(): void;
|
|
27
28
|
/**
|
|
@@ -53,9 +54,9 @@ export declare class HookManager {
|
|
|
53
54
|
*/
|
|
54
55
|
hasHooks(event: HookEvent, toolName?: string): boolean;
|
|
55
56
|
/**
|
|
56
|
-
* Validate
|
|
57
|
+
* Validate Wave configuration structure and content
|
|
57
58
|
*/
|
|
58
|
-
validateConfiguration(config:
|
|
59
|
+
validateConfiguration(config: WaveConfiguration): ValidationResult;
|
|
59
60
|
/**
|
|
60
61
|
* Validate partial hook configuration structure and content
|
|
61
62
|
*/
|
|
@@ -64,6 +65,10 @@ export declare class HookManager {
|
|
|
64
65
|
* Get current configuration
|
|
65
66
|
*/
|
|
66
67
|
getConfiguration(): PartialHookConfiguration | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Get current environment variables
|
|
70
|
+
*/
|
|
71
|
+
getEnvironmentVars(): Record<string, string> | undefined;
|
|
67
72
|
/**
|
|
68
73
|
* Clear current configuration
|
|
69
74
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hookManager.d.ts","sourceRoot":"","sources":["../../src/managers/hookManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,KAAK,SAAS,EAEd,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EAItB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,qBAAa,WAAW;IACtB,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAG/B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,WAA+B,EACxC,MAAM,CAAC,EAAE,MAAM;IAOjB;;;OAGG;IACH,iBAAiB,CACf,SAAS,CAAC,EAAE,wBAAwB,EACpC,YAAY,CAAC,EAAE,wBAAwB,GACtC,IAAI;IAyBP;;;OAGG;IACH,6BAA6B,IAAI,IAAI;
|
|
1
|
+
{"version":3,"file":"hookManager.d.ts","sourceRoot":"","sources":["../../src/managers/hookManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,KAAK,SAAS,EAEd,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EAItB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,qBAAa,WAAW;IACtB,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAG/B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,WAA+B,EACxC,MAAM,CAAC,EAAE,MAAM;IAOjB;;;OAGG;IACH,iBAAiB,CACf,SAAS,CAAC,EAAE,wBAAwB,EACpC,YAAY,CAAC,EAAE,wBAAwB,GACtC,IAAI;IAyBP;;;OAGG;IACH,6BAA6B,IAAI,IAAI;IA6CrC;;OAEG;IACG,YAAY,CAChB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,GAC3D,OAAO,CAAC,mBAAmB,EAAE,CAAC;IA0HjC;;;OAGG;IACH,kBAAkB,CAChB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,mBAAmB,EAAE,EAC9B,cAAc,CAAC,EAAE,cAAc,EAC/B,MAAM,CAAC,EAAE,MAAM,EACf,cAAc,CAAC,EAAE,MAAM,GACtB;QACD,WAAW,EAAE,OAAO,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;IAuCD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAezB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAyD3B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAQ9B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO;IAWtD;;OAEG;IACH,qBAAqB,CAAC,MAAM,EAAE,iBAAiB,GAAG,gBAAgB;IA8DlE;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAyCpC;;OAEG;IACH,gBAAgB,IAAI,wBAAwB,GAAG,SAAS;IAOxD;;OAEG;IACH,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS;IAOxD;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAI1B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAmDhC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA8BhC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAa/B;;OAEG;IACH,OAAO,CAAC,aAAa;IA4BrB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAqC3B;;OAEG;IACH,qBAAqB,IAAI;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;KAC3C;CA6CF"}
|