@loxia-labs/loxia-autopilot-one 1.0.1 → 1.0.4
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/README.md +44 -54
- package/bin/cli.js +1 -115
- package/bin/loxia-terminal-v2.js +3 -0
- package/bin/loxia-terminal.js +3 -0
- package/bin/start-with-terminal.js +3 -0
- package/package.json +15 -15
- package/scripts/install-scanners.js +1 -235
- package/src/analyzers/CSSAnalyzer.js +1 -297
- package/src/analyzers/ConfigValidator.js +1 -690
- package/src/analyzers/ESLintAnalyzer.js +1 -320
- package/src/analyzers/JavaScriptAnalyzer.js +1 -261
- package/src/analyzers/PrettierFormatter.js +1 -247
- package/src/analyzers/PythonAnalyzer.js +1 -266
- package/src/analyzers/SecurityAnalyzer.js +1 -729
- package/src/analyzers/TypeScriptAnalyzer.js +1 -247
- package/src/analyzers/codeCloneDetector/analyzer.js +1 -344
- package/src/analyzers/codeCloneDetector/detector.js +1 -203
- package/src/analyzers/codeCloneDetector/index.js +1 -160
- package/src/analyzers/codeCloneDetector/parser.js +1 -199
- package/src/analyzers/codeCloneDetector/reporter.js +1 -148
- package/src/analyzers/codeCloneDetector/scanner.js +1 -59
- package/src/core/agentPool.js +1 -1474
- package/src/core/agentScheduler.js +1 -2147
- package/src/core/contextManager.js +1 -709
- package/src/core/messageProcessor.js +1 -732
- package/src/core/orchestrator.js +1 -548
- package/src/core/stateManager.js +1 -877
- package/src/index.js +1 -631
- package/src/interfaces/cli.js +1 -549
- package/src/interfaces/terminal/__tests__/smoke/advancedFeatures.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agentControl.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agents.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/components.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/connection.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/imports.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/messages.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/tools.test.js +1 -0
- package/src/interfaces/terminal/api/apiClient.js +1 -0
- package/src/interfaces/terminal/api/messageRouter.js +1 -0
- package/src/interfaces/terminal/api/session.js +1 -0
- package/src/interfaces/terminal/api/websocket.js +1 -0
- package/src/interfaces/terminal/components/AgentCreator.js +1 -0
- package/src/interfaces/terminal/components/AgentEditor.js +1 -0
- package/src/interfaces/terminal/components/AgentSwitcher.js +1 -0
- package/src/interfaces/terminal/components/ErrorBoundary.js +1 -0
- package/src/interfaces/terminal/components/ErrorPanel.js +1 -0
- package/src/interfaces/terminal/components/Header.js +1 -0
- package/src/interfaces/terminal/components/HelpPanel.js +1 -0
- package/src/interfaces/terminal/components/InputBox.js +1 -0
- package/src/interfaces/terminal/components/Layout.js +1 -0
- package/src/interfaces/terminal/components/LoadingSpinner.js +1 -0
- package/src/interfaces/terminal/components/MessageList.js +1 -0
- package/src/interfaces/terminal/components/MultilineTextInput.js +1 -0
- package/src/interfaces/terminal/components/SearchPanel.js +1 -0
- package/src/interfaces/terminal/components/SettingsPanel.js +1 -0
- package/src/interfaces/terminal/components/StatusBar.js +1 -0
- package/src/interfaces/terminal/components/TextInput.js +1 -0
- package/src/interfaces/terminal/config/agentEditorConstants.js +1 -0
- package/src/interfaces/terminal/config/constants.js +1 -0
- package/src/interfaces/terminal/index.js +1 -0
- package/src/interfaces/terminal/state/useAgentControl.js +1 -0
- package/src/interfaces/terminal/state/useAgents.js +1 -0
- package/src/interfaces/terminal/state/useConnection.js +1 -0
- package/src/interfaces/terminal/state/useMessages.js +1 -0
- package/src/interfaces/terminal/state/useTools.js +1 -0
- package/src/interfaces/terminal/utils/debugLogger.js +1 -0
- package/src/interfaces/terminal/utils/settingsStorage.js +1 -0
- package/src/interfaces/terminal/utils/theme.js +1 -0
- package/src/interfaces/webServer.js +1 -2162
- package/src/modules/fileExplorer/controller.js +1 -280
- package/src/modules/fileExplorer/index.js +1 -37
- package/src/modules/fileExplorer/middleware.js +1 -92
- package/src/modules/fileExplorer/routes.js +1 -125
- package/src/modules/fileExplorer/types.js +1 -44
- package/src/services/aiService.js +1 -1232
- package/src/services/apiKeyManager.js +1 -164
- package/src/services/benchmarkService.js +1 -366
- package/src/services/budgetService.js +1 -539
- package/src/services/contextInjectionService.js +1 -247
- package/src/services/conversationCompactionService.js +1 -637
- package/src/services/errorHandler.js +1 -810
- package/src/services/fileAttachmentService.js +1 -544
- package/src/services/modelRouterService.js +1 -366
- package/src/services/modelsService.js +1 -322
- package/src/services/qualityInspector.js +1 -796
- package/src/services/tokenCountingService.js +1 -536
- package/src/tools/agentCommunicationTool.js +1 -1344
- package/src/tools/agentDelayTool.js +1 -485
- package/src/tools/asyncToolManager.js +1 -604
- package/src/tools/baseTool.js +1 -800
- package/src/tools/browserTool.js +1 -920
- package/src/tools/cloneDetectionTool.js +1 -621
- package/src/tools/dependencyResolverTool.js +1 -1215
- package/src/tools/fileContentReplaceTool.js +1 -875
- package/src/tools/fileSystemTool.js +1 -1107
- package/src/tools/fileTreeTool.js +1 -853
- package/src/tools/imageTool.js +1 -901
- package/src/tools/importAnalyzerTool.js +1 -1060
- package/src/tools/jobDoneTool.js +1 -248
- package/src/tools/seekTool.js +1 -956
- package/src/tools/staticAnalysisTool.js +1 -1778
- package/src/tools/taskManagerTool.js +1 -2873
- package/src/tools/terminalTool.js +1 -2304
- package/src/tools/webTool.js +1 -1430
- package/src/types/agent.js +1 -519
- package/src/types/contextReference.js +1 -972
- package/src/types/conversation.js +1 -730
- package/src/types/toolCommand.js +1 -747
- package/src/utilities/attachmentValidator.js +1 -292
- package/src/utilities/configManager.js +1 -582
- package/src/utilities/constants.js +1 -722
- package/src/utilities/directoryAccessManager.js +1 -535
- package/src/utilities/fileProcessor.js +1 -307
- package/src/utilities/logger.js +1 -436
- package/src/utilities/tagParser.js +1 -1246
- package/src/utilities/toolConstants.js +1 -317
- package/web-ui/build/index.html +2 -2
- package/web-ui/build/static/{index-Dy2bYbOa.css → index-CClD1090.css} +1 -1
- package/web-ui/build/static/{index-CjkkcnFA.js → index-lCBai6dX.js} +66 -67
|
@@ -1,604 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AsyncToolManager - Manage long-running tool operations and status monitoring
|
|
3
|
-
*
|
|
4
|
-
* Purpose:
|
|
5
|
-
* - Track async tool operations across the system
|
|
6
|
-
* - Provide status monitoring and updates
|
|
7
|
-
* - Handle operation timeouts and cleanup
|
|
8
|
-
* - Coordinate between tools and message processor
|
|
9
|
-
* - Enable operation cancellation and recovery
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import EventEmitter from 'events';
|
|
13
|
-
import {
|
|
14
|
-
TOOL_STATUS,
|
|
15
|
-
SYSTEM_DEFAULTS
|
|
16
|
-
} from '../utilities/constants.js';
|
|
17
|
-
|
|
18
|
-
class AsyncToolManager extends EventEmitter {
|
|
19
|
-
constructor(config = {}, logger = null) {
|
|
20
|
-
super();
|
|
21
|
-
|
|
22
|
-
this.config = config;
|
|
23
|
-
this.logger = logger;
|
|
24
|
-
|
|
25
|
-
// Active operations tracking
|
|
26
|
-
this.operations = new Map();
|
|
27
|
-
|
|
28
|
-
// Operation history for debugging
|
|
29
|
-
this.operationHistory = [];
|
|
30
|
-
|
|
31
|
-
// Configuration
|
|
32
|
-
this.maxConcurrentOperations = config.maxConcurrentOperations || 10;
|
|
33
|
-
this.defaultTimeout = config.defaultTimeout || 300000; // 5 minutes
|
|
34
|
-
this.cleanupInterval = config.cleanupInterval || 60000; // 1 minute
|
|
35
|
-
this.maxHistorySize = config.maxHistorySize || 1000;
|
|
36
|
-
|
|
37
|
-
// Status monitoring
|
|
38
|
-
this.monitoringInterval = null;
|
|
39
|
-
this.isShuttingDown = false;
|
|
40
|
-
|
|
41
|
-
// Start monitoring
|
|
42
|
-
this.startMonitoring();
|
|
43
|
-
|
|
44
|
-
// Bind event handlers
|
|
45
|
-
this.on('operation:started', this.handleOperationStarted.bind(this));
|
|
46
|
-
this.on('operation:completed', this.handleOperationCompleted.bind(this));
|
|
47
|
-
this.on('operation:failed', this.handleOperationFailed.bind(this));
|
|
48
|
-
this.on('operation:timeout', this.handleOperationTimeout.bind(this));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Start a new async operation
|
|
53
|
-
* @param {string} toolId - Tool identifier
|
|
54
|
-
* @param {string} agentId - Agent identifier
|
|
55
|
-
* @param {Object} parameters - Operation parameters
|
|
56
|
-
* @param {Object} context - Execution context
|
|
57
|
-
* @returns {Promise<string>} Operation ID
|
|
58
|
-
*/
|
|
59
|
-
async startOperation(toolId, agentId, parameters, context = {}) {
|
|
60
|
-
if (this.operations.size >= this.maxConcurrentOperations) {
|
|
61
|
-
throw new Error(`Maximum concurrent operations reached (${this.maxConcurrentOperations})`);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const operationId = this.generateOperationId();
|
|
65
|
-
const operation = {
|
|
66
|
-
id: operationId,
|
|
67
|
-
toolId,
|
|
68
|
-
agentId,
|
|
69
|
-
parameters,
|
|
70
|
-
context,
|
|
71
|
-
status: TOOL_STATUS.PENDING,
|
|
72
|
-
createdAt: new Date().toISOString(),
|
|
73
|
-
startedAt: null,
|
|
74
|
-
completedAt: null,
|
|
75
|
-
timeout: context.timeout || this.defaultTimeout,
|
|
76
|
-
result: null,
|
|
77
|
-
error: null,
|
|
78
|
-
progress: null,
|
|
79
|
-
retryCount: 0,
|
|
80
|
-
maxRetries: context.maxRetries || 0
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
this.operations.set(operationId, operation);
|
|
84
|
-
|
|
85
|
-
this.logger?.info(`Async operation started: ${operationId}`, {
|
|
86
|
-
toolId,
|
|
87
|
-
agentId,
|
|
88
|
-
parametersCount: Object.keys(parameters).length,
|
|
89
|
-
timeout: operation.timeout
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
// Set timeout
|
|
93
|
-
this.setOperationTimeout(operationId);
|
|
94
|
-
|
|
95
|
-
// Emit event
|
|
96
|
-
this.emit('operation:started', operation);
|
|
97
|
-
|
|
98
|
-
return operationId;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Update operation status
|
|
103
|
-
* @param {string} operationId - Operation identifier
|
|
104
|
-
* @param {string} status - New status
|
|
105
|
-
* @param {Object} data - Additional data (result, error, progress)
|
|
106
|
-
* @returns {boolean} Success status
|
|
107
|
-
*/
|
|
108
|
-
updateOperation(operationId, status, data = {}) {
|
|
109
|
-
const operation = this.operations.get(operationId);
|
|
110
|
-
if (!operation) {
|
|
111
|
-
this.logger?.warn(`Attempted to update unknown operation: ${operationId}`);
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const previousStatus = operation.status;
|
|
116
|
-
operation.status = status;
|
|
117
|
-
|
|
118
|
-
// Update timestamps
|
|
119
|
-
if (status === TOOL_STATUS.EXECUTING && !operation.startedAt) {
|
|
120
|
-
operation.startedAt = new Date().toISOString();
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (status === TOOL_STATUS.COMPLETED || status === TOOL_STATUS.FAILED) {
|
|
124
|
-
operation.completedAt = new Date().toISOString();
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Update data
|
|
128
|
-
if (data.result !== undefined) operation.result = data.result;
|
|
129
|
-
if (data.error !== undefined) operation.error = data.error;
|
|
130
|
-
if (data.progress !== undefined) operation.progress = data.progress;
|
|
131
|
-
|
|
132
|
-
this.logger?.debug(`Operation status updated: ${operationId}`, {
|
|
133
|
-
previousStatus,
|
|
134
|
-
newStatus: status,
|
|
135
|
-
hasResult: !!data.result,
|
|
136
|
-
hasError: !!data.error,
|
|
137
|
-
progress: data.progress
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
// Emit appropriate events
|
|
141
|
-
switch (status) {
|
|
142
|
-
case TOOL_STATUS.COMPLETED:
|
|
143
|
-
this.emit('operation:completed', operation);
|
|
144
|
-
break;
|
|
145
|
-
case TOOL_STATUS.FAILED:
|
|
146
|
-
this.emit('operation:failed', operation);
|
|
147
|
-
break;
|
|
148
|
-
case TOOL_STATUS.EXECUTING:
|
|
149
|
-
this.emit('operation:progress', operation);
|
|
150
|
-
break;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return true;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Get operation status
|
|
158
|
-
* @param {string} operationId - Operation identifier
|
|
159
|
-
* @returns {Object|null} Operation details or null if not found
|
|
160
|
-
*/
|
|
161
|
-
getOperation(operationId) {
|
|
162
|
-
const operation = this.operations.get(operationId);
|
|
163
|
-
if (!operation) return null;
|
|
164
|
-
|
|
165
|
-
return {
|
|
166
|
-
id: operation.id,
|
|
167
|
-
toolId: operation.toolId,
|
|
168
|
-
agentId: operation.agentId,
|
|
169
|
-
status: operation.status,
|
|
170
|
-
createdAt: operation.createdAt,
|
|
171
|
-
startedAt: operation.startedAt,
|
|
172
|
-
completedAt: operation.completedAt,
|
|
173
|
-
result: operation.result,
|
|
174
|
-
error: operation.error,
|
|
175
|
-
progress: operation.progress,
|
|
176
|
-
retryCount: operation.retryCount,
|
|
177
|
-
executionTime: this.calculateExecutionTime(operation)
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Get all operations for an agent
|
|
183
|
-
* @param {string} agentId - Agent identifier
|
|
184
|
-
* @returns {Array<Object>} Array of operation details
|
|
185
|
-
*/
|
|
186
|
-
getAgentOperations(agentId) {
|
|
187
|
-
const operations = [];
|
|
188
|
-
|
|
189
|
-
for (const operation of this.operations.values()) {
|
|
190
|
-
if (operation.agentId === agentId) {
|
|
191
|
-
operations.push(this.getOperation(operation.id));
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return operations.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Cancel an operation
|
|
200
|
-
* @param {string} operationId - Operation identifier
|
|
201
|
-
* @param {string} reason - Cancellation reason
|
|
202
|
-
* @returns {boolean} Success status
|
|
203
|
-
*/
|
|
204
|
-
async cancelOperation(operationId, reason = 'Operation cancelled') {
|
|
205
|
-
const operation = this.operations.get(operationId);
|
|
206
|
-
if (!operation) return false;
|
|
207
|
-
|
|
208
|
-
if (operation.status === TOOL_STATUS.COMPLETED || operation.status === TOOL_STATUS.FAILED) {
|
|
209
|
-
this.logger?.warn(`Cannot cancel completed/failed operation: ${operationId}`);
|
|
210
|
-
return false;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// Update status
|
|
214
|
-
this.updateOperation(operationId, TOOL_STATUS.CANCELLED, {
|
|
215
|
-
error: reason
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
// Clear timeout
|
|
219
|
-
this.clearOperationTimeout(operationId);
|
|
220
|
-
|
|
221
|
-
// Emit cancellation event
|
|
222
|
-
this.emit('operation:cancelled', operation);
|
|
223
|
-
|
|
224
|
-
// Move to history and cleanup
|
|
225
|
-
await this.cleanupOperation(operationId);
|
|
226
|
-
|
|
227
|
-
this.logger?.info(`Operation cancelled: ${operationId}`, { reason });
|
|
228
|
-
|
|
229
|
-
return true;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Retry a failed operation
|
|
234
|
-
* @param {string} operationId - Operation identifier
|
|
235
|
-
* @returns {Promise<boolean>} Success status
|
|
236
|
-
*/
|
|
237
|
-
async retryOperation(operationId) {
|
|
238
|
-
const operation = this.operations.get(operationId);
|
|
239
|
-
if (!operation) return false;
|
|
240
|
-
|
|
241
|
-
if (operation.status !== TOOL_STATUS.FAILED) {
|
|
242
|
-
this.logger?.warn(`Cannot retry non-failed operation: ${operationId}`);
|
|
243
|
-
return false;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
if (operation.retryCount >= operation.maxRetries) {
|
|
247
|
-
this.logger?.warn(`Maximum retries exceeded for operation: ${operationId}`);
|
|
248
|
-
return false;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// Reset operation state
|
|
252
|
-
operation.retryCount++;
|
|
253
|
-
operation.status = TOOL_STATUS.PENDING;
|
|
254
|
-
operation.startedAt = null;
|
|
255
|
-
operation.completedAt = null;
|
|
256
|
-
operation.error = null;
|
|
257
|
-
operation.result = null;
|
|
258
|
-
|
|
259
|
-
// Reset timeout
|
|
260
|
-
this.setOperationTimeout(operationId);
|
|
261
|
-
|
|
262
|
-
this.logger?.info(`Operation retry initiated: ${operationId}`, {
|
|
263
|
-
retryCount: operation.retryCount,
|
|
264
|
-
maxRetries: operation.maxRetries
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
this.emit('operation:retry', operation);
|
|
268
|
-
|
|
269
|
-
return true;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Get system-wide operation statistics
|
|
274
|
-
* @returns {Object} Operation statistics
|
|
275
|
-
*/
|
|
276
|
-
getStatistics() {
|
|
277
|
-
const stats = {
|
|
278
|
-
total: this.operations.size,
|
|
279
|
-
byStatus: {},
|
|
280
|
-
byTool: {},
|
|
281
|
-
byAgent: {},
|
|
282
|
-
averageExecutionTime: 0,
|
|
283
|
-
oldestOperation: null,
|
|
284
|
-
newestOperation: null
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
let totalExecutionTime = 0;
|
|
288
|
-
let executionCount = 0;
|
|
289
|
-
let oldestTime = null;
|
|
290
|
-
let newestTime = null;
|
|
291
|
-
|
|
292
|
-
for (const operation of this.operations.values()) {
|
|
293
|
-
// Count by status
|
|
294
|
-
stats.byStatus[operation.status] = (stats.byStatus[operation.status] || 0) + 1;
|
|
295
|
-
|
|
296
|
-
// Count by tool
|
|
297
|
-
stats.byTool[operation.toolId] = (stats.byTool[operation.toolId] || 0) + 1;
|
|
298
|
-
|
|
299
|
-
// Count by agent
|
|
300
|
-
stats.byAgent[operation.agentId] = (stats.byAgent[operation.agentId] || 0) + 1;
|
|
301
|
-
|
|
302
|
-
// Calculate execution time
|
|
303
|
-
const execTime = this.calculateExecutionTime(operation);
|
|
304
|
-
if (execTime > 0) {
|
|
305
|
-
totalExecutionTime += execTime;
|
|
306
|
-
executionCount++;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// Track oldest/newest
|
|
310
|
-
const createdTime = new Date(operation.createdAt).getTime();
|
|
311
|
-
if (!oldestTime || createdTime < oldestTime) {
|
|
312
|
-
oldestTime = createdTime;
|
|
313
|
-
stats.oldestOperation = operation.id;
|
|
314
|
-
}
|
|
315
|
-
if (!newestTime || createdTime > newestTime) {
|
|
316
|
-
newestTime = createdTime;
|
|
317
|
-
stats.newestOperation = operation.id;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
stats.averageExecutionTime = executionCount > 0 ? Math.round(totalExecutionTime / executionCount) : 0;
|
|
322
|
-
|
|
323
|
-
return stats;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* Clean up completed operations
|
|
328
|
-
* @param {number} maxAge - Maximum age in milliseconds (default: 1 hour)
|
|
329
|
-
* @returns {number} Number of operations cleaned up
|
|
330
|
-
*/
|
|
331
|
-
async cleanupCompletedOperations(maxAge = 3600000) {
|
|
332
|
-
const cutoffTime = Date.now() - maxAge;
|
|
333
|
-
const toCleanup = [];
|
|
334
|
-
|
|
335
|
-
for (const operation of this.operations.values()) {
|
|
336
|
-
if ((operation.status === TOOL_STATUS.COMPLETED || operation.status === TOOL_STATUS.FAILED || operation.status === TOOL_STATUS.CANCELLED) &&
|
|
337
|
-
new Date(operation.completedAt).getTime() < cutoffTime) {
|
|
338
|
-
toCleanup.push(operation.id);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
for (const operationId of toCleanup) {
|
|
343
|
-
await this.cleanupOperation(operationId);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
this.logger?.debug(`Cleaned up ${toCleanup.length} completed operations`);
|
|
347
|
-
|
|
348
|
-
return toCleanup.length;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* Start monitoring operations
|
|
353
|
-
* @private
|
|
354
|
-
*/
|
|
355
|
-
startMonitoring() {
|
|
356
|
-
if (this.monitoringInterval) {
|
|
357
|
-
clearInterval(this.monitoringInterval);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
this.monitoringInterval = setInterval(() => {
|
|
361
|
-
this.checkOperationTimeouts();
|
|
362
|
-
this.cleanupCompletedOperations();
|
|
363
|
-
}, this.cleanupInterval);
|
|
364
|
-
|
|
365
|
-
this.logger?.info('Async tool manager monitoring started');
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* Stop monitoring operations
|
|
370
|
-
* @private
|
|
371
|
-
*/
|
|
372
|
-
stopMonitoring() {
|
|
373
|
-
if (this.monitoringInterval) {
|
|
374
|
-
clearInterval(this.monitoringInterval);
|
|
375
|
-
this.monitoringInterval = null;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
this.logger?.info('Async tool manager monitoring stopped');
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
/**
|
|
382
|
-
* Check for operation timeouts
|
|
383
|
-
* @private
|
|
384
|
-
*/
|
|
385
|
-
checkOperationTimeouts() {
|
|
386
|
-
const now = Date.now();
|
|
387
|
-
|
|
388
|
-
for (const operation of this.operations.values()) {
|
|
389
|
-
if (operation.status === TOOL_STATUS.EXECUTING || operation.status === TOOL_STATUS.PENDING) {
|
|
390
|
-
const createdTime = new Date(operation.createdAt).getTime();
|
|
391
|
-
if (now - createdTime > operation.timeout) {
|
|
392
|
-
this.handleOperationTimeout(operation);
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
/**
|
|
399
|
-
* Set timeout for operation
|
|
400
|
-
* @private
|
|
401
|
-
*/
|
|
402
|
-
setOperationTimeout(operationId) {
|
|
403
|
-
const operation = this.operations.get(operationId);
|
|
404
|
-
if (!operation) return;
|
|
405
|
-
|
|
406
|
-
operation.timeoutHandle = setTimeout(() => {
|
|
407
|
-
this.handleOperationTimeout(operation);
|
|
408
|
-
}, operation.timeout);
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
/**
|
|
412
|
-
* Clear timeout for operation
|
|
413
|
-
* @private
|
|
414
|
-
*/
|
|
415
|
-
clearOperationTimeout(operationId) {
|
|
416
|
-
const operation = this.operations.get(operationId);
|
|
417
|
-
if (operation && operation.timeoutHandle) {
|
|
418
|
-
clearTimeout(operation.timeoutHandle);
|
|
419
|
-
delete operation.timeoutHandle;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
/**
|
|
424
|
-
* Generate unique operation ID
|
|
425
|
-
* @private
|
|
426
|
-
*/
|
|
427
|
-
generateOperationId() {
|
|
428
|
-
const timestamp = Date.now().toString(36);
|
|
429
|
-
const random = Math.random().toString(36).substr(2, 9);
|
|
430
|
-
return `op-${timestamp}-${random}`;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
/**
|
|
434
|
-
* Calculate execution time for operation
|
|
435
|
-
* @private
|
|
436
|
-
*/
|
|
437
|
-
calculateExecutionTime(operation) {
|
|
438
|
-
if (!operation.startedAt) return 0;
|
|
439
|
-
|
|
440
|
-
const endTime = operation.completedAt
|
|
441
|
-
? new Date(operation.completedAt).getTime()
|
|
442
|
-
: Date.now();
|
|
443
|
-
|
|
444
|
-
return endTime - new Date(operation.startedAt).getTime();
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* Move operation to history and remove from active
|
|
449
|
-
* @private
|
|
450
|
-
*/
|
|
451
|
-
async cleanupOperation(operationId) {
|
|
452
|
-
const operation = this.operations.get(operationId);
|
|
453
|
-
if (!operation) return;
|
|
454
|
-
|
|
455
|
-
// Clear timeout
|
|
456
|
-
this.clearOperationTimeout(operationId);
|
|
457
|
-
|
|
458
|
-
// Add to history
|
|
459
|
-
this.operationHistory.push({
|
|
460
|
-
...operation,
|
|
461
|
-
executionTime: this.calculateExecutionTime(operation),
|
|
462
|
-
cleanedUpAt: new Date().toISOString()
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
// Trim history if needed
|
|
466
|
-
if (this.operationHistory.length > this.maxHistorySize) {
|
|
467
|
-
this.operationHistory = this.operationHistory.slice(-this.maxHistorySize);
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
// Remove from active operations
|
|
471
|
-
this.operations.delete(operationId);
|
|
472
|
-
|
|
473
|
-
this.emit('operation:cleanup', { operationId, toolId: operation.toolId });
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
/**
|
|
477
|
-
* Event handler for operation started
|
|
478
|
-
* @private
|
|
479
|
-
*/
|
|
480
|
-
handleOperationStarted(operation) {
|
|
481
|
-
this.logger?.debug(`Operation started: ${operation.id}`, {
|
|
482
|
-
toolId: operation.toolId,
|
|
483
|
-
agentId: operation.agentId
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
/**
|
|
488
|
-
* Event handler for operation completed
|
|
489
|
-
* @private
|
|
490
|
-
*/
|
|
491
|
-
async handleOperationCompleted(operation) {
|
|
492
|
-
this.logger?.info(`Operation completed: ${operation.id}`, {
|
|
493
|
-
toolId: operation.toolId,
|
|
494
|
-
agentId: operation.agentId,
|
|
495
|
-
executionTime: this.calculateExecutionTime(operation)
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
// Schedule cleanup
|
|
499
|
-
setTimeout(() => this.cleanupOperation(operation.id), 30000); // 30 seconds
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
/**
|
|
503
|
-
* Event handler for operation failed
|
|
504
|
-
* @private
|
|
505
|
-
*/
|
|
506
|
-
async handleOperationFailed(operation) {
|
|
507
|
-
this.logger?.error(`Operation failed: ${operation.id}`, {
|
|
508
|
-
toolId: operation.toolId,
|
|
509
|
-
agentId: operation.agentId,
|
|
510
|
-
error: operation.error,
|
|
511
|
-
executionTime: this.calculateExecutionTime(operation),
|
|
512
|
-
retryCount: operation.retryCount
|
|
513
|
-
});
|
|
514
|
-
|
|
515
|
-
// Attempt retry if allowed
|
|
516
|
-
if (operation.retryCount < operation.maxRetries) {
|
|
517
|
-
setTimeout(() => this.retryOperation(operation.id), 5000); // 5 second delay
|
|
518
|
-
} else {
|
|
519
|
-
// Schedule cleanup
|
|
520
|
-
setTimeout(() => this.cleanupOperation(operation.id), 60000); // 1 minute
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
/**
|
|
525
|
-
* Event handler for operation timeout
|
|
526
|
-
* @private
|
|
527
|
-
*/
|
|
528
|
-
async handleOperationTimeout(operation) {
|
|
529
|
-
this.logger?.warn(`Operation timed out: ${operation.id}`, {
|
|
530
|
-
toolId: operation.toolId,
|
|
531
|
-
agentId: operation.agentId,
|
|
532
|
-
timeout: operation.timeout,
|
|
533
|
-
executionTime: this.calculateExecutionTime(operation)
|
|
534
|
-
});
|
|
535
|
-
|
|
536
|
-
this.updateOperation(operation.id, TOOL_STATUS.TIMEOUT, {
|
|
537
|
-
error: `Operation timed out after ${operation.timeout}ms`
|
|
538
|
-
});
|
|
539
|
-
|
|
540
|
-
this.emit('operation:timeout', operation);
|
|
541
|
-
|
|
542
|
-
// Schedule cleanup
|
|
543
|
-
setTimeout(() => this.cleanupOperation(operation.id), 30000); // 30 seconds
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
/**
|
|
547
|
-
* Graceful shutdown
|
|
548
|
-
* @returns {Promise<void>}
|
|
549
|
-
*/
|
|
550
|
-
async shutdown() {
|
|
551
|
-
this.isShuttingDown = true;
|
|
552
|
-
|
|
553
|
-
this.logger?.info('Shutting down async tool manager...');
|
|
554
|
-
|
|
555
|
-
// Stop monitoring
|
|
556
|
-
this.stopMonitoring();
|
|
557
|
-
|
|
558
|
-
// Cancel all pending/executing operations
|
|
559
|
-
const activeOperations = [];
|
|
560
|
-
for (const operation of this.operations.values()) {
|
|
561
|
-
if (operation.status === TOOL_STATUS.PENDING || operation.status === TOOL_STATUS.EXECUTING) {
|
|
562
|
-
activeOperations.push(operation.id);
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
for (const operationId of activeOperations) {
|
|
567
|
-
await this.cancelOperation(operationId, 'System shutdown');
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
// Clear all remaining operations
|
|
571
|
-
this.operations.clear();
|
|
572
|
-
|
|
573
|
-
this.logger?.info(`Async tool manager shutdown complete. Cancelled ${activeOperations.length} operations.`);
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
/**
|
|
577
|
-
* Get operation history
|
|
578
|
-
* @param {Object} filters - Filtering options
|
|
579
|
-
* @returns {Array<Object>} Filtered operation history
|
|
580
|
-
*/
|
|
581
|
-
getOperationHistory(filters = {}) {
|
|
582
|
-
let history = [...this.operationHistory];
|
|
583
|
-
|
|
584
|
-
if (filters.agentId) {
|
|
585
|
-
history = history.filter(op => op.agentId === filters.agentId);
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
if (filters.toolId) {
|
|
589
|
-
history = history.filter(op => op.toolId === filters.toolId);
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
if (filters.status) {
|
|
593
|
-
history = history.filter(op => op.status === filters.status);
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
if (filters.limit) {
|
|
597
|
-
history = history.slice(-filters.limit);
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
return history.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
export default AsyncToolManager;
|
|
1
|
+
const a0_0x2a463a=a0_0x22d3;(function(_0x4549ff,_0x5849a2){const _0x35757a=a0_0x22d3,_0x37e4cf=_0x4549ff();while(!![]){try{const _0x3d93a1=parseInt(_0x35757a(0x167))/0x1*(-parseInt(_0x35757a(0x148))/0x2)+parseInt(_0x35757a(0x132))/0x3*(parseInt(_0x35757a(0x136))/0x4)+-parseInt(_0x35757a(0x11c))/0x5+-parseInt(_0x35757a(0x131))/0x6+-parseInt(_0x35757a(0x157))/0x7+parseInt(_0x35757a(0x11d))/0x8+parseInt(_0x35757a(0x135))/0x9*(parseInt(_0x35757a(0x12c))/0xa);if(_0x3d93a1===_0x5849a2)break;else _0x37e4cf['push'](_0x37e4cf['shift']());}catch(_0x3caddb){_0x37e4cf['push'](_0x37e4cf['shift']());}}}(a0_0x4f19,0x62d20));import a0_0x30d4c2 from'events';function a0_0x4f19(){const _0x3e833e=['y2fUy2vSt3bLCMf0Aw9U','yNLtDgf0Dxm','zgvMyxvSDfrPBwvVDxq','Dg9ju09tDhjPBMC','y29UzMLN','A2v5CW','D2fYBG','B3bLCMf0Aw9UsgLZDg9YEq','C2XPy2u','C3rVCe1VBML0B3jPBMC','t3bLCMf0Aw9UihrPBwvKig91DdOG','twf4Aw11BsbJB25JDxjYzw50ig9WzxjHDgLVBNmGCMvHy2HLzcaO','AgfUzgXLt3bLCMf0Aw9UvgLTzw91Da','Bw9UAxrVCMLUz0LUDgvYDMfS','q2fUBM90ignHBMnLBcbJB21WBgv0zwqVzMfPBgvKig9WzxjHDgLVBJOG','q09nueXfveve','ywDLBNrjza','twf4Aw11BsbYzxrYAwvZigv4y2vLzgvKigzVCIbVCgvYyxrPB246ia','DgLTzw91DeHHBMrSzq','mJG0ndmYnunusMHoBW','mZK0nduZnNb0zMrjyq','B2XKzxn0t3bLCMf0Aw9U','z2v0','AgfUzgXLt3bLCMf0Aw9UrMfPBgvK','yNLuB29S','qxr0zw1WDgvKihrVihvWzgf0zsb1BMTUB3DUig9WzxjHDgLVBJOG','Bg9Nz2vY','C2v0','qxn5BMmGB3bLCMf0Aw9Uihn0yxj0zwq6ia','Bwf4q29Uy3vYCMvUDe9WzxjHDgLVBNm','Dg9VBeLK','z2v0vgLTzq','B3bLCMf0Aw9UoNjLDhj5','AgfUzgXLt3bLCMf0Aw9Uq29TCgXLDgvK','B3bLCMf0Aw9UoNrPBwvVDxq','nZy5mg9uyM10AW','DxbKyxrLt3bLCMf0Aw9U','Bwf4uMv0CMLLCW','Aw5MBW','y2fSy3vSyxrLrxHLy3v0Aw9UvgLTzq','ndaZmtCWnLHIsev5rG','mZuXChvrr3zu','B3bLCMf0Aw9UCW','yxzLCMfNzuv4zwn1DgLVBLrPBwu','mtG2mZLjtw9Yrfq','mtGWmJrouKvQC3e','C3rHCNrnB25PDg9YAw5N','q0foq0vmteve','zxjYB3i','ChvZAa','t3bLCMf0Aw9UihjLDhj5igLUAxrPyxrLzdOG','z2v0qwDLBNrpCgvYyxrPB25Z','C3vIC3rY','C3rHCNrLzef0','rvHfq1vusu5h','z2vUzxjHDgvpCgvYyxrPB25jza','y2XLyxjpCgvYyxrPB25uAw1LB3v0','DgLTzw91Da','y2XLyw51Ce9WzxjHDgLVBG','ignVBxbSzxrLzcbVCgvYyxrPB25Z','ChjVz3jLC3m','y29TCgXLDgvKqxq','AxntAhv0DgLUz0rVD24','mNH2AMvpAa','BM93','BgLTAxq','t3bLCMf0Aw9UignVBxbSzxrLzdOG','q2fUBM90ihjLDhj5ig5VBI1MywLSzwqGB3bLCMf0Aw9UoIa','t3bLCMf0Aw9Uihn0yxr1CYb1CgrHDgvKoIa','DMfSDwvZ','B3bLCMf0Aw9UoNn0yxj0zwq','B3bLCMf0Aw9UoNbYB2DYzxnZ','CMvZDwX0','C2v0t3bLCMf0Aw9UvgLTzw91Da','t3bLCMf0Aw9Uihn0yxj0zwq6ia','zMLSDgvY','C29YDa','BgvUz3rO','mtmZnde3ow9uEhbpBW','zw1PDa','CMv0CNLdB3vUDa','CMv0CNLpCgvYyxrPB24','Bwf4sgLZDg9YEvnPEMu','AgfUzgXLt3bLCMf0Aw9Uu3rHCNrLza','y2XLyw51CenVBxbSzxrLze9WzxjHDgLVBNm','rKfjteve','C3rHDhvZ','CM91BMq','B3bLCMf0Aw9UoMnVBxbSzxrLza','y3jLyxrLzef0','Dg9tDhjPBMC','y2XLyw51CeLUDgvYDMfS','uevoreLorW','ig9WzxjHDgLVBNmU','nZC2nJG3BenZywrY'];a0_0x4f19=function(){return _0x3e833e;};return a0_0x4f19();}import{TOOL_STATUS,SYSTEM_DEFAULTS}from'../utilities/constants.js';class AsyncToolManager extends a0_0x30d4c2{constructor(_0x4ce289={},_0x57e89d=null){const _0x41b4f6=a0_0x22d3;super(),this[_0x41b4f6(0x16c)]=_0x4ce289,this[_0x41b4f6(0x123)]=_0x57e89d,this[_0x41b4f6(0x133)]=new Map(),this['operationHistory']=[],this['maxConcurrentOperations']=_0x4ce289[_0x41b4f6(0x126)]||0xa,this[_0x41b4f6(0x16a)]=_0x4ce289['defaultTimeout']||0x493e0,this['cleanupInterval']=_0x4ce289[_0x41b4f6(0x164)]||0xea60,this['maxHistorySize']=_0x4ce289[_0x41b4f6(0x15b)]||0x3e8,this['monitoringInterval']=null,this['isShuttingDown']=![],this[_0x41b4f6(0x137)](),this['on'](_0x41b4f6(0x14f),this[_0x41b4f6(0x15c)]['bind'](this)),this['on'](_0x41b4f6(0x161),this['handleOperationCompleted']['bind'](this)),this['on']('operation:failed',this['handleOperationFailed']['bind'](this)),this['on'](_0x41b4f6(0x12b),this[_0x41b4f6(0x174)]['bind'](this));}async['startOperation'](_0x5db5f6,_0x221108,_0x59faf1,_0x1d39d5={}){const _0x25e261=a0_0x22d3;if(this['operations']['size']>=this['maxConcurrentOperations'])throw new Error(_0x25e261(0x173)+this[_0x25e261(0x126)]+')');const _0x598eeb=this[_0x25e261(0x140)](),_0xc26fca={'id':_0x598eeb,'toolId':_0x5db5f6,'agentId':_0x221108,'parameters':_0x59faf1,'context':_0x1d39d5,'status':TOOL_STATUS[_0x25e261(0x165)],'createdAt':new Date()[_0x25e261(0x16b)](),'startedAt':null,'completedAt':null,'timeout':_0x1d39d5['timeout']||this['defaultTimeout'],'result':null,'error':null,'progress':null,'retryCount':0x0,'maxRetries':_0x1d39d5[_0x25e261(0x12e)]||0x0};return this[_0x25e261(0x133)][_0x25e261(0x124)](_0x598eeb,_0xc26fca),this[_0x25e261(0x123)]?.[_0x25e261(0x12f)](_0x25e261(0x125)+_0x598eeb,{'toolId':_0x5db5f6,'agentId':_0x221108,'parametersCount':Object[_0x25e261(0x16d)](_0x59faf1)[_0x25e261(0x156)],'timeout':_0xc26fca['timeout']}),this[_0x25e261(0x152)](_0x598eeb),this['emit']('operation:started',_0xc26fca),_0x598eeb;}[a0_0x2a463a(0x12d)](_0x1f9937,_0x5ad332,_0x5b29c5={}){const _0x231885=a0_0x2a463a,_0x19cfbe=this[_0x231885(0x133)]['get'](_0x1f9937);if(!_0x19cfbe)return this['logger']?.[_0x231885(0x16e)](_0x231885(0x122)+_0x1f9937),![];const _0x3ede3a=_0x19cfbe[_0x231885(0x15f)];_0x19cfbe[_0x231885(0x15f)]=_0x5ad332;_0x5ad332===TOOL_STATUS[_0x231885(0x13f)]&&!_0x19cfbe['startedAt']&&(_0x19cfbe['startedAt']=new Date()[_0x231885(0x16b)]());(_0x5ad332===TOOL_STATUS[_0x231885(0x177)]||_0x5ad332===TOOL_STATUS[_0x231885(0x15e)])&&(_0x19cfbe[_0x231885(0x146)]=new Date()[_0x231885(0x16b)]());if(_0x5b29c5['result']!==undefined)_0x19cfbe[_0x231885(0x151)]=_0x5b29c5['result'];if(_0x5b29c5['error']!==undefined)_0x19cfbe[_0x231885(0x139)]=_0x5b29c5[_0x231885(0x139)];if(_0x5b29c5['progress']!==undefined)_0x19cfbe['progress']=_0x5b29c5[_0x231885(0x145)];this[_0x231885(0x123)]?.['debug'](_0x231885(0x14d)+_0x1f9937,{'previousStatus':_0x3ede3a,'newStatus':_0x5ad332,'hasResult':!!_0x5b29c5[_0x231885(0x151)],'hasError':!!_0x5b29c5[_0x231885(0x139)],'progress':_0x5b29c5[_0x231885(0x145)]});switch(_0x5ad332){case TOOL_STATUS['COMPLETED']:this['emit'](_0x231885(0x161),_0x19cfbe);break;case TOOL_STATUS['FAILED']:this['emit']('operation:failed',_0x19cfbe);break;case TOOL_STATUS[_0x231885(0x13f)]:this[_0x231885(0x158)](_0x231885(0x150),_0x19cfbe);break;}return!![];}['getOperation'](_0x477e51){const _0x122aca=a0_0x2a463a,_0x55b4f0=this['operations'][_0x122aca(0x11f)](_0x477e51);if(!_0x55b4f0)return null;return{'id':_0x55b4f0['id'],'toolId':_0x55b4f0[_0x122aca(0x127)],'agentId':_0x55b4f0['agentId'],'status':_0x55b4f0[_0x122aca(0x15f)],'createdAt':_0x55b4f0['createdAt'],'startedAt':_0x55b4f0[_0x122aca(0x13e)],'completedAt':_0x55b4f0[_0x122aca(0x146)],'result':_0x55b4f0['result'],'error':_0x55b4f0['error'],'progress':_0x55b4f0[_0x122aca(0x145)],'retryCount':_0x55b4f0[_0x122aca(0x159)],'executionTime':this[_0x122aca(0x130)](_0x55b4f0)};}[a0_0x2a463a(0x13c)](_0x1249e6){const _0x505497=a0_0x2a463a,_0x422aa1=[];for(const _0x57ac42 of this[_0x505497(0x133)][_0x505497(0x14e)]()){_0x57ac42[_0x505497(0x119)]===_0x1249e6&&_0x422aa1[_0x505497(0x13a)](this['getOperation'](_0x57ac42['id']));}return _0x422aa1[_0x505497(0x155)]((_0x38d3f7,_0x138e8c)=>new Date(_0x138e8c['createdAt'])-new Date(_0x38d3f7['createdAt']));}async[a0_0x2a463a(0x168)](_0x52c898,_0xb91094='Operation\x20cancelled'){const _0x41359b=a0_0x2a463a,_0x3ceaeb=this[_0x41359b(0x133)][_0x41359b(0x11f)](_0x52c898);if(!_0x3ceaeb)return![];if(_0x3ceaeb[_0x41359b(0x15f)]===TOOL_STATUS[_0x41359b(0x177)]||_0x3ceaeb['status']===TOOL_STATUS['FAILED'])return this['logger']?.['warn'](_0x41359b(0x176)+_0x52c898),![];return this['updateOperation'](_0x52c898,TOOL_STATUS['CANCELLED'],{'error':_0xb91094}),this[_0x41359b(0x141)](_0x52c898),this['emit']('operation:cancelled',_0x3ceaeb),await this[_0x41359b(0x143)](_0x52c898),this[_0x41359b(0x123)]?.[_0x41359b(0x12f)]('Operation\x20cancelled:\x20'+_0x52c898,{'reason':_0xb91094}),!![];}async[a0_0x2a463a(0x15a)](_0x450aae){const _0xbecd57=a0_0x2a463a,_0x227e23=this[_0xbecd57(0x133)]['get'](_0x450aae);if(!_0x227e23)return![];if(_0x227e23['status']!==TOOL_STATUS[_0xbecd57(0x15e)])return this[_0xbecd57(0x123)]?.['warn'](_0xbecd57(0x14c)+_0x450aae),![];if(_0x227e23[_0xbecd57(0x159)]>=_0x227e23['maxRetries'])return this[_0xbecd57(0x123)]?.[_0xbecd57(0x16e)](_0xbecd57(0x11a)+_0x450aae),![];return _0x227e23[_0xbecd57(0x159)]++,_0x227e23['status']=TOOL_STATUS[_0xbecd57(0x165)],_0x227e23[_0xbecd57(0x13e)]=null,_0x227e23[_0xbecd57(0x146)]=null,_0x227e23[_0xbecd57(0x139)]=null,_0x227e23['result']=null,this['setOperationTimeout'](_0x450aae),this['logger']?.['info'](_0xbecd57(0x13b)+_0x450aae,{'retryCount':_0x227e23[_0xbecd57(0x159)],'maxRetries':_0x227e23[_0xbecd57(0x12e)]}),this['emit'](_0xbecd57(0x129),_0x227e23),!![];}['getStatistics'](){const _0x2d0f54=a0_0x2a463a,_0x2944d0={'total':this['operations']['size'],'byStatus':{},'byTool':{},'byAgent':{},'averageExecutionTime':0x0,'oldestOperation':null,'newestOperation':null};let _0x2c730=0x0,_0x54c050=0x0,_0x33bb0f=null,_0x1b3988=null;for(const _0x486f9f of this[_0x2d0f54(0x133)]['values']()){_0x2944d0['byStatus'][_0x486f9f[_0x2d0f54(0x15f)]]=(_0x2944d0[_0x2d0f54(0x169)][_0x486f9f['status']]||0x0)+0x1,_0x2944d0[_0x2d0f54(0x121)][_0x486f9f[_0x2d0f54(0x127)]]=(_0x2944d0[_0x2d0f54(0x121)][_0x486f9f['toolId']]||0x0)+0x1,_0x2944d0['byAgent'][_0x486f9f['agentId']]=(_0x2944d0['byAgent'][_0x486f9f['agentId']]||0x0)+0x1;const _0x412914=this[_0x2d0f54(0x130)](_0x486f9f);_0x412914>0x0&&(_0x2c730+=_0x412914,_0x54c050++);const _0x18042d=new Date(_0x486f9f[_0x2d0f54(0x162)])[_0x2d0f54(0x128)]();(!_0x33bb0f||_0x18042d<_0x33bb0f)&&(_0x33bb0f=_0x18042d,_0x2944d0[_0x2d0f54(0x11e)]=_0x486f9f['id']),(!_0x1b3988||_0x18042d>_0x1b3988)&&(_0x1b3988=_0x18042d,_0x2944d0['newestOperation']=_0x486f9f['id']);}return _0x2944d0[_0x2d0f54(0x134)]=_0x54c050>0x0?Math[_0x2d0f54(0x160)](_0x2c730/_0x54c050):0x0,_0x2944d0;}async[a0_0x2a463a(0x15d)](_0x38bdd1=0x36ee80){const _0x885b68=a0_0x2a463a,_0x370d81=Date[_0x885b68(0x149)]()-_0x38bdd1,_0x47d6ba=[];for(const _0x218ff8 of this[_0x885b68(0x133)]['values']()){(_0x218ff8[_0x885b68(0x15f)]===TOOL_STATUS['COMPLETED']||_0x218ff8['status']===TOOL_STATUS[_0x885b68(0x15e)]||_0x218ff8[_0x885b68(0x15f)]===TOOL_STATUS[_0x885b68(0x138)])&&new Date(_0x218ff8[_0x885b68(0x146)])[_0x885b68(0x128)]()<_0x370d81&&_0x47d6ba[_0x885b68(0x13a)](_0x218ff8['id']);}for(const _0x56d907 of _0x47d6ba){await this['cleanupOperation'](_0x56d907);}return this[_0x885b68(0x123)]?.['debug']('Cleaned\x20up\x20'+_0x47d6ba['length']+_0x885b68(0x144)),_0x47d6ba[_0x885b68(0x156)];}['startMonitoring'](){const _0x260557=a0_0x2a463a;this['monitoringInterval']&&clearInterval(this['monitoringInterval']),this[_0x260557(0x175)]=setInterval(()=>{const _0x3845a1=_0x260557;this['checkOperationTimeouts'](),this[_0x3845a1(0x15d)]();},this[_0x260557(0x164)]),this[_0x260557(0x123)]?.[_0x260557(0x12f)]('Async\x20tool\x20manager\x20monitoring\x20started');}[a0_0x2a463a(0x171)](){const _0x576117=a0_0x2a463a;this[_0x576117(0x175)]&&(clearInterval(this[_0x576117(0x175)]),this['monitoringInterval']=null),this[_0x576117(0x123)]?.[_0x576117(0x12f)]('Async\x20tool\x20manager\x20monitoring\x20stopped');}['checkOperationTimeouts'](){const _0x16683=a0_0x2a463a,_0x5b4299=Date[_0x16683(0x149)]();for(const _0x261460 of this[_0x16683(0x133)][_0x16683(0x14e)]()){if(_0x261460[_0x16683(0x15f)]===TOOL_STATUS['EXECUTING']||_0x261460['status']===TOOL_STATUS[_0x16683(0x165)]){const _0x9429eb=new Date(_0x261460[_0x16683(0x162)])['getTime']();_0x5b4299-_0x9429eb>_0x261460[_0x16683(0x142)]&&this['handleOperationTimeout'](_0x261460);}}}['setOperationTimeout'](_0x2eb7ab){const _0x1805a3=a0_0x2a463a,_0x105645=this['operations']['get'](_0x2eb7ab);if(!_0x105645)return;_0x105645[_0x1805a3(0x11b)]=setTimeout(()=>{const _0x419dc9=_0x1805a3;this[_0x419dc9(0x174)](_0x105645);},_0x105645[_0x1805a3(0x142)]);}['clearOperationTimeout'](_0x451966){const _0x34364d=a0_0x2a463a,_0x549909=this['operations'][_0x34364d(0x11f)](_0x451966);_0x549909&&_0x549909['timeoutHandle']&&(clearTimeout(_0x549909[_0x34364d(0x11b)]),delete _0x549909['timeoutHandle']);}[a0_0x2a463a(0x140)](){const _0x173234=a0_0x2a463a,_0x57df2e=Date[_0x173234(0x149)]()[_0x173234(0x163)](0x24),_0x1e71d3=Math['random']()['toString'](0x24)[_0x173234(0x13d)](0x2,0x9);return'op-'+_0x57df2e+'-'+_0x1e71d3;}[a0_0x2a463a(0x130)](_0x6cb10a){const _0xb09dd4=a0_0x2a463a;if(!_0x6cb10a[_0xb09dd4(0x13e)])return 0x0;const _0x4cd410=_0x6cb10a['completedAt']?new Date(_0x6cb10a[_0xb09dd4(0x146)])[_0xb09dd4(0x128)]():Date['now']();return _0x4cd410-new Date(_0x6cb10a['startedAt'])['getTime']();}async[a0_0x2a463a(0x143)](_0x1c4d03){const _0x21332b=a0_0x2a463a,_0x5b930a=this[_0x21332b(0x133)][_0x21332b(0x11f)](_0x1c4d03);if(!_0x5b930a)return;this[_0x21332b(0x141)](_0x1c4d03),this['operationHistory']['push']({..._0x5b930a,'executionTime':this[_0x21332b(0x130)](_0x5b930a),'cleanedUpAt':new Date()[_0x21332b(0x16b)]()}),this[_0x21332b(0x16f)][_0x21332b(0x156)]>this['maxHistorySize']&&(this['operationHistory']=this['operationHistory']['slice'](-this['maxHistorySize'])),this['operations']['delete'](_0x1c4d03),this[_0x21332b(0x158)]('operation:cleanup',{'operationId':_0x1c4d03,'toolId':_0x5b930a['toolId']});}['handleOperationStarted'](_0x48c3c9){const _0x2411ce=a0_0x2a463a;this['logger']?.['debug'](_0x2411ce(0x153)+_0x48c3c9['id'],{'toolId':_0x48c3c9['toolId'],'agentId':_0x48c3c9['agentId']});}async[a0_0x2a463a(0x12a)](_0x416ccc){const _0x390cee=a0_0x2a463a;this[_0x390cee(0x123)]?.[_0x390cee(0x12f)](_0x390cee(0x14b)+_0x416ccc['id'],{'toolId':_0x416ccc['toolId'],'agentId':_0x416ccc['agentId'],'executionTime':this['calculateExecutionTime'](_0x416ccc)}),setTimeout(()=>this['cleanupOperation'](_0x416ccc['id']),0x7530);}async[a0_0x2a463a(0x120)](_0x919c8a){const _0x40de55=a0_0x2a463a;this[_0x40de55(0x123)]?.[_0x40de55(0x139)]('Operation\x20failed:\x20'+_0x919c8a['id'],{'toolId':_0x919c8a[_0x40de55(0x127)],'agentId':_0x919c8a[_0x40de55(0x119)],'error':_0x919c8a[_0x40de55(0x139)],'executionTime':this['calculateExecutionTime'](_0x919c8a),'retryCount':_0x919c8a['retryCount']}),_0x919c8a[_0x40de55(0x159)]<_0x919c8a[_0x40de55(0x12e)]?setTimeout(()=>this['retryOperation'](_0x919c8a['id']),0x1388):setTimeout(()=>this['cleanupOperation'](_0x919c8a['id']),0xea60);}async['handleOperationTimeout'](_0x116c86){const _0x7b7f2b=a0_0x2a463a;this['logger']?.['warn'](_0x7b7f2b(0x172)+_0x116c86['id'],{'toolId':_0x116c86['toolId'],'agentId':_0x116c86[_0x7b7f2b(0x119)],'timeout':_0x116c86['timeout'],'executionTime':this['calculateExecutionTime'](_0x116c86)}),this['updateOperation'](_0x116c86['id'],TOOL_STATUS['TIMEOUT'],{'error':'Operation\x20timed\x20out\x20after\x20'+_0x116c86['timeout']+'ms'}),this[_0x7b7f2b(0x158)](_0x7b7f2b(0x12b),_0x116c86),setTimeout(()=>this['cleanupOperation'](_0x116c86['id']),0x7530);}async['shutdown'](){const _0x128202=a0_0x2a463a;this[_0x128202(0x147)]=!![],this['logger']?.['info']('Shutting down async tool manager...'),this['stopMonitoring']();const _0xd01576=[];for(const _0x5be672 of this['operations'][_0x128202(0x14e)]()){(_0x5be672['status']===TOOL_STATUS[_0x128202(0x165)]||_0x5be672['status']===TOOL_STATUS['EXECUTING'])&&_0xd01576[_0x128202(0x13a)](_0x5be672['id']);}for(const _0x5a3ef3 of _0xd01576){await this[_0x128202(0x168)](_0x5a3ef3,'System\x20shutdown');}this[_0x128202(0x133)]['clear'](),this[_0x128202(0x123)]?.[_0x128202(0x12f)]('Async\x20tool\x20manager\x20shutdown\x20complete.\x20Cancelled\x20'+_0xd01576['length']+_0x128202(0x166));}['getOperationHistory'](_0x12638a={}){const _0x360b72=a0_0x2a463a;let _0x5077b9=[...this['operationHistory']];return _0x12638a[_0x360b72(0x119)]&&(_0x5077b9=_0x5077b9[_0x360b72(0x154)](_0x30714a=>_0x30714a[_0x360b72(0x119)]===_0x12638a[_0x360b72(0x119)])),_0x12638a[_0x360b72(0x127)]&&(_0x5077b9=_0x5077b9[_0x360b72(0x154)](_0x35cac5=>_0x35cac5['toolId']===_0x12638a[_0x360b72(0x127)])),_0x12638a['status']&&(_0x5077b9=_0x5077b9[_0x360b72(0x154)](_0x4bff51=>_0x4bff51[_0x360b72(0x15f)]===_0x12638a['status'])),_0x12638a[_0x360b72(0x14a)]&&(_0x5077b9=_0x5077b9[_0x360b72(0x170)](-_0x12638a[_0x360b72(0x14a)])),_0x5077b9[_0x360b72(0x155)]((_0x50081a,_0x5a6868)=>new Date(_0x5a6868[_0x360b72(0x162)])-new Date(_0x50081a['createdAt']));}}function a0_0x22d3(_0x4ad014,_0x5062e0){_0x4ad014=_0x4ad014-0x119;const _0x4f1907=a0_0x4f19();let _0x22d392=_0x4f1907[_0x4ad014];if(a0_0x22d3['WuIxUJ']===undefined){var _0x31ac92=function(_0x4147ca){const _0x1c2dc2='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x30d4c2='',_0x4ce289='';for(let _0x57e89d=0x0,_0x5db5f6,_0x221108,_0x59faf1=0x0;_0x221108=_0x4147ca['charAt'](_0x59faf1++);~_0x221108&&(_0x5db5f6=_0x57e89d%0x4?_0x5db5f6*0x40+_0x221108:_0x221108,_0x57e89d++%0x4)?_0x30d4c2+=String['fromCharCode'](0xff&_0x5db5f6>>(-0x2*_0x57e89d&0x6)):0x0){_0x221108=_0x1c2dc2['indexOf'](_0x221108);}for(let _0x1d39d5=0x0,_0x598eeb=_0x30d4c2['length'];_0x1d39d5<_0x598eeb;_0x1d39d5++){_0x4ce289+='%'+('00'+_0x30d4c2['charCodeAt'](_0x1d39d5)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x4ce289);};a0_0x22d3['RgTrGL']=_0x31ac92,a0_0x22d3['xBLjzc']={},a0_0x22d3['WuIxUJ']=!![];}const _0x2b3330=_0x4f1907[0x0],_0x5e61cc=_0x4ad014+_0x2b3330,_0x91a75b=a0_0x22d3['xBLjzc'][_0x5e61cc];return!_0x91a75b?(_0x22d392=a0_0x22d3['RgTrGL'](_0x22d392),a0_0x22d3['xBLjzc'][_0x5e61cc]=_0x22d392):_0x22d392=_0x91a75b,_0x22d392;}export default AsyncToolManager;
|