tachibot-mcp 2.0.2
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/.env.example +260 -0
- package/CHANGELOG.md +54 -0
- package/CODE_OF_CONDUCT.md +56 -0
- package/CONTRIBUTING.md +54 -0
- package/Dockerfile +36 -0
- package/LICENSE +644 -0
- package/README.md +201 -0
- package/SECURITY.md +95 -0
- package/dist/personality/komaai-expressions.js +12 -0
- package/dist/profiles/balanced.json +33 -0
- package/dist/profiles/code_focus.json +33 -0
- package/dist/profiles/full.json +33 -0
- package/dist/profiles/minimal.json +33 -0
- package/dist/profiles/research_power.json +33 -0
- package/dist/scripts/build-profiles.js +46 -0
- package/dist/src/application/services/focus/FocusModeRegistry.js +46 -0
- package/dist/src/application/services/focus/FocusTool.service.js +109 -0
- package/dist/src/application/services/focus/ModeRegistry.js +46 -0
- package/dist/src/application/services/focus/modes/focus-deep.mode.js +27 -0
- package/dist/src/application/services/focus/modes/status.mode.js +50 -0
- package/dist/src/application/services/focus/modes/tachibot-status.mode.js +50 -0
- package/dist/src/collaborative-orchestrator.js +391 -0
- package/dist/src/config/model-constants.js +188 -0
- package/dist/src/config/model-defaults.js +57 -0
- package/dist/src/config/model-preferences.js +382 -0
- package/dist/src/config/timeout-config.js +130 -0
- package/dist/src/config.js +173 -0
- package/dist/src/domain/interfaces/IFocusMode.js +5 -0
- package/dist/src/domain/interfaces/IProvider.js +6 -0
- package/dist/src/domain/interfaces/ITool.js +5 -0
- package/dist/src/focus-deep.js +245 -0
- package/dist/src/infrastructure/ascii/art/robots.ascii.js +16 -0
- package/dist/src/mcp-client.js +90 -0
- package/dist/src/memory/index.js +17 -0
- package/dist/src/memory/memory-config.js +135 -0
- package/dist/src/memory/memory-interface.js +174 -0
- package/dist/src/memory/memory-manager.js +383 -0
- package/dist/src/memory/providers/devlog-provider.js +385 -0
- package/dist/src/memory/providers/hybrid-provider.js +399 -0
- package/dist/src/memory/providers/local-provider.js +388 -0
- package/dist/src/memory/providers/mem0-provider.js +337 -0
- package/dist/src/modes/architect.js +477 -0
- package/dist/src/modes/auditor.js +362 -0
- package/dist/src/modes/challenger.js +841 -0
- package/dist/src/modes/code-reviewer.js +382 -0
- package/dist/src/modes/commit-guardian.js +424 -0
- package/dist/src/modes/documentation-writer.js +572 -0
- package/dist/src/modes/scout.js +587 -0
- package/dist/src/modes/shared/helpers/challenger-helpers.js +454 -0
- package/dist/src/modes/shared/helpers/index.js +17 -0
- package/dist/src/modes/shared/helpers/scout-helpers.js +270 -0
- package/dist/src/modes/shared/helpers/verifier-helpers.js +332 -0
- package/dist/src/modes/test-architect.js +767 -0
- package/dist/src/modes/verifier.js +378 -0
- package/dist/src/monitoring/performance-monitor.js +435 -0
- package/dist/src/optimization/batch-executor.js +121 -0
- package/dist/src/optimization/context-pruner.js +196 -0
- package/dist/src/optimization/cost-monitor.js +338 -0
- package/dist/src/optimization/index.js +65 -0
- package/dist/src/optimization/model-router.js +264 -0
- package/dist/src/optimization/result-cache.js +114 -0
- package/dist/src/optimization/token-optimizer.js +257 -0
- package/dist/src/optimization/token-tracker.js +118 -0
- package/dist/src/orchestrator-instructions.js +128 -0
- package/dist/src/orchestrator-lite.js +139 -0
- package/dist/src/orchestrator.js +191 -0
- package/dist/src/orchestrators/collaborative/interfaces/IToolExecutionEngine.js +1 -0
- package/dist/src/orchestrators/collaborative/interfaces/IToolExecutionStrategy.js +5 -0
- package/dist/src/orchestrators/collaborative/interfaces/IVisualizationRenderer.js +1 -0
- package/dist/src/orchestrators/collaborative/registries/ModelProviderRegistry.js +95 -0
- package/dist/src/orchestrators/collaborative/registries/ToolAdapterRegistry.js +64 -0
- package/dist/src/orchestrators/collaborative/services/tool-execution/ToolExecutionService.js +502 -0
- package/dist/src/orchestrators/collaborative/services/visualization/VisualizationService.js +206 -0
- package/dist/src/orchestrators/collaborative/types/session-types.js +5 -0
- package/dist/src/profiles/balanced.js +37 -0
- package/dist/src/profiles/code_focus.js +37 -0
- package/dist/src/profiles/debug_intensive.js +59 -0
- package/dist/src/profiles/full.js +37 -0
- package/dist/src/profiles/minimal.js +37 -0
- package/dist/src/profiles/research_code.js +59 -0
- package/dist/src/profiles/research_power.js +37 -0
- package/dist/src/profiles/types.js +5 -0
- package/dist/src/profiles/workflow_builder.js +53 -0
- package/dist/src/prompt-engineer-lite.js +78 -0
- package/dist/src/prompt-engineer.js +399 -0
- package/dist/src/reasoning-chain.js +508 -0
- package/dist/src/sequential-thinking.js +291 -0
- package/dist/src/server-diagnostic.js +74 -0
- package/dist/src/server-raw.js +158 -0
- package/dist/src/server-simple.js +58 -0
- package/dist/src/server.js +514 -0
- package/dist/src/session/session-logger.js +617 -0
- package/dist/src/session/session-manager.js +571 -0
- package/dist/src/session/session-tools.js +400 -0
- package/dist/src/tools/advanced-modes.js +200 -0
- package/dist/src/tools/claude-integration.js +356 -0
- package/dist/src/tools/consolidated/ai-router.js +174 -0
- package/dist/src/tools/consolidated/ai-tool.js +48 -0
- package/dist/src/tools/consolidated/brainstorm-tool.js +87 -0
- package/dist/src/tools/consolidated/environment-detector.js +80 -0
- package/dist/src/tools/consolidated/index.js +50 -0
- package/dist/src/tools/consolidated/search-tool.js +110 -0
- package/dist/src/tools/consolidated/workflow-tool.js +238 -0
- package/dist/src/tools/gemini-tools.js +329 -0
- package/dist/src/tools/grok-enhanced.js +376 -0
- package/dist/src/tools/grok-tools.js +299 -0
- package/dist/src/tools/lmstudio-tools.js +223 -0
- package/dist/src/tools/openai-tools.js +498 -0
- package/dist/src/tools/openrouter-tools.js +317 -0
- package/dist/src/tools/optimized-wrapper.js +204 -0
- package/dist/src/tools/perplexity-tools.js +294 -0
- package/dist/src/tools/pingpong-tool.js +343 -0
- package/dist/src/tools/qwen-wrapper.js +74 -0
- package/dist/src/tools/tool-router.js +444 -0
- package/dist/src/tools/unified-ai-provider.js +260 -0
- package/dist/src/tools/workflow-runner.js +425 -0
- package/dist/src/tools/workflow-validator-tool.js +107 -0
- package/dist/src/types.js +23 -0
- package/dist/src/utils/input-validator.js +130 -0
- package/dist/src/utils/model-router.js +91 -0
- package/dist/src/utils/progress-stream.js +255 -0
- package/dist/src/utils/provider-router.js +88 -0
- package/dist/src/utils/smart-api-client.js +146 -0
- package/dist/src/utils/table-builder.js +218 -0
- package/dist/src/utils/timestamp-formatter.js +134 -0
- package/dist/src/utils/tool-compressor.js +257 -0
- package/dist/src/utils/tool-config.js +201 -0
- package/dist/src/validators/dependency-graph-validator.js +147 -0
- package/dist/src/validators/interpolation-validator.js +222 -0
- package/dist/src/validators/output-usage-validator.js +151 -0
- package/dist/src/validators/syntax-validator.js +102 -0
- package/dist/src/validators/tool-registry-validator.js +123 -0
- package/dist/src/validators/tool-types.js +97 -0
- package/dist/src/validators/types.js +8 -0
- package/dist/src/validators/workflow-validator.js +134 -0
- package/dist/src/visualizer-lite.js +42 -0
- package/dist/src/visualizer.js +179 -0
- package/dist/src/workflows/circuit-breaker.js +199 -0
- package/dist/src/workflows/custom-workflows.js +451 -0
- package/dist/src/workflows/engine/AutoSynthesizer.js +97 -0
- package/dist/src/workflows/engine/StepParameterResolver.js +74 -0
- package/dist/src/workflows/engine/VariableInterpolator.js +123 -0
- package/dist/src/workflows/engine/WorkflowDiscovery.js +125 -0
- package/dist/src/workflows/engine/WorkflowExecutionEngine.js +485 -0
- package/dist/src/workflows/engine/WorkflowExecutor.js +113 -0
- package/dist/src/workflows/engine/WorkflowFileManager.js +244 -0
- package/dist/src/workflows/engine/WorkflowHelpers.js +114 -0
- package/dist/src/workflows/engine/WorkflowOutputFormatter.js +83 -0
- package/dist/src/workflows/engine/events/WorkflowEventBus.js +132 -0
- package/dist/src/workflows/engine/events/interfaces/IEventBus.js +5 -0
- package/dist/src/workflows/engine/handlers/ErrorRecoveryHandler.js +162 -0
- package/dist/src/workflows/engine/handlers/PromptEnhancementHandler.js +115 -0
- package/dist/src/workflows/engine/handlers/SessionPersistenceHandler.js +167 -0
- package/dist/src/workflows/engine/handlers/StepExecutionHandler.js +231 -0
- package/dist/src/workflows/engine/handlers/ToolInvocationHandler.js +46 -0
- package/dist/src/workflows/engine/interfaces/IAutoSynthesizer.js +5 -0
- package/dist/src/workflows/engine/interfaces/IStepParameterResolver.js +5 -0
- package/dist/src/workflows/engine/interfaces/IVariableInterpolator.js +5 -0
- package/dist/src/workflows/engine/interfaces/IWorkflowDiscovery.js +4 -0
- package/dist/src/workflows/engine/interfaces/IWorkflowFileManager.js +5 -0
- package/dist/src/workflows/engine/interfaces/IWorkflowOutputFormatter.js +5 -0
- package/dist/src/workflows/engine/state/WorkflowStateMachine.js +194 -0
- package/dist/src/workflows/engine/state/interfaces/IStateMachine.js +17 -0
- package/dist/src/workflows/fallback-strategies.js +373 -0
- package/dist/src/workflows/message-queue.js +455 -0
- package/dist/src/workflows/model-router.js +189 -0
- package/dist/src/workflows/orchestrator-examples.js +174 -0
- package/dist/src/workflows/orchestrator-integration.js +200 -0
- package/dist/src/workflows/self-healing.js +524 -0
- package/dist/src/workflows/tool-mapper.js +407 -0
- package/dist/src/workflows/tool-orchestrator.js +796 -0
- package/dist/src/workflows/workflow-engine.js +573 -0
- package/dist/src/workflows/workflow-parser.js +283 -0
- package/dist/src/workflows/workflow-types.js +95 -0
- package/dist/src/workflows.js +568 -0
- package/dist/test-workflow-file-output.js +93 -0
- package/docs/API_KEYS.md +570 -0
- package/docs/CLAUDE_CODE_SETUP.md +181 -0
- package/docs/CLAUDE_DESKTOP_MANUAL.md +127 -0
- package/docs/CONFIGURATION.md +745 -0
- package/docs/FOCUS_MODES.md +240 -0
- package/docs/INSTALLATION_BOTH.md +145 -0
- package/docs/TERMS.md +352 -0
- package/docs/TOOLS_REFERENCE.md +1622 -0
- package/docs/TOOL_PARAMETERS.md +496 -0
- package/docs/TOOL_PROFILES.md +236 -0
- package/docs/WORKFLOWS.md +987 -0
- package/docs/WORKFLOW_OUTPUT.md +198 -0
- package/docs/WORKFLOW_PROGRESS_TRACKING.md +305 -0
- package/docs/workflows/design-brainstorm.md +335 -0
- package/package.json +97 -0
- package/profiles/balanced.json +37 -0
- package/profiles/code_focus.json +37 -0
- package/profiles/debug_intensive.json +34 -0
- package/profiles/full.json +37 -0
- package/profiles/minimal.json +37 -0
- package/profiles/research_power.json +37 -0
- package/profiles/workflow_builder.json +37 -0
- package/smithery.yaml +66 -0
- package/start.sh +8 -0
- package/tools.config.json +81 -0
- package/tsconfig.json +18 -0
- package/workflows/accessibility-code-audit.yaml +92 -0
- package/workflows/code-architecture-review.yaml +202 -0
- package/workflows/code-review.yaml +142 -0
- package/workflows/core/iterative-problem-solver.yaml +283 -0
- package/workflows/creative-brainstorm-yaml.yaml +215 -0
- package/workflows/pingpong.yaml +141 -0
- package/workflows/system/README.md +412 -0
- package/workflows/system/challenger.yaml +175 -0
- package/workflows/system/scout.yaml +164 -0
- package/workflows/system/verifier.yaml +133 -0
- package/workflows/ultra-creative-brainstorm.yaml +318 -0
- package/workflows/ux-research-flow.yaml +92 -0
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { CircuitBreakerManager } from './circuit-breaker.js';
|
|
3
|
+
import { MessageQueueOrchestrator } from './message-queue.js';
|
|
4
|
+
import { healthMonitor, alertManager } from './fallback-strategies.js';
|
|
5
|
+
/**
|
|
6
|
+
* Self-healing subagent instance
|
|
7
|
+
*/
|
|
8
|
+
export class SelfHealingSubagent extends EventEmitter {
|
|
9
|
+
constructor(config) {
|
|
10
|
+
super();
|
|
11
|
+
this.config = config;
|
|
12
|
+
this.performanceMetrics = [];
|
|
13
|
+
this.isRestarting = false;
|
|
14
|
+
this.health = {
|
|
15
|
+
id: config.id,
|
|
16
|
+
status: 'healthy',
|
|
17
|
+
lastHeartbeat: Date.now(),
|
|
18
|
+
failureCount: 0,
|
|
19
|
+
restartCount: 0,
|
|
20
|
+
memoryUsage: 0,
|
|
21
|
+
cpuUsage: 0,
|
|
22
|
+
tasksProcessed: 0,
|
|
23
|
+
avgResponseTime: 0
|
|
24
|
+
};
|
|
25
|
+
this.startHealthMonitoring();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Start health monitoring
|
|
29
|
+
*/
|
|
30
|
+
startHealthMonitoring() {
|
|
31
|
+
this.healthCheckInterval = setInterval(async () => {
|
|
32
|
+
try {
|
|
33
|
+
await this.performHealthCheck();
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
await this.handleHealthCheckFailure(error);
|
|
37
|
+
}
|
|
38
|
+
}, 10000); // Check every 10 seconds
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Perform health check
|
|
42
|
+
*/
|
|
43
|
+
async performHealthCheck() {
|
|
44
|
+
const now = Date.now();
|
|
45
|
+
// Check heartbeat timeout (30 seconds)
|
|
46
|
+
if (now - this.health.lastHeartbeat > 30000) {
|
|
47
|
+
throw new Error('Heartbeat timeout');
|
|
48
|
+
}
|
|
49
|
+
// Check memory usage
|
|
50
|
+
if (this.health.memoryUsage > this.config.memoryLimit * 0.9) {
|
|
51
|
+
this.health.status = 'degraded';
|
|
52
|
+
this.emit('memory-pressure', {
|
|
53
|
+
id: this.config.id,
|
|
54
|
+
usage: this.health.memoryUsage
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// Check CPU usage
|
|
58
|
+
if (this.health.cpuUsage > this.config.cpuLimit * 0.9) {
|
|
59
|
+
this.health.status = 'degraded';
|
|
60
|
+
this.emit('cpu-pressure', {
|
|
61
|
+
id: this.config.id,
|
|
62
|
+
usage: this.health.cpuUsage
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
// Check response time degradation
|
|
66
|
+
if (this.health.avgResponseTime > this.config.timeout * 0.8) {
|
|
67
|
+
this.health.status = 'degraded';
|
|
68
|
+
this.emit('slow-response', {
|
|
69
|
+
id: this.config.id,
|
|
70
|
+
avgTime: this.health.avgResponseTime
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
// Recover if metrics are good
|
|
74
|
+
if (this.health.status === 'degraded' &&
|
|
75
|
+
this.health.memoryUsage < this.config.memoryLimit * 0.7 &&
|
|
76
|
+
this.health.cpuUsage < this.config.cpuLimit * 0.7 &&
|
|
77
|
+
this.health.avgResponseTime < this.config.timeout * 0.5) {
|
|
78
|
+
this.health.status = 'healthy';
|
|
79
|
+
this.emit('recovered', { id: this.config.id });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Handle health check failure
|
|
84
|
+
*/
|
|
85
|
+
async handleHealthCheckFailure(error) {
|
|
86
|
+
this.health.failureCount++;
|
|
87
|
+
if (this.health.failureCount >= 3) {
|
|
88
|
+
this.health.status = 'failed';
|
|
89
|
+
await this.selfHeal();
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
this.health.status = 'degraded';
|
|
93
|
+
this.emit('health-degraded', {
|
|
94
|
+
id: this.config.id,
|
|
95
|
+
error: error.message
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Self-heal by restarting
|
|
101
|
+
*/
|
|
102
|
+
async selfHeal() {
|
|
103
|
+
if (this.isRestarting) {
|
|
104
|
+
return; // Already restarting
|
|
105
|
+
}
|
|
106
|
+
if (this.health.restartCount >= this.config.maxRetries) {
|
|
107
|
+
// Escalate - too many restarts
|
|
108
|
+
this.health.status = 'failed';
|
|
109
|
+
this.emit('escalate-failure', {
|
|
110
|
+
id: this.config.id,
|
|
111
|
+
restarts: this.health.restartCount
|
|
112
|
+
});
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
this.isRestarting = true;
|
|
116
|
+
this.health.status = 'recovering';
|
|
117
|
+
this.emit('self-healing', { id: this.config.id });
|
|
118
|
+
try {
|
|
119
|
+
// Restart the subagent
|
|
120
|
+
await this.restart();
|
|
121
|
+
// Reset health metrics
|
|
122
|
+
this.health.failureCount = 0;
|
|
123
|
+
this.health.status = 'healthy';
|
|
124
|
+
this.health.restartCount++;
|
|
125
|
+
this.health.lastHeartbeat = Date.now();
|
|
126
|
+
this.emit('self-healed', {
|
|
127
|
+
id: this.config.id,
|
|
128
|
+
restartCount: this.health.restartCount
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
this.health.status = 'failed';
|
|
133
|
+
this.emit('self-heal-failed', {
|
|
134
|
+
id: this.config.id,
|
|
135
|
+
error: error.message
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
finally {
|
|
139
|
+
this.isRestarting = false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Restart the subagent
|
|
144
|
+
*/
|
|
145
|
+
async restart() {
|
|
146
|
+
// Stop current instance
|
|
147
|
+
this.stop();
|
|
148
|
+
// Wait a moment
|
|
149
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
150
|
+
// Start new instance
|
|
151
|
+
await this.start();
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Start the subagent
|
|
155
|
+
*/
|
|
156
|
+
async start() {
|
|
157
|
+
// Implementation depends on runtime (serverless, container, etc.)
|
|
158
|
+
// This is a placeholder for the actual start logic
|
|
159
|
+
this.emit('started', { id: this.config.id });
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Stop the subagent
|
|
163
|
+
*/
|
|
164
|
+
stop() {
|
|
165
|
+
if (this.healthCheckInterval) {
|
|
166
|
+
clearInterval(this.healthCheckInterval);
|
|
167
|
+
}
|
|
168
|
+
this.emit('stopped', { id: this.config.id });
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Update heartbeat
|
|
172
|
+
*/
|
|
173
|
+
updateHeartbeat() {
|
|
174
|
+
this.health.lastHeartbeat = Date.now();
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Update metrics
|
|
178
|
+
*/
|
|
179
|
+
updateMetrics(metrics) {
|
|
180
|
+
Object.assign(this.health, metrics);
|
|
181
|
+
// Update performance history
|
|
182
|
+
if (metrics.avgResponseTime !== undefined) {
|
|
183
|
+
this.performanceMetrics.push(metrics.avgResponseTime);
|
|
184
|
+
if (this.performanceMetrics.length > 100) {
|
|
185
|
+
this.performanceMetrics.shift();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Get health status
|
|
191
|
+
*/
|
|
192
|
+
getHealth() {
|
|
193
|
+
return { ...this.health };
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Predict failure probability
|
|
197
|
+
*/
|
|
198
|
+
predictFailure() {
|
|
199
|
+
if (this.performanceMetrics.length < 10) {
|
|
200
|
+
return 0; // Not enough data
|
|
201
|
+
}
|
|
202
|
+
// Simple trend analysis
|
|
203
|
+
const recent = this.performanceMetrics.slice(-10);
|
|
204
|
+
const older = this.performanceMetrics.slice(-20, -10);
|
|
205
|
+
if (older.length === 0)
|
|
206
|
+
return 0;
|
|
207
|
+
const recentAvg = recent.reduce((a, b) => a + b, 0) / recent.length;
|
|
208
|
+
const olderAvg = older.reduce((a, b) => a + b, 0) / older.length;
|
|
209
|
+
// Calculate degradation rate
|
|
210
|
+
const degradation = (recentAvg - olderAvg) / olderAvg;
|
|
211
|
+
// Combine with current health metrics
|
|
212
|
+
let probability = 0;
|
|
213
|
+
if (degradation > 0.5)
|
|
214
|
+
probability += 0.3;
|
|
215
|
+
if (this.health.failureCount > 0)
|
|
216
|
+
probability += 0.2;
|
|
217
|
+
if (this.health.status === 'degraded')
|
|
218
|
+
probability += 0.3;
|
|
219
|
+
if (this.health.memoryUsage > this.config.memoryLimit * 0.8)
|
|
220
|
+
probability += 0.1;
|
|
221
|
+
if (this.health.cpuUsage > this.config.cpuLimit * 0.8)
|
|
222
|
+
probability += 0.1;
|
|
223
|
+
return Math.min(probability, 1.0);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Cleanup
|
|
227
|
+
*/
|
|
228
|
+
cleanup() {
|
|
229
|
+
this.stop();
|
|
230
|
+
this.removeAllListeners();
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Manager for multiple self-healing subagents
|
|
235
|
+
*/
|
|
236
|
+
export class SelfHealingManager extends EventEmitter {
|
|
237
|
+
constructor() {
|
|
238
|
+
super();
|
|
239
|
+
this.subagents = new Map();
|
|
240
|
+
this.taskRoutes = new Map();
|
|
241
|
+
this.circuitBreakers = new CircuitBreakerManager();
|
|
242
|
+
this.messageQueue = new MessageQueueOrchestrator();
|
|
243
|
+
this.startPredictiveMonitoring();
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Register a new subagent
|
|
247
|
+
*/
|
|
248
|
+
registerSubagent(config) {
|
|
249
|
+
const subagent = new SelfHealingSubagent(config);
|
|
250
|
+
// Set up event listeners
|
|
251
|
+
subagent.on('self-healing', (data) => this.handleSelfHealing(data));
|
|
252
|
+
subagent.on('escalate-failure', (data) => this.handleEscalation(data));
|
|
253
|
+
subagent.on('health-degraded', (data) => this.handleDegradation(data));
|
|
254
|
+
this.subagents.set(config.id, subagent);
|
|
255
|
+
// Register with health monitor
|
|
256
|
+
healthMonitor.startMonitoring(config.id, async () => {
|
|
257
|
+
const health = subagent.getHealth();
|
|
258
|
+
return health.status === 'healthy';
|
|
259
|
+
});
|
|
260
|
+
this.emit('subagent-registered', { id: config.id });
|
|
261
|
+
return subagent;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Handle self-healing event
|
|
265
|
+
*/
|
|
266
|
+
handleSelfHealing(data) {
|
|
267
|
+
// Reroute pending tasks
|
|
268
|
+
this.rerouteTasks(data.id);
|
|
269
|
+
// Notify other systems
|
|
270
|
+
this.emit('subagent-healing', data);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Handle escalation
|
|
274
|
+
*/
|
|
275
|
+
handleEscalation(data) {
|
|
276
|
+
// Try to spawn replacement
|
|
277
|
+
this.spawnReplacement(data.id);
|
|
278
|
+
// Alert administrators
|
|
279
|
+
alertManager.checkAlerts({
|
|
280
|
+
subagentFailed: data.id,
|
|
281
|
+
restarts: data.restarts
|
|
282
|
+
});
|
|
283
|
+
this.emit('subagent-escalated', data);
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Handle degradation
|
|
287
|
+
*/
|
|
288
|
+
handleDegradation(data) {
|
|
289
|
+
// Reduce load on degraded subagent
|
|
290
|
+
this.reduceLoad(data.id);
|
|
291
|
+
// Monitor for recovery
|
|
292
|
+
this.emit('subagent-degraded', data);
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Reroute tasks from failed subagent
|
|
296
|
+
*/
|
|
297
|
+
rerouteTasks(failedAgentId) {
|
|
298
|
+
const healthyAgents = this.getHealthySubagents();
|
|
299
|
+
if (healthyAgents.length === 0) {
|
|
300
|
+
this.emit('no-healthy-agents', { failedAgent: failedAgentId });
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
// Find tasks assigned to failed agent
|
|
304
|
+
for (const [taskId, route] of this.taskRoutes.entries()) {
|
|
305
|
+
if (route.currentAgent === failedAgentId) {
|
|
306
|
+
// Select new agent (round-robin for simplicity)
|
|
307
|
+
const newAgent = healthyAgents[route.rerouteCount % healthyAgents.length];
|
|
308
|
+
route.currentAgent = newAgent.config.id;
|
|
309
|
+
route.rerouteCount++;
|
|
310
|
+
route.timestamp = Date.now();
|
|
311
|
+
// Send reroute message
|
|
312
|
+
this.messageQueue.delegateToSubagent({
|
|
313
|
+
id: taskId,
|
|
314
|
+
type: 'reroute',
|
|
315
|
+
config: {
|
|
316
|
+
from: failedAgentId,
|
|
317
|
+
to: newAgent.config.id
|
|
318
|
+
},
|
|
319
|
+
payload: {}
|
|
320
|
+
});
|
|
321
|
+
this.emit('task-rerouted', {
|
|
322
|
+
taskId,
|
|
323
|
+
from: failedAgentId,
|
|
324
|
+
to: newAgent.config.id
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Spawn replacement subagent
|
|
331
|
+
*/
|
|
332
|
+
async spawnReplacement(failedAgentId) {
|
|
333
|
+
const failed = this.subagents.get(failedAgentId);
|
|
334
|
+
if (!failed)
|
|
335
|
+
return;
|
|
336
|
+
const config = failed.config;
|
|
337
|
+
const newId = `${config.type}-replacement-${Date.now()}`;
|
|
338
|
+
try {
|
|
339
|
+
// Spawn new subagent
|
|
340
|
+
await this.messageQueue.spawnEphemeralSubagent(config.type, {
|
|
341
|
+
...config.config,
|
|
342
|
+
id: newId
|
|
343
|
+
});
|
|
344
|
+
// Register new subagent
|
|
345
|
+
this.registerSubagent({
|
|
346
|
+
...config,
|
|
347
|
+
id: newId
|
|
348
|
+
});
|
|
349
|
+
// Remove failed subagent
|
|
350
|
+
this.removeSubagent(failedAgentId);
|
|
351
|
+
this.emit('replacement-spawned', {
|
|
352
|
+
failed: failedAgentId,
|
|
353
|
+
replacement: newId
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
catch (error) {
|
|
357
|
+
this.emit('replacement-failed', {
|
|
358
|
+
failed: failedAgentId,
|
|
359
|
+
error: error.message
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Reduce load on degraded subagent
|
|
365
|
+
*/
|
|
366
|
+
reduceLoad(agentId) {
|
|
367
|
+
// Implement load reduction strategy
|
|
368
|
+
// For example, reduce batch size or increase processing interval
|
|
369
|
+
const subagent = this.subagents.get(agentId);
|
|
370
|
+
if (subagent) {
|
|
371
|
+
// Update circuit breaker to be more conservative
|
|
372
|
+
const breaker = this.circuitBreakers.getOrCreateCircuitBreaker(agentId, {
|
|
373
|
+
failureThreshold: 2, // More sensitive
|
|
374
|
+
recoveryTimeout: 60000 // Longer recovery
|
|
375
|
+
});
|
|
376
|
+
this.emit('load-reduced', { agentId });
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Get healthy subagents
|
|
381
|
+
*/
|
|
382
|
+
getHealthySubagents() {
|
|
383
|
+
const healthy = [];
|
|
384
|
+
for (const subagent of this.subagents.values()) {
|
|
385
|
+
const health = subagent.getHealth();
|
|
386
|
+
if (health.status === 'healthy') {
|
|
387
|
+
healthy.push(subagent);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
return healthy;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Start predictive monitoring
|
|
394
|
+
*/
|
|
395
|
+
startPredictiveMonitoring() {
|
|
396
|
+
this.predictionInterval = setInterval(() => {
|
|
397
|
+
this.predictFailures();
|
|
398
|
+
}, 30000); // Check every 30 seconds
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Predict and prevent failures
|
|
402
|
+
*/
|
|
403
|
+
predictFailures() {
|
|
404
|
+
for (const [id, subagent] of this.subagents.entries()) {
|
|
405
|
+
const failureProbability = subagent.predictFailure();
|
|
406
|
+
if (failureProbability > 0.7) {
|
|
407
|
+
// High risk - take preventive action
|
|
408
|
+
this.emit('high-failure-risk', {
|
|
409
|
+
agentId: id,
|
|
410
|
+
probability: failureProbability
|
|
411
|
+
});
|
|
412
|
+
// Preventive actions
|
|
413
|
+
this.takePreventiveAction(id, failureProbability);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Take preventive action for high-risk subagent
|
|
419
|
+
*/
|
|
420
|
+
takePreventiveAction(agentId, probability) {
|
|
421
|
+
if (probability > 0.9) {
|
|
422
|
+
// Very high risk - spawn backup immediately
|
|
423
|
+
this.spawnReplacement(agentId);
|
|
424
|
+
}
|
|
425
|
+
else if (probability > 0.8) {
|
|
426
|
+
// High risk - reduce load and prepare backup
|
|
427
|
+
this.reduceLoad(agentId);
|
|
428
|
+
this.prepareBackup(agentId);
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
// Moderate risk - just reduce load
|
|
432
|
+
this.reduceLoad(agentId);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Prepare backup subagent
|
|
437
|
+
*/
|
|
438
|
+
prepareBackup(agentId) {
|
|
439
|
+
const subagent = this.subagents.get(agentId);
|
|
440
|
+
if (!subagent)
|
|
441
|
+
return;
|
|
442
|
+
// Pre-warm a backup instance
|
|
443
|
+
const config = subagent.config;
|
|
444
|
+
const backupId = `${config.type}-backup-${Date.now()}`;
|
|
445
|
+
this.emit('backup-preparing', {
|
|
446
|
+
original: agentId,
|
|
447
|
+
backup: backupId
|
|
448
|
+
});
|
|
449
|
+
// Register but don't activate yet
|
|
450
|
+
// Will be activated if original fails
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Remove subagent
|
|
454
|
+
*/
|
|
455
|
+
removeSubagent(agentId) {
|
|
456
|
+
const subagent = this.subagents.get(agentId);
|
|
457
|
+
if (subagent) {
|
|
458
|
+
subagent.cleanup();
|
|
459
|
+
this.subagents.delete(agentId);
|
|
460
|
+
healthMonitor.stopMonitoring(agentId);
|
|
461
|
+
this.emit('subagent-removed', { id: agentId });
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Get system health report
|
|
466
|
+
*/
|
|
467
|
+
getHealthReport() {
|
|
468
|
+
let healthy = 0;
|
|
469
|
+
let degraded = 0;
|
|
470
|
+
let failed = 0;
|
|
471
|
+
let recovering = 0;
|
|
472
|
+
const predictions = [];
|
|
473
|
+
for (const [id, subagent] of this.subagents.entries()) {
|
|
474
|
+
const health = subagent.getHealth();
|
|
475
|
+
switch (health.status) {
|
|
476
|
+
case 'healthy':
|
|
477
|
+
healthy++;
|
|
478
|
+
break;
|
|
479
|
+
case 'degraded':
|
|
480
|
+
degraded++;
|
|
481
|
+
break;
|
|
482
|
+
case 'failed':
|
|
483
|
+
failed++;
|
|
484
|
+
break;
|
|
485
|
+
case 'recovering':
|
|
486
|
+
recovering++;
|
|
487
|
+
break;
|
|
488
|
+
}
|
|
489
|
+
predictions.push({
|
|
490
|
+
agentId: id,
|
|
491
|
+
failureProbability: subagent.predictFailure()
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
const total = this.subagents.size;
|
|
495
|
+
const healthScore = total === 0 ? 1 : healthy / total;
|
|
496
|
+
return {
|
|
497
|
+
total,
|
|
498
|
+
healthy,
|
|
499
|
+
degraded,
|
|
500
|
+
failed,
|
|
501
|
+
recovering,
|
|
502
|
+
healthScore,
|
|
503
|
+
predictions: predictions.sort((a, b) => b.failureProbability - a.failureProbability)
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Cleanup
|
|
508
|
+
*/
|
|
509
|
+
cleanup() {
|
|
510
|
+
if (this.predictionInterval) {
|
|
511
|
+
clearInterval(this.predictionInterval);
|
|
512
|
+
}
|
|
513
|
+
for (const subagent of this.subagents.values()) {
|
|
514
|
+
subagent.cleanup();
|
|
515
|
+
}
|
|
516
|
+
this.subagents.clear();
|
|
517
|
+
this.taskRoutes.clear();
|
|
518
|
+
this.circuitBreakers.cleanup();
|
|
519
|
+
this.messageQueue.cleanup();
|
|
520
|
+
this.removeAllListeners();
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
// Export singleton instance
|
|
524
|
+
export const selfHealingManager = new SelfHealingManager();
|