@loxia-labs/loxia-autopilot-one 1.0.1 → 1.0.3
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 +14 -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_0x43050a=a0_0x33f1;(function(_0x255cfa,_0x230a73){const _0x1d87f7=a0_0x33f1,_0x1c6f76=_0x255cfa();while(!![]){try{const _0x142280=-parseInt(_0x1d87f7(0x247))/0x1+-parseInt(_0x1d87f7(0x249))/0x2*(parseInt(_0x1d87f7(0x24b))/0x3)+parseInt(_0x1d87f7(0x237))/0x4*(parseInt(_0x1d87f7(0x1f2))/0x5)+-parseInt(_0x1d87f7(0x1f1))/0x6*(-parseInt(_0x1d87f7(0x241))/0x7)+-parseInt(_0x1d87f7(0x1fb))/0x8+-parseInt(_0x1d87f7(0x232))/0x9+-parseInt(_0x1d87f7(0x228))/0xa*(-parseInt(_0x1d87f7(0x203))/0xb);if(_0x142280===_0x230a73)break;else _0x1c6f76['push'](_0x1c6f76['shift']());}catch(_0x5041ff){_0x1c6f76['push'](_0x1c6f76['shift']());}}}(a0_0x532f,0x38c5c));function a0_0x532f(){const _0x54c506=['AgfUzgXLt3bLCMf0Aw9UvgLTzw91Da','zw1PDa','BM93','Aw5MBW','BMv3zxn0t3bLCMf0Aw9U','Dg9VBeLK','t3bLCMf0Aw9UihrPBwvKig91DcbHzNrLCIa','z2v0u3rHDgLZDgLJCW','B3bLCMf0Aw9UsgLZDg9YEq','B3bLCMf0Aw9UoNn0yxj0zwq','yNLtDgf0Dxm','ndmXote0mgfxAwzHAq','Bwf4uMv0CMLLCW','Dg9tDhjPBMC','qxn5BMmGB3bLCMf0Aw9Uihn0yxj0zwq6ia','B2XKzxn0t3bLCMf0Aw9U','CMfUzg9T','rKfjteve','t3bLCMf0Aw9UihrPBwvKig91DdOG','t3bLCMf0Aw9Uihn0yxj0zwq6ia','ywDLBNrjza','mZCZndiZnu1HEhLjDa','y2XLyw51CeLUDgvYDMfS','t3bLCMf0Aw9UignHBMnLBgXLza','z2v0t3bLCMf0Aw9UsgLZDg9YEq','C3rHCNrLzef0','ne16y1L5wq','Dg9ju09tDhjPBMC','B3bLCMf0Aw9UoNrPBwvVDxq','q2fUBM90ignHBMnLBcbJB21WBgv0zwqVzMfPBgvKig9WzxjHDgLVBJOG','qxr0zw1WDgvKihrVihvWzgf0zsb1BMTUB3DUig9WzxjHDgLVBJOG','yNLuB29S','D2fYBG','y29TCgXLDgvKqxq','zgvMyxvSDfrPBwvVDxq','C2v0t3bLCMf0Aw9UvgLTzw91Da','mtrmrfjMy08','BgLTAxq','zMLSDgvY','ChvZAa','DgLTzw91Da','C3rVCe1VBML0B3jPBMC','mZu1mtG4uwvVrw9I','B3bLCMf0Aw9UoMnHBMnLBgXLza','nda0ndCWANfTCeDT','t3bLCMf0Aw9Uihn0yxr1CYb1CgrHDgvKoIa','nNLZDgL2ua','DgLTzw91DeHHBMrSzq','nJiXmZmWD25JCenc','mJaZmJu1CM9iuhLN','y2fSy3vSyxrLrxHLy3v0Aw9UvgLTzq','yMLUza','CMvZDwX0','ignVBxbSzxrLzcbVCgvYyxrPB25Z','z2v0','DMfSDwvZ','yNLbz2vUDa','t3bLCMf0Aw9UignVBxbSzxrLzdOG','mta5mteYmfLAvffMBa','zxjYB3i','ChjVz3jLC3m','BgvUz3rO','q09nueXfveve','y3jLyxrLzef0','AxntAhv0DgLUz0rVD24','CMv0CNLdB3vUDa','mZnICgLxtKO','AgfUzgXLt3bLCMf0Aw9UrMfPBgvK','zgvIDwC','twf4Aw11BsbYzxrYAwvZigv4y2vLzgvKigzVCIbVCgvYyxrPB246ia','y29UzMLN','DxbKyxrLt3bLCMf0Aw9U','y2XLyxjpCgvYyxrPB25uAw1LB3v0','z2vUzxjHDgvpCgvYyxrPB25jza','C3vIC3rY','B3bLCMf0Aw9UoMnVBxbSzxrLza','y2fUy2vSt3bLCMf0Aw9U','C2XPy2u','AgfUzgXLt3bLCMf0Aw9Uu3rHCNrLza','B3bLCMf0Aw9UCW','Bg9Nz2vY','C3rHDhvZ','u3LZDgvTihnODxrKB3DU','rvHfq1vusu5h','q0foq0vmteve','Bw9UAxrVCMLUz0LUDgvYDMfS','C3rHCNrnB25PDg9YAw5N','y2XLyw51Ce9WzxjHDgLVBG','AgfUzgXLt3bLCMf0Aw9Uq29TCgXLDgvK','qxn5BMmGDg9VBcbTyw5Hz2vYig1VBML0B3jPBMCGC3rHCNrLza','CMv0CNLpCgvYyxrPB24','z2v0vgLTzq'];a0_0x532f=function(){return _0x54c506;};return a0_0x532f();}import a0_0x357292 from'events';import{TOOL_STATUS,SYSTEM_DEFAULTS}from'../utilities/constants.js';function a0_0x33f1(_0x3905b7,_0x3ca26b){_0x3905b7=_0x3905b7-0x1f0;const _0x532f07=a0_0x532f();let _0x33f1f8=_0x532f07[_0x3905b7];if(a0_0x33f1['lifagL']===undefined){var _0x1e53fd=function(_0x27a077){const _0x350ccb='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x357292='',_0x1b61be='';for(let _0x201868=0x0,_0x5aa482,_0x486746,_0x3d01c5=0x0;_0x486746=_0x27a077['charAt'](_0x3d01c5++);~_0x486746&&(_0x5aa482=_0x201868%0x4?_0x5aa482*0x40+_0x486746:_0x486746,_0x201868++%0x4)?_0x357292+=String['fromCharCode'](0xff&_0x5aa482>>(-0x2*_0x201868&0x6)):0x0){_0x486746=_0x350ccb['indexOf'](_0x486746);}for(let _0x526019=0x0,_0x3fc7d0=_0x357292['length'];_0x526019<_0x3fc7d0;_0x526019++){_0x1b61be+='%'+('00'+_0x357292['charCodeAt'](_0x526019)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x1b61be);};a0_0x33f1['jNmgub']=_0x1e53fd,a0_0x33f1['ISxPoY']={},a0_0x33f1['lifagL']=!![];}const _0x2e9c16=_0x532f07[0x0],_0xe76ce3=_0x3905b7+_0x2e9c16,_0x4cb498=a0_0x33f1['ISxPoY'][_0xe76ce3];return!_0x4cb498?(_0x33f1f8=a0_0x33f1['jNmgub'](_0x33f1f8),a0_0x33f1['ISxPoY'][_0xe76ce3]=_0x33f1f8):_0x33f1f8=_0x4cb498,_0x33f1f8;}class AsyncToolManager extends a0_0x357292{constructor(_0x1b61be={},_0x201868=null){const _0x42c7d1=a0_0x33f1;super(),this[_0x42c7d1(0x207)]=_0x1b61be,this['logger']=_0x201868,this[_0x42c7d1(0x210)]=new Map(),this[_0x42c7d1(0x225)]=[],this['maxConcurrentOperations']=_0x1b61be['maxConcurrentOperations']||0xa,this[_0x42c7d1(0x23f)]=_0x1b61be[_0x42c7d1(0x23f)]||0x493e0,this[_0x42c7d1(0x233)]=_0x1b61be['cleanupInterval']||0xea60,this['maxHistorySize']=_0x1b61be['maxHistorySize']||0x3e8,this['monitoringInterval']=null,this[_0x42c7d1(0x201)]=![],this['startMonitoring'](),this['on']('operation:started',this['handleOperationStarted']['bind'](this)),this['on']('operation:completed',this[_0x42c7d1(0x219)][_0x42c7d1(0x1f4)](this)),this['on']('operation:failed',this[_0x42c7d1(0x204)]['bind'](this)),this['on']('operation:timeout',this[_0x42c7d1(0x21d)][_0x42c7d1(0x1f4)](this));}async['startOperation'](_0x5aa482,_0x486746,_0x3d01c5,_0x526019={}){const _0x203c58=a0_0x33f1;if(this['operations']['size']>=this['maxConcurrentOperations'])throw new Error('Maximum\x20concurrent\x20operations\x20reached\x20('+this['maxConcurrentOperations']+')');const _0x3fc7d0=this[_0x203c58(0x20a)](),_0x3a20a7={'id':_0x3fc7d0,'toolId':_0x5aa482,'agentId':_0x486746,'parameters':_0x3d01c5,'context':_0x526019,'status':TOOL_STATUS['PENDING'],'createdAt':new Date()['toISOString'](),'startedAt':null,'completedAt':null,'timeout':_0x526019[_0x203c58(0x245)]||this[_0x203c58(0x23f)],'result':null,'error':null,'progress':null,'retryCount':0x0,'maxRetries':_0x526019['maxRetries']||0x0};return this['operations']['set'](_0x3fc7d0,_0x3a20a7),this['logger']?.[_0x203c58(0x220)](_0x203c58(0x22b)+_0x3fc7d0,{'toolId':_0x5aa482,'agentId':_0x486746,'parametersCount':Object['keys'](_0x3d01c5)[_0x203c58(0x1fe)],'timeout':_0x3a20a7['timeout']}),this[_0x203c58(0x240)](_0x3fc7d0),this[_0x203c58(0x21e)](_0x203c58(0x226),_0x3a20a7),_0x3fc7d0;}[a0_0x43050a(0x208)](_0x4de540,_0x1ede1b,_0x423c6f={}){const _0x59911b=a0_0x43050a,_0x7647f2=this['operations'][_0x59911b(0x1f7)](_0x4de540);if(!_0x7647f2)return this['logger']?.[_0x59911b(0x23d)](_0x59911b(0x23b)+_0x4de540),![];const _0xb91183=_0x7647f2[_0x59911b(0x212)];_0x7647f2[_0x59911b(0x212)]=_0x1ede1b;_0x1ede1b===TOOL_STATUS[_0x59911b(0x214)]&&!_0x7647f2[_0x59911b(0x236)]&&(_0x7647f2['startedAt']=new Date()[_0x59911b(0x238)]());(_0x1ede1b===TOOL_STATUS[_0x59911b(0x1ff)]||_0x1ede1b===TOOL_STATUS['FAILED'])&&(_0x7647f2[_0x59911b(0x23e)]=new Date()['toISOString']());if(_0x423c6f[_0x59911b(0x1f5)]!==undefined)_0x7647f2[_0x59911b(0x1f5)]=_0x423c6f['result'];if(_0x423c6f[_0x59911b(0x1fc)]!==undefined)_0x7647f2[_0x59911b(0x1fc)]=_0x423c6f['error'];if(_0x423c6f[_0x59911b(0x1fd)]!==undefined)_0x7647f2['progress']=_0x423c6f[_0x59911b(0x1fd)];this['logger']?.[_0x59911b(0x205)](_0x59911b(0x24a)+_0x4de540,{'previousStatus':_0xb91183,'newStatus':_0x1ede1b,'hasResult':!!_0x423c6f[_0x59911b(0x1f5)],'hasError':!!_0x423c6f[_0x59911b(0x1fc)],'progress':_0x423c6f['progress']});switch(_0x1ede1b){case TOOL_STATUS['COMPLETED']:this[_0x59911b(0x21e)](_0x59911b(0x20c),_0x7647f2);break;case TOOL_STATUS[_0x59911b(0x22e)]:this['emit']('operation:failed',_0x7647f2);break;case TOOL_STATUS[_0x59911b(0x214)]:this['emit']('operation:progress',_0x7647f2);break;}return!![];}['getOperation'](_0x49dae3){const _0x57ccd4=a0_0x43050a,_0x3b0d01=this[_0x57ccd4(0x210)][_0x57ccd4(0x1f7)](_0x49dae3);if(!_0x3b0d01)return null;return{'id':_0x3b0d01['id'],'toolId':_0x3b0d01['toolId'],'agentId':_0x3b0d01[_0x57ccd4(0x231)],'status':_0x3b0d01[_0x57ccd4(0x212)],'createdAt':_0x3b0d01['createdAt'],'startedAt':_0x3b0d01[_0x57ccd4(0x236)],'completedAt':_0x3b0d01['completedAt'],'result':_0x3b0d01[_0x57ccd4(0x1f5)],'error':_0x3b0d01[_0x57ccd4(0x1fc)],'progress':_0x3b0d01[_0x57ccd4(0x1fd)],'retryCount':_0x3b0d01['retryCount'],'executionTime':this[_0x57ccd4(0x1f3)](_0x3b0d01)};}['getAgentOperations'](_0x5e50fd){const _0x5675ce=a0_0x43050a,_0x2dc182=[];for(const _0x1cc194 of this[_0x5675ce(0x210)][_0x5675ce(0x1f8)]()){_0x1cc194['agentId']===_0x5e50fd&&_0x2dc182[_0x5675ce(0x244)](this['getOperation'](_0x1cc194['id']));}return _0x2dc182['sort']((_0x1d1924,_0xe41a63)=>new Date(_0xe41a63['createdAt'])-new Date(_0x1d1924[_0x5675ce(0x200)]));}async['cancelOperation'](_0x3878d6,_0x1a0b25=a0_0x43050a(0x234)){const _0x587846=a0_0x43050a,_0x4edd7c=this[_0x587846(0x210)]['get'](_0x3878d6);if(!_0x4edd7c)return![];if(_0x4edd7c[_0x587846(0x212)]===TOOL_STATUS['COMPLETED']||_0x4edd7c['status']===TOOL_STATUS[_0x587846(0x22e)])return this['logger']?.[_0x587846(0x23d)](_0x587846(0x23a)+_0x3878d6),![];return this[_0x587846(0x208)](_0x3878d6,TOOL_STATUS[_0x587846(0x215)],{'error':_0x1a0b25}),this['clearOperationTimeout'](_0x3878d6),this[_0x587846(0x21e)](_0x587846(0x248),_0x4edd7c),await this[_0x587846(0x218)](_0x3878d6),this[_0x587846(0x211)]?.[_0x587846(0x220)]('Operation\x20cancelled:\x20'+_0x3878d6,{'reason':_0x1a0b25}),!![];}async['retryOperation'](_0x292b63){const _0x5416b3=a0_0x43050a,_0x2f1cd6=this['operations']['get'](_0x292b63);if(!_0x2f1cd6)return![];if(_0x2f1cd6[_0x5416b3(0x212)]!==TOOL_STATUS['FAILED'])return this['logger']?.['warn']('Cannot\x20retry\x20non-failed\x20operation:\x20'+_0x292b63),![];if(_0x2f1cd6[_0x5416b3(0x202)]>=_0x2f1cd6[_0x5416b3(0x229)])return this['logger']?.['warn'](_0x5416b3(0x206)+_0x292b63),![];return _0x2f1cd6['retryCount']++,_0x2f1cd6['status']=TOOL_STATUS['PENDING'],_0x2f1cd6[_0x5416b3(0x236)]=null,_0x2f1cd6[_0x5416b3(0x23e)]=null,_0x2f1cd6['error']=null,_0x2f1cd6[_0x5416b3(0x1f5)]=null,this['setOperationTimeout'](_0x292b63),this['logger']?.['info']('Operation\x20retry\x20initiated:\x20'+_0x292b63,{'retryCount':_0x2f1cd6[_0x5416b3(0x202)],'maxRetries':_0x2f1cd6[_0x5416b3(0x229)]}),this[_0x5416b3(0x21e)]('operation:retry',_0x2f1cd6),!![];}[a0_0x43050a(0x224)](){const _0x33c65d=a0_0x43050a,_0x172dd6={'total':this[_0x33c65d(0x210)]['size'],'byStatus':{},'byTool':{},'byAgent':{},'averageExecutionTime':0x0,'oldestOperation':null,'newestOperation':null};let _0x3a28bc=0x0,_0x1267fe=0x0,_0x201716=null,_0x284cdb=null;for(const _0x2b45bf of this['operations'][_0x33c65d(0x1f8)]()){_0x172dd6['byStatus'][_0x2b45bf[_0x33c65d(0x212)]]=(_0x172dd6[_0x33c65d(0x227)][_0x2b45bf[_0x33c65d(0x212)]]||0x0)+0x1,_0x172dd6['byTool'][_0x2b45bf[_0x33c65d(0x222)]]=(_0x172dd6[_0x33c65d(0x23c)][_0x2b45bf['toolId']]||0x0)+0x1,_0x172dd6[_0x33c65d(0x1f9)][_0x2b45bf[_0x33c65d(0x231)]]=(_0x172dd6[_0x33c65d(0x1f9)][_0x2b45bf[_0x33c65d(0x231)]]||0x0)+0x1;const _0x2276c5=this[_0x33c65d(0x1f3)](_0x2b45bf);_0x2276c5>0x0&&(_0x3a28bc+=_0x2276c5,_0x1267fe++);const _0x1f44da=new Date(_0x2b45bf['createdAt'])['getTime']();(!_0x201716||_0x1f44da<_0x201716)&&(_0x201716=_0x1f44da,_0x172dd6[_0x33c65d(0x22c)]=_0x2b45bf['id']),(!_0x284cdb||_0x1f44da>_0x284cdb)&&(_0x284cdb=_0x1f44da,_0x172dd6[_0x33c65d(0x221)]=_0x2b45bf['id']);}return _0x172dd6['averageExecutionTime']=_0x1267fe>0x0?Math['round'](_0x3a28bc/_0x1267fe):0x0,_0x172dd6;}async['cleanupCompletedOperations'](_0x141fb4=0x36ee80){const _0x3c5686=a0_0x43050a,_0x5d9c4f=Date['now']()-_0x141fb4,_0x476178=[];for(const _0x24bb0d of this[_0x3c5686(0x210)][_0x3c5686(0x1f8)]()){(_0x24bb0d['status']===TOOL_STATUS[_0x3c5686(0x1ff)]||_0x24bb0d['status']===TOOL_STATUS['FAILED']||_0x24bb0d['status']===TOOL_STATUS['CANCELLED'])&&new Date(_0x24bb0d[_0x3c5686(0x23e)])[_0x3c5686(0x21c)]()<_0x5d9c4f&&_0x476178['push'](_0x24bb0d['id']);}for(const _0x229e37 of _0x476178){await this['cleanupOperation'](_0x229e37);}return this[_0x3c5686(0x211)]?.[_0x3c5686(0x205)]('Cleaned\x20up\x20'+_0x476178['length']+_0x3c5686(0x1f6)),_0x476178[_0x3c5686(0x1fe)];}[a0_0x43050a(0x217)](){const _0x585640=a0_0x43050a;this['monitoringInterval']&&clearInterval(this['monitoringInterval']),this['monitoringInterval']=setInterval(()=>{this['checkOperationTimeouts'](),this['cleanupCompletedOperations']();},this['cleanupInterval']),this['logger']?.[_0x585640(0x220)](_0x585640(0x21a));}[a0_0x43050a(0x246)](){const _0x15bcb9=a0_0x43050a;this['monitoringInterval']&&(clearInterval(this['monitoringInterval']),this[_0x15bcb9(0x216)]=null),this['logger']?.['info']('Async\x20tool\x20manager\x20monitoring\x20stopped');}['checkOperationTimeouts'](){const _0x532192=a0_0x43050a,_0x2a812d=Date[_0x532192(0x21f)]();for(const _0x1b8696 of this['operations']['values']()){if(_0x1b8696['status']===TOOL_STATUS['EXECUTING']||_0x1b8696['status']===TOOL_STATUS['PENDING']){const _0x14e707=new Date(_0x1b8696['createdAt'])['getTime']();_0x2a812d-_0x14e707>_0x1b8696[_0x532192(0x245)]&&this['handleOperationTimeout'](_0x1b8696);}}}[a0_0x43050a(0x240)](_0x5b3f19){const _0xb0f040=a0_0x43050a,_0x4f681d=this[_0xb0f040(0x210)]['get'](_0x5b3f19);if(!_0x4f681d)return;_0x4f681d['timeoutHandle']=setTimeout(()=>{this['handleOperationTimeout'](_0x4f681d);},_0x4f681d[_0xb0f040(0x245)]);}[a0_0x43050a(0x209)](_0x37b318){const _0x361822=a0_0x43050a,_0x25eb44=this['operations'][_0x361822(0x1f7)](_0x37b318);_0x25eb44&&_0x25eb44[_0x361822(0x1f0)]&&(clearTimeout(_0x25eb44['timeoutHandle']),delete _0x25eb44['timeoutHandle']);}[a0_0x43050a(0x20a)](){const _0x3a3d1c=a0_0x43050a,_0x16a408=Date['now']()[_0x3a3d1c(0x22a)](0x24),_0x9acdbe=Math[_0x3a3d1c(0x22d)]()['toString'](0x24)[_0x3a3d1c(0x20b)](0x2,0x9);return'op-'+_0x16a408+'-'+_0x9acdbe;}[a0_0x43050a(0x1f3)](_0xc5d50e){const _0x404e4d=a0_0x43050a;if(!_0xc5d50e['startedAt'])return 0x0;const _0x160d4d=_0xc5d50e[_0x404e4d(0x23e)]?new Date(_0xc5d50e['completedAt'])[_0x404e4d(0x21c)]():Date[_0x404e4d(0x21f)]();return _0x160d4d-new Date(_0xc5d50e[_0x404e4d(0x236)])['getTime']();}async['cleanupOperation'](_0x5d7c70){const _0x8a9a90=a0_0x43050a,_0x8aa98a=this['operations']['get'](_0x5d7c70);if(!_0x8aa98a)return;this['clearOperationTimeout'](_0x5d7c70),this[_0x8a9a90(0x225)]['push']({..._0x8aa98a,'executionTime':this['calculateExecutionTime'](_0x8aa98a),'cleanedUpAt':new Date()[_0x8a9a90(0x238)]()}),this['operationHistory'][_0x8a9a90(0x1fe)]>this['maxHistorySize']&&(this[_0x8a9a90(0x225)]=this[_0x8a9a90(0x225)][_0x8a9a90(0x20e)](-this['maxHistorySize'])),this[_0x8a9a90(0x210)]['delete'](_0x5d7c70),this['emit']('operation:cleanup',{'operationId':_0x5d7c70,'toolId':_0x8aa98a['toolId']});}[a0_0x43050a(0x20f)](_0x21ad0c){const _0x3ded2e=a0_0x43050a;this['logger']?.[_0x3ded2e(0x205)](_0x3ded2e(0x230)+_0x21ad0c['id'],{'toolId':_0x21ad0c['toolId'],'agentId':_0x21ad0c['agentId']});}async['handleOperationCompleted'](_0x30cc1d){const _0x8b9ec2=a0_0x43050a;this[_0x8b9ec2(0x211)]?.[_0x8b9ec2(0x220)](_0x8b9ec2(0x1fa)+_0x30cc1d['id'],{'toolId':_0x30cc1d[_0x8b9ec2(0x222)],'agentId':_0x30cc1d['agentId'],'executionTime':this[_0x8b9ec2(0x1f3)](_0x30cc1d)}),setTimeout(()=>this[_0x8b9ec2(0x218)](_0x30cc1d['id']),0x7530);}async[a0_0x43050a(0x204)](_0x1213a4){const _0x40e59b=a0_0x43050a;this[_0x40e59b(0x211)]?.['error']('Operation\x20failed:\x20'+_0x1213a4['id'],{'toolId':_0x1213a4[_0x40e59b(0x222)],'agentId':_0x1213a4['agentId'],'error':_0x1213a4['error'],'executionTime':this['calculateExecutionTime'](_0x1213a4),'retryCount':_0x1213a4[_0x40e59b(0x202)]}),_0x1213a4['retryCount']<_0x1213a4[_0x40e59b(0x229)]?setTimeout(()=>this[_0x40e59b(0x21b)](_0x1213a4['id']),0x1388):setTimeout(()=>this['cleanupOperation'](_0x1213a4['id']),0xea60);}async['handleOperationTimeout'](_0x8b84c0){const _0xe6d17a=a0_0x43050a;this['logger']?.[_0xe6d17a(0x23d)](_0xe6d17a(0x22f)+_0x8b84c0['id'],{'toolId':_0x8b84c0['toolId'],'agentId':_0x8b84c0[_0xe6d17a(0x231)],'timeout':_0x8b84c0['timeout'],'executionTime':this[_0xe6d17a(0x1f3)](_0x8b84c0)}),this[_0xe6d17a(0x208)](_0x8b84c0['id'],TOOL_STATUS['TIMEOUT'],{'error':_0xe6d17a(0x223)+_0x8b84c0['timeout']+'ms'}),this['emit'](_0xe6d17a(0x239),_0x8b84c0),setTimeout(()=>this[_0xe6d17a(0x218)](_0x8b84c0['id']),0x7530);}async['shutdown'](){const _0x1d2515=a0_0x43050a;this['isShuttingDown']=!![],this['logger']?.[_0x1d2515(0x220)]('Shutting down async tool manager...'),this[_0x1d2515(0x246)]();const _0x11d0b1=[];for(const _0x2f6a8f of this[_0x1d2515(0x210)]['values']()){(_0x2f6a8f[_0x1d2515(0x212)]===TOOL_STATUS['PENDING']||_0x2f6a8f['status']===TOOL_STATUS[_0x1d2515(0x214)])&&_0x11d0b1['push'](_0x2f6a8f['id']);}for(const _0x1c6ce5 of _0x11d0b1){await this[_0x1d2515(0x20d)](_0x1c6ce5,_0x1d2515(0x213));}this['operations']['clear'](),this[_0x1d2515(0x211)]?.[_0x1d2515(0x220)]('Async\x20tool\x20manager\x20shutdown\x20complete.\x20Cancelled\x20'+_0x11d0b1['length']+'\x20operations.');}[a0_0x43050a(0x235)](_0x2619ab={}){const _0x5d4257=a0_0x43050a;let _0x3e679f=[...this[_0x5d4257(0x225)]];return _0x2619ab['agentId']&&(_0x3e679f=_0x3e679f['filter'](_0x14559b=>_0x14559b[_0x5d4257(0x231)]===_0x2619ab[_0x5d4257(0x231)])),_0x2619ab[_0x5d4257(0x222)]&&(_0x3e679f=_0x3e679f[_0x5d4257(0x243)](_0x11660a=>_0x11660a['toolId']===_0x2619ab['toolId'])),_0x2619ab[_0x5d4257(0x212)]&&(_0x3e679f=_0x3e679f['filter'](_0x86a4e1=>_0x86a4e1['status']===_0x2619ab[_0x5d4257(0x212)])),_0x2619ab[_0x5d4257(0x242)]&&(_0x3e679f=_0x3e679f['slice'](-_0x2619ab[_0x5d4257(0x242)])),_0x3e679f['sort']((_0x4261cb,_0x2ab38e)=>new Date(_0x2ab38e['createdAt'])-new Date(_0x4261cb[_0x5d4257(0x200)]));}}export default AsyncToolManager;
|