snow-flow 2.0.2 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{.claude/mcp-config.json → .mcp.json} +13 -12
- package/.releaserc.json +47 -0
- package/README.md +48 -1
- package/package.json +1 -1
- package/.claude/claude-settings.json +0 -15
- package/.claude/commands/analysis/README.md +0 -9
- package/.claude/commands/automation/README.md +0 -9
- package/.claude/commands/github/README.md +0 -11
- package/.claude/commands/helpers/standard-checkpoint-hooks.sh +0 -179
- package/.claude/commands/hooks/README.md +0 -11
- package/.claude/commands/monitoring/README.md +0 -9
- package/.claude/commands/optimization/README.md +0 -9
- package/.claude/commands/training/README.md +0 -9
- package/.claude/commands/workflows/README.md +0 -9
- package/.claude/config.json +0 -36
- package/.claude/helpers/github-setup.sh +0 -28
- package/.claude/helpers/quick-start.sh +0 -19
- package/.claude/helpers/setup-mcp.sh +0 -18
- package/.claude/settings.json +0 -114
- package/.claude/settings.local.json +0 -33
- package/.claude-flow/metrics/agent-metrics.json +0 -1
- package/.claude-flow/metrics/performance.json +0 -9
- package/.claude-flow/metrics/system-metrics.json +0 -15986
- package/.claude-flow/metrics/task-metrics.json +0 -10
- package/.roo/README.md +0 -402
- package/.roo/mcp-list.txt +0 -257
- package/.roo/mcp.json +0 -32
- package/.roo/workflows/basic-tdd.json +0 -32
- package/.roomodes +0 -201
- package/CLAUDE.md +0 -393
- package/bin/snow-flow.js +0 -3
- package/dist/cli.js.bak +0 -2052
- package/dist/config/snow-flow-config.d.ts +0 -1492
- package/dist/config/snow-flow-config.js +0 -938
- package/scripts/create-env.js +0 -91
- package/scripts/postinstall.js +0 -30
- package/scripts/register-mcp-servers.js +0 -210
- package/scripts/reset-mcp-servers.js +0 -246
- package/scripts/setup-mcp.js +0 -106
- package/scripts/update-version.js +0 -31
- package/src/agents/README.md +0 -192
- package/src/agents/base-agent.ts +0 -251
- package/src/agents/coordinator.ts +0 -971
- package/src/agents/index.ts +0 -18
- package/src/agents/queen-403-handler.ts +0 -230
- package/src/agents/queen-agent.ts +0 -1399
- package/src/agents/script-writer-agent.ts +0 -769
- package/src/agents/security-agent.ts +0 -726
- package/src/agents/widget-creator-agent.ts +0 -568
- package/src/api/error-handling.ts +0 -1758
- package/src/api/natural-language-mapper.ts +0 -630
- package/src/api/performance-optimizer.ts +0 -891
- package/src/api/transaction-manager.ts +0 -754
- package/src/cli/deploy-artifact.ts +0 -304
- package/src/cli/snow-flow-cli-integration.ts +0 -434
- package/src/cli.ts +0 -4455
- package/src/cli.ts.bak +0 -5616
- package/src/compliance/advanced-compliance-system.ts +0 -1268
- package/src/compliance/index.ts +0 -19
- package/src/config/snow-flow-config.ts +0 -1019
- package/src/documentation/index.ts +0 -16
- package/src/documentation/self-documenting-system.ts +0 -1421
- package/src/dynamic-version.ts +0 -44
- package/src/healing/index.ts +0 -20
- package/src/healing/self-healing-system.ts +0 -1435
- package/src/health/README.md +0 -161
- package/src/health/system-health.ts +0 -995
- package/src/index.ts +0 -60
- package/src/intelligence/acl-analyzer.ts +0 -377
- package/src/intelligence/auto-resolution-engine.ts +0 -643
- package/src/intelligence/gap-analysis-engine.ts +0 -488
- package/src/intelligence/manual-instructions-generator.ts +0 -744
- package/src/intelligence/mcp-coverage-analyzer.ts +0 -708
- package/src/intelligence/multi-pass-requirements-analyzer.ts +0 -603
- package/src/intelligence/performance-recommendations-engine.ts +0 -1223
- package/src/intelligence/requirements-analyzer.ts +0 -1148
- package/src/intelligence/task-analyzer.ts +0 -628
- package/src/managers/scope-manager.ts +0 -555
- package/src/mcp/advanced/servicenow-advanced-features-mcp.ts +0 -16110
- package/src/mcp/base-mcp-server.ts +0 -660
- package/src/mcp/http-transport-wrapper.ts +0 -426
- package/src/mcp/service-discovery-client.ts +0 -312
- package/src/mcp/servicenow-automation-mcp-refactored.ts +0 -678
- package/src/mcp/servicenow-automation-mcp.ts +0 -838
- package/src/mcp/servicenow-deployment-mcp-refactored.ts +0 -1292
- package/src/mcp/servicenow-deployment-mcp.ts +0 -7244
- package/src/mcp/servicenow-graph-memory-mcp-refactored.ts +0 -721
- package/src/mcp/servicenow-graph-memory-mcp.ts +0 -832
- package/src/mcp/servicenow-integration-mcp-refactored.ts +0 -655
- package/src/mcp/servicenow-integration-mcp.ts +0 -819
- package/src/mcp/servicenow-intelligent-mcp-refactored.ts +0 -977
- package/src/mcp/servicenow-intelligent-mcp.ts +0 -4638
- package/src/mcp/servicenow-mcp-server.ts +0 -728
- package/src/mcp/servicenow-memory-mcp.ts +0 -474
- package/src/mcp/servicenow-operations-mcp-refactored.ts +0 -1995
- package/src/mcp/servicenow-operations-mcp.ts +0 -3384
- package/src/mcp/servicenow-platform-development-mcp-refactored.ts +0 -611
- package/src/mcp/servicenow-platform-development-mcp.ts +0 -970
- package/src/mcp/servicenow-progressive-indexer.ts +0 -370
- package/src/mcp/servicenow-reporting-analytics-mcp-refactored.ts +0 -695
- package/src/mcp/servicenow-reporting-analytics-mcp.ts +0 -1123
- package/src/mcp/servicenow-security-compliance-mcp-refactored.ts +0 -642
- package/src/mcp/servicenow-security-compliance-mcp.ts +0 -1157
- package/src/mcp/servicenow-update-set-mcp-refactored.ts +0 -751
- package/src/mcp/servicenow-update-set-mcp.ts +0 -811
- package/src/mcp/shared/agent-context-provider.ts +0 -365
- package/src/mcp/shared/base-mcp-server.ts +0 -2463
- package/src/mcp/shared/mcp-memory-manager.ts +0 -540
- package/src/mcp/shared/mcp-resource-manager.ts +0 -367
- package/src/mcp/snow-flow-mcp.ts +0 -911
- package/src/mcp/start-all-mcp-servers.ts +0 -102
- package/src/mcp/start-servicenow-mcp.ts +0 -67
- package/src/monitoring/enhanced-monitoring-system.ts +0 -1345
- package/src/monitoring/performance-tracker.ts +0 -777
- package/src/optimization/cost-optimization-engine.ts +0 -1125
- package/src/optimization/index.ts +0 -10
- package/src/queen/README.md +0 -403
- package/src/queen/agent-factory.ts +0 -574
- package/src/queen/index.ts +0 -94
- package/src/queen/mcp-execution-bridge.ts +0 -681
- package/src/queen/neural-learning.ts +0 -319
- package/src/queen/parallel-agent-engine.ts +0 -848
- package/src/queen/queen-memory-system.ts +0 -490
- package/src/queen/queen-memory.ts +0 -456
- package/src/queen/servicenow-queen.ts +0 -1029
- package/src/queen/types.ts +0 -87
- package/src/rollback/smart-rollback-system.ts +0 -866
- package/src/schemas/deployment.schema.json +0 -58
- package/src/schemas/flow.schema.json +0 -79
- package/src/schemas/widget.schema.json +0 -72
- package/src/snow-flow-system.ts +0 -541
- package/src/sparc/sparc-help.ts +0 -49
- package/src/sparc/team-sparc.ts +0 -88
- package/src/strategies/global-scope-strategy.ts +0 -736
- package/src/templates/base/application.template.json +0 -45
- package/src/templates/base/business_rule.template.json +0 -33
- package/src/templates/base/script_include.template.json +0 -18
- package/src/templates/base/table.template.json +0 -64
- package/src/templates/base/widget.template.json +0 -25
- package/src/templates/patterns/composite.incident-management.template.json +0 -140
- package/src/templates/patterns/widget.dashboard.template.json +0 -238
- package/src/templates/patterns/widget.datatable.template.json +0 -292
- package/src/testing/integration-test-suite.ts +0 -1276
- package/src/types/index.ts +0 -183
- package/src/types/neo4j-driver.d.ts +0 -23
- package/src/types/servicenow.types.ts +0 -307
- package/src/types/snow-flow.types.ts +0 -186
- package/src/types/todo.types.ts +0 -70
- package/src/utils/action-type-cache.ts +0 -286
- package/src/utils/agent-detector.ts +0 -573
- package/src/utils/artifact-tracker.ts +0 -379
- package/src/utils/dependency-detector.ts +0 -233
- package/src/utils/deployment-metadata-handler.ts +0 -518
- package/src/utils/error-recovery.ts +0 -680
- package/src/utils/logger.ts +0 -60
- package/src/utils/mcp-auth-middleware.ts +0 -262
- package/src/utils/mcp-config-manager.ts +0 -270
- package/src/utils/mcp-server-manager.ts +0 -446
- package/src/utils/mcp-tool-registry.ts +0 -298
- package/src/utils/migrate-snow-flow.ts +0 -98
- package/src/utils/oauth-html-templates.ts +0 -188
- package/src/utils/scope-utils.ts +0 -443
- package/src/utils/servicenow-client.ts +0 -3321
- package/src/utils/servicenow-id-generator.ts +0 -181
- package/src/utils/snow-memory-manager.ts +0 -605
- package/src/utils/snow-oauth.ts +0 -797
- package/src/utils/template-engine.ts +0 -463
- package/src/utils/theme-manager.ts +0 -295
- package/src/utils/unified-auth-store.ts +0 -222
- package/src/utils/update-set-importer.ts +0 -422
- package/src/utils/update-set-xml-packager.ts +0 -371
- package/src/utils/widget-template-generator.ts +0 -1744
- package/src/version.ts +0 -1950
|
@@ -1,680 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Snow-Flow Error Handling & Recovery System
|
|
3
|
-
* Implements comprehensive error recovery patterns from MCP Architecture
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { EventEmitter } from 'events';
|
|
7
|
-
import { Logger } from './logger';
|
|
8
|
-
import { MemorySystem } from '../memory/memory-system';
|
|
9
|
-
|
|
10
|
-
export interface ErrorContext {
|
|
11
|
-
operation: string;
|
|
12
|
-
sessionId?: string;
|
|
13
|
-
agentId?: string;
|
|
14
|
-
artifactId?: string;
|
|
15
|
-
attemptNumber?: number;
|
|
16
|
-
fallbackStrategies?: string[];
|
|
17
|
-
metadata?: Record<string, any>;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface RecoveryStrategy {
|
|
21
|
-
name: string;
|
|
22
|
-
condition: (error: Error, context: ErrorContext) => boolean;
|
|
23
|
-
execute: (error: Error, context: ErrorContext) => Promise<RecoveryResult>;
|
|
24
|
-
priority: number;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface RecoveryResult {
|
|
28
|
-
success: boolean;
|
|
29
|
-
strategyUsed?: string;
|
|
30
|
-
result?: any;
|
|
31
|
-
error?: Error;
|
|
32
|
-
nextStrategies?: string[];
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface ErrorMetrics {
|
|
36
|
-
totalErrors: number;
|
|
37
|
-
recoveredErrors: number;
|
|
38
|
-
failedRecoveries: number;
|
|
39
|
-
errorsByType: Record<string, number>;
|
|
40
|
-
recoveryStrategiesUsed: Record<string, number>;
|
|
41
|
-
averageRecoveryTime: number;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export class ErrorRecovery extends EventEmitter {
|
|
45
|
-
private logger: Logger;
|
|
46
|
-
private strategies: Map<string, RecoveryStrategy> = new Map();
|
|
47
|
-
private errorHistory: ErrorRecord[] = [];
|
|
48
|
-
private memory?: MemorySystem;
|
|
49
|
-
private maxRetries = 3;
|
|
50
|
-
private retryDelay = 1000;
|
|
51
|
-
private exponentialBackoff = true;
|
|
52
|
-
|
|
53
|
-
constructor(logger: Logger, memory?: MemorySystem) {
|
|
54
|
-
super();
|
|
55
|
-
this.logger = logger;
|
|
56
|
-
this.memory = memory;
|
|
57
|
-
this.initializeDefaultStrategies();
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Initialize default recovery strategies
|
|
62
|
-
*/
|
|
63
|
-
private initializeDefaultStrategies(): void {
|
|
64
|
-
// Retry strategy
|
|
65
|
-
this.registerStrategy({
|
|
66
|
-
name: 'retry',
|
|
67
|
-
condition: (error, context) => {
|
|
68
|
-
return (context.attemptNumber || 0) < this.maxRetries &&
|
|
69
|
-
!this.isUnrecoverable(error);
|
|
70
|
-
},
|
|
71
|
-
execute: async (error, context) => {
|
|
72
|
-
const attempt = (context.attemptNumber || 0) + 1;
|
|
73
|
-
const delay = this.calculateRetryDelay(attempt);
|
|
74
|
-
|
|
75
|
-
this.logger.info(`Retrying operation ${context.operation} (attempt ${attempt}/${this.maxRetries})`);
|
|
76
|
-
await this.delay(delay);
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
success: false,
|
|
80
|
-
strategyUsed: 'retry',
|
|
81
|
-
nextStrategies: ['retry', 'fallback']
|
|
82
|
-
};
|
|
83
|
-
},
|
|
84
|
-
priority: 100
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
// Permission escalation strategy
|
|
88
|
-
this.registerStrategy({
|
|
89
|
-
name: 'permission_escalation',
|
|
90
|
-
condition: (error) => this.isPermissionError(error),
|
|
91
|
-
execute: async (error, context) => {
|
|
92
|
-
this.logger.info('Attempting permission escalation...');
|
|
93
|
-
|
|
94
|
-
try {
|
|
95
|
-
// Request elevated permissions through Queen agent
|
|
96
|
-
await this.requestPermissionEscalation(context);
|
|
97
|
-
|
|
98
|
-
return {
|
|
99
|
-
success: true,
|
|
100
|
-
strategyUsed: 'permission_escalation'
|
|
101
|
-
};
|
|
102
|
-
} catch (escalationError) {
|
|
103
|
-
return {
|
|
104
|
-
success: false,
|
|
105
|
-
error: escalationError as Error,
|
|
106
|
-
nextStrategies: ['manual_intervention']
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
priority: 90
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
// Scope fallback strategy
|
|
114
|
-
this.registerStrategy({
|
|
115
|
-
name: 'scope_fallback',
|
|
116
|
-
condition: (error) => this.isScopeError(error),
|
|
117
|
-
execute: async (error, context) => {
|
|
118
|
-
this.logger.info('Attempting global scope fallback...');
|
|
119
|
-
|
|
120
|
-
try {
|
|
121
|
-
// Modify context to use global scope
|
|
122
|
-
const globalContext = {
|
|
123
|
-
...context,
|
|
124
|
-
metadata: {
|
|
125
|
-
...context.metadata,
|
|
126
|
-
scope: 'global',
|
|
127
|
-
fallbackReason: 'scope_error'
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
return {
|
|
132
|
-
success: true,
|
|
133
|
-
strategyUsed: 'scope_fallback',
|
|
134
|
-
result: globalContext
|
|
135
|
-
};
|
|
136
|
-
} catch (fallbackError) {
|
|
137
|
-
return {
|
|
138
|
-
success: false,
|
|
139
|
-
error: fallbackError as Error
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
},
|
|
143
|
-
priority: 85
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
// Cache invalidation strategy
|
|
147
|
-
this.registerStrategy({
|
|
148
|
-
name: 'cache_invalidation',
|
|
149
|
-
condition: (error) => this.isDataConsistencyError(error),
|
|
150
|
-
execute: async (error, context) => {
|
|
151
|
-
this.logger.info('Invalidating cache and refreshing data...');
|
|
152
|
-
|
|
153
|
-
try {
|
|
154
|
-
if (this.memory) {
|
|
155
|
-
await this.memory.invalidateCache(context.sessionId || 'global');
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return {
|
|
159
|
-
success: true,
|
|
160
|
-
strategyUsed: 'cache_invalidation',
|
|
161
|
-
nextStrategies: ['retry']
|
|
162
|
-
};
|
|
163
|
-
} catch (cacheError) {
|
|
164
|
-
return {
|
|
165
|
-
success: false,
|
|
166
|
-
error: cacheError as Error
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
},
|
|
170
|
-
priority: 80
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
// Partial success strategy
|
|
174
|
-
this.registerStrategy({
|
|
175
|
-
name: 'partial_success',
|
|
176
|
-
condition: (error, context) => {
|
|
177
|
-
return context.metadata?.allowPartial === true &&
|
|
178
|
-
this.canPartiallySucceed(error);
|
|
179
|
-
},
|
|
180
|
-
execute: async (error, context) => {
|
|
181
|
-
this.logger.info('Attempting partial success recovery...');
|
|
182
|
-
|
|
183
|
-
const partialResult = await this.extractPartialSuccess(error, context);
|
|
184
|
-
|
|
185
|
-
return {
|
|
186
|
-
success: true,
|
|
187
|
-
strategyUsed: 'partial_success',
|
|
188
|
-
result: partialResult
|
|
189
|
-
};
|
|
190
|
-
},
|
|
191
|
-
priority: 70
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
// Manual intervention strategy
|
|
195
|
-
this.registerStrategy({
|
|
196
|
-
name: 'manual_intervention',
|
|
197
|
-
condition: () => true, // Last resort
|
|
198
|
-
execute: async (error, context) => {
|
|
199
|
-
this.logger.warn('Manual intervention required');
|
|
200
|
-
|
|
201
|
-
// Generate manual steps
|
|
202
|
-
const manualSteps = await this.generateManualSteps(error, context);
|
|
203
|
-
|
|
204
|
-
// Store for later retrieval
|
|
205
|
-
if (this.memory) {
|
|
206
|
-
await this.memory.store(`manual_intervention_${context.sessionId}`, {
|
|
207
|
-
error: error.message,
|
|
208
|
-
context,
|
|
209
|
-
steps: manualSteps,
|
|
210
|
-
timestamp: new Date()
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return {
|
|
215
|
-
success: false,
|
|
216
|
-
strategyUsed: 'manual_intervention',
|
|
217
|
-
result: { manualSteps },
|
|
218
|
-
error: new Error('Manual intervention required. Check logs for instructions.')
|
|
219
|
-
};
|
|
220
|
-
},
|
|
221
|
-
priority: 10
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Register a custom recovery strategy
|
|
227
|
-
*/
|
|
228
|
-
registerStrategy(strategy: RecoveryStrategy): void {
|
|
229
|
-
this.strategies.set(strategy.name, strategy);
|
|
230
|
-
this.logger.debug(`Registered recovery strategy: ${strategy.name}`);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Handle an error with automatic recovery
|
|
235
|
-
*/
|
|
236
|
-
async handleError(error: Error, context: ErrorContext): Promise<RecoveryResult> {
|
|
237
|
-
const startTime = Date.now();
|
|
238
|
-
|
|
239
|
-
this.logger.error(`Error in operation ${context.operation}:`, error);
|
|
240
|
-
this.recordError(error, context);
|
|
241
|
-
|
|
242
|
-
// Get applicable strategies sorted by priority
|
|
243
|
-
const applicableStrategies = this.getApplicableStrategies(error, context);
|
|
244
|
-
|
|
245
|
-
let lastResult: RecoveryResult = {
|
|
246
|
-
success: false,
|
|
247
|
-
error
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
// Try each strategy in order
|
|
251
|
-
for (const strategy of applicableStrategies) {
|
|
252
|
-
try {
|
|
253
|
-
this.logger.info(`Attempting recovery strategy: ${strategy.name}`);
|
|
254
|
-
lastResult = await strategy.execute(error, context);
|
|
255
|
-
|
|
256
|
-
if (lastResult.success) {
|
|
257
|
-
const duration = Date.now() - startTime;
|
|
258
|
-
this.recordRecovery(strategy.name, duration);
|
|
259
|
-
this.emit('recovery:success', {
|
|
260
|
-
strategy: strategy.name,
|
|
261
|
-
duration,
|
|
262
|
-
context
|
|
263
|
-
});
|
|
264
|
-
return lastResult;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// If strategy suggests next strategies, filter to those
|
|
268
|
-
if (lastResult.nextStrategies) {
|
|
269
|
-
const nextStrategies = lastResult.nextStrategies
|
|
270
|
-
.map(name => this.strategies.get(name))
|
|
271
|
-
.filter(s => s && s.condition(error, context))
|
|
272
|
-
.sort((a, b) => b!.priority - a!.priority);
|
|
273
|
-
|
|
274
|
-
if (nextStrategies.length > 0) {
|
|
275
|
-
// Continue with suggested strategies
|
|
276
|
-
for (const nextStrategy of nextStrategies) {
|
|
277
|
-
if (nextStrategy && !applicableStrategies.includes(nextStrategy)) {
|
|
278
|
-
applicableStrategies.push(nextStrategy);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
} catch (strategyError) {
|
|
284
|
-
this.logger.error(`Recovery strategy ${strategy.name} failed:`, strategyError);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// All strategies failed
|
|
289
|
-
const duration = Date.now() - startTime;
|
|
290
|
-
this.recordFailedRecovery(error, context, duration);
|
|
291
|
-
this.emit('recovery:failed', {
|
|
292
|
-
error,
|
|
293
|
-
context,
|
|
294
|
-
duration,
|
|
295
|
-
strategiesAttempted: applicableStrategies.map(s => s.name)
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
return lastResult;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Handle critical errors that affect the entire system
|
|
303
|
-
*/
|
|
304
|
-
async handleCriticalError(error: Error, context: ErrorContext): Promise<void> {
|
|
305
|
-
this.logger.error('CRITICAL ERROR:', error);
|
|
306
|
-
|
|
307
|
-
// Notify all active agents
|
|
308
|
-
this.emit('critical:error', { error, context });
|
|
309
|
-
|
|
310
|
-
// Attempt emergency recovery
|
|
311
|
-
const emergencyStrategies = context.fallbackStrategies || [
|
|
312
|
-
'emergency_shutdown',
|
|
313
|
-
'data_preservation',
|
|
314
|
-
'rollback_all'
|
|
315
|
-
];
|
|
316
|
-
|
|
317
|
-
for (const strategyName of emergencyStrategies) {
|
|
318
|
-
try {
|
|
319
|
-
await this.executeEmergencyStrategy(strategyName, error, context);
|
|
320
|
-
} catch (emergencyError) {
|
|
321
|
-
this.logger.error(`Emergency strategy ${strategyName} failed:`, emergencyError);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* Attempt to recover a failed swarm session
|
|
328
|
-
*/
|
|
329
|
-
async attemptSwarmRecovery(sessionId: string, error: Error): Promise<RecoveryResult> {
|
|
330
|
-
const context: ErrorContext = {
|
|
331
|
-
operation: 'swarm_execution',
|
|
332
|
-
sessionId,
|
|
333
|
-
fallbackStrategies: [
|
|
334
|
-
'resume_from_checkpoint',
|
|
335
|
-
'restart_failed_agents',
|
|
336
|
-
'rollback_to_stable'
|
|
337
|
-
]
|
|
338
|
-
};
|
|
339
|
-
|
|
340
|
-
// Check if we have a checkpoint
|
|
341
|
-
if (this.memory) {
|
|
342
|
-
const checkpoint = await this.memory.get(`checkpoint_${sessionId}`);
|
|
343
|
-
if (checkpoint) {
|
|
344
|
-
try {
|
|
345
|
-
const result = await this.resumeFromCheckpoint(sessionId, checkpoint);
|
|
346
|
-
return {
|
|
347
|
-
success: true,
|
|
348
|
-
strategyUsed: 'resume_from_checkpoint',
|
|
349
|
-
result
|
|
350
|
-
};
|
|
351
|
-
} catch (resumeError) {
|
|
352
|
-
this.logger.error('Failed to resume from checkpoint:', resumeError);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// Try standard error recovery
|
|
358
|
-
return this.handleError(error, context);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* Get error metrics
|
|
363
|
-
*/
|
|
364
|
-
getMetrics(): ErrorMetrics {
|
|
365
|
-
const metrics: ErrorMetrics = {
|
|
366
|
-
totalErrors: this.errorHistory.length,
|
|
367
|
-
recoveredErrors: 0,
|
|
368
|
-
failedRecoveries: 0,
|
|
369
|
-
errorsByType: {},
|
|
370
|
-
recoveryStrategiesUsed: {},
|
|
371
|
-
averageRecoveryTime: 0
|
|
372
|
-
};
|
|
373
|
-
|
|
374
|
-
let totalRecoveryTime = 0;
|
|
375
|
-
let recoveryCount = 0;
|
|
376
|
-
|
|
377
|
-
for (const record of this.errorHistory) {
|
|
378
|
-
// Count by type
|
|
379
|
-
const errorType = record.error.name || 'Unknown';
|
|
380
|
-
metrics.errorsByType[errorType] = (metrics.errorsByType[errorType] || 0) + 1;
|
|
381
|
-
|
|
382
|
-
// Count recoveries
|
|
383
|
-
if (record.recovered) {
|
|
384
|
-
metrics.recoveredErrors++;
|
|
385
|
-
if (record.recoveryStrategy) {
|
|
386
|
-
metrics.recoveryStrategiesUsed[record.recoveryStrategy] =
|
|
387
|
-
(metrics.recoveryStrategiesUsed[record.recoveryStrategy] || 0) + 1;
|
|
388
|
-
}
|
|
389
|
-
if (record.recoveryDuration) {
|
|
390
|
-
totalRecoveryTime += record.recoveryDuration;
|
|
391
|
-
recoveryCount++;
|
|
392
|
-
}
|
|
393
|
-
} else {
|
|
394
|
-
metrics.failedRecoveries++;
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
if (recoveryCount > 0) {
|
|
399
|
-
metrics.averageRecoveryTime = totalRecoveryTime / recoveryCount;
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
return metrics;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
/**
|
|
406
|
-
* Clear error history
|
|
407
|
-
*/
|
|
408
|
-
clearHistory(): void {
|
|
409
|
-
this.errorHistory = [];
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* Private helper methods
|
|
414
|
-
*/
|
|
415
|
-
private getApplicableStrategies(error: Error, context: ErrorContext): RecoveryStrategy[] {
|
|
416
|
-
const strategies = Array.from(this.strategies.values())
|
|
417
|
-
.filter(strategy => strategy.condition(error, context))
|
|
418
|
-
.sort((a, b) => b.priority - a.priority);
|
|
419
|
-
|
|
420
|
-
// If custom fallback strategies specified, prioritize those
|
|
421
|
-
if (context.fallbackStrategies) {
|
|
422
|
-
const customStrategies = context.fallbackStrategies
|
|
423
|
-
.map(name => this.strategies.get(name))
|
|
424
|
-
.filter(s => s && s.condition(error, context)) as RecoveryStrategy[];
|
|
425
|
-
|
|
426
|
-
return [...customStrategies, ...strategies];
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
return strategies;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
private isUnrecoverable(error: Error): boolean {
|
|
433
|
-
const unrecoverableErrors = [
|
|
434
|
-
'ENOTFOUND',
|
|
435
|
-
'ECONNREFUSED',
|
|
436
|
-
'ETIMEDOUT',
|
|
437
|
-
'CERT_HAS_EXPIRED'
|
|
438
|
-
];
|
|
439
|
-
|
|
440
|
-
return unrecoverableErrors.some(code =>
|
|
441
|
-
error.message.includes(code) || (error as any).code === code
|
|
442
|
-
);
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
private isPermissionError(error: Error): boolean {
|
|
446
|
-
const permissionIndicators = [
|
|
447
|
-
'permission denied',
|
|
448
|
-
'access denied',
|
|
449
|
-
'unauthorized',
|
|
450
|
-
'401',
|
|
451
|
-
'403',
|
|
452
|
-
'insufficient privileges'
|
|
453
|
-
];
|
|
454
|
-
|
|
455
|
-
const errorMessage = error.message.toLowerCase();
|
|
456
|
-
return permissionIndicators.some(indicator =>
|
|
457
|
-
errorMessage.includes(indicator)
|
|
458
|
-
);
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
private isScopeError(error: Error): boolean {
|
|
462
|
-
const scopeIndicators = [
|
|
463
|
-
'scope not found',
|
|
464
|
-
'application scope',
|
|
465
|
-
'wrong scope',
|
|
466
|
-
'scope mismatch'
|
|
467
|
-
];
|
|
468
|
-
|
|
469
|
-
const errorMessage = error.message.toLowerCase();
|
|
470
|
-
return scopeIndicators.some(indicator =>
|
|
471
|
-
errorMessage.includes(indicator)
|
|
472
|
-
);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
private isDataConsistencyError(error: Error): boolean {
|
|
476
|
-
const consistencyIndicators = [
|
|
477
|
-
'data inconsistency',
|
|
478
|
-
'stale data',
|
|
479
|
-
'cache invalid',
|
|
480
|
-
'version mismatch'
|
|
481
|
-
];
|
|
482
|
-
|
|
483
|
-
const errorMessage = error.message.toLowerCase();
|
|
484
|
-
return consistencyIndicators.some(indicator =>
|
|
485
|
-
errorMessage.includes(indicator)
|
|
486
|
-
);
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
private canPartiallySucceed(error: Error): boolean {
|
|
490
|
-
// Determine if the operation can partially succeed
|
|
491
|
-
return error.message.includes('partial') ||
|
|
492
|
-
error.message.includes('some operations failed');
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
private calculateRetryDelay(attemptNumber: number): number {
|
|
496
|
-
if (this.exponentialBackoff) {
|
|
497
|
-
return Math.min(
|
|
498
|
-
this.retryDelay * Math.pow(2, attemptNumber - 1),
|
|
499
|
-
30000 // Max 30 seconds
|
|
500
|
-
);
|
|
501
|
-
}
|
|
502
|
-
return this.retryDelay;
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
private async requestPermissionEscalation(context: ErrorContext): Promise<void> {
|
|
506
|
-
// Emit event for Queen agent to handle
|
|
507
|
-
this.emit('permission:escalation:requested', context);
|
|
508
|
-
|
|
509
|
-
// Wait for escalation (with timeout)
|
|
510
|
-
return new Promise((resolve, reject) => {
|
|
511
|
-
const timeout = setTimeout(() => {
|
|
512
|
-
reject(new Error('Permission escalation timeout'));
|
|
513
|
-
}, 30000);
|
|
514
|
-
|
|
515
|
-
this.once('permission:escalation:granted', () => {
|
|
516
|
-
clearTimeout(timeout);
|
|
517
|
-
resolve();
|
|
518
|
-
});
|
|
519
|
-
|
|
520
|
-
this.once('permission:escalation:denied', () => {
|
|
521
|
-
clearTimeout(timeout);
|
|
522
|
-
reject(new Error('Permission escalation denied'));
|
|
523
|
-
});
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
private async extractPartialSuccess(error: Error, context: ErrorContext): Promise<any> {
|
|
528
|
-
// Extract any partial results from the error context
|
|
529
|
-
if ((error as any).partialResult) {
|
|
530
|
-
return (error as any).partialResult;
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
// Check memory for partial results
|
|
534
|
-
if (this.memory && context.sessionId) {
|
|
535
|
-
const partialData = await this.memory.get(`partial_${context.sessionId}`);
|
|
536
|
-
if (partialData) {
|
|
537
|
-
return partialData;
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
return null;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
private async generateManualSteps(error: Error, context: ErrorContext): Promise<string[]> {
|
|
545
|
-
const steps: string[] = [];
|
|
546
|
-
|
|
547
|
-
if (this.isPermissionError(error)) {
|
|
548
|
-
steps.push('1. Log into ServiceNow as an administrator');
|
|
549
|
-
steps.push('2. Navigate to System Security > Users and Groups > Users');
|
|
550
|
-
steps.push('3. Find the integration user and click on it');
|
|
551
|
-
steps.push('4. Go to the Roles tab and add required roles');
|
|
552
|
-
steps.push('5. Save the changes and retry the operation');
|
|
553
|
-
} else if (this.isScopeError(error)) {
|
|
554
|
-
steps.push('1. Log into ServiceNow as an administrator');
|
|
555
|
-
steps.push('2. Navigate to System Applications > Applications');
|
|
556
|
-
steps.push('3. Switch to the Global scope');
|
|
557
|
-
steps.push('4. Retry the operation in Global scope');
|
|
558
|
-
steps.push('5. If successful, move the artifact to the desired scope');
|
|
559
|
-
} else {
|
|
560
|
-
steps.push('1. Check ServiceNow instance availability');
|
|
561
|
-
steps.push('2. Verify network connectivity');
|
|
562
|
-
steps.push('3. Check authentication credentials');
|
|
563
|
-
steps.push('4. Review error logs for specific issues');
|
|
564
|
-
steps.push('5. Contact support if issue persists');
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
return steps;
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
private async executeEmergencyStrategy(
|
|
571
|
-
strategyName: string,
|
|
572
|
-
error: Error,
|
|
573
|
-
context: ErrorContext
|
|
574
|
-
): Promise<void> {
|
|
575
|
-
switch (strategyName) {
|
|
576
|
-
case 'emergency_shutdown':
|
|
577
|
-
this.emit('system:emergency:shutdown', { error, context });
|
|
578
|
-
break;
|
|
579
|
-
|
|
580
|
-
case 'data_preservation':
|
|
581
|
-
if (this.memory) {
|
|
582
|
-
await this.memory.createEmergencyBackup();
|
|
583
|
-
}
|
|
584
|
-
break;
|
|
585
|
-
|
|
586
|
-
case 'rollback_all':
|
|
587
|
-
this.emit('system:rollback:all', { error, context });
|
|
588
|
-
break;
|
|
589
|
-
|
|
590
|
-
default:
|
|
591
|
-
this.logger.warn(`Unknown emergency strategy: ${strategyName}`);
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
private async resumeFromCheckpoint(sessionId: string, checkpoint: any): Promise<any> {
|
|
596
|
-
this.logger.info(`Resuming session ${sessionId} from checkpoint`);
|
|
597
|
-
|
|
598
|
-
// Emit event for system to resume
|
|
599
|
-
this.emit('session:resume', {
|
|
600
|
-
sessionId,
|
|
601
|
-
checkpoint
|
|
602
|
-
});
|
|
603
|
-
|
|
604
|
-
return checkpoint;
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
private recordError(error: Error, context: ErrorContext): void {
|
|
608
|
-
this.errorHistory.push({
|
|
609
|
-
error,
|
|
610
|
-
context,
|
|
611
|
-
timestamp: new Date(),
|
|
612
|
-
recovered: false
|
|
613
|
-
});
|
|
614
|
-
|
|
615
|
-
// Limit history size
|
|
616
|
-
if (this.errorHistory.length > 1000) {
|
|
617
|
-
this.errorHistory = this.errorHistory.slice(-500);
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
private recordRecovery(strategyName: string, duration: number): void {
|
|
622
|
-
const lastError = this.errorHistory[this.errorHistory.length - 1];
|
|
623
|
-
if (lastError) {
|
|
624
|
-
lastError.recovered = true;
|
|
625
|
-
lastError.recoveryStrategy = strategyName;
|
|
626
|
-
lastError.recoveryDuration = duration;
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
private recordFailedRecovery(error: Error, context: ErrorContext, duration: number): void {
|
|
631
|
-
const lastError = this.errorHistory[this.errorHistory.length - 1];
|
|
632
|
-
if (lastError) {
|
|
633
|
-
lastError.recovered = false;
|
|
634
|
-
lastError.recoveryDuration = duration;
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
private delay(ms: number): Promise<void> {
|
|
639
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
// Type definitions
|
|
644
|
-
interface ErrorRecord {
|
|
645
|
-
error: Error;
|
|
646
|
-
context: ErrorContext;
|
|
647
|
-
timestamp: Date;
|
|
648
|
-
recovered: boolean;
|
|
649
|
-
recoveryStrategy?: string;
|
|
650
|
-
recoveryDuration?: number;
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
// Export pre-configured strategies
|
|
654
|
-
export const FALLBACK_STRATEGIES = {
|
|
655
|
-
widget_deployment: [
|
|
656
|
-
'retry',
|
|
657
|
-
'scope_fallback',
|
|
658
|
-
'permission_escalation',
|
|
659
|
-
'partial_success',
|
|
660
|
-
'manual_intervention'
|
|
661
|
-
],
|
|
662
|
-
flow_creation: [
|
|
663
|
-
'retry',
|
|
664
|
-
'cache_invalidation',
|
|
665
|
-
'scope_fallback',
|
|
666
|
-
'manual_intervention'
|
|
667
|
-
],
|
|
668
|
-
script_execution: [
|
|
669
|
-
'retry',
|
|
670
|
-
'permission_escalation',
|
|
671
|
-
'partial_success',
|
|
672
|
-
'manual_intervention'
|
|
673
|
-
],
|
|
674
|
-
integration_failure: [
|
|
675
|
-
'retry',
|
|
676
|
-
'cache_invalidation',
|
|
677
|
-
'partial_success',
|
|
678
|
-
'manual_intervention'
|
|
679
|
-
]
|
|
680
|
-
};
|