@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.
Files changed (120) hide show
  1. package/README.md +44 -54
  2. package/bin/cli.js +1 -115
  3. package/bin/loxia-terminal-v2.js +3 -0
  4. package/bin/loxia-terminal.js +3 -0
  5. package/bin/start-with-terminal.js +3 -0
  6. package/package.json +15 -15
  7. package/scripts/install-scanners.js +1 -235
  8. package/src/analyzers/CSSAnalyzer.js +1 -297
  9. package/src/analyzers/ConfigValidator.js +1 -690
  10. package/src/analyzers/ESLintAnalyzer.js +1 -320
  11. package/src/analyzers/JavaScriptAnalyzer.js +1 -261
  12. package/src/analyzers/PrettierFormatter.js +1 -247
  13. package/src/analyzers/PythonAnalyzer.js +1 -266
  14. package/src/analyzers/SecurityAnalyzer.js +1 -729
  15. package/src/analyzers/TypeScriptAnalyzer.js +1 -247
  16. package/src/analyzers/codeCloneDetector/analyzer.js +1 -344
  17. package/src/analyzers/codeCloneDetector/detector.js +1 -203
  18. package/src/analyzers/codeCloneDetector/index.js +1 -160
  19. package/src/analyzers/codeCloneDetector/parser.js +1 -199
  20. package/src/analyzers/codeCloneDetector/reporter.js +1 -148
  21. package/src/analyzers/codeCloneDetector/scanner.js +1 -59
  22. package/src/core/agentPool.js +1 -1474
  23. package/src/core/agentScheduler.js +1 -2147
  24. package/src/core/contextManager.js +1 -709
  25. package/src/core/messageProcessor.js +1 -732
  26. package/src/core/orchestrator.js +1 -548
  27. package/src/core/stateManager.js +1 -877
  28. package/src/index.js +1 -631
  29. package/src/interfaces/cli.js +1 -549
  30. package/src/interfaces/terminal/__tests__/smoke/advancedFeatures.test.js +1 -0
  31. package/src/interfaces/terminal/__tests__/smoke/agentControl.test.js +1 -0
  32. package/src/interfaces/terminal/__tests__/smoke/agents.test.js +1 -0
  33. package/src/interfaces/terminal/__tests__/smoke/components.test.js +1 -0
  34. package/src/interfaces/terminal/__tests__/smoke/connection.test.js +1 -0
  35. package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +1 -0
  36. package/src/interfaces/terminal/__tests__/smoke/imports.test.js +1 -0
  37. package/src/interfaces/terminal/__tests__/smoke/messages.test.js +1 -0
  38. package/src/interfaces/terminal/__tests__/smoke/tools.test.js +1 -0
  39. package/src/interfaces/terminal/api/apiClient.js +1 -0
  40. package/src/interfaces/terminal/api/messageRouter.js +1 -0
  41. package/src/interfaces/terminal/api/session.js +1 -0
  42. package/src/interfaces/terminal/api/websocket.js +1 -0
  43. package/src/interfaces/terminal/components/AgentCreator.js +1 -0
  44. package/src/interfaces/terminal/components/AgentEditor.js +1 -0
  45. package/src/interfaces/terminal/components/AgentSwitcher.js +1 -0
  46. package/src/interfaces/terminal/components/ErrorBoundary.js +1 -0
  47. package/src/interfaces/terminal/components/ErrorPanel.js +1 -0
  48. package/src/interfaces/terminal/components/Header.js +1 -0
  49. package/src/interfaces/terminal/components/HelpPanel.js +1 -0
  50. package/src/interfaces/terminal/components/InputBox.js +1 -0
  51. package/src/interfaces/terminal/components/Layout.js +1 -0
  52. package/src/interfaces/terminal/components/LoadingSpinner.js +1 -0
  53. package/src/interfaces/terminal/components/MessageList.js +1 -0
  54. package/src/interfaces/terminal/components/MultilineTextInput.js +1 -0
  55. package/src/interfaces/terminal/components/SearchPanel.js +1 -0
  56. package/src/interfaces/terminal/components/SettingsPanel.js +1 -0
  57. package/src/interfaces/terminal/components/StatusBar.js +1 -0
  58. package/src/interfaces/terminal/components/TextInput.js +1 -0
  59. package/src/interfaces/terminal/config/agentEditorConstants.js +1 -0
  60. package/src/interfaces/terminal/config/constants.js +1 -0
  61. package/src/interfaces/terminal/index.js +1 -0
  62. package/src/interfaces/terminal/state/useAgentControl.js +1 -0
  63. package/src/interfaces/terminal/state/useAgents.js +1 -0
  64. package/src/interfaces/terminal/state/useConnection.js +1 -0
  65. package/src/interfaces/terminal/state/useMessages.js +1 -0
  66. package/src/interfaces/terminal/state/useTools.js +1 -0
  67. package/src/interfaces/terminal/utils/debugLogger.js +1 -0
  68. package/src/interfaces/terminal/utils/settingsStorage.js +1 -0
  69. package/src/interfaces/terminal/utils/theme.js +1 -0
  70. package/src/interfaces/webServer.js +1 -2162
  71. package/src/modules/fileExplorer/controller.js +1 -280
  72. package/src/modules/fileExplorer/index.js +1 -37
  73. package/src/modules/fileExplorer/middleware.js +1 -92
  74. package/src/modules/fileExplorer/routes.js +1 -125
  75. package/src/modules/fileExplorer/types.js +1 -44
  76. package/src/services/aiService.js +1 -1232
  77. package/src/services/apiKeyManager.js +1 -164
  78. package/src/services/benchmarkService.js +1 -366
  79. package/src/services/budgetService.js +1 -539
  80. package/src/services/contextInjectionService.js +1 -247
  81. package/src/services/conversationCompactionService.js +1 -637
  82. package/src/services/errorHandler.js +1 -810
  83. package/src/services/fileAttachmentService.js +1 -544
  84. package/src/services/modelRouterService.js +1 -366
  85. package/src/services/modelsService.js +1 -322
  86. package/src/services/qualityInspector.js +1 -796
  87. package/src/services/tokenCountingService.js +1 -536
  88. package/src/tools/agentCommunicationTool.js +1 -1344
  89. package/src/tools/agentDelayTool.js +1 -485
  90. package/src/tools/asyncToolManager.js +1 -604
  91. package/src/tools/baseTool.js +1 -800
  92. package/src/tools/browserTool.js +1 -920
  93. package/src/tools/cloneDetectionTool.js +1 -621
  94. package/src/tools/dependencyResolverTool.js +1 -1215
  95. package/src/tools/fileContentReplaceTool.js +1 -875
  96. package/src/tools/fileSystemTool.js +1 -1107
  97. package/src/tools/fileTreeTool.js +1 -853
  98. package/src/tools/imageTool.js +1 -901
  99. package/src/tools/importAnalyzerTool.js +1 -1060
  100. package/src/tools/jobDoneTool.js +1 -248
  101. package/src/tools/seekTool.js +1 -956
  102. package/src/tools/staticAnalysisTool.js +1 -1778
  103. package/src/tools/taskManagerTool.js +1 -2873
  104. package/src/tools/terminalTool.js +1 -2304
  105. package/src/tools/webTool.js +1 -1430
  106. package/src/types/agent.js +1 -519
  107. package/src/types/contextReference.js +1 -972
  108. package/src/types/conversation.js +1 -730
  109. package/src/types/toolCommand.js +1 -747
  110. package/src/utilities/attachmentValidator.js +1 -292
  111. package/src/utilities/configManager.js +1 -582
  112. package/src/utilities/constants.js +1 -722
  113. package/src/utilities/directoryAccessManager.js +1 -535
  114. package/src/utilities/fileProcessor.js +1 -307
  115. package/src/utilities/logger.js +1 -436
  116. package/src/utilities/tagParser.js +1 -1246
  117. package/src/utilities/toolConstants.js +1 -317
  118. package/web-ui/build/index.html +2 -2
  119. package/web-ui/build/static/{index-Dy2bYbOa.css → index-CClD1090.css} +1 -1
  120. package/web-ui/build/static/{index-CjkkcnFA.js → index-lCBai6dX.js} +66 -67
@@ -1,810 +1 @@
1
- import { ERROR_TYPES, HTTP_STATUS, AGENT_STATUS } from '../utilities/constants.js';
2
-
3
- /**
4
- * Comprehensive error handling service for the Loxia AI Agents System
5
- * Provides error classification, recovery strategies, and monitoring
6
- */
7
- export class ErrorHandler {
8
- constructor(config, logger) {
9
- this.config = config || {};
10
- this.logger = logger;
11
- this.errorStats = {
12
- totalErrors: 0,
13
- errorsByType: new Map(),
14
- errorsByAgent: new Map(),
15
- recoveryAttempts: 0,
16
- successfulRecoveries: 0,
17
- criticalErrors: 0
18
- };
19
-
20
- this.recoveryStrategies = new Map();
21
- this.errorSubscribers = new Set();
22
- this.errorQueue = [];
23
- this.isProcessingQueue = false;
24
-
25
- this.initializeRecoveryStrategies();
26
- this.setupErrorProcessing();
27
- }
28
-
29
- /**
30
- * Handle an error with appropriate classification and recovery
31
- * @param {Error|Object} error - Error object or error data
32
- * @param {Object} context - Error context information
33
- * @returns {Object} Error handling result
34
- */
35
- async handleError(error, context = {}) {
36
- try {
37
- const errorInfo = this.classifyError(error, context);
38
- const handlingResult = await this.processError(errorInfo);
39
-
40
- this.updateErrorStats(errorInfo);
41
- this.notifySubscribers(errorInfo, handlingResult);
42
-
43
- return handlingResult;
44
-
45
- } catch (handlingError) {
46
- this.logger.error('Error handling failed', {
47
- originalError: error.message,
48
- handlingError: handlingError.message
49
- });
50
-
51
- return {
52
- success: false,
53
- error: handlingError,
54
- recovery: null,
55
- severity: 'critical'
56
- };
57
- }
58
- }
59
-
60
- /**
61
- * Classify error by type, severity, and context
62
- * @param {Error|Object} error - Error to classify
63
- * @param {Object} context - Error context
64
- * @returns {Object} Classified error information
65
- */
66
- classifyError(error, context = {}) {
67
- const errorInfo = {
68
- id: this.generateErrorId(),
69
- timestamp: new Date().toISOString(),
70
- message: error.message || error.toString(),
71
- stack: error.stack || null,
72
- code: error.code || null,
73
- type: this.determineErrorType(error, context),
74
- severity: this.determineSeverity(error, context),
75
- context: { ...context },
76
- recoverable: true,
77
- retryCount: context.retryCount || 0,
78
- maxRetries: this.getMaxRetries(error, context)
79
- };
80
-
81
- // Additional classification based on context
82
- if (context.agentId) {
83
- errorInfo.agentId = context.agentId;
84
- }
85
-
86
- if (context.toolId) {
87
- errorInfo.toolId = context.toolId;
88
- }
89
-
90
- if (context.operationId) {
91
- errorInfo.operationId = context.operationId;
92
- }
93
-
94
- // Determine if error is recoverable
95
- errorInfo.recoverable = this.isRecoverable(errorInfo);
96
-
97
- return errorInfo;
98
- }
99
-
100
- /**
101
- * Process error with appropriate recovery strategy
102
- * @param {Object} errorInfo - Classified error information
103
- * @returns {Object} Processing result
104
- */
105
- async processError(errorInfo) {
106
- try {
107
- this.logger.error('Processing error', {
108
- errorId: errorInfo.id,
109
- type: errorInfo.type,
110
- severity: errorInfo.severity,
111
- agentId: errorInfo.agentId,
112
- message: errorInfo.message
113
- });
114
-
115
- // Check if this is a critical error requiring immediate attention
116
- if (errorInfo.severity === 'critical') {
117
- await this.handleCriticalError(errorInfo);
118
- }
119
-
120
- // Attempt recovery if error is recoverable
121
- let recoveryResult = null;
122
- if (errorInfo.recoverable && errorInfo.retryCount < errorInfo.maxRetries) {
123
- recoveryResult = await this.attemptRecovery(errorInfo);
124
- }
125
-
126
- // Log error for monitoring and analysis
127
- await this.logError(errorInfo, recoveryResult);
128
-
129
- return {
130
- success: recoveryResult?.success || false,
131
- errorId: errorInfo.id,
132
- errorType: errorInfo.type,
133
- severity: errorInfo.severity,
134
- recovery: recoveryResult,
135
- shouldRetry: this.shouldRetry(errorInfo, recoveryResult),
136
- retryDelay: this.calculateRetryDelay(errorInfo)
137
- };
138
-
139
- } catch (processingError) {
140
- this.logger.error('Error processing failed', {
141
- errorId: errorInfo.id,
142
- processingError: processingError.message
143
- });
144
-
145
- return {
146
- success: false,
147
- errorId: errorInfo.id,
148
- errorType: errorInfo.type,
149
- severity: 'critical',
150
- recovery: null,
151
- shouldRetry: false
152
- };
153
- }
154
- }
155
-
156
- /**
157
- * Attempt to recover from an error using appropriate strategy
158
- * @param {Object} errorInfo - Error information
159
- * @returns {Object} Recovery result
160
- */
161
- async attemptRecovery(errorInfo) {
162
- try {
163
- this.errorStats.recoveryAttempts++;
164
-
165
- const strategy = this.recoveryStrategies.get(errorInfo.type) ||
166
- this.recoveryStrategies.get('default');
167
-
168
- if (!strategy) {
169
- this.logger.warn('No recovery strategy found', { errorType: errorInfo.type });
170
- return { success: false, reason: 'No recovery strategy available' };
171
- }
172
-
173
- this.logger.info('Attempting error recovery', {
174
- errorId: errorInfo.id,
175
- errorType: errorInfo.type,
176
- strategy: strategy.name,
177
- retryCount: errorInfo.retryCount
178
- });
179
-
180
- const recoveryResult = await strategy.recover(errorInfo);
181
-
182
- if (recoveryResult.success) {
183
- this.errorStats.successfulRecoveries++;
184
- this.logger.info('Error recovery successful', {
185
- errorId: errorInfo.id,
186
- strategy: strategy.name
187
- });
188
- } else {
189
- this.logger.warn('Error recovery failed', {
190
- errorId: errorInfo.id,
191
- strategy: strategy.name,
192
- reason: recoveryResult.reason
193
- });
194
- }
195
-
196
- return recoveryResult;
197
-
198
- } catch (recoveryError) {
199
- this.logger.error('Recovery attempt failed', {
200
- errorId: errorInfo.id,
201
- recoveryError: recoveryError.message
202
- });
203
-
204
- return {
205
- success: false,
206
- reason: `Recovery attempt failed: ${recoveryError.message}`
207
- };
208
- }
209
- }
210
-
211
- /**
212
- * Handle critical errors that require immediate attention
213
- * @param {Object} errorInfo - Critical error information
214
- */
215
- async handleCriticalError(errorInfo) {
216
- try {
217
- this.errorStats.criticalErrors++;
218
-
219
- this.logger.error('Critical error detected', {
220
- errorId: errorInfo.id,
221
- message: errorInfo.message,
222
- context: errorInfo.context
223
- });
224
-
225
- // Emit critical error event
226
- if (typeof process !== 'undefined' && process.emit) {
227
- process.emit('criticalError', errorInfo);
228
- }
229
-
230
- // Take immediate protective actions based on error type
231
- switch (errorInfo.type) {
232
- case ERROR_TYPES.AUTHENTICATION_FAILED:
233
- await this.handleAuthenticationFailure(errorInfo);
234
- break;
235
-
236
- case ERROR_TYPES.RATE_LIMIT_EXCEEDED:
237
- await this.handleRateLimitExceeded(errorInfo);
238
- break;
239
-
240
- case ERROR_TYPES.OPERATION_TIMEOUT:
241
- await this.handleOperationTimeout(errorInfo);
242
- break;
243
-
244
- default:
245
- await this.handleGenericCriticalError(errorInfo);
246
- }
247
-
248
- } catch (criticalHandlingError) {
249
- this.logger.error('Critical error handling failed', {
250
- errorId: errorInfo.id,
251
- handlingError: criticalHandlingError.message
252
- });
253
- }
254
- }
255
-
256
- /**
257
- * Determine error type based on error and context
258
- * @param {Error|Object} error - Error object
259
- * @param {Object} context - Error context
260
- * @returns {string} Error type
261
- */
262
- determineErrorType(error, context) {
263
- // Check error code or HTTP status
264
- if (error.code === 'ENOENT' || error.status === HTTP_STATUS.NOT_FOUND) {
265
- return ERROR_TYPES.FILE_NOT_FOUND;
266
- }
267
-
268
- if (error.code === 'EACCES' || error.status === HTTP_STATUS.FORBIDDEN) {
269
- return ERROR_TYPES.PERMISSION_DENIED;
270
- }
271
-
272
- if (error.status === HTTP_STATUS.UNAUTHORIZED) {
273
- return ERROR_TYPES.AUTHENTICATION_FAILED;
274
- }
275
-
276
- if (error.status === HTTP_STATUS.TOO_MANY_REQUESTS) {
277
- return ERROR_TYPES.RATE_LIMIT_EXCEEDED;
278
- }
279
-
280
- // Check error message patterns
281
- const message = error.message?.toLowerCase() || '';
282
-
283
- if (message.includes('timeout') || message.includes('timed out')) {
284
- return ERROR_TYPES.OPERATION_TIMEOUT;
285
- }
286
-
287
- if (message.includes('validation') || message.includes('invalid')) {
288
- return ERROR_TYPES.VALIDATION_ERROR;
289
- }
290
-
291
- if (message.includes('config') || message.includes('configuration')) {
292
- return ERROR_TYPES.CONFIGURATION_ERROR;
293
- }
294
-
295
- // Check context for additional clues
296
- if (context.operation === 'file_operation') {
297
- return ERROR_TYPES.FILE_NOT_FOUND;
298
- }
299
-
300
- if (context.operation === 'api_request') {
301
- return ERROR_TYPES.RATE_LIMIT_EXCEEDED;
302
- }
303
-
304
- return ERROR_TYPES.UNKNOWN_ERROR;
305
- }
306
-
307
- /**
308
- * Determine error severity
309
- * @param {Error|Object} error - Error object
310
- * @param {Object} context - Error context
311
- * @returns {string} Error severity
312
- */
313
- determineSeverity(error, context) {
314
- const criticalTypes = [
315
- ERROR_TYPES.AUTHENTICATION_FAILED,
316
- ERROR_TYPES.CONFIGURATION_ERROR
317
- ];
318
-
319
- const highTypes = [
320
- ERROR_TYPES.RATE_LIMIT_EXCEEDED,
321
- ERROR_TYPES.OPERATION_TIMEOUT,
322
- ERROR_TYPES.PERMISSION_DENIED
323
- ];
324
-
325
- const errorType = this.determineErrorType(error, context);
326
-
327
- if (criticalTypes.includes(errorType)) {
328
- return 'critical';
329
- }
330
-
331
- if (highTypes.includes(errorType)) {
332
- return 'high';
333
- }
334
-
335
- // Check retry count
336
- const retryCount = (context && context.retryCount) || 0;
337
- if (retryCount >= 3) {
338
- return 'high';
339
- }
340
-
341
- // Check if error is affecting agent operation
342
- if (context && context.agentId && context.operation === 'agent_communication') {
343
- return 'medium';
344
- }
345
-
346
- return 'low';
347
- }
348
-
349
- /**
350
- * Check if error is recoverable
351
- * @param {Object} errorInfo - Error information
352
- * @returns {boolean} True if recoverable
353
- */
354
- isRecoverable(errorInfo) {
355
- const nonRecoverableTypes = [
356
- ERROR_TYPES.AUTHENTICATION_FAILED,
357
- ERROR_TYPES.CONFIGURATION_ERROR
358
- ];
359
-
360
- if (nonRecoverableTypes.includes(errorInfo.type)) {
361
- return false;
362
- }
363
-
364
- // Not recoverable if max retries exceeded
365
- if (errorInfo.retryCount >= errorInfo.maxRetries) {
366
- return false;
367
- }
368
-
369
- // Not recoverable if critical severity
370
- if (errorInfo.severity === 'critical') {
371
- return false;
372
- }
373
-
374
- return true;
375
- }
376
-
377
- /**
378
- * Get maximum retry attempts for error type
379
- * @param {Error|Object} error - Error object
380
- * @param {Object} context - Error context
381
- * @returns {number} Maximum retries
382
- */
383
- getMaxRetries(error, context) {
384
- const errorType = this.determineErrorType(error, context);
385
-
386
- const retryLimits = {
387
- [ERROR_TYPES.RATE_LIMIT_EXCEEDED]: 5,
388
- [ERROR_TYPES.OPERATION_TIMEOUT]: 3,
389
- [ERROR_TYPES.FILE_NOT_FOUND]: 2,
390
- [ERROR_TYPES.PERMISSION_DENIED]: 1,
391
- [ERROR_TYPES.VALIDATION_ERROR]: 2,
392
- [ERROR_TYPES.UNKNOWN_ERROR]: 3
393
- };
394
-
395
- return retryLimits[errorType] || 3;
396
- }
397
-
398
- /**
399
- * Determine if error should be retried
400
- * @param {Object} errorInfo - Error information
401
- * @param {Object} recoveryResult - Recovery result
402
- * @returns {boolean} True if should retry
403
- */
404
- shouldRetry(errorInfo, recoveryResult) {
405
- if (!errorInfo.recoverable) {
406
- return false;
407
- }
408
-
409
- if (errorInfo.retryCount >= errorInfo.maxRetries) {
410
- return false;
411
- }
412
-
413
- if (recoveryResult && recoveryResult.success) {
414
- return false; // Recovery succeeded, no need to retry
415
- }
416
-
417
- return true;
418
- }
419
-
420
- /**
421
- * Calculate retry delay based on error information
422
- * @param {Object} errorInfo - Error information
423
- * @returns {number} Delay in milliseconds
424
- */
425
- calculateRetryDelay(errorInfo) {
426
- const baseDelay = 1000; // 1 second
427
- const maxDelay = 30000; // 30 seconds
428
-
429
- // Exponential backoff with jitter
430
- const exponentialDelay = baseDelay * Math.pow(2, errorInfo.retryCount);
431
- const jitter = Math.random() * 1000; // Random jitter up to 1 second
432
-
433
- return Math.min(exponentialDelay + jitter, maxDelay);
434
- }
435
-
436
- /**
437
- * Initialize recovery strategies for different error types
438
- */
439
- initializeRecoveryStrategies() {
440
- // File not found recovery
441
- this.recoveryStrategies.set(ERROR_TYPES.FILE_NOT_FOUND, {
442
- name: 'file_not_found_recovery',
443
- recover: async (errorInfo) => {
444
- if (errorInfo.context.filePath) {
445
- // Try to check if file exists in different location
446
- // or create directory structure if needed
447
- return {
448
- success: false,
449
- reason: 'File recovery not implemented yet',
450
- suggestion: 'Check file path and permissions'
451
- };
452
- }
453
- return { success: false, reason: 'No file path provided' };
454
- }
455
- });
456
-
457
- // Rate limit recovery
458
- this.recoveryStrategies.set(ERROR_TYPES.RATE_LIMIT_EXCEEDED, {
459
- name: 'rate_limit_recovery',
460
- recover: async (errorInfo) => {
461
- const waitTime = this.calculateRateLimitWait(errorInfo);
462
- this.logger.info('Waiting for rate limit recovery', { waitTime });
463
-
464
- await new Promise(resolve => setTimeout(resolve, waitTime));
465
-
466
- return {
467
- success: true,
468
- action: 'waited_for_rate_limit',
469
- waitTime
470
- };
471
- }
472
- });
473
-
474
- // Operation timeout recovery
475
- this.recoveryStrategies.set(ERROR_TYPES.OPERATION_TIMEOUT, {
476
- name: 'timeout_recovery',
477
- recover: async (errorInfo) => {
478
- // Try to increase timeout for next attempt
479
- if (errorInfo.context.timeout) {
480
- const newTimeout = Math.min(errorInfo.context.timeout * 1.5, 300000); // Max 5 minutes
481
- return {
482
- success: true,
483
- action: 'increased_timeout',
484
- newTimeout
485
- };
486
- }
487
-
488
- return { success: false, reason: 'Cannot adjust timeout' };
489
- }
490
- });
491
-
492
- // Permission denied recovery
493
- this.recoveryStrategies.set(ERROR_TYPES.PERMISSION_DENIED, {
494
- name: 'permission_recovery',
495
- recover: async (errorInfo) => {
496
- return {
497
- success: false,
498
- reason: 'Permission errors require manual intervention',
499
- suggestion: 'Check file/directory permissions'
500
- };
501
- }
502
- });
503
-
504
- // Validation error recovery
505
- this.recoveryStrategies.set(ERROR_TYPES.VALIDATION_ERROR, {
506
- name: 'validation_recovery',
507
- recover: async (errorInfo) => {
508
- // Try to clean/sanitize input data
509
- if (errorInfo.context.inputData) {
510
- return {
511
- success: true,
512
- action: 'data_sanitization',
513
- suggestion: 'Input data was sanitized for retry'
514
- };
515
- }
516
-
517
- return { success: false, reason: 'No input data to sanitize' };
518
- }
519
- });
520
-
521
- // Default recovery strategy
522
- this.recoveryStrategies.set('default', {
523
- name: 'default_recovery',
524
- recover: async (errorInfo) => {
525
- // Generic recovery: wait and retry
526
- const delay = this.calculateRetryDelay(errorInfo);
527
- await new Promise(resolve => setTimeout(resolve, delay));
528
-
529
- return {
530
- success: true,
531
- action: 'delay_retry',
532
- delay
533
- };
534
- }
535
- });
536
- }
537
-
538
- /**
539
- * Handle authentication failure
540
- * @param {Object} errorInfo - Error information
541
- */
542
- async handleAuthenticationFailure(errorInfo) {
543
- this.logger.error('Authentication failure detected', { errorId: errorInfo.id });
544
-
545
- // Could trigger token refresh, re-authentication, etc.
546
- if (errorInfo.agentId) {
547
- // Pause agent until authentication is resolved
548
- // await this.orchestrator.pauseAgent(errorInfo.agentId, 300, 'Authentication failure');
549
- }
550
- }
551
-
552
- /**
553
- * Handle rate limit exceeded
554
- * @param {Object} errorInfo - Error information
555
- */
556
- async handleRateLimitExceeded(errorInfo) {
557
- const waitTime = this.calculateRateLimitWait(errorInfo);
558
-
559
- this.logger.warn('Rate limit exceeded, implementing backoff', {
560
- errorId: errorInfo.id,
561
- waitTime,
562
- agentId: errorInfo.agentId
563
- });
564
-
565
- if (errorInfo.agentId) {
566
- // Pause agent temporarily
567
- // await this.orchestrator.pauseAgent(errorInfo.agentId, waitTime / 1000, 'Rate limit exceeded');
568
- }
569
- }
570
-
571
- /**
572
- * Handle operation timeout
573
- * @param {Object} errorInfo - Error information
574
- */
575
- async handleOperationTimeout(errorInfo) {
576
- this.logger.error('Operation timeout detected', {
577
- errorId: errorInfo.id,
578
- operation: errorInfo.context.operation,
579
- timeout: errorInfo.context.timeout
580
- });
581
-
582
- // Could cancel ongoing operations, adjust timeouts, etc.
583
- }
584
-
585
- /**
586
- * Handle generic critical error
587
- * @param {Object} errorInfo - Error information
588
- */
589
- async handleGenericCriticalError(errorInfo) {
590
- this.logger.error('Generic critical error', {
591
- errorId: errorInfo.id,
592
- type: errorInfo.type,
593
- message: errorInfo.message
594
- });
595
-
596
- // Generic protective measures
597
- if (errorInfo.agentId) {
598
- // Could pause agent for safety
599
- this.logger.warn('Considering agent pause due to critical error', {
600
- agentId: errorInfo.agentId
601
- });
602
- }
603
- }
604
-
605
- /**
606
- * Calculate wait time for rate limit recovery
607
- * @param {Object} errorInfo - Error information
608
- * @returns {number} Wait time in milliseconds
609
- */
610
- calculateRateLimitWait(errorInfo) {
611
- const baseWait = 60000; // 1 minute
612
- const retryMultiplier = Math.pow(2, errorInfo.retryCount);
613
- const maxWait = 300000; // 5 minutes
614
-
615
- return Math.min(baseWait * retryMultiplier, maxWait);
616
- }
617
-
618
- /**
619
- * Log error for monitoring and analysis
620
- * @param {Object} errorInfo - Error information
621
- * @param {Object} recoveryResult - Recovery result
622
- */
623
- async logError(errorInfo, recoveryResult) {
624
- try {
625
- const logEntry = {
626
- errorId: errorInfo.id,
627
- timestamp: errorInfo.timestamp,
628
- type: errorInfo.type,
629
- severity: errorInfo.severity,
630
- message: errorInfo.message,
631
- agentId: errorInfo.agentId,
632
- toolId: errorInfo.toolId,
633
- operationId: errorInfo.operationId,
634
- retryCount: errorInfo.retryCount,
635
- recoveryAttempted: !!recoveryResult,
636
- recoverySuccess: recoveryResult?.success || false,
637
- recoveryAction: recoveryResult?.action || null
638
- };
639
-
640
- // Store in error queue for batch processing
641
- this.errorQueue.push(logEntry);
642
-
643
- // Process queue if not already processing
644
- if (!this.isProcessingQueue) {
645
- this.processErrorQueue();
646
- }
647
-
648
- } catch (loggingError) {
649
- this.logger.error('Error logging failed', {
650
- errorId: errorInfo.id,
651
- loggingError: loggingError.message
652
- });
653
- }
654
- }
655
-
656
- /**
657
- * Process error queue for batch operations
658
- */
659
- async processErrorQueue() {
660
- if (this.isProcessingQueue || this.errorQueue.length === 0) {
661
- return;
662
- }
663
-
664
- this.isProcessingQueue = true;
665
-
666
- try {
667
- while (this.errorQueue.length > 0) {
668
- const batch = this.errorQueue.splice(0, 10); // Process 10 at a time
669
-
670
- // Here you would typically save to database, send to monitoring service, etc.
671
- this.logger.debug('Processing error batch', { batchSize: batch.length });
672
-
673
- // Simulate async processing
674
- await new Promise(resolve => setTimeout(resolve, 100));
675
- }
676
- } catch (processingError) {
677
- this.logger.error('Error queue processing failed', { error: processingError.message });
678
- } finally {
679
- this.isProcessingQueue = false;
680
- }
681
- }
682
-
683
- /**
684
- * Setup error processing infrastructure
685
- */
686
- setupErrorProcessing() {
687
- // Setup periodic queue processing
688
- setInterval(() => {
689
- if (this.errorQueue.length > 0) {
690
- this.processErrorQueue();
691
- }
692
- }, 5000); // Process every 5 seconds
693
-
694
- // Setup global error handlers
695
- if (typeof process !== 'undefined') {
696
- process.on('uncaughtException', (error) => {
697
- this.handleError(error, {
698
- type: 'uncaught_exception',
699
- severity: 'critical'
700
- });
701
- });
702
-
703
- process.on('unhandledRejection', (reason, promise) => {
704
- this.handleError(new Error(`Unhandled Rejection: ${reason}`), {
705
- type: 'unhandled_rejection',
706
- severity: 'high',
707
- promise: promise.toString()
708
- });
709
- });
710
- }
711
- }
712
-
713
- /**
714
- * Update error statistics
715
- * @param {Object} errorInfo - Error information
716
- */
717
- updateErrorStats(errorInfo) {
718
- this.errorStats.totalErrors++;
719
-
720
- // Update error type statistics
721
- if (!this.errorStats.errorsByType.has(errorInfo.type)) {
722
- this.errorStats.errorsByType.set(errorInfo.type, 0);
723
- }
724
- this.errorStats.errorsByType.set(
725
- errorInfo.type,
726
- this.errorStats.errorsByType.get(errorInfo.type) + 1
727
- );
728
-
729
- // Update agent error statistics
730
- if (errorInfo.agentId) {
731
- if (!this.errorStats.errorsByAgent.has(errorInfo.agentId)) {
732
- this.errorStats.errorsByAgent.set(errorInfo.agentId, 0);
733
- }
734
- this.errorStats.errorsByAgent.set(
735
- errorInfo.agentId,
736
- this.errorStats.errorsByAgent.get(errorInfo.agentId) + 1
737
- );
738
- }
739
- }
740
-
741
- /**
742
- * Subscribe to error notifications
743
- * @param {Function} callback - Callback function
744
- */
745
- subscribe(callback) {
746
- this.errorSubscribers.add(callback);
747
- return () => this.errorSubscribers.delete(callback);
748
- }
749
-
750
- /**
751
- * Notify error subscribers
752
- * @param {Object} errorInfo - Error information
753
- * @param {Object} handlingResult - Handling result
754
- */
755
- notifySubscribers(errorInfo, handlingResult) {
756
- this.errorSubscribers.forEach(callback => {
757
- try {
758
- callback(errorInfo, handlingResult);
759
- } catch (callbackError) {
760
- this.logger.error('Error subscriber callback failed', {
761
- error: callbackError.message
762
- });
763
- }
764
- });
765
- }
766
-
767
- /**
768
- * Generate unique error ID
769
- * @returns {string} Error ID
770
- */
771
- generateErrorId() {
772
- return `err_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
773
- }
774
-
775
- /**
776
- * Get error statistics
777
- * @returns {Object} Error statistics
778
- */
779
- getErrorStats() {
780
- return {
781
- totalErrors: this.errorStats.totalErrors,
782
- errorsByType: Object.fromEntries(this.errorStats.errorsByType),
783
- errorsByAgent: Object.fromEntries(this.errorStats.errorsByAgent),
784
- recoveryAttempts: this.errorStats.recoveryAttempts,
785
- successfulRecoveries: this.errorStats.successfulRecoveries,
786
- recoverySuccessRate: this.errorStats.recoveryAttempts > 0
787
- ? this.errorStats.successfulRecoveries / this.errorStats.recoveryAttempts
788
- : 0,
789
- criticalErrors: this.errorStats.criticalErrors,
790
- queueLength: this.errorQueue.length
791
- };
792
- }
793
-
794
- /**
795
- * Clear error statistics (for testing or reset)
796
- */
797
- clearErrorStats() {
798
- this.errorStats = {
799
- totalErrors: 0,
800
- errorsByType: new Map(),
801
- errorsByAgent: new Map(),
802
- recoveryAttempts: 0,
803
- successfulRecoveries: 0,
804
- criticalErrors: 0
805
- };
806
- this.errorQueue = [];
807
- }
808
- }
809
-
810
- export default ErrorHandler;
1
+ function a0_0x1651(_0x4e4ed6,_0x398249){_0x4e4ed6=_0x4e4ed6-0x1c6;const _0x10bef7=a0_0x10be();let _0x165177=_0x10bef7[_0x4e4ed6];if(a0_0x1651['hMyRCD']===undefined){var _0x4d44ca=function(_0x4869a2){const _0x5189df='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x5ace9e='',_0x4a702d='';for(let _0x49b217=0x0,_0x22e167,_0x50981d,_0xbea1c1=0x0;_0x50981d=_0x4869a2['charAt'](_0xbea1c1++);~_0x50981d&&(_0x22e167=_0x49b217%0x4?_0x22e167*0x40+_0x50981d:_0x50981d,_0x49b217++%0x4)?_0x5ace9e+=String['fromCharCode'](0xff&_0x22e167>>(-0x2*_0x49b217&0x6)):0x0){_0x50981d=_0x5189df['indexOf'](_0x50981d);}for(let _0x157593=0x0,_0x39f712=_0x5ace9e['length'];_0x157593<_0x39f712;_0x157593++){_0x4a702d+='%'+('00'+_0x5ace9e['charCodeAt'](_0x157593)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x4a702d);};a0_0x1651['gnVUtx']=_0x4d44ca,a0_0x1651['uIiqvV']={},a0_0x1651['hMyRCD']=!![];}const _0x34d6f0=_0x10bef7[0x0],_0x2fcae2=_0x4e4ed6+_0x34d6f0,_0x5cca63=a0_0x1651['uIiqvV'][_0x2fcae2];return!_0x5cca63?(_0x165177=a0_0x1651['gnVUtx'](_0x165177),a0_0x1651['uIiqvV'][_0x2fcae2]=_0x165177):_0x165177=_0x5cca63,_0x165177;}function a0_0x10be(){const _0x3830bb=['BMfTzq','t3bLCMf0Aw9UihrPBwvVDxqGzgv0zwn0zwq','uhjVy2vZC2LUzYbLCNjVCIbIyxrJAa','CMf0zv9SAw1PDf9YzwnVDMvYEq','zxjYB3jZqNLbz2vUDa','AgfUzgXLr2vUzxjPy0nYAxrPy2fSrxjYB3i','B3bLCMf0Aw9U','Dw5KzwzPBMvK','q29UC2LKzxjPBMCGywDLBNqGCgf1C2uGzhvLihrVignYAxrPy2fSigvYCM9Y','Cg93','Dg9VBeLK','tM8GAw5WDxqGzgf0ysb0BYbZyw5PDgL6zq','C2v0','ntGXmZG0qLvUq0zj','tM8GCMvJB3zLCNKGC3rYyxrLz3KGyxzHAwXHyMXL','tM8GCMvJB3zLCNKGC3rYyxrLz3KGzM91BMq','zgvIDwC','Dg90ywXfCNjVCNm','vu5ltK9xtL9fuLjpuG','y29UzMLN','AgfUzgXLt3bLCMf0Aw9UvgLTzw91Da','AgfUzgXLqxv0AgvUDgLJyxrPB25gywLSDxjL','mJqXmdiYCKTMBejR','ChjVy2vZC0vYCM9YuxvLDwu','Dw5Oyw5KBgvKx3jLAMvJDgLVBG','zxjYB3i','BwvKAxvT','B3bLCMf0Aw9Uswq','uKfurv9msu1jvf9fwenfrurfra','qxv0AgvUDgLJyxrPB24GzMfPBhvYzsbKzxrLy3rLza','BgvUz3rO','vKfmsurbveLptL9fuLjpuG','mZqWmKLVBMP4sa','nNDlsLvODG','zgf0yv9Zyw5PDgL6yxrPB24','zxjYB3jtDwjZy3jPyMvYCW','y2fSy3vSyxrLuMf0zuXPBwL0v2fPDa','Dg9tDhjPBMC','y2XHC3nPzNLfCNjVCG','AgfZ','Aw5JCMvHC2vKx3rPBwvVDxq','Aw5JBhvKzxm','ywDLBNrjza','mti1odvLwuXtzK4','zgv0zxjTAw5Lu2v2zxjPDhK','zNjVBuvUDhjPzxm','BwvZC2fNzq','nJK5odC2mevbsvf6qW','Bg9NrxjYB3i','C2v0DxbfCNjVCLbYB2nLC3nPBMC','q09orKLhvvjbveLptL9fuLjpuG','C3rHDhvZ','sw5WDxqGzgf0ysb3yxmGC2fUAxrPEMvKigzVCIbYzxrYEq','CMv0CNLdB3vUDa','z2vUzxjHDgvfCNjVCKLK','DxbKyxrLrxjYB3jtDgf0CW','Aw5MBW','uevstuLtu0LptL9eru5jruq','zgvSzxrL','zgvSyxLFCMv0CNK','uMvJB3zLCNKGyxr0zw1WDcbMywLSzwq6ia','D2fYBG','zxjYB3jrDwv1zq','BM90Awz5u3vIC2nYAwjLCNm','odm3odiYmfLJyNntDG','AxnszwnVDMvYywjSzq','y2XLyxjfCNjVCLn0yxrZ','q3jPDgLJywWGzxjYB3iGzgv0zwn0zwq','mty5mtC5mLfVz2rbuW','t1bfuKfusu9ox1rjtuvpvvq','AgfUzgXLq3jPDgLJywXfCNjVCG','CMvJB3zLCNLbDhrLBxb0CW','ywrK','CMfUzg9T','ru5pru5u','rK9sqKLerevo','Dw5JyxvNAhrFzxHJzxb0Aw9U','DgLTzw91Da','ChjVy2vZC0vYCM9Y','y29UDgv4Da','DgLTzxn0yw1W','DhLWzq','y3jPDgLJywW','q2HLy2SGzMLSzs9KAxjLy3rVCNKGCgvYBwLZC2LVBNm','y29UzMLNDxjHDgLVBG','zxjYxW','Dw5JyxvNAhrfEgnLChrPB24','uhjVy2vZC2LUzYbLCNjVCG','zgv0zxjTAw5LrxjYB3juExbL','CMvJB3zLCNLtDhjHDgvNAwvZ','C3vIC2nYAwjL','rufdq0vt','y29Kzq','zMLSzv9UB3rFzM91BMrFCMvJB3zLCNK','qvvusevoveLdqvrjt05FrKfjteve','DMfSAwrHDgLVBL9YzwnVDMvYEq','AgLNAa','mJHMsuTVtwC','q2HLy2SGzMLSzsbWyxrOigfUzcbWzxjTAxnZAw9UCW','AxnqCM9JzxnZAw5NuxvLDwu','zxjYB3jtDgf0CW','BwLU','y2fSy3vSyxrLuMv0CNLezwXHEq','Bg9Nz2vY','z2v0','ywDLBNrFy29TBxvUAwnHDgLVBG','zMLSzvbHDgG','C3vJy2vZCW','Bwf4uMv0CMLLCW','DgLTzwqGB3v0','rKLmrv9ot1rFrK9vtKq','zxjYB3jZqNLuExbL','C2HVDwXKuMv0CNK','v2fPDgLUzYbMB3iGCMf0zsbSAw1PDcbYzwnVDMvYEq','y3jPDgLJywXfCNjVCG','rxjYB3iGChjVy2vZC2LUzYbMywLSzwq','nwLKrwfJAW','ntG4odmZm3vWu3nSvW','z2v0rxjYB3jtDgf0CW','rxjYB3iGCMvJB3zLCNKGC3vJy2vZC2z1Ba','C3vJy2vZC2z1BfjLy292zxjPzxm','yxr0zw1WDfjLy292zxj5','C2v2zxjPDhK','mZz2DMfdBum'];a0_0x10be=function(){return _0x3830bb;};return a0_0x10be();}const a0_0x55125b=a0_0x1651;(function(_0x47a5ba,_0x42bd7b){const _0x401b6a=a0_0x1651,_0x13537c=_0x47a5ba();while(!![]){try{const _0x1fc723=-parseInt(_0x401b6a(0x1c9))/0x1*(-parseInt(_0x401b6a(0x1e7))/0x2)+parseInt(_0x401b6a(0x1f2))/0x3*(-parseInt(_0x401b6a(0x215))/0x4)+-parseInt(_0x401b6a(0x1fc))/0x5*(-parseInt(_0x401b6a(0x1f1))/0x6)+parseInt(_0x401b6a(0x232))/0x7*(-parseInt(_0x401b6a(0x1de))/0x8)+parseInt(_0x401b6a(0x200))/0x9+parseInt(_0x401b6a(0x211))/0xa+-parseInt(_0x401b6a(0x1ca))/0xb*(parseInt(_0x401b6a(0x1d0))/0xc);if(_0x1fc723===_0x42bd7b)break;else _0x13537c['push'](_0x13537c['shift']());}catch(_0x2bac86){_0x13537c['push'](_0x13537c['shift']());}}}(a0_0x10be,0xdc603));import{ERROR_TYPES,HTTP_STATUS,AGENT_STATUS}from'../utilities/constants.js';export class ErrorHandler{constructor(_0x5ace9e,_0x4a702d){const _0x6c4376=a0_0x1651;this[_0x6c4376(0x1e4)]=_0x5ace9e||{},this['logger']=_0x4a702d,this['errorStats']={'totalErrors':0x0,'errorsByType':new Map(),'errorsByAgent':new Map(),'recoveryAttempts':0x0,'successfulRecoveries':0x0,'criticalErrors':0x0},this[_0x6c4376(0x22a)]=new Map(),this['errorSubscribers']=new Set(),this[_0x6c4376(0x20f)]=[],this[_0x6c4376(0x234)]=![],this['initializeRecoveryStrategies'](),this[_0x6c4376(0x202)]();}async['handleError'](_0x49b217,_0x22e167={}){const _0x31f185=a0_0x1651;try{const _0x50981d=this[_0x31f185(0x1f7)](_0x49b217,_0x22e167),_0xbea1c1=await this[_0x31f185(0x21f)](_0x50981d);return this[_0x31f185(0x208)](_0x50981d),this['notifySubscribers'](_0x50981d,_0xbea1c1),_0xbea1c1;}catch(_0x157593){return this[_0x31f185(0x238)][_0x31f185(0x1ea)]('Error\x20handling\x20failed',{'originalError':_0x49b217[_0x31f185(0x1ff)],'handlingError':_0x157593['message']}),{'success':![],'error':_0x157593,'recovery':null,'severity':'critical'};}}['classifyError'](_0x39f712,_0xbbc7e8={}){const _0x59d9c8=a0_0x1651,_0x5a15d8={'id':this['generateErrorId'](),'timestamp':new Date()['toISOString'](),'message':_0x39f712[_0x59d9c8(0x1ff)]||_0x39f712[_0x59d9c8(0x1f6)](),'stack':_0x39f712['stack']||null,'code':_0x39f712['code']||null,'type':this[_0x59d9c8(0x229)](_0x39f712,_0xbbc7e8),'severity':this[_0x59d9c8(0x1fd)](_0x39f712,_0xbbc7e8),'context':{..._0xbbc7e8},'recoverable':!![],'retryCount':_0xbbc7e8['retryCount']||0x0,'maxRetries':this['getMaxRetries'](_0x39f712,_0xbbc7e8)};return _0xbbc7e8['agentId']&&(_0x5a15d8['agentId']=_0xbbc7e8[_0x59d9c8(0x1fb)]),_0xbbc7e8['toolId']&&(_0x5a15d8['toolId']=_0xbbc7e8['toolId']),_0xbbc7e8['operationId']&&(_0x5a15d8['operationId']=_0xbbc7e8[_0x59d9c8(0x1ec)]),_0x5a15d8['recoverable']=this[_0x59d9c8(0x212)](_0x5a15d8),_0x5a15d8;}async['processError'](_0x16a272){const _0xd14a94=a0_0x1651;try{this['logger'][_0xd14a94(0x1ea)](_0xd14a94(0x228),{'errorId':_0x16a272['id'],'type':_0x16a272['type'],'severity':_0x16a272['severity'],'agentId':_0x16a272['agentId'],'message':_0x16a272[_0xd14a94(0x1ff)]});_0x16a272['severity']===_0xd14a94(0x223)&&await this['handleCriticalError'](_0x16a272);let _0x3c4ef9=null;return _0x16a272['recoverable']&&_0x16a272[_0xd14a94(0x206)]<_0x16a272['maxRetries']&&(_0x3c4ef9=await this[_0xd14a94(0x1ce)](_0x16a272)),await this[_0xd14a94(0x201)](_0x16a272,_0x3c4ef9),{'success':_0x3c4ef9?.[_0xd14a94(0x23c)]||![],'errorId':_0x16a272['id'],'errorType':_0x16a272[_0xd14a94(0x222)],'severity':_0x16a272[_0xd14a94(0x1cf)],'recovery':_0x3c4ef9,'shouldRetry':this[_0xd14a94(0x241)](_0x16a272,_0x3c4ef9),'retryDelay':this[_0xd14a94(0x237)](_0x16a272)};}catch(processingError){return this[_0xd14a94(0x238)][_0xd14a94(0x1ea)](_0xd14a94(0x1c8),{'errorId':_0x16a272['id'],'processingError':processingError['message']}),{'success':![],'errorId':_0x16a272['id'],'errorType':_0x16a272[_0xd14a94(0x222)],'severity':'critical','recovery':null,'shouldRetry':![]};}}async[a0_0x55125b(0x1ce)](_0x3b665e){const _0x4a3d74=a0_0x55125b;try{this[_0x4a3d74(0x235)][_0x4a3d74(0x218)]++;const _0x3bde8c=this[_0x4a3d74(0x22a)][_0x4a3d74(0x239)](_0x3b665e[_0x4a3d74(0x222)])||this[_0x4a3d74(0x22a)]['get']('default');if(!_0x3bde8c)return this[_0x4a3d74(0x238)]['warn'](_0x4a3d74(0x1e0),{'errorType':_0x3b665e['type']}),{'success':![],'reason':_0x4a3d74(0x1df)};this[_0x4a3d74(0x238)]['info']('Attempting\x20error\x20recovery',{'errorId':_0x3b665e['id'],'errorType':_0x3b665e['type'],'strategy':_0x3bde8c['name'],'retryCount':_0x3b665e[_0x4a3d74(0x206)]});const _0x2bd124=await _0x3bde8c['recover'](_0x3b665e);return _0x2bd124['success']?(this[_0x4a3d74(0x235)][_0x4a3d74(0x1cd)]++,this[_0x4a3d74(0x238)][_0x4a3d74(0x209)](_0x4a3d74(0x1cc),{'errorId':_0x3b665e['id'],'strategy':_0x3bde8c[_0x4a3d74(0x1d1)]})):this[_0x4a3d74(0x238)]['warn']('Error\x20recovery\x20failed',{'errorId':_0x3b665e['id'],'strategy':_0x3bde8c[_0x4a3d74(0x1d1)],'reason':_0x2bd124['reason']}),_0x2bd124;}catch(_0xa36480){return this[_0x4a3d74(0x238)]['error']('Recovery\x20attempt\x20failed',{'errorId':_0x3b665e['id'],'recoveryError':_0xa36480['message']}),{'success':![],'reason':_0x4a3d74(0x20d)+_0xa36480[_0x4a3d74(0x1ff)]};}}async[a0_0x55125b(0x217)](_0x290eca){const _0x2223b5=a0_0x55125b;try{this[_0x2223b5(0x235)]['criticalErrors']++,this[_0x2223b5(0x238)]['error'](_0x2223b5(0x214),{'errorId':_0x290eca['id'],'message':_0x290eca['message'],'context':_0x290eca['context']});typeof process!=='undefined'&&process['emit']&&process['emit'](_0x2223b5(0x1c7),_0x290eca);switch(_0x290eca['type']){case ERROR_TYPES['AUTHENTICATION_FAILED']:await this[_0x2223b5(0x1e6)](_0x290eca);break;case ERROR_TYPES[_0x2223b5(0x1ed)]:await this['handleRateLimitExceeded'](_0x290eca);break;case ERROR_TYPES[_0x2223b5(0x216)]:await this['handleOperationTimeout'](_0x290eca);break;default:await this[_0x2223b5(0x1d6)](_0x290eca);}}catch(_0x2aaa71){this['logger'][_0x2223b5(0x1ea)]('Critical\x20error\x20handling\x20failed',{'errorId':_0x290eca['id'],'handlingError':_0x2aaa71[_0x2223b5(0x1ff)]});}}[a0_0x55125b(0x229)](_0x33de1b,_0x2ff497){const _0x3dadb8=a0_0x55125b;if(_0x33de1b['code']===_0x3dadb8(0x21b)||_0x33de1b['status']===HTTP_STATUS['NOT_FOUND'])return ERROR_TYPES[_0x3dadb8(0x23f)];if(_0x33de1b[_0x3dadb8(0x22d)]===_0x3dadb8(0x22c)||_0x33de1b['status']===HTTP_STATUS[_0x3dadb8(0x21c)])return ERROR_TYPES['PERMISSION_DENIED'];if(_0x33de1b[_0x3dadb8(0x204)]===HTTP_STATUS['UNAUTHORIZED'])return ERROR_TYPES['AUTHENTICATION_FAILED'];if(_0x33de1b['status']===HTTP_STATUS['TOO_MANY_REQUESTS'])return ERROR_TYPES['RATE_LIMIT_EXCEEDED'];const _0x3d2532=_0x33de1b['message']?.['toLowerCase']()||'';if(_0x3d2532[_0x3dadb8(0x1fa)](_0x3dadb8(0x21e))||_0x3d2532[_0x3dadb8(0x1fa)](_0x3dadb8(0x23e)))return ERROR_TYPES['OPERATION_TIMEOUT'];if(_0x3d2532[_0x3dadb8(0x1fa)]('validation')||_0x3d2532[_0x3dadb8(0x1fa)]('invalid'))return ERROR_TYPES['VALIDATION_ERROR'];if(_0x3d2532[_0x3dadb8(0x1fa)]('config')||_0x3d2532['includes'](_0x3dadb8(0x225)))return ERROR_TYPES[_0x3dadb8(0x203)];if(_0x2ff497['operation']==='file_operation')return ERROR_TYPES['FILE_NOT_FOUND'];if(_0x2ff497[_0x3dadb8(0x1d7)]==='api_request')return ERROR_TYPES[_0x3dadb8(0x1ed)];return ERROR_TYPES['UNKNOWN_ERROR'];}['determineSeverity'](_0x76d6e9,_0x26edf5){const _0x34b711=a0_0x55125b,_0x4e78de=[ERROR_TYPES[_0x34b711(0x22f)],ERROR_TYPES[_0x34b711(0x203)]],_0x350fac=[ERROR_TYPES[_0x34b711(0x1ed)],ERROR_TYPES['OPERATION_TIMEOUT'],ERROR_TYPES['PERMISSION_DENIED']],_0x41b7b9=this[_0x34b711(0x229)](_0x76d6e9,_0x26edf5);if(_0x4e78de[_0x34b711(0x1fa)](_0x41b7b9))return'critical';if(_0x350fac['includes'](_0x41b7b9))return _0x34b711(0x231);const _0x10e561=_0x26edf5&&_0x26edf5[_0x34b711(0x206)]||0x0;if(_0x10e561>=0x3)return _0x34b711(0x231);if(_0x26edf5&&_0x26edf5['agentId']&&_0x26edf5['operation']===_0x34b711(0x23a))return _0x34b711(0x1eb);return'low';}['isRecoverable'](_0x33479c){const _0x13296d=a0_0x55125b,_0x4ca117=[ERROR_TYPES['AUTHENTICATION_FAILED'],ERROR_TYPES['CONFIGURATION_ERROR']];if(_0x4ca117['includes'](_0x33479c['type']))return![];if(_0x33479c[_0x13296d(0x206)]>=_0x33479c[_0x13296d(0x23d)])return![];if(_0x33479c[_0x13296d(0x1cf)]==='critical')return![];return!![];}['getMaxRetries'](_0x1e6d61,_0x3feec7){const _0x38a496=a0_0x55125b,_0x3f9ee8=this['determineErrorType'](_0x1e6d61,_0x3feec7),_0x279fd1={[ERROR_TYPES['RATE_LIMIT_EXCEEDED']]:0x5,[ERROR_TYPES[_0x38a496(0x216)]]:0x3,[ERROR_TYPES[_0x38a496(0x23f)]]:0x2,[ERROR_TYPES['PERMISSION_DENIED']]:0x1,[ERROR_TYPES[_0x38a496(0x1f0)]]:0x2,[ERROR_TYPES[_0x38a496(0x1e3)]]:0x3};return _0x279fd1[_0x3f9ee8]||0x3;}[a0_0x55125b(0x241)](_0x341fa9,_0x36ebbb){const _0x474d1e=a0_0x55125b;if(!_0x341fa9['recoverable'])return![];if(_0x341fa9[_0x474d1e(0x206)]>=_0x341fa9['maxRetries'])return![];if(_0x36ebbb&&_0x36ebbb[_0x474d1e(0x23c)])return![];return!![];}['calculateRetryDelay'](_0x329826){const _0x219677=a0_0x55125b,_0x3b5e65=0x3e8,_0x5a7544=0x7530,_0xaf8074=_0x3b5e65*Math[_0x219677(0x1da)](0x2,_0x329826['retryCount']),_0x3a9e0a=Math[_0x219677(0x21a)]()*0x3e8;return Math['min'](_0xaf8074+_0x3a9e0a,_0x5a7544);}['initializeRecoveryStrategies'](){const _0x49d959=a0_0x55125b;this['recoveryStrategies']['set'](ERROR_TYPES['FILE_NOT_FOUND'],{'name':_0x49d959(0x22e),'recover':async _0x3104f1=>{const _0x3c5975=_0x49d959;if(_0x3104f1[_0x3c5975(0x220)][_0x3c5975(0x23b)])return{'success':![],'reason':'File\x20recovery\x20not\x20implemented\x20yet','suggestion':_0x3c5975(0x233)};return{'success':![],'reason':'No\x20file\x20path\x20provided'};}}),this[_0x49d959(0x22a)][_0x49d959(0x1dd)](ERROR_TYPES[_0x49d959(0x1ed)],{'name':_0x49d959(0x1d4),'recover':async _0x804db8=>{const _0x23ad3f=_0x49d959,_0xdb73b0=this['calculateRateLimitWait'](_0x804db8);return this['logger']['info'](_0x23ad3f(0x1c6),{'waitTime':_0xdb73b0}),await new Promise(_0x49c549=>setTimeout(_0x49c549,_0xdb73b0)),{'success':!![],'action':'waited_for_rate_limit','waitTime':_0xdb73b0};}}),this['recoveryStrategies']['set'](ERROR_TYPES[_0x49d959(0x216)],{'name':'timeout_recovery','recover':async _0x4a3f16=>{const _0x2a3f95=_0x49d959;if(_0x4a3f16[_0x2a3f95(0x220)]['timeout']){const _0x284c58=Math[_0x2a3f95(0x236)](_0x4a3f16[_0x2a3f95(0x220)][_0x2a3f95(0x21e)]*1.5,0x493e0);return{'success':!![],'action':_0x2a3f95(0x1f9),'newTimeout':_0x284c58};}return{'success':![],'reason':'Cannot\x20adjust\x20timeout'};}}),this[_0x49d959(0x22a)][_0x49d959(0x1dd)](ERROR_TYPES[_0x49d959(0x20a)],{'name':'permission_recovery','recover':async _0x464dac=>{const _0x1a7092=_0x49d959;return{'success':![],'reason':'Permission\x20errors\x20require\x20manual\x20intervention','suggestion':_0x1a7092(0x224)};}}),this[_0x49d959(0x22a)]['set'](ERROR_TYPES['VALIDATION_ERROR'],{'name':_0x49d959(0x230),'recover':async _0x111961=>{const _0x356995=_0x49d959;if(_0x111961['context']['inputData'])return{'success':!![],'action':_0x356995(0x1f3),'suggestion':_0x356995(0x205)};return{'success':![],'reason':_0x356995(0x1dc)};}}),this[_0x49d959(0x22a)][_0x49d959(0x1dd)]('default',{'name':'default_recovery','recover':async _0x158c31=>{const _0xcc4c57=_0x49d959,_0x366361=this[_0xcc4c57(0x237)](_0x158c31);return await new Promise(_0x26dd3b=>setTimeout(_0x26dd3b,_0x366361)),{'success':!![],'action':_0xcc4c57(0x20c),'delay':_0x366361};}});}async['handleAuthenticationFailure'](_0x10c06d){const _0x2f48d8=a0_0x55125b;this['logger'][_0x2f48d8(0x1ea)](_0x2f48d8(0x1ee),{'errorId':_0x10c06d['id']});if(_0x10c06d['agentId']){}}async['handleRateLimitExceeded'](_0x4908cc){const _0x52463d=a0_0x55125b,_0x51e84d=this[_0x52463d(0x1f5)](_0x4908cc);this[_0x52463d(0x238)][_0x52463d(0x20e)]('Rate\x20limit\x20exceeded,\x20implementing\x20backoff',{'errorId':_0x4908cc['id'],'waitTime':_0x51e84d,'agentId':_0x4908cc['agentId']});if(_0x4908cc[_0x52463d(0x1fb)]){}}async[a0_0x55125b(0x1e5)](_0x1bb8e6){const _0x5d7ae2=a0_0x55125b;this['logger']['error'](_0x5d7ae2(0x1d2),{'errorId':_0x1bb8e6['id'],'operation':_0x1bb8e6['context']['operation'],'timeout':_0x1bb8e6[_0x5d7ae2(0x220)][_0x5d7ae2(0x21e)]});}async[a0_0x55125b(0x1d6)](_0x183528){const _0x804f6f=a0_0x55125b;this[_0x804f6f(0x238)][_0x804f6f(0x1ea)]('Generic\x20critical\x20error',{'errorId':_0x183528['id'],'type':_0x183528[_0x804f6f(0x222)],'message':_0x183528['message']}),_0x183528[_0x804f6f(0x1fb)]&&this['logger'][_0x804f6f(0x20e)](_0x804f6f(0x1d9),{'agentId':_0x183528['agentId']});}['calculateRateLimitWait'](_0x57d402){const _0x2681e1=a0_0x55125b,_0xf62bed=0xea60,_0x8a9ef5=Math[_0x2681e1(0x1da)](0x2,_0x57d402[_0x2681e1(0x206)]),_0x4c9cd4=0x493e0;return Math[_0x2681e1(0x236)](_0xf62bed*_0x8a9ef5,_0x4c9cd4);}async[a0_0x55125b(0x201)](_0x580fd4,_0x5b2e8d){const _0x49c2cc=a0_0x55125b;try{const _0x3cc9d8={'errorId':_0x580fd4['id'],'timestamp':_0x580fd4[_0x49c2cc(0x221)],'type':_0x580fd4['type'],'severity':_0x580fd4[_0x49c2cc(0x1cf)],'message':_0x580fd4[_0x49c2cc(0x1ff)],'agentId':_0x580fd4[_0x49c2cc(0x1fb)],'toolId':_0x580fd4[_0x49c2cc(0x1db)],'operationId':_0x580fd4[_0x49c2cc(0x1ec)],'retryCount':_0x580fd4[_0x49c2cc(0x206)],'recoveryAttempted':!!_0x5b2e8d,'recoverySuccess':_0x5b2e8d?.[_0x49c2cc(0x23c)]||![],'recoveryAction':_0x5b2e8d?.['action']||null};this[_0x49c2cc(0x20f)]['push'](_0x3cc9d8),!this['isProcessingQueue']&&this[_0x49c2cc(0x1e8)]();}catch(_0x1fd31c){this['logger'][_0x49c2cc(0x1ea)]('Error\x20logging\x20failed',{'errorId':_0x580fd4['id'],'loggingError':_0x1fd31c['message']});}}async[a0_0x55125b(0x1e8)](){const _0x4a726b=a0_0x55125b;if(this[_0x4a726b(0x234)]||this[_0x4a726b(0x20f)]['length']===0x0)return;this[_0x4a726b(0x234)]=!![];try{while(this['errorQueue'][_0x4a726b(0x1ef)]>0x0){const _0xedd82c=this[_0x4a726b(0x20f)]['splice'](0x0,0xa);this[_0x4a726b(0x238)][_0x4a726b(0x1e1)](_0x4a726b(0x1d3),{'batchSize':_0xedd82c['length']}),await new Promise(_0x3d258f=>setTimeout(_0x3d258f,0x64));}}catch(processingError){this[_0x4a726b(0x238)]['error']('Error\x20queue\x20processing\x20failed',{'error':processingError['message']});}finally{this['isProcessingQueue']=![];}}['setupErrorProcessing'](){const _0x1630e7=a0_0x55125b;setInterval(()=>{const _0x1be9fd=a0_0x1651;this[_0x1be9fd(0x20f)]['length']>0x0&&this['processErrorQueue']();},0x1388),typeof process!==_0x1630e7(0x1d8)&&(process['on'](_0x1630e7(0x227),_0x36901d=>{const _0x1b45d2=_0x1630e7;this['handleError'](_0x36901d,{'type':_0x1b45d2(0x21d),'severity':'critical'});}),process['on']('unhandledRejection',(_0x185313,_0x2672bd)=>{const _0x4656d2=_0x1630e7;this['handleError'](new Error('Unhandled\x20Rejection:\x20'+_0x185313),{'type':_0x4656d2(0x1e9),'severity':'high','promise':_0x2672bd['toString']()});}));}['updateErrorStats'](_0x2d6e46){const _0x554b64=a0_0x55125b;this[_0x554b64(0x235)][_0x554b64(0x1e2)]++,!this[_0x554b64(0x235)]['errorsByType'][_0x554b64(0x1f8)](_0x2d6e46[_0x554b64(0x222)])&&this['errorStats'][_0x554b64(0x240)][_0x554b64(0x1dd)](_0x2d6e46[_0x554b64(0x222)],0x0),this['errorStats']['errorsByType'][_0x554b64(0x1dd)](_0x2d6e46['type'],this['errorStats'][_0x554b64(0x240)]['get'](_0x2d6e46['type'])+0x1),_0x2d6e46[_0x554b64(0x1fb)]&&(!this['errorStats']['errorsByAgent'][_0x554b64(0x1f8)](_0x2d6e46['agentId'])&&this[_0x554b64(0x235)][_0x554b64(0x1d5)][_0x554b64(0x1dd)](_0x2d6e46['agentId'],0x0),this['errorStats']['errorsByAgent'][_0x554b64(0x1dd)](_0x2d6e46[_0x554b64(0x1fb)],this['errorStats']['errorsByAgent']['get'](_0x2d6e46['agentId'])+0x1));}[a0_0x55125b(0x22b)](_0x581209){const _0x49cecd=a0_0x55125b;return this['errorSubscribers'][_0x49cecd(0x219)](_0x581209),()=>this['errorSubscribers'][_0x49cecd(0x20b)](_0x581209);}[a0_0x55125b(0x210)](_0x3f80cf,_0x23891b){const _0x5b9526=a0_0x55125b;this[_0x5b9526(0x1f4)]['forEach'](_0x57ebf0=>{try{_0x57ebf0(_0x3f80cf,_0x23891b);}catch(_0x771c24){this['logger']['error']('Error\x20subscriber\x20callback\x20failed',{'error':_0x771c24['message']});}});}[a0_0x55125b(0x207)](){const _0x4a8c04=a0_0x55125b;return _0x4a8c04(0x226)+Date['now']()+'_'+Math[_0x4a8c04(0x21a)]()[_0x4a8c04(0x1f6)](0x24)['substr'](0x2,0x9);}[a0_0x55125b(0x1cb)](){const _0x19ccc9=a0_0x55125b;return{'totalErrors':this['errorStats'][_0x19ccc9(0x1e2)],'errorsByType':Object[_0x19ccc9(0x1fe)](this[_0x19ccc9(0x235)]['errorsByType']),'errorsByAgent':Object[_0x19ccc9(0x1fe)](this['errorStats'][_0x19ccc9(0x1d5)]),'recoveryAttempts':this[_0x19ccc9(0x235)]['recoveryAttempts'],'successfulRecoveries':this[_0x19ccc9(0x235)][_0x19ccc9(0x1cd)],'recoverySuccessRate':this['errorStats'][_0x19ccc9(0x218)]>0x0?this[_0x19ccc9(0x235)][_0x19ccc9(0x1cd)]/this['errorStats'][_0x19ccc9(0x218)]:0x0,'criticalErrors':this[_0x19ccc9(0x235)]['criticalErrors'],'queueLength':this[_0x19ccc9(0x20f)][_0x19ccc9(0x1ef)]};}[a0_0x55125b(0x213)](){this['errorStats']={'totalErrors':0x0,'errorsByType':new Map(),'errorsByAgent':new Map(),'recoveryAttempts':0x0,'successfulRecoveries':0x0,'criticalErrors':0x0},this['errorQueue']=[];}}export default ErrorHandler;