genesis-ai-cli 7.4.5
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 +78 -0
- package/README.md +282 -0
- package/dist/src/active-inference/actions.d.ts +75 -0
- package/dist/src/active-inference/actions.js +250 -0
- package/dist/src/active-inference/autonomous-loop.d.ts +103 -0
- package/dist/src/active-inference/autonomous-loop.js +289 -0
- package/dist/src/active-inference/core.d.ts +85 -0
- package/dist/src/active-inference/core.js +555 -0
- package/dist/src/active-inference/demo-autonomous-loop.d.ts +8 -0
- package/dist/src/active-inference/demo-autonomous-loop.js +338 -0
- package/dist/src/active-inference/demo-value-integration.d.ts +8 -0
- package/dist/src/active-inference/demo-value-integration.js +174 -0
- package/dist/src/active-inference/index.d.ts +32 -0
- package/dist/src/active-inference/index.js +88 -0
- package/dist/src/active-inference/integration.d.ts +114 -0
- package/dist/src/active-inference/integration.js +698 -0
- package/dist/src/active-inference/memory-integration.d.ts +51 -0
- package/dist/src/active-inference/memory-integration.js +232 -0
- package/dist/src/active-inference/observations.d.ts +67 -0
- package/dist/src/active-inference/observations.js +147 -0
- package/dist/src/active-inference/test-active-inference.d.ts +8 -0
- package/dist/src/active-inference/test-active-inference.js +320 -0
- package/dist/src/active-inference/test-value-integration.d.ts +6 -0
- package/dist/src/active-inference/test-value-integration.js +168 -0
- package/dist/src/active-inference/types.d.ts +150 -0
- package/dist/src/active-inference/types.js +59 -0
- package/dist/src/active-inference/value-integration.d.ts +164 -0
- package/dist/src/active-inference/value-integration.js +459 -0
- package/dist/src/agents/base-agent.d.ts +53 -0
- package/dist/src/agents/base-agent.js +178 -0
- package/dist/src/agents/builder.d.ts +67 -0
- package/dist/src/agents/builder.js +537 -0
- package/dist/src/agents/critic.d.ts +35 -0
- package/dist/src/agents/critic.js +322 -0
- package/dist/src/agents/ethicist.d.ts +54 -0
- package/dist/src/agents/ethicist.js +393 -0
- package/dist/src/agents/explorer.d.ts +26 -0
- package/dist/src/agents/explorer.js +216 -0
- package/dist/src/agents/feeling.d.ts +41 -0
- package/dist/src/agents/feeling.js +320 -0
- package/dist/src/agents/index.d.ts +111 -0
- package/dist/src/agents/index.js +222 -0
- package/dist/src/agents/memory.d.ts +69 -0
- package/dist/src/agents/memory.js +404 -0
- package/dist/src/agents/message-bus.d.ts +88 -0
- package/dist/src/agents/message-bus.js +267 -0
- package/dist/src/agents/narrator.d.ts +90 -0
- package/dist/src/agents/narrator.js +473 -0
- package/dist/src/agents/planner.d.ts +38 -0
- package/dist/src/agents/planner.js +341 -0
- package/dist/src/agents/predictor.d.ts +73 -0
- package/dist/src/agents/predictor.js +506 -0
- package/dist/src/agents/sensor.d.ts +88 -0
- package/dist/src/agents/sensor.js +377 -0
- package/dist/src/agents/test-agents.d.ts +6 -0
- package/dist/src/agents/test-agents.js +73 -0
- package/dist/src/agents/types.d.ts +194 -0
- package/dist/src/agents/types.js +7 -0
- package/dist/src/brain/index.d.ts +185 -0
- package/dist/src/brain/index.js +843 -0
- package/dist/src/brain/trace.d.ts +91 -0
- package/dist/src/brain/trace.js +327 -0
- package/dist/src/brain/types.d.ts +165 -0
- package/dist/src/brain/types.js +51 -0
- package/dist/src/cli/chat.d.ts +237 -0
- package/dist/src/cli/chat.js +1959 -0
- package/dist/src/cli/dispatcher.d.ts +182 -0
- package/dist/src/cli/dispatcher.js +718 -0
- package/dist/src/cli/human-loop.d.ts +170 -0
- package/dist/src/cli/human-loop.js +543 -0
- package/dist/src/cli/index.d.ts +12 -0
- package/dist/src/cli/index.js +28 -0
- package/dist/src/cli/interactive.d.ts +141 -0
- package/dist/src/cli/interactive.js +757 -0
- package/dist/src/cli/ui.d.ts +205 -0
- package/dist/src/cli/ui.js +632 -0
- package/dist/src/consciousness/attention-schema.d.ts +154 -0
- package/dist/src/consciousness/attention-schema.js +432 -0
- package/dist/src/consciousness/global-workspace.d.ts +149 -0
- package/dist/src/consciousness/global-workspace.js +422 -0
- package/dist/src/consciousness/index.d.ts +186 -0
- package/dist/src/consciousness/index.js +476 -0
- package/dist/src/consciousness/phi-calculator.d.ts +119 -0
- package/dist/src/consciousness/phi-calculator.js +445 -0
- package/dist/src/consciousness/phi-decisions.d.ts +169 -0
- package/dist/src/consciousness/phi-decisions.js +383 -0
- package/dist/src/consciousness/phi-monitor.d.ts +153 -0
- package/dist/src/consciousness/phi-monitor.js +465 -0
- package/dist/src/consciousness/types.d.ts +260 -0
- package/dist/src/consciousness/types.js +44 -0
- package/dist/src/daemon/dream-mode.d.ts +115 -0
- package/dist/src/daemon/dream-mode.js +470 -0
- package/dist/src/daemon/index.d.ts +162 -0
- package/dist/src/daemon/index.js +542 -0
- package/dist/src/daemon/maintenance.d.ts +139 -0
- package/dist/src/daemon/maintenance.js +549 -0
- package/dist/src/daemon/process.d.ts +82 -0
- package/dist/src/daemon/process.js +442 -0
- package/dist/src/daemon/scheduler.d.ts +90 -0
- package/dist/src/daemon/scheduler.js +494 -0
- package/dist/src/daemon/types.d.ts +213 -0
- package/dist/src/daemon/types.js +50 -0
- package/dist/src/epistemic/index.d.ts +74 -0
- package/dist/src/epistemic/index.js +225 -0
- package/dist/src/grounding/epistemic-stack.d.ts +100 -0
- package/dist/src/grounding/epistemic-stack.js +408 -0
- package/dist/src/grounding/feedback.d.ts +98 -0
- package/dist/src/grounding/feedback.js +276 -0
- package/dist/src/grounding/index.d.ts +123 -0
- package/dist/src/grounding/index.js +224 -0
- package/dist/src/grounding/verifier.d.ts +149 -0
- package/dist/src/grounding/verifier.js +484 -0
- package/dist/src/healing/detector.d.ts +110 -0
- package/dist/src/healing/detector.js +436 -0
- package/dist/src/healing/fixer.d.ts +138 -0
- package/dist/src/healing/fixer.js +572 -0
- package/dist/src/healing/index.d.ts +23 -0
- package/dist/src/healing/index.js +43 -0
- package/dist/src/hooks/index.d.ts +135 -0
- package/dist/src/hooks/index.js +317 -0
- package/dist/src/index.d.ts +23 -0
- package/dist/src/index.js +1266 -0
- package/dist/src/kernel/index.d.ts +155 -0
- package/dist/src/kernel/index.js +795 -0
- package/dist/src/kernel/invariants.d.ts +153 -0
- package/dist/src/kernel/invariants.js +355 -0
- package/dist/src/kernel/test-kernel.d.ts +6 -0
- package/dist/src/kernel/test-kernel.js +108 -0
- package/dist/src/kernel/test-real-mcp.d.ts +10 -0
- package/dist/src/kernel/test-real-mcp.js +295 -0
- package/dist/src/llm/index.d.ts +146 -0
- package/dist/src/llm/index.js +428 -0
- package/dist/src/llm/router.d.ts +136 -0
- package/dist/src/llm/router.js +510 -0
- package/dist/src/mcp/index.d.ts +85 -0
- package/dist/src/mcp/index.js +657 -0
- package/dist/src/mcp/resilient.d.ts +139 -0
- package/dist/src/mcp/resilient.js +417 -0
- package/dist/src/memory/cache.d.ts +118 -0
- package/dist/src/memory/cache.js +356 -0
- package/dist/src/memory/cognitive-workspace.d.ts +231 -0
- package/dist/src/memory/cognitive-workspace.js +521 -0
- package/dist/src/memory/consolidation.d.ts +99 -0
- package/dist/src/memory/consolidation.js +443 -0
- package/dist/src/memory/episodic.d.ts +114 -0
- package/dist/src/memory/episodic.js +394 -0
- package/dist/src/memory/forgetting.d.ts +134 -0
- package/dist/src/memory/forgetting.js +324 -0
- package/dist/src/memory/index.d.ts +211 -0
- package/dist/src/memory/index.js +367 -0
- package/dist/src/memory/indexer.d.ts +123 -0
- package/dist/src/memory/indexer.js +479 -0
- package/dist/src/memory/procedural.d.ts +136 -0
- package/dist/src/memory/procedural.js +479 -0
- package/dist/src/memory/semantic.d.ts +132 -0
- package/dist/src/memory/semantic.js +497 -0
- package/dist/src/memory/types.d.ts +193 -0
- package/dist/src/memory/types.js +15 -0
- package/dist/src/orchestrator.d.ts +65 -0
- package/dist/src/orchestrator.js +317 -0
- package/dist/src/persistence/index.d.ts +257 -0
- package/dist/src/persistence/index.js +763 -0
- package/dist/src/pipeline/executor.d.ts +51 -0
- package/dist/src/pipeline/executor.js +695 -0
- package/dist/src/pipeline/index.d.ts +7 -0
- package/dist/src/pipeline/index.js +11 -0
- package/dist/src/self-production.d.ts +67 -0
- package/dist/src/self-production.js +205 -0
- package/dist/src/subagents/executor.d.ts +58 -0
- package/dist/src/subagents/executor.js +283 -0
- package/dist/src/subagents/index.d.ts +37 -0
- package/dist/src/subagents/index.js +53 -0
- package/dist/src/subagents/registry.d.ts +23 -0
- package/dist/src/subagents/registry.js +167 -0
- package/dist/src/subagents/types.d.ts +79 -0
- package/dist/src/subagents/types.js +14 -0
- package/dist/src/tools/bash.d.ts +139 -0
- package/dist/src/tools/bash.js +583 -0
- package/dist/src/tools/edit.d.ts +125 -0
- package/dist/src/tools/edit.js +424 -0
- package/dist/src/tools/git.d.ts +179 -0
- package/dist/src/tools/git.js +504 -0
- package/dist/src/tools/index.d.ts +21 -0
- package/dist/src/tools/index.js +163 -0
- package/dist/src/types.d.ts +145 -0
- package/dist/src/types.js +7 -0
- package/dist/src/world-model/decoder.d.ts +163 -0
- package/dist/src/world-model/decoder.js +517 -0
- package/dist/src/world-model/digital-twin.d.ts +219 -0
- package/dist/src/world-model/digital-twin.js +695 -0
- package/dist/src/world-model/encoder.d.ts +141 -0
- package/dist/src/world-model/encoder.js +564 -0
- package/dist/src/world-model/index.d.ts +221 -0
- package/dist/src/world-model/index.js +772 -0
- package/dist/src/world-model/predictor.d.ts +161 -0
- package/dist/src/world-model/predictor.js +681 -0
- package/dist/src/world-model/test-value-jepa.d.ts +8 -0
- package/dist/src/world-model/test-value-jepa.js +430 -0
- package/dist/src/world-model/types.d.ts +341 -0
- package/dist/src/world-model/types.js +69 -0
- package/dist/src/world-model/value-jepa.d.ts +247 -0
- package/dist/src/world-model/value-jepa.js +622 -0
- package/dist/test/brain.test.d.ts +11 -0
- package/dist/test/brain.test.js +358 -0
- package/dist/test/cli/dispatcher.test.d.ts +4 -0
- package/dist/test/cli/dispatcher.test.js +332 -0
- package/dist/test/cli/human-loop.test.d.ts +4 -0
- package/dist/test/cli/human-loop.test.js +270 -0
- package/dist/test/grounding/feedback.test.d.ts +4 -0
- package/dist/test/grounding/feedback.test.js +462 -0
- package/dist/test/grounding/verifier.test.d.ts +4 -0
- package/dist/test/grounding/verifier.test.js +442 -0
- package/dist/test/grounding.test.d.ts +6 -0
- package/dist/test/grounding.test.js +246 -0
- package/dist/test/healing/detector.test.d.ts +4 -0
- package/dist/test/healing/detector.test.js +266 -0
- package/dist/test/healing/fixer.test.d.ts +4 -0
- package/dist/test/healing/fixer.test.js +369 -0
- package/dist/test/integration.test.d.ts +5 -0
- package/dist/test/integration.test.js +290 -0
- package/dist/test/tools/bash.test.d.ts +4 -0
- package/dist/test/tools/bash.test.js +348 -0
- package/dist/test/tools/edit.test.d.ts +4 -0
- package/dist/test/tools/edit.test.js +350 -0
- package/dist/test/tools/git.test.d.ts +4 -0
- package/dist/test/tools/git.test.js +350 -0
- package/package.json +60 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Genesis 6.8 - Resilient MCP Wrapper
|
|
3
|
+
*
|
|
4
|
+
* Wraps MCP server calls with:
|
|
5
|
+
* - Timeout handling
|
|
6
|
+
* - Automatic retry with exponential backoff
|
|
7
|
+
* - Fallback to local cache when offline
|
|
8
|
+
* - Circuit breaker pattern
|
|
9
|
+
* - Health monitoring
|
|
10
|
+
*/
|
|
11
|
+
export type MCPServerName = 'arxiv' | 'semantic-scholar' | 'context7' | 'wolfram' | 'gemini' | 'brave-search' | 'exa' | 'firecrawl' | 'openai' | 'github' | 'stability-ai' | 'memory' | 'filesystem';
|
|
12
|
+
export interface MCPCallOptions {
|
|
13
|
+
/** Timeout in ms (default: 30000) */
|
|
14
|
+
timeout?: number;
|
|
15
|
+
/** Maximum retries (default: 2) */
|
|
16
|
+
maxRetries?: number;
|
|
17
|
+
/** Use cache if offline (default: true) */
|
|
18
|
+
useCacheFallback?: boolean;
|
|
19
|
+
/** Priority: 'high' skips queue, 'low' can be delayed */
|
|
20
|
+
priority?: 'high' | 'normal' | 'low';
|
|
21
|
+
}
|
|
22
|
+
export interface MCPCallResult<T = unknown> {
|
|
23
|
+
/** Whether call succeeded */
|
|
24
|
+
success: boolean;
|
|
25
|
+
/** Response data */
|
|
26
|
+
data?: T;
|
|
27
|
+
/** Error message if failed */
|
|
28
|
+
error?: string;
|
|
29
|
+
/** Whether result came from cache */
|
|
30
|
+
cached: boolean;
|
|
31
|
+
/** Latency in ms */
|
|
32
|
+
latency: number;
|
|
33
|
+
/** Server that handled the call */
|
|
34
|
+
server: MCPServerName;
|
|
35
|
+
/** Number of retries needed */
|
|
36
|
+
retries: number;
|
|
37
|
+
}
|
|
38
|
+
export interface ServerHealth {
|
|
39
|
+
/** Server name */
|
|
40
|
+
name: MCPServerName;
|
|
41
|
+
/** Is server currently available */
|
|
42
|
+
available: boolean;
|
|
43
|
+
/** Success rate (0-1) */
|
|
44
|
+
successRate: number;
|
|
45
|
+
/** Average latency in ms */
|
|
46
|
+
avgLatency: number;
|
|
47
|
+
/** Last successful call timestamp */
|
|
48
|
+
lastSuccess: number;
|
|
49
|
+
/** Last failure timestamp */
|
|
50
|
+
lastFailure: number;
|
|
51
|
+
/** Consecutive failures */
|
|
52
|
+
consecutiveFailures: number;
|
|
53
|
+
/** Is circuit breaker open (blocking calls) */
|
|
54
|
+
circuitOpen: boolean;
|
|
55
|
+
}
|
|
56
|
+
export interface ResilientConfig {
|
|
57
|
+
/** Default timeout in ms */
|
|
58
|
+
defaultTimeout: number;
|
|
59
|
+
/** Default max retries */
|
|
60
|
+
defaultMaxRetries: number;
|
|
61
|
+
/** Circuit breaker threshold (consecutive failures to open) */
|
|
62
|
+
circuitBreakerThreshold: number;
|
|
63
|
+
/** Circuit breaker reset time in ms */
|
|
64
|
+
circuitBreakerResetTime: number;
|
|
65
|
+
/** Enable logging */
|
|
66
|
+
logCalls: boolean;
|
|
67
|
+
}
|
|
68
|
+
export declare class ResilientMCP {
|
|
69
|
+
private config;
|
|
70
|
+
private health;
|
|
71
|
+
private callHistory;
|
|
72
|
+
constructor(config?: Partial<ResilientConfig>);
|
|
73
|
+
/**
|
|
74
|
+
* Initialize health tracking for all servers
|
|
75
|
+
*/
|
|
76
|
+
private initializeHealth;
|
|
77
|
+
/**
|
|
78
|
+
* Call an MCP server with resilience features
|
|
79
|
+
*/
|
|
80
|
+
call<T = unknown>(server: MCPServerName, tool: string, params: Record<string, unknown>, options?: MCPCallOptions): Promise<MCPCallResult<T>>;
|
|
81
|
+
/**
|
|
82
|
+
* Execute the actual MCP call
|
|
83
|
+
*/
|
|
84
|
+
private executeCall;
|
|
85
|
+
/**
|
|
86
|
+
* Simulate MCP call (placeholder for actual SDK integration)
|
|
87
|
+
*/
|
|
88
|
+
private simulateMCPCall;
|
|
89
|
+
/**
|
|
90
|
+
* Try fallback strategies when primary server fails
|
|
91
|
+
*/
|
|
92
|
+
private tryFallback;
|
|
93
|
+
/**
|
|
94
|
+
* Try to find result in local cache
|
|
95
|
+
*/
|
|
96
|
+
private tryCache;
|
|
97
|
+
/**
|
|
98
|
+
* Try to find result in project index
|
|
99
|
+
*/
|
|
100
|
+
private tryProjectIndex;
|
|
101
|
+
/**
|
|
102
|
+
* Find an alternative server in the same category
|
|
103
|
+
*/
|
|
104
|
+
private findAlternativeServer;
|
|
105
|
+
private recordSuccess;
|
|
106
|
+
private recordFailure;
|
|
107
|
+
private updateSuccessRate;
|
|
108
|
+
/**
|
|
109
|
+
* Get health status for all servers
|
|
110
|
+
*/
|
|
111
|
+
getHealth(): ServerHealth[];
|
|
112
|
+
/**
|
|
113
|
+
* Get health status for a specific server
|
|
114
|
+
*/
|
|
115
|
+
getServerHealth(server: MCPServerName): ServerHealth | undefined;
|
|
116
|
+
/**
|
|
117
|
+
* Reset circuit breaker for a server
|
|
118
|
+
*/
|
|
119
|
+
resetCircuitBreaker(server: MCPServerName): void;
|
|
120
|
+
/**
|
|
121
|
+
* Check if a server is available
|
|
122
|
+
*/
|
|
123
|
+
isAvailable(server: MCPServerName): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Get list of available servers
|
|
126
|
+
*/
|
|
127
|
+
getAvailableServers(): MCPServerName[];
|
|
128
|
+
private delay;
|
|
129
|
+
}
|
|
130
|
+
export declare function getResilientMCP(config?: Partial<ResilientConfig>): ResilientMCP;
|
|
131
|
+
export declare function resetResilientMCP(): void;
|
|
132
|
+
/**
|
|
133
|
+
* Call MCP server with automatic resilience
|
|
134
|
+
*/
|
|
135
|
+
export declare function mcpCall<T = unknown>(server: MCPServerName, tool: string, params: Record<string, unknown>, options?: MCPCallOptions): Promise<MCPCallResult<T>>;
|
|
136
|
+
/**
|
|
137
|
+
* Check if MCP servers are healthy
|
|
138
|
+
*/
|
|
139
|
+
export declare function mcpHealthCheck(): ServerHealth[];
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Genesis 6.8 - Resilient MCP Wrapper
|
|
4
|
+
*
|
|
5
|
+
* Wraps MCP server calls with:
|
|
6
|
+
* - Timeout handling
|
|
7
|
+
* - Automatic retry with exponential backoff
|
|
8
|
+
* - Fallback to local cache when offline
|
|
9
|
+
* - Circuit breaker pattern
|
|
10
|
+
* - Health monitoring
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.ResilientMCP = void 0;
|
|
14
|
+
exports.getResilientMCP = getResilientMCP;
|
|
15
|
+
exports.resetResilientMCP = resetResilientMCP;
|
|
16
|
+
exports.mcpCall = mcpCall;
|
|
17
|
+
exports.mcpHealthCheck = mcpHealthCheck;
|
|
18
|
+
const cache_js_1 = require("../memory/cache.js");
|
|
19
|
+
const indexer_js_1 = require("../memory/indexer.js");
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// Default Config
|
|
22
|
+
// ============================================================================
|
|
23
|
+
const DEFAULT_CONFIG = {
|
|
24
|
+
defaultTimeout: 30000,
|
|
25
|
+
defaultMaxRetries: 2,
|
|
26
|
+
circuitBreakerThreshold: 5,
|
|
27
|
+
circuitBreakerResetTime: 60000,
|
|
28
|
+
logCalls: false,
|
|
29
|
+
};
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Server Categories (for fallback logic)
|
|
32
|
+
// ============================================================================
|
|
33
|
+
const SERVER_CATEGORIES = {
|
|
34
|
+
search: ['brave-search', 'exa', 'gemini', 'firecrawl'],
|
|
35
|
+
papers: ['arxiv', 'semantic-scholar'],
|
|
36
|
+
docs: ['context7'],
|
|
37
|
+
math: ['wolfram'],
|
|
38
|
+
code: ['github', 'openai'],
|
|
39
|
+
images: ['stability-ai'],
|
|
40
|
+
storage: ['memory', 'filesystem'],
|
|
41
|
+
};
|
|
42
|
+
// ============================================================================
|
|
43
|
+
// Resilient MCP Wrapper
|
|
44
|
+
// ============================================================================
|
|
45
|
+
class ResilientMCP {
|
|
46
|
+
config;
|
|
47
|
+
health = new Map();
|
|
48
|
+
callHistory = [];
|
|
49
|
+
constructor(config) {
|
|
50
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
51
|
+
this.initializeHealth();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Initialize health tracking for all servers
|
|
55
|
+
*/
|
|
56
|
+
initializeHealth() {
|
|
57
|
+
const servers = [
|
|
58
|
+
'arxiv', 'semantic-scholar', 'context7', 'wolfram',
|
|
59
|
+
'gemini', 'brave-search', 'exa', 'firecrawl',
|
|
60
|
+
'openai', 'github', 'stability-ai',
|
|
61
|
+
'memory', 'filesystem',
|
|
62
|
+
];
|
|
63
|
+
for (const server of servers) {
|
|
64
|
+
this.health.set(server, {
|
|
65
|
+
name: server,
|
|
66
|
+
available: true,
|
|
67
|
+
successRate: 1,
|
|
68
|
+
avgLatency: 0,
|
|
69
|
+
lastSuccess: 0,
|
|
70
|
+
lastFailure: 0,
|
|
71
|
+
consecutiveFailures: 0,
|
|
72
|
+
circuitOpen: false,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// ==========================================================================
|
|
77
|
+
// Core Call Method
|
|
78
|
+
// ==========================================================================
|
|
79
|
+
/**
|
|
80
|
+
* Call an MCP server with resilience features
|
|
81
|
+
*/
|
|
82
|
+
async call(server, tool, params, options = {}) {
|
|
83
|
+
const { timeout = this.config.defaultTimeout, maxRetries = this.config.defaultMaxRetries, useCacheFallback = true, } = options;
|
|
84
|
+
const startTime = Date.now();
|
|
85
|
+
const health = this.health.get(server);
|
|
86
|
+
// Check circuit breaker
|
|
87
|
+
if (health.circuitOpen) {
|
|
88
|
+
const timeSinceLastFailure = Date.now() - health.lastFailure;
|
|
89
|
+
if (timeSinceLastFailure < this.config.circuitBreakerResetTime) {
|
|
90
|
+
// Circuit still open - try cache or alternative
|
|
91
|
+
if (useCacheFallback) {
|
|
92
|
+
return this.tryFallback(server, tool, params, startTime);
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
success: false,
|
|
96
|
+
error: `Circuit breaker open for ${server}`,
|
|
97
|
+
cached: false,
|
|
98
|
+
latency: Date.now() - startTime,
|
|
99
|
+
server,
|
|
100
|
+
retries: 0,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
// Reset circuit breaker (half-open state)
|
|
104
|
+
health.circuitOpen = false;
|
|
105
|
+
}
|
|
106
|
+
// Try the call with retries
|
|
107
|
+
let lastError = '';
|
|
108
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
109
|
+
try {
|
|
110
|
+
const result = await this.executeCall(server, tool, params, timeout);
|
|
111
|
+
this.recordSuccess(server, Date.now() - startTime);
|
|
112
|
+
return {
|
|
113
|
+
success: true,
|
|
114
|
+
data: result,
|
|
115
|
+
cached: false,
|
|
116
|
+
latency: Date.now() - startTime,
|
|
117
|
+
server,
|
|
118
|
+
retries: attempt,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
lastError = error instanceof Error ? error.message : String(error);
|
|
123
|
+
if (this.config.logCalls) {
|
|
124
|
+
console.log(`[MCP] ${server}.${tool} attempt ${attempt + 1} failed: ${lastError}`);
|
|
125
|
+
}
|
|
126
|
+
// Exponential backoff before retry
|
|
127
|
+
if (attempt < maxRetries) {
|
|
128
|
+
await this.delay(Math.pow(2, attempt) * 500);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// All retries failed
|
|
133
|
+
this.recordFailure(server);
|
|
134
|
+
// Try fallback
|
|
135
|
+
if (useCacheFallback) {
|
|
136
|
+
return this.tryFallback(server, tool, params, startTime, lastError);
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
success: false,
|
|
140
|
+
error: lastError,
|
|
141
|
+
cached: false,
|
|
142
|
+
latency: Date.now() - startTime,
|
|
143
|
+
server,
|
|
144
|
+
retries: maxRetries,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Execute the actual MCP call
|
|
149
|
+
*/
|
|
150
|
+
async executeCall(server, tool, params, timeout) {
|
|
151
|
+
// This is a placeholder - in real implementation, this would call the MCP SDK
|
|
152
|
+
// For now, we simulate the call structure
|
|
153
|
+
const controller = new AbortController();
|
|
154
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
155
|
+
try {
|
|
156
|
+
// Simulate MCP call based on server type
|
|
157
|
+
// In production, this would use @modelcontextprotocol/sdk
|
|
158
|
+
const result = await this.simulateMCPCall(server, tool, params, controller.signal);
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
clearTimeout(timeoutId);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Simulate MCP call (placeholder for actual SDK integration)
|
|
167
|
+
*/
|
|
168
|
+
async simulateMCPCall(server, tool, params, signal) {
|
|
169
|
+
// In production, this would be replaced with actual MCP SDK calls
|
|
170
|
+
// For now, throw to trigger fallback logic demonstration
|
|
171
|
+
if (server === 'filesystem' || server === 'memory') {
|
|
172
|
+
// Local servers always work
|
|
173
|
+
return { success: true, tool, params };
|
|
174
|
+
}
|
|
175
|
+
// Simulate network call
|
|
176
|
+
const response = await fetch(`http://localhost:3000/mcp/${server}/${tool}`, {
|
|
177
|
+
method: 'POST',
|
|
178
|
+
headers: { 'Content-Type': 'application/json' },
|
|
179
|
+
body: JSON.stringify(params),
|
|
180
|
+
signal,
|
|
181
|
+
}).catch(() => {
|
|
182
|
+
throw new Error(`${server} is offline or unreachable`);
|
|
183
|
+
});
|
|
184
|
+
if (!response.ok) {
|
|
185
|
+
throw new Error(`${server} returned ${response.status}`);
|
|
186
|
+
}
|
|
187
|
+
return response.json();
|
|
188
|
+
}
|
|
189
|
+
// ==========================================================================
|
|
190
|
+
// Fallback Logic
|
|
191
|
+
// ==========================================================================
|
|
192
|
+
/**
|
|
193
|
+
* Try fallback strategies when primary server fails
|
|
194
|
+
*/
|
|
195
|
+
async tryFallback(server, tool, params, startTime, originalError) {
|
|
196
|
+
// Strategy 1: Try local cache
|
|
197
|
+
const cacheResult = this.tryCache(server, tool, params);
|
|
198
|
+
if (cacheResult) {
|
|
199
|
+
return {
|
|
200
|
+
success: true,
|
|
201
|
+
data: cacheResult,
|
|
202
|
+
cached: true,
|
|
203
|
+
latency: Date.now() - startTime,
|
|
204
|
+
server,
|
|
205
|
+
retries: 0,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
// Strategy 2: Try project indexer for search operations
|
|
209
|
+
if (tool.includes('search') || tool.includes('find')) {
|
|
210
|
+
const indexResult = await this.tryProjectIndex(params);
|
|
211
|
+
if (indexResult) {
|
|
212
|
+
return {
|
|
213
|
+
success: true,
|
|
214
|
+
data: indexResult,
|
|
215
|
+
cached: true,
|
|
216
|
+
latency: Date.now() - startTime,
|
|
217
|
+
server,
|
|
218
|
+
retries: 0,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// Strategy 3: Try alternative server in same category
|
|
223
|
+
const alternative = this.findAlternativeServer(server);
|
|
224
|
+
if (alternative) {
|
|
225
|
+
if (this.config.logCalls) {
|
|
226
|
+
console.log(`[MCP] Trying alternative server: ${alternative}`);
|
|
227
|
+
}
|
|
228
|
+
// Recursive call with alternative (but no further fallback)
|
|
229
|
+
return this.call(alternative, tool, params, { useCacheFallback: false });
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
success: false,
|
|
233
|
+
error: originalError || `${server} unavailable, no fallback found`,
|
|
234
|
+
cached: false,
|
|
235
|
+
latency: Date.now() - startTime,
|
|
236
|
+
server,
|
|
237
|
+
retries: 0,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Try to find result in local cache
|
|
242
|
+
*/
|
|
243
|
+
tryCache(server, tool, params) {
|
|
244
|
+
// For now, only cache fix results
|
|
245
|
+
if (server === 'openai' && tool.includes('fix')) {
|
|
246
|
+
const cache = (0, cache_js_1.getFixCache)();
|
|
247
|
+
const errorMessage = params.error;
|
|
248
|
+
const filePath = params.file;
|
|
249
|
+
if (errorMessage && filePath) {
|
|
250
|
+
const cached = cache.lookup(errorMessage, filePath, '');
|
|
251
|
+
if (cached) {
|
|
252
|
+
return { fix: cached.fix, cached: true };
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Try to find result in project index
|
|
260
|
+
*/
|
|
261
|
+
async tryProjectIndex(params) {
|
|
262
|
+
const query = params.query || params.search || params.q;
|
|
263
|
+
if (!query)
|
|
264
|
+
return null;
|
|
265
|
+
try {
|
|
266
|
+
const indexer = (0, indexer_js_1.getProjectIndexer)();
|
|
267
|
+
const results = indexer.search(query, { limit: 5 });
|
|
268
|
+
if (results.length > 0) {
|
|
269
|
+
return {
|
|
270
|
+
source: 'local-index',
|
|
271
|
+
results: results.map(r => ({
|
|
272
|
+
file: r.path,
|
|
273
|
+
matches: r.matches.length,
|
|
274
|
+
preview: r.matches[0]?.content || '',
|
|
275
|
+
})),
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
// Index not available
|
|
281
|
+
}
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Find an alternative server in the same category
|
|
286
|
+
*/
|
|
287
|
+
findAlternativeServer(server) {
|
|
288
|
+
for (const [, servers] of Object.entries(SERVER_CATEGORIES)) {
|
|
289
|
+
const index = servers.indexOf(server);
|
|
290
|
+
if (index !== -1) {
|
|
291
|
+
// Find next available server in category
|
|
292
|
+
for (let i = 1; i < servers.length; i++) {
|
|
293
|
+
const alt = servers[(index + i) % servers.length];
|
|
294
|
+
const health = this.health.get(alt);
|
|
295
|
+
if (health && !health.circuitOpen && health.consecutiveFailures < 3) {
|
|
296
|
+
return alt;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
// ==========================================================================
|
|
304
|
+
// Health Tracking
|
|
305
|
+
// ==========================================================================
|
|
306
|
+
recordSuccess(server, latency) {
|
|
307
|
+
const health = this.health.get(server);
|
|
308
|
+
health.lastSuccess = Date.now();
|
|
309
|
+
health.consecutiveFailures = 0;
|
|
310
|
+
health.circuitOpen = false;
|
|
311
|
+
health.available = true;
|
|
312
|
+
// Update average latency
|
|
313
|
+
health.avgLatency = health.avgLatency === 0
|
|
314
|
+
? latency
|
|
315
|
+
: health.avgLatency * 0.9 + latency * 0.1;
|
|
316
|
+
// Update success rate
|
|
317
|
+
this.callHistory.push({ server, success: true, latency, timestamp: Date.now() });
|
|
318
|
+
this.updateSuccessRate(server);
|
|
319
|
+
}
|
|
320
|
+
recordFailure(server) {
|
|
321
|
+
const health = this.health.get(server);
|
|
322
|
+
health.lastFailure = Date.now();
|
|
323
|
+
health.consecutiveFailures++;
|
|
324
|
+
// Check circuit breaker
|
|
325
|
+
if (health.consecutiveFailures >= this.config.circuitBreakerThreshold) {
|
|
326
|
+
health.circuitOpen = true;
|
|
327
|
+
health.available = false;
|
|
328
|
+
console.log(`[MCP] Circuit breaker OPEN for ${server}`);
|
|
329
|
+
}
|
|
330
|
+
this.callHistory.push({ server, success: false, latency: 0, timestamp: Date.now() });
|
|
331
|
+
this.updateSuccessRate(server);
|
|
332
|
+
}
|
|
333
|
+
updateSuccessRate(server) {
|
|
334
|
+
const recentCalls = this.callHistory
|
|
335
|
+
.filter(c => c.server === server && Date.now() - c.timestamp < 300000); // Last 5 min
|
|
336
|
+
if (recentCalls.length > 0) {
|
|
337
|
+
const health = this.health.get(server);
|
|
338
|
+
health.successRate = recentCalls.filter(c => c.success).length / recentCalls.length;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
// ==========================================================================
|
|
342
|
+
// Public API
|
|
343
|
+
// ==========================================================================
|
|
344
|
+
/**
|
|
345
|
+
* Get health status for all servers
|
|
346
|
+
*/
|
|
347
|
+
getHealth() {
|
|
348
|
+
return Array.from(this.health.values());
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Get health status for a specific server
|
|
352
|
+
*/
|
|
353
|
+
getServerHealth(server) {
|
|
354
|
+
return this.health.get(server);
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Reset circuit breaker for a server
|
|
358
|
+
*/
|
|
359
|
+
resetCircuitBreaker(server) {
|
|
360
|
+
const health = this.health.get(server);
|
|
361
|
+
if (health) {
|
|
362
|
+
health.circuitOpen = false;
|
|
363
|
+
health.consecutiveFailures = 0;
|
|
364
|
+
health.available = true;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Check if a server is available
|
|
369
|
+
*/
|
|
370
|
+
isAvailable(server) {
|
|
371
|
+
const health = this.health.get(server);
|
|
372
|
+
return health ? health.available && !health.circuitOpen : false;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Get list of available servers
|
|
376
|
+
*/
|
|
377
|
+
getAvailableServers() {
|
|
378
|
+
return Array.from(this.health.entries())
|
|
379
|
+
.filter(([, h]) => h.available && !h.circuitOpen)
|
|
380
|
+
.map(([name]) => name);
|
|
381
|
+
}
|
|
382
|
+
// ==========================================================================
|
|
383
|
+
// Utilities
|
|
384
|
+
// ==========================================================================
|
|
385
|
+
delay(ms) {
|
|
386
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
exports.ResilientMCP = ResilientMCP;
|
|
390
|
+
// ============================================================================
|
|
391
|
+
// Singleton
|
|
392
|
+
// ============================================================================
|
|
393
|
+
let resilientMCPInstance = null;
|
|
394
|
+
function getResilientMCP(config) {
|
|
395
|
+
if (!resilientMCPInstance) {
|
|
396
|
+
resilientMCPInstance = new ResilientMCP(config);
|
|
397
|
+
}
|
|
398
|
+
return resilientMCPInstance;
|
|
399
|
+
}
|
|
400
|
+
function resetResilientMCP() {
|
|
401
|
+
resilientMCPInstance = null;
|
|
402
|
+
}
|
|
403
|
+
// ============================================================================
|
|
404
|
+
// Convenience Functions
|
|
405
|
+
// ============================================================================
|
|
406
|
+
/**
|
|
407
|
+
* Call MCP server with automatic resilience
|
|
408
|
+
*/
|
|
409
|
+
async function mcpCall(server, tool, params, options) {
|
|
410
|
+
return getResilientMCP().call(server, tool, params, options);
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Check if MCP servers are healthy
|
|
414
|
+
*/
|
|
415
|
+
function mcpHealthCheck() {
|
|
416
|
+
return getResilientMCP().getHealth();
|
|
417
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Genesis 6.8 - SQLite Fix Cache
|
|
3
|
+
*
|
|
4
|
+
* Stores successful fixes from Self-Healing module for instant reuse.
|
|
5
|
+
* Uses better-sqlite3 for synchronous, high-performance operations.
|
|
6
|
+
*
|
|
7
|
+
* Key: SHA256(error_message + file_path + context)
|
|
8
|
+
* Value: Applied fix with metadata
|
|
9
|
+
*/
|
|
10
|
+
export interface CachedFix {
|
|
11
|
+
/** Unique hash of error + context */
|
|
12
|
+
id: string;
|
|
13
|
+
/** Original error message */
|
|
14
|
+
errorMessage: string;
|
|
15
|
+
/** Error type (syntax, type, runtime, test, build, lint) */
|
|
16
|
+
errorType: string;
|
|
17
|
+
/** File path where error occurred */
|
|
18
|
+
filePath: string;
|
|
19
|
+
/** Code context around error */
|
|
20
|
+
context: string;
|
|
21
|
+
/** Applied fix */
|
|
22
|
+
fix: string;
|
|
23
|
+
/** Number of times this fix was used successfully */
|
|
24
|
+
successCount: number;
|
|
25
|
+
/** Last time this fix was used */
|
|
26
|
+
lastUsed: number;
|
|
27
|
+
/** When this fix was first created */
|
|
28
|
+
createdAt: number;
|
|
29
|
+
/** LLM provider that generated this fix (for stats) */
|
|
30
|
+
provider?: string;
|
|
31
|
+
/** Latency when fix was generated (for stats) */
|
|
32
|
+
latencyMs?: number;
|
|
33
|
+
}
|
|
34
|
+
export interface CacheStats {
|
|
35
|
+
totalFixes: number;
|
|
36
|
+
totalHits: number;
|
|
37
|
+
hitRate: number;
|
|
38
|
+
avgLatencySaved: number;
|
|
39
|
+
topErrors: Array<{
|
|
40
|
+
type: string;
|
|
41
|
+
count: number;
|
|
42
|
+
}>;
|
|
43
|
+
dbSizeBytes: number;
|
|
44
|
+
}
|
|
45
|
+
export interface CacheConfig {
|
|
46
|
+
/** Path to SQLite database file */
|
|
47
|
+
dbPath: string;
|
|
48
|
+
/** Maximum number of fixes to cache (LRU eviction) */
|
|
49
|
+
maxFixes: number;
|
|
50
|
+
/** Minimum success count to keep a fix during eviction */
|
|
51
|
+
minSuccessCount: number;
|
|
52
|
+
/** Enable FTS5 for full-text search */
|
|
53
|
+
enableFTS: boolean;
|
|
54
|
+
}
|
|
55
|
+
export declare class FixCache {
|
|
56
|
+
private config;
|
|
57
|
+
private cache;
|
|
58
|
+
constructor(config?: Partial<CacheConfig>);
|
|
59
|
+
/**
|
|
60
|
+
* Generate cache key from error details
|
|
61
|
+
*/
|
|
62
|
+
generateKey(errorMessage: string, filePath: string, context?: string): string;
|
|
63
|
+
/**
|
|
64
|
+
* Look up a cached fix
|
|
65
|
+
*/
|
|
66
|
+
lookup(errorMessage: string, filePath: string, context?: string): CachedFix | null;
|
|
67
|
+
/**
|
|
68
|
+
* Store a successful fix
|
|
69
|
+
*/
|
|
70
|
+
store(params: {
|
|
71
|
+
errorMessage: string;
|
|
72
|
+
errorType: string;
|
|
73
|
+
filePath: string;
|
|
74
|
+
context: string;
|
|
75
|
+
fix: string;
|
|
76
|
+
provider?: string;
|
|
77
|
+
latencyMs?: number;
|
|
78
|
+
}): CachedFix;
|
|
79
|
+
/**
|
|
80
|
+
* Search for similar errors
|
|
81
|
+
*/
|
|
82
|
+
searchSimilar(query: string, limit?: number): CachedFix[];
|
|
83
|
+
/**
|
|
84
|
+
* Get all cached fixes
|
|
85
|
+
*/
|
|
86
|
+
getAll(): CachedFix[];
|
|
87
|
+
/**
|
|
88
|
+
* Get cache statistics
|
|
89
|
+
*/
|
|
90
|
+
stats(): CacheStats;
|
|
91
|
+
/**
|
|
92
|
+
* Clear all cached fixes
|
|
93
|
+
*/
|
|
94
|
+
clear(): void;
|
|
95
|
+
/**
|
|
96
|
+
* Delete a specific fix
|
|
97
|
+
*/
|
|
98
|
+
delete(id: string): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Close the cache (save to disk)
|
|
101
|
+
*/
|
|
102
|
+
close(): void;
|
|
103
|
+
private evictIfNeeded;
|
|
104
|
+
}
|
|
105
|
+
export declare function getFixCache(config?: Partial<CacheConfig>): FixCache;
|
|
106
|
+
export declare function resetFixCache(): void;
|
|
107
|
+
/**
|
|
108
|
+
* Try to get a cached fix before calling LLM
|
|
109
|
+
*/
|
|
110
|
+
export declare function getCachedFixOrGenerate(errorMessage: string, errorType: string, filePath: string, context: string, generateFix: () => Promise<{
|
|
111
|
+
fix: string;
|
|
112
|
+
provider: string;
|
|
113
|
+
latencyMs: number;
|
|
114
|
+
}>): Promise<{
|
|
115
|
+
fix: string;
|
|
116
|
+
cached: boolean;
|
|
117
|
+
latencyMs: number;
|
|
118
|
+
}>;
|