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.
Files changed (227) hide show
  1. package/.env.example +78 -0
  2. package/README.md +282 -0
  3. package/dist/src/active-inference/actions.d.ts +75 -0
  4. package/dist/src/active-inference/actions.js +250 -0
  5. package/dist/src/active-inference/autonomous-loop.d.ts +103 -0
  6. package/dist/src/active-inference/autonomous-loop.js +289 -0
  7. package/dist/src/active-inference/core.d.ts +85 -0
  8. package/dist/src/active-inference/core.js +555 -0
  9. package/dist/src/active-inference/demo-autonomous-loop.d.ts +8 -0
  10. package/dist/src/active-inference/demo-autonomous-loop.js +338 -0
  11. package/dist/src/active-inference/demo-value-integration.d.ts +8 -0
  12. package/dist/src/active-inference/demo-value-integration.js +174 -0
  13. package/dist/src/active-inference/index.d.ts +32 -0
  14. package/dist/src/active-inference/index.js +88 -0
  15. package/dist/src/active-inference/integration.d.ts +114 -0
  16. package/dist/src/active-inference/integration.js +698 -0
  17. package/dist/src/active-inference/memory-integration.d.ts +51 -0
  18. package/dist/src/active-inference/memory-integration.js +232 -0
  19. package/dist/src/active-inference/observations.d.ts +67 -0
  20. package/dist/src/active-inference/observations.js +147 -0
  21. package/dist/src/active-inference/test-active-inference.d.ts +8 -0
  22. package/dist/src/active-inference/test-active-inference.js +320 -0
  23. package/dist/src/active-inference/test-value-integration.d.ts +6 -0
  24. package/dist/src/active-inference/test-value-integration.js +168 -0
  25. package/dist/src/active-inference/types.d.ts +150 -0
  26. package/dist/src/active-inference/types.js +59 -0
  27. package/dist/src/active-inference/value-integration.d.ts +164 -0
  28. package/dist/src/active-inference/value-integration.js +459 -0
  29. package/dist/src/agents/base-agent.d.ts +53 -0
  30. package/dist/src/agents/base-agent.js +178 -0
  31. package/dist/src/agents/builder.d.ts +67 -0
  32. package/dist/src/agents/builder.js +537 -0
  33. package/dist/src/agents/critic.d.ts +35 -0
  34. package/dist/src/agents/critic.js +322 -0
  35. package/dist/src/agents/ethicist.d.ts +54 -0
  36. package/dist/src/agents/ethicist.js +393 -0
  37. package/dist/src/agents/explorer.d.ts +26 -0
  38. package/dist/src/agents/explorer.js +216 -0
  39. package/dist/src/agents/feeling.d.ts +41 -0
  40. package/dist/src/agents/feeling.js +320 -0
  41. package/dist/src/agents/index.d.ts +111 -0
  42. package/dist/src/agents/index.js +222 -0
  43. package/dist/src/agents/memory.d.ts +69 -0
  44. package/dist/src/agents/memory.js +404 -0
  45. package/dist/src/agents/message-bus.d.ts +88 -0
  46. package/dist/src/agents/message-bus.js +267 -0
  47. package/dist/src/agents/narrator.d.ts +90 -0
  48. package/dist/src/agents/narrator.js +473 -0
  49. package/dist/src/agents/planner.d.ts +38 -0
  50. package/dist/src/agents/planner.js +341 -0
  51. package/dist/src/agents/predictor.d.ts +73 -0
  52. package/dist/src/agents/predictor.js +506 -0
  53. package/dist/src/agents/sensor.d.ts +88 -0
  54. package/dist/src/agents/sensor.js +377 -0
  55. package/dist/src/agents/test-agents.d.ts +6 -0
  56. package/dist/src/agents/test-agents.js +73 -0
  57. package/dist/src/agents/types.d.ts +194 -0
  58. package/dist/src/agents/types.js +7 -0
  59. package/dist/src/brain/index.d.ts +185 -0
  60. package/dist/src/brain/index.js +843 -0
  61. package/dist/src/brain/trace.d.ts +91 -0
  62. package/dist/src/brain/trace.js +327 -0
  63. package/dist/src/brain/types.d.ts +165 -0
  64. package/dist/src/brain/types.js +51 -0
  65. package/dist/src/cli/chat.d.ts +237 -0
  66. package/dist/src/cli/chat.js +1959 -0
  67. package/dist/src/cli/dispatcher.d.ts +182 -0
  68. package/dist/src/cli/dispatcher.js +718 -0
  69. package/dist/src/cli/human-loop.d.ts +170 -0
  70. package/dist/src/cli/human-loop.js +543 -0
  71. package/dist/src/cli/index.d.ts +12 -0
  72. package/dist/src/cli/index.js +28 -0
  73. package/dist/src/cli/interactive.d.ts +141 -0
  74. package/dist/src/cli/interactive.js +757 -0
  75. package/dist/src/cli/ui.d.ts +205 -0
  76. package/dist/src/cli/ui.js +632 -0
  77. package/dist/src/consciousness/attention-schema.d.ts +154 -0
  78. package/dist/src/consciousness/attention-schema.js +432 -0
  79. package/dist/src/consciousness/global-workspace.d.ts +149 -0
  80. package/dist/src/consciousness/global-workspace.js +422 -0
  81. package/dist/src/consciousness/index.d.ts +186 -0
  82. package/dist/src/consciousness/index.js +476 -0
  83. package/dist/src/consciousness/phi-calculator.d.ts +119 -0
  84. package/dist/src/consciousness/phi-calculator.js +445 -0
  85. package/dist/src/consciousness/phi-decisions.d.ts +169 -0
  86. package/dist/src/consciousness/phi-decisions.js +383 -0
  87. package/dist/src/consciousness/phi-monitor.d.ts +153 -0
  88. package/dist/src/consciousness/phi-monitor.js +465 -0
  89. package/dist/src/consciousness/types.d.ts +260 -0
  90. package/dist/src/consciousness/types.js +44 -0
  91. package/dist/src/daemon/dream-mode.d.ts +115 -0
  92. package/dist/src/daemon/dream-mode.js +470 -0
  93. package/dist/src/daemon/index.d.ts +162 -0
  94. package/dist/src/daemon/index.js +542 -0
  95. package/dist/src/daemon/maintenance.d.ts +139 -0
  96. package/dist/src/daemon/maintenance.js +549 -0
  97. package/dist/src/daemon/process.d.ts +82 -0
  98. package/dist/src/daemon/process.js +442 -0
  99. package/dist/src/daemon/scheduler.d.ts +90 -0
  100. package/dist/src/daemon/scheduler.js +494 -0
  101. package/dist/src/daemon/types.d.ts +213 -0
  102. package/dist/src/daemon/types.js +50 -0
  103. package/dist/src/epistemic/index.d.ts +74 -0
  104. package/dist/src/epistemic/index.js +225 -0
  105. package/dist/src/grounding/epistemic-stack.d.ts +100 -0
  106. package/dist/src/grounding/epistemic-stack.js +408 -0
  107. package/dist/src/grounding/feedback.d.ts +98 -0
  108. package/dist/src/grounding/feedback.js +276 -0
  109. package/dist/src/grounding/index.d.ts +123 -0
  110. package/dist/src/grounding/index.js +224 -0
  111. package/dist/src/grounding/verifier.d.ts +149 -0
  112. package/dist/src/grounding/verifier.js +484 -0
  113. package/dist/src/healing/detector.d.ts +110 -0
  114. package/dist/src/healing/detector.js +436 -0
  115. package/dist/src/healing/fixer.d.ts +138 -0
  116. package/dist/src/healing/fixer.js +572 -0
  117. package/dist/src/healing/index.d.ts +23 -0
  118. package/dist/src/healing/index.js +43 -0
  119. package/dist/src/hooks/index.d.ts +135 -0
  120. package/dist/src/hooks/index.js +317 -0
  121. package/dist/src/index.d.ts +23 -0
  122. package/dist/src/index.js +1266 -0
  123. package/dist/src/kernel/index.d.ts +155 -0
  124. package/dist/src/kernel/index.js +795 -0
  125. package/dist/src/kernel/invariants.d.ts +153 -0
  126. package/dist/src/kernel/invariants.js +355 -0
  127. package/dist/src/kernel/test-kernel.d.ts +6 -0
  128. package/dist/src/kernel/test-kernel.js +108 -0
  129. package/dist/src/kernel/test-real-mcp.d.ts +10 -0
  130. package/dist/src/kernel/test-real-mcp.js +295 -0
  131. package/dist/src/llm/index.d.ts +146 -0
  132. package/dist/src/llm/index.js +428 -0
  133. package/dist/src/llm/router.d.ts +136 -0
  134. package/dist/src/llm/router.js +510 -0
  135. package/dist/src/mcp/index.d.ts +85 -0
  136. package/dist/src/mcp/index.js +657 -0
  137. package/dist/src/mcp/resilient.d.ts +139 -0
  138. package/dist/src/mcp/resilient.js +417 -0
  139. package/dist/src/memory/cache.d.ts +118 -0
  140. package/dist/src/memory/cache.js +356 -0
  141. package/dist/src/memory/cognitive-workspace.d.ts +231 -0
  142. package/dist/src/memory/cognitive-workspace.js +521 -0
  143. package/dist/src/memory/consolidation.d.ts +99 -0
  144. package/dist/src/memory/consolidation.js +443 -0
  145. package/dist/src/memory/episodic.d.ts +114 -0
  146. package/dist/src/memory/episodic.js +394 -0
  147. package/dist/src/memory/forgetting.d.ts +134 -0
  148. package/dist/src/memory/forgetting.js +324 -0
  149. package/dist/src/memory/index.d.ts +211 -0
  150. package/dist/src/memory/index.js +367 -0
  151. package/dist/src/memory/indexer.d.ts +123 -0
  152. package/dist/src/memory/indexer.js +479 -0
  153. package/dist/src/memory/procedural.d.ts +136 -0
  154. package/dist/src/memory/procedural.js +479 -0
  155. package/dist/src/memory/semantic.d.ts +132 -0
  156. package/dist/src/memory/semantic.js +497 -0
  157. package/dist/src/memory/types.d.ts +193 -0
  158. package/dist/src/memory/types.js +15 -0
  159. package/dist/src/orchestrator.d.ts +65 -0
  160. package/dist/src/orchestrator.js +317 -0
  161. package/dist/src/persistence/index.d.ts +257 -0
  162. package/dist/src/persistence/index.js +763 -0
  163. package/dist/src/pipeline/executor.d.ts +51 -0
  164. package/dist/src/pipeline/executor.js +695 -0
  165. package/dist/src/pipeline/index.d.ts +7 -0
  166. package/dist/src/pipeline/index.js +11 -0
  167. package/dist/src/self-production.d.ts +67 -0
  168. package/dist/src/self-production.js +205 -0
  169. package/dist/src/subagents/executor.d.ts +58 -0
  170. package/dist/src/subagents/executor.js +283 -0
  171. package/dist/src/subagents/index.d.ts +37 -0
  172. package/dist/src/subagents/index.js +53 -0
  173. package/dist/src/subagents/registry.d.ts +23 -0
  174. package/dist/src/subagents/registry.js +167 -0
  175. package/dist/src/subagents/types.d.ts +79 -0
  176. package/dist/src/subagents/types.js +14 -0
  177. package/dist/src/tools/bash.d.ts +139 -0
  178. package/dist/src/tools/bash.js +583 -0
  179. package/dist/src/tools/edit.d.ts +125 -0
  180. package/dist/src/tools/edit.js +424 -0
  181. package/dist/src/tools/git.d.ts +179 -0
  182. package/dist/src/tools/git.js +504 -0
  183. package/dist/src/tools/index.d.ts +21 -0
  184. package/dist/src/tools/index.js +163 -0
  185. package/dist/src/types.d.ts +145 -0
  186. package/dist/src/types.js +7 -0
  187. package/dist/src/world-model/decoder.d.ts +163 -0
  188. package/dist/src/world-model/decoder.js +517 -0
  189. package/dist/src/world-model/digital-twin.d.ts +219 -0
  190. package/dist/src/world-model/digital-twin.js +695 -0
  191. package/dist/src/world-model/encoder.d.ts +141 -0
  192. package/dist/src/world-model/encoder.js +564 -0
  193. package/dist/src/world-model/index.d.ts +221 -0
  194. package/dist/src/world-model/index.js +772 -0
  195. package/dist/src/world-model/predictor.d.ts +161 -0
  196. package/dist/src/world-model/predictor.js +681 -0
  197. package/dist/src/world-model/test-value-jepa.d.ts +8 -0
  198. package/dist/src/world-model/test-value-jepa.js +430 -0
  199. package/dist/src/world-model/types.d.ts +341 -0
  200. package/dist/src/world-model/types.js +69 -0
  201. package/dist/src/world-model/value-jepa.d.ts +247 -0
  202. package/dist/src/world-model/value-jepa.js +622 -0
  203. package/dist/test/brain.test.d.ts +11 -0
  204. package/dist/test/brain.test.js +358 -0
  205. package/dist/test/cli/dispatcher.test.d.ts +4 -0
  206. package/dist/test/cli/dispatcher.test.js +332 -0
  207. package/dist/test/cli/human-loop.test.d.ts +4 -0
  208. package/dist/test/cli/human-loop.test.js +270 -0
  209. package/dist/test/grounding/feedback.test.d.ts +4 -0
  210. package/dist/test/grounding/feedback.test.js +462 -0
  211. package/dist/test/grounding/verifier.test.d.ts +4 -0
  212. package/dist/test/grounding/verifier.test.js +442 -0
  213. package/dist/test/grounding.test.d.ts +6 -0
  214. package/dist/test/grounding.test.js +246 -0
  215. package/dist/test/healing/detector.test.d.ts +4 -0
  216. package/dist/test/healing/detector.test.js +266 -0
  217. package/dist/test/healing/fixer.test.d.ts +4 -0
  218. package/dist/test/healing/fixer.test.js +369 -0
  219. package/dist/test/integration.test.d.ts +5 -0
  220. package/dist/test/integration.test.js +290 -0
  221. package/dist/test/tools/bash.test.d.ts +4 -0
  222. package/dist/test/tools/bash.test.js +348 -0
  223. package/dist/test/tools/edit.test.d.ts +4 -0
  224. package/dist/test/tools/edit.test.js +350 -0
  225. package/dist/test/tools/git.test.d.ts +4 -0
  226. package/dist/test/tools/git.test.js +350 -0
  227. package/package.json +60 -0
@@ -0,0 +1,510 @@
1
+ "use strict";
2
+ /**
3
+ * Genesis 6.8 - Hybrid LLM Router
4
+ *
5
+ * Intelligent routing between local (Ollama) and cloud (OpenAI/Anthropic) LLMs.
6
+ *
7
+ * Routing Logic:
8
+ * - Simple tasks (syntax fix, file ops, search) -> Local (fast, free)
9
+ * - Complex tasks (architecture, design, creative) -> Cloud (high quality)
10
+ *
11
+ * Factors considered:
12
+ * - Task complexity (heuristic analysis)
13
+ * - Token count estimation
14
+ * - Ollama availability
15
+ * - User preference
16
+ * - Cost optimization
17
+ */
18
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ var desc = Object.getOwnPropertyDescriptor(m, k);
21
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
22
+ desc = { enumerable: true, get: function() { return m[k]; } };
23
+ }
24
+ Object.defineProperty(o, k2, desc);
25
+ }) : (function(o, m, k, k2) {
26
+ if (k2 === undefined) k2 = k;
27
+ o[k2] = m[k];
28
+ }));
29
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
30
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
31
+ }) : function(o, v) {
32
+ o["default"] = v;
33
+ });
34
+ var __importStar = (this && this.__importStar) || (function () {
35
+ var ownKeys = function(o) {
36
+ ownKeys = Object.getOwnPropertyNames || function (o) {
37
+ var ar = [];
38
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
39
+ return ar;
40
+ };
41
+ return ownKeys(o);
42
+ };
43
+ return function (mod) {
44
+ if (mod && mod.__esModule) return mod;
45
+ var result = {};
46
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
47
+ __setModuleDefault(result, mod);
48
+ return result;
49
+ };
50
+ })();
51
+ Object.defineProperty(exports, "__esModule", { value: true });
52
+ exports.HybridRouter = void 0;
53
+ exports.detectHardware = detectHardware;
54
+ exports.analyzeComplexity = analyzeComplexity;
55
+ exports.estimateTokens = estimateTokens;
56
+ exports.estimateCost = estimateCost;
57
+ exports.getHybridRouter = getHybridRouter;
58
+ exports.resetHybridRouter = resetHybridRouter;
59
+ exports.smartChat = smartChat;
60
+ exports.localChat = localChat;
61
+ exports.cloudChat = cloudChat;
62
+ const index_js_1 = require("./index.js");
63
+ const os = __importStar(require("os"));
64
+ /**
65
+ * Detect hardware capabilities and recommend router config
66
+ */
67
+ function detectHardware() {
68
+ const cpus = os.cpus();
69
+ const cpu = cpus[0]?.model || 'Unknown';
70
+ const cores = cpus.length;
71
+ const memoryGB = Math.round(os.totalmem() / (1024 ** 3));
72
+ // Detect Apple Silicon
73
+ const isAppleSilicon = cpu.includes('Apple M') ||
74
+ process.arch === 'arm64' && process.platform === 'darwin';
75
+ // Determine tier
76
+ let tier;
77
+ let recommendedThreshold;
78
+ let recommendedMaxTokens;
79
+ if (isAppleSilicon && memoryGB >= 24) {
80
+ // M3 Pro/Max/Ultra or M4 Pro/Max - top tier
81
+ tier = 'ultra';
82
+ recommendedThreshold = 'creative'; // Only creative to cloud
83
+ recommendedMaxTokens = 16384; // Can handle large context
84
+ }
85
+ else if (isAppleSilicon && memoryGB >= 16) {
86
+ // M1/M2/M3/M4 base with good RAM
87
+ tier = 'high';
88
+ recommendedThreshold = 'creative';
89
+ recommendedMaxTokens = 8192;
90
+ }
91
+ else if (cores >= 8 && memoryGB >= 16) {
92
+ // Good desktop/laptop
93
+ tier = 'medium';
94
+ recommendedThreshold = 'complex';
95
+ recommendedMaxTokens = 4096;
96
+ }
97
+ else {
98
+ // Limited hardware
99
+ tier = 'low';
100
+ recommendedThreshold = 'moderate'; // Route more to cloud
101
+ recommendedMaxTokens = 2048;
102
+ }
103
+ return {
104
+ cpu,
105
+ isAppleSilicon,
106
+ cores,
107
+ memoryGB,
108
+ tier,
109
+ recommendedThreshold,
110
+ recommendedMaxTokens,
111
+ };
112
+ }
113
+ // ============================================================================
114
+ // Default Config
115
+ // ============================================================================
116
+ const DEFAULT_CONFIG = {
117
+ preferLocal: true,
118
+ forceCloud: false,
119
+ localMaxTokens: 8192, // M4 Pro can handle larger context
120
+ cloudThreshold: 'creative', // Only creative → cloud (M4 Pro is fast enough for complex)
121
+ autoFallback: true,
122
+ logDecisions: false,
123
+ };
124
+ // ============================================================================
125
+ // Complexity Analysis
126
+ // ============================================================================
127
+ const COMPLEXITY_SCORES = {
128
+ trivial: 0,
129
+ simple: 1,
130
+ moderate: 2,
131
+ complex: 3,
132
+ creative: 4,
133
+ };
134
+ /**
135
+ * Keywords that indicate simple/local tasks
136
+ */
137
+ const LOCAL_KEYWORDS = [
138
+ // Syntax & Formatting
139
+ 'fix syntax', 'typo', 'spelling', 'indent', 'format',
140
+ 'semicolon', 'bracket', 'parenthesis', 'quote',
141
+ // File Operations
142
+ 'rename', 'move file', 'delete file', 'list files',
143
+ 'find file', 'search', 'grep', 'locate',
144
+ // Simple Code Tasks
145
+ 'add import', 'remove import', 'update import',
146
+ 'add export', 'rename variable', 'rename function',
147
+ 'add comment', 'remove comment', 'update comment',
148
+ // Git Operations
149
+ 'git status', 'git diff', 'git log', 'git add',
150
+ 'commit message', 'branch name',
151
+ // Quick Fixes
152
+ 'missing semicolon', 'missing bracket', 'missing import',
153
+ 'unused variable', 'undefined variable',
154
+ 'type error', 'typescript error',
155
+ ];
156
+ /**
157
+ * Keywords that indicate complex/cloud tasks
158
+ */
159
+ const CLOUD_KEYWORDS = [
160
+ // Architecture
161
+ 'design', 'architect', 'structure', 'pattern',
162
+ 'refactor', 'restructure', 'reorganize',
163
+ // Creative
164
+ 'create', 'implement', 'build', 'develop',
165
+ 'new feature', 'add feature', 'write from scratch',
166
+ // Complex Analysis
167
+ 'analyze', 'review', 'evaluate', 'assess',
168
+ 'optimize', 'improve', 'enhance',
169
+ // Documentation
170
+ 'document', 'explain', 'describe', 'tutorial',
171
+ 'readme', 'api docs', 'specification',
172
+ // Testing
173
+ 'write tests', 'test coverage', 'integration test',
174
+ 'e2e test', 'test strategy',
175
+ // Multi-step
176
+ 'step by step', 'multiple files', 'across the codebase',
177
+ 'entire project', 'all files',
178
+ ];
179
+ /**
180
+ * Analyze task complexity from the prompt
181
+ */
182
+ function analyzeComplexity(prompt) {
183
+ const lower = prompt.toLowerCase();
184
+ const indicators = [];
185
+ let localScore = 0;
186
+ let cloudScore = 0;
187
+ // Check local keywords
188
+ for (const keyword of LOCAL_KEYWORDS) {
189
+ if (lower.includes(keyword)) {
190
+ localScore++;
191
+ indicators.push(`local: "${keyword}"`);
192
+ }
193
+ }
194
+ // Check cloud keywords
195
+ for (const keyword of CLOUD_KEYWORDS) {
196
+ if (lower.includes(keyword)) {
197
+ cloudScore++;
198
+ indicators.push(`cloud: "${keyword}"`);
199
+ }
200
+ }
201
+ // Additional heuristics
202
+ const wordCount = prompt.split(/\s+/).length;
203
+ const hasCode = prompt.includes('```') || prompt.includes('function ') || prompt.includes('class ');
204
+ const hasMultipleQuestions = (prompt.match(/\?/g) || []).length > 1;
205
+ const hasNumberedList = /\d+\.\s/.test(prompt);
206
+ if (wordCount > 200) {
207
+ cloudScore += 2;
208
+ indicators.push('long prompt');
209
+ }
210
+ if (hasCode && wordCount > 100) {
211
+ cloudScore++;
212
+ indicators.push('code + explanation');
213
+ }
214
+ if (hasMultipleQuestions) {
215
+ cloudScore++;
216
+ indicators.push('multiple questions');
217
+ }
218
+ if (hasNumberedList) {
219
+ cloudScore++;
220
+ indicators.push('multi-step task');
221
+ }
222
+ // Calculate final complexity
223
+ const netScore = cloudScore - localScore;
224
+ let complexity;
225
+ if (netScore <= -2)
226
+ complexity = 'trivial';
227
+ else if (netScore <= 0)
228
+ complexity = 'simple';
229
+ else if (netScore <= 2)
230
+ complexity = 'moderate';
231
+ else if (netScore <= 4)
232
+ complexity = 'complex';
233
+ else
234
+ complexity = 'creative';
235
+ // Confidence based on indicator count
236
+ const totalIndicators = localScore + cloudScore;
237
+ const confidence = Math.min(0.9, 0.3 + (totalIndicators * 0.1));
238
+ return { complexity, confidence, indicators };
239
+ }
240
+ /**
241
+ * Estimate token count from prompt
242
+ */
243
+ function estimateTokens(text) {
244
+ // Rough estimation: ~4 characters per token for English
245
+ return Math.ceil(text.length / 4);
246
+ }
247
+ /**
248
+ * Estimate cost for cloud provider
249
+ */
250
+ function estimateCost(inputTokens, outputTokens, provider) {
251
+ // Prices per 1M tokens (as of 2024)
252
+ const prices = {
253
+ openai: { input: 2.5, output: 10 }, // GPT-4o
254
+ anthropic: { input: 3, output: 15 }, // Claude Sonnet
255
+ ollama: { input: 0, output: 0 }, // Free!
256
+ };
257
+ const p = prices[provider];
258
+ return ((inputTokens * p.input) + (outputTokens * p.output)) / 1_000_000;
259
+ }
260
+ // ============================================================================
261
+ // Hybrid Router Class
262
+ // ============================================================================
263
+ class HybridRouter {
264
+ config;
265
+ stats = {
266
+ totalRequests: 0,
267
+ localRequests: 0,
268
+ cloudRequests: 0,
269
+ fallbacks: 0,
270
+ avgLocalLatency: 0,
271
+ avgCloudLatency: 0,
272
+ estimatedSavings: 0,
273
+ };
274
+ localBridge = null;
275
+ cloudBridge = null;
276
+ hardwareProfile;
277
+ constructor(config) {
278
+ // Detect hardware and auto-configure
279
+ this.hardwareProfile = detectHardware();
280
+ // Apply hardware-based defaults, then user overrides
281
+ this.config = {
282
+ ...DEFAULT_CONFIG,
283
+ cloudThreshold: this.hardwareProfile.recommendedThreshold,
284
+ localMaxTokens: this.hardwareProfile.recommendedMaxTokens,
285
+ ...config,
286
+ };
287
+ if (this.config.logDecisions) {
288
+ console.log(`[Router] Hardware: ${this.hardwareProfile.tier} tier (${this.hardwareProfile.cpu})`);
289
+ console.log(`[Router] Config: cloudThreshold=${this.config.cloudThreshold}, localMaxTokens=${this.config.localMaxTokens}`);
290
+ }
291
+ }
292
+ /**
293
+ * Get detected hardware profile
294
+ */
295
+ getHardwareProfile() {
296
+ return { ...this.hardwareProfile };
297
+ }
298
+ // ==========================================================================
299
+ // Routing Logic
300
+ // ==========================================================================
301
+ /**
302
+ * Decide which provider to use
303
+ */
304
+ async route(prompt) {
305
+ const { complexity, confidence, indicators } = analyzeComplexity(prompt);
306
+ const estimatedTokens = estimateTokens(prompt);
307
+ const estimatedOutputTokens = Math.min(estimatedTokens * 2, 2000);
308
+ // Force cloud if configured
309
+ if (this.config.forceCloud) {
310
+ return {
311
+ provider: process.env.ANTHROPIC_API_KEY ? 'anthropic' : 'openai',
312
+ reason: 'Force cloud mode enabled',
313
+ complexity,
314
+ confidence: 1,
315
+ estimatedTokens,
316
+ estimatedCost: estimateCost(estimatedTokens, estimatedOutputTokens, 'anthropic'),
317
+ tryLocalFirst: false,
318
+ };
319
+ }
320
+ // Check if Ollama is available
321
+ const ollamaAvailable = await this.isOllamaAvailable();
322
+ // Prefer local if configured and available
323
+ if (this.config.preferLocal && ollamaAvailable) {
324
+ const threshold = COMPLEXITY_SCORES[this.config.cloudThreshold];
325
+ const score = COMPLEXITY_SCORES[complexity];
326
+ if (score < threshold) {
327
+ return {
328
+ provider: 'ollama',
329
+ reason: `Task complexity (${complexity}) below cloud threshold (${this.config.cloudThreshold})`,
330
+ complexity,
331
+ confidence,
332
+ estimatedTokens,
333
+ estimatedCost: 0,
334
+ tryLocalFirst: true,
335
+ };
336
+ }
337
+ }
338
+ // Token limit check for local
339
+ if (estimatedTokens > this.config.localMaxTokens) {
340
+ return {
341
+ provider: process.env.ANTHROPIC_API_KEY ? 'anthropic' : 'openai',
342
+ reason: `Token count (${estimatedTokens}) exceeds local limit (${this.config.localMaxTokens})`,
343
+ complexity,
344
+ confidence,
345
+ estimatedTokens,
346
+ estimatedCost: estimateCost(estimatedTokens, estimatedOutputTokens, 'anthropic'),
347
+ tryLocalFirst: false,
348
+ };
349
+ }
350
+ // Default: use local if available, else cloud
351
+ if (ollamaAvailable) {
352
+ return {
353
+ provider: 'ollama',
354
+ reason: 'Local model available, using for cost savings',
355
+ complexity,
356
+ confidence,
357
+ estimatedTokens,
358
+ estimatedCost: 0,
359
+ tryLocalFirst: true,
360
+ };
361
+ }
362
+ return {
363
+ provider: process.env.ANTHROPIC_API_KEY ? 'anthropic' : 'openai',
364
+ reason: 'Ollama not available, using cloud',
365
+ complexity,
366
+ confidence,
367
+ estimatedTokens,
368
+ estimatedCost: estimateCost(estimatedTokens, estimatedOutputTokens, 'anthropic'),
369
+ tryLocalFirst: false,
370
+ };
371
+ }
372
+ /**
373
+ * Execute request with routing
374
+ */
375
+ async execute(prompt, systemPrompt) {
376
+ const decision = await this.route(prompt);
377
+ if (this.config.logDecisions) {
378
+ console.log(`[Router] ${decision.provider}: ${decision.reason} (${decision.complexity}, ${decision.confidence.toFixed(2)})`);
379
+ }
380
+ this.stats.totalRequests++;
381
+ try {
382
+ const bridge = this.getBridge(decision.provider);
383
+ const response = await bridge.chat(prompt, systemPrompt);
384
+ // Update stats
385
+ if (decision.provider === 'ollama') {
386
+ this.stats.localRequests++;
387
+ this.stats.avgLocalLatency = this.updateAverage(this.stats.avgLocalLatency, response.latency, this.stats.localRequests);
388
+ // Calculate savings vs cloud
389
+ const cloudCost = estimateCost(response.usage?.inputTokens || 0, response.usage?.outputTokens || 0, 'anthropic');
390
+ this.stats.estimatedSavings += cloudCost;
391
+ }
392
+ else {
393
+ this.stats.cloudRequests++;
394
+ this.stats.avgCloudLatency = this.updateAverage(this.stats.avgCloudLatency, response.latency, this.stats.cloudRequests);
395
+ }
396
+ return { ...response, routingDecision: decision };
397
+ }
398
+ catch (error) {
399
+ // Auto-fallback if enabled
400
+ if (this.config.autoFallback && decision.provider === 'ollama') {
401
+ console.log('[Router] Local failed, falling back to cloud...');
402
+ this.stats.fallbacks++;
403
+ const fallbackProvider = process.env.ANTHROPIC_API_KEY ? 'anthropic' : 'openai';
404
+ const bridge = this.getBridge(fallbackProvider);
405
+ const response = await bridge.chat(prompt, systemPrompt);
406
+ return {
407
+ ...response,
408
+ routingDecision: {
409
+ ...decision,
410
+ provider: fallbackProvider,
411
+ reason: `Fallback from Ollama: ${error instanceof Error ? error.message : 'Unknown error'}`,
412
+ },
413
+ };
414
+ }
415
+ throw error;
416
+ }
417
+ }
418
+ // ==========================================================================
419
+ // Helpers
420
+ // ==========================================================================
421
+ async isOllamaAvailable() {
422
+ try {
423
+ const response = await fetch('http://localhost:11434/api/tags', {
424
+ signal: AbortSignal.timeout(1000),
425
+ });
426
+ return response.ok;
427
+ }
428
+ catch {
429
+ return false;
430
+ }
431
+ }
432
+ getBridge(provider) {
433
+ if (provider === 'ollama') {
434
+ if (!this.localBridge) {
435
+ this.localBridge = new index_js_1.LLMBridge({ provider: 'ollama' });
436
+ }
437
+ return this.localBridge;
438
+ }
439
+ if (!this.cloudBridge) {
440
+ this.cloudBridge = new index_js_1.LLMBridge({ provider });
441
+ }
442
+ return this.cloudBridge;
443
+ }
444
+ updateAverage(current, newValue, count) {
445
+ return current + (newValue - current) / count;
446
+ }
447
+ // ==========================================================================
448
+ // Stats & Config
449
+ // ==========================================================================
450
+ getStats() {
451
+ return { ...this.stats };
452
+ }
453
+ resetStats() {
454
+ this.stats = {
455
+ totalRequests: 0,
456
+ localRequests: 0,
457
+ cloudRequests: 0,
458
+ fallbacks: 0,
459
+ avgLocalLatency: 0,
460
+ avgCloudLatency: 0,
461
+ estimatedSavings: 0,
462
+ };
463
+ }
464
+ getConfig() {
465
+ return { ...this.config };
466
+ }
467
+ setConfig(config) {
468
+ this.config = { ...this.config, ...config };
469
+ }
470
+ }
471
+ exports.HybridRouter = HybridRouter;
472
+ // ============================================================================
473
+ // Singleton
474
+ // ============================================================================
475
+ let routerInstance = null;
476
+ function getHybridRouter(config) {
477
+ if (!routerInstance) {
478
+ routerInstance = new HybridRouter(config);
479
+ }
480
+ return routerInstance;
481
+ }
482
+ function resetHybridRouter() {
483
+ routerInstance = null;
484
+ }
485
+ // ============================================================================
486
+ // Convenience Functions
487
+ // ============================================================================
488
+ /**
489
+ * Smart chat: automatically routes to best provider
490
+ */
491
+ async function smartChat(prompt, systemPrompt) {
492
+ const router = getHybridRouter();
493
+ const result = await router.execute(prompt, systemPrompt);
494
+ return result;
495
+ }
496
+ /**
497
+ * Force local chat (Ollama)
498
+ */
499
+ async function localChat(prompt, systemPrompt) {
500
+ const bridge = new index_js_1.LLMBridge({ provider: 'ollama' });
501
+ return bridge.chat(prompt, systemPrompt);
502
+ }
503
+ /**
504
+ * Force cloud chat
505
+ */
506
+ async function cloudChat(prompt, systemPrompt) {
507
+ const provider = process.env.ANTHROPIC_API_KEY ? 'anthropic' : 'openai';
508
+ const bridge = new index_js_1.LLMBridge({ provider });
509
+ return bridge.chat(prompt, systemPrompt);
510
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Genesis 6.8 - Real MCP Client Module
3
+ *
4
+ * Connects to actual MCP servers using @modelcontextprotocol/sdk.
5
+ * Spawns servers on demand and manages connections.
6
+ *
7
+ * Environment Variables:
8
+ * - GENESIS_MCP_MODE: 'real' | 'simulated' | 'hybrid' (default: 'simulated')
9
+ * - GENESIS_MCP_TIMEOUT: Timeout in ms (default: 30000)
10
+ * - GENESIS_MCP_LOG: Enable MCP call logging (default: false)
11
+ */
12
+ export * from './resilient.js';
13
+ import { MCPServerName } from '../types.js';
14
+ export type MCPMode = 'real' | 'simulated' | 'hybrid';
15
+ export interface MCPCallOptions {
16
+ timeout?: number;
17
+ retries?: number;
18
+ fallbackToSimulated?: boolean;
19
+ }
20
+ export interface MCPCallResult<T = any> {
21
+ success: boolean;
22
+ data?: T;
23
+ error?: string;
24
+ server: MCPServerName;
25
+ tool: string;
26
+ mode: 'real' | 'simulated';
27
+ latency: number;
28
+ timestamp: Date;
29
+ }
30
+ export interface MCPClientConfig {
31
+ mode: MCPMode;
32
+ timeout: number;
33
+ logCalls: boolean;
34
+ onCall?: (server: MCPServerName, tool: string, params: any) => void;
35
+ onResult?: (result: MCPCallResult) => void;
36
+ }
37
+ interface MCPServerInfo {
38
+ command: string;
39
+ args: string[] | (() => string[]);
40
+ envVars?: Record<string, string> | (() => Record<string, string>);
41
+ tools: string[];
42
+ }
43
+ /**
44
+ * Registry of MCP servers and how to spawn them.
45
+ * These are the 13 MCP servers Genesis uses.
46
+ *
47
+ * Package sources (verified on npm):
48
+ * - Official: @modelcontextprotocol/server-*
49
+ * - Third-party: arxiv-mcp-server, @brave/brave-search-mcp-server, etc.
50
+ */
51
+ declare const MCP_SERVER_REGISTRY: Record<MCPServerName, MCPServerInfo>;
52
+ /**
53
+ * MCP Tool definition with full schema (from MCP SDK)
54
+ */
55
+ export interface MCPToolDefinition {
56
+ name: string;
57
+ description?: string;
58
+ inputSchema?: {
59
+ type: 'object';
60
+ properties?: Record<string, {
61
+ type?: string;
62
+ description?: string;
63
+ enum?: string[];
64
+ items?: any;
65
+ }>;
66
+ required?: string[];
67
+ };
68
+ }
69
+ export interface IMCPClient {
70
+ call<T = any>(server: MCPServerName, tool: string, params: Record<string, any>, options?: MCPCallOptions): Promise<MCPCallResult<T>>;
71
+ listTools(server: MCPServerName): Promise<string[]>;
72
+ listToolsWithSchema(server: MCPServerName): Promise<MCPToolDefinition[]>;
73
+ discoverAllTools(): Promise<Record<MCPServerName, MCPToolDefinition[]>>;
74
+ isAvailable(server: MCPServerName): Promise<boolean>;
75
+ getMode(): MCPMode;
76
+ setMode(mode: MCPMode): void;
77
+ close(): Promise<void>;
78
+ }
79
+ export declare function getMCPClient(config?: Partial<MCPClientConfig>): IMCPClient;
80
+ export declare function resetMCPClient(): void;
81
+ export declare const mcpClient: IMCPClient;
82
+ export declare function isSimulatedMode(): boolean;
83
+ export declare function isSimulatedResult(result: MCPCallResult): boolean;
84
+ export declare function logMCPMode(): void;
85
+ export { MCP_SERVER_REGISTRY };