ruvector 0.2.23 → 0.2.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/bin/cli.js +332 -79
  2. package/bin/mcp-server.js +94 -22
  3. package/dist/analysis/complexity.d.ts +52 -0
  4. package/dist/analysis/complexity.d.ts.map +1 -0
  5. package/dist/analysis/complexity.js +146 -0
  6. package/dist/analysis/index.d.ts +15 -0
  7. package/dist/analysis/index.d.ts.map +1 -0
  8. package/dist/analysis/index.js +38 -0
  9. package/dist/analysis/patterns.d.ts +71 -0
  10. package/dist/analysis/patterns.d.ts.map +1 -0
  11. package/dist/analysis/patterns.js +243 -0
  12. package/dist/analysis/security.d.ts +51 -0
  13. package/dist/analysis/security.d.ts.map +1 -0
  14. package/dist/analysis/security.js +139 -0
  15. package/dist/core/adaptive-embedder.d.ts +156 -0
  16. package/dist/core/adaptive-embedder.d.ts.map +1 -0
  17. package/dist/core/adaptive-embedder.js +838 -0
  18. package/dist/core/agentdb-fast.d.ts +149 -0
  19. package/dist/core/agentdb-fast.d.ts.map +1 -0
  20. package/dist/core/agentdb-fast.js +301 -0
  21. package/dist/core/ast-parser.d.ts +108 -0
  22. package/dist/core/ast-parser.d.ts.map +1 -0
  23. package/dist/core/ast-parser.js +602 -0
  24. package/dist/core/attention-fallbacks.d.ts +321 -0
  25. package/dist/core/attention-fallbacks.d.ts.map +1 -0
  26. package/dist/core/attention-fallbacks.js +552 -0
  27. package/dist/core/cluster-wrapper.d.ts +148 -0
  28. package/dist/core/cluster-wrapper.d.ts.map +1 -0
  29. package/dist/core/cluster-wrapper.js +271 -0
  30. package/dist/core/coverage-router.d.ts +88 -0
  31. package/dist/core/coverage-router.d.ts.map +1 -0
  32. package/dist/core/coverage-router.js +315 -0
  33. package/dist/core/diff-embeddings.d.ts +93 -0
  34. package/dist/core/diff-embeddings.d.ts.map +1 -0
  35. package/dist/core/diff-embeddings.js +334 -0
  36. package/dist/core/diskann-wrapper.d.ts +53 -0
  37. package/dist/core/diskann-wrapper.d.ts.map +1 -0
  38. package/dist/core/diskann-wrapper.js +105 -0
  39. package/dist/core/gnn-wrapper.d.ts +143 -0
  40. package/dist/core/gnn-wrapper.d.ts.map +1 -0
  41. package/dist/core/gnn-wrapper.js +213 -0
  42. package/dist/core/graph-algorithms.d.ts +83 -0
  43. package/dist/core/graph-algorithms.d.ts.map +1 -0
  44. package/dist/core/graph-algorithms.js +514 -0
  45. package/dist/core/graph-wrapper.d.ts +147 -0
  46. package/dist/core/graph-wrapper.d.ts.map +1 -0
  47. package/dist/core/graph-wrapper.js +299 -0
  48. package/dist/core/index.d.ts +50 -0
  49. package/dist/core/index.d.ts.map +1 -0
  50. package/dist/core/index.js +92 -0
  51. package/dist/core/intelligence-engine.d.ts +258 -0
  52. package/dist/core/intelligence-engine.d.ts.map +1 -0
  53. package/dist/core/intelligence-engine.js +1026 -0
  54. package/dist/core/learning-engine.d.ts +162 -0
  55. package/dist/core/learning-engine.d.ts.map +1 -0
  56. package/dist/core/learning-engine.js +609 -0
  57. package/dist/core/neural-embeddings.d.ts +393 -0
  58. package/dist/core/neural-embeddings.d.ts.map +1 -0
  59. package/dist/core/neural-embeddings.js +1091 -0
  60. package/dist/core/neural-perf.d.ts +331 -0
  61. package/dist/core/neural-perf.d.ts.map +1 -0
  62. package/dist/core/neural-perf.js +704 -0
  63. package/dist/core/onnx/loader.js +348 -0
  64. package/dist/core/onnx/pkg/LICENSE +21 -0
  65. package/dist/core/onnx/pkg/loader.js +348 -0
  66. package/dist/core/onnx/pkg/package.json +3 -0
  67. package/dist/core/onnx/pkg/ruvector_onnx_embeddings_wasm.d.ts +112 -0
  68. package/dist/core/onnx/pkg/ruvector_onnx_embeddings_wasm.js +5 -0
  69. package/dist/core/onnx/pkg/ruvector_onnx_embeddings_wasm_bg.js +638 -0
  70. package/dist/core/onnx/pkg/ruvector_onnx_embeddings_wasm_bg.wasm +0 -0
  71. package/dist/core/onnx/pkg/ruvector_onnx_embeddings_wasm_bg.wasm.d.ts +29 -0
  72. package/dist/core/onnx-embedder.d.ts +105 -0
  73. package/dist/core/onnx-embedder.d.ts.map +1 -0
  74. package/dist/core/onnx-embedder.js +414 -0
  75. package/dist/core/onnx-optimized.d.ts +109 -0
  76. package/dist/core/onnx-optimized.d.ts.map +1 -0
  77. package/dist/core/onnx-optimized.js +419 -0
  78. package/dist/core/parallel-intelligence.d.ts +109 -0
  79. package/dist/core/parallel-intelligence.d.ts.map +1 -0
  80. package/dist/core/parallel-intelligence.js +340 -0
  81. package/dist/core/parallel-workers.d.ts +177 -0
  82. package/dist/core/parallel-workers.d.ts.map +1 -0
  83. package/dist/core/parallel-workers.js +783 -0
  84. package/dist/core/router-wrapper.d.ts +75 -0
  85. package/dist/core/router-wrapper.d.ts.map +1 -0
  86. package/dist/core/router-wrapper.js +243 -0
  87. package/dist/core/rvf-wrapper.d.ts +86 -0
  88. package/dist/core/rvf-wrapper.d.ts.map +1 -0
  89. package/dist/core/rvf-wrapper.js +102 -0
  90. package/dist/core/sona-wrapper.d.ts +226 -0
  91. package/dist/core/sona-wrapper.d.ts.map +1 -0
  92. package/dist/core/sona-wrapper.js +282 -0
  93. package/dist/core/tensor-compress.d.ts +134 -0
  94. package/dist/core/tensor-compress.d.ts.map +1 -0
  95. package/dist/core/tensor-compress.js +432 -0
  96. package/dist/index.d.ts +160 -0
  97. package/dist/index.d.ts.map +1 -0
  98. package/dist/index.js +359 -0
  99. package/dist/services/embedding-service.d.ts +136 -0
  100. package/dist/services/embedding-service.d.ts.map +1 -0
  101. package/dist/services/embedding-service.js +294 -0
  102. package/dist/services/index.d.ts +6 -0
  103. package/dist/services/index.d.ts.map +1 -0
  104. package/dist/services/index.js +26 -0
  105. package/dist/types.d.ts +145 -0
  106. package/dist/types.d.ts.map +1 -0
  107. package/dist/types.js +2 -0
  108. package/dist/workers/benchmark.d.ts +44 -0
  109. package/dist/workers/benchmark.d.ts.map +1 -0
  110. package/dist/workers/benchmark.js +230 -0
  111. package/dist/workers/index.d.ts +10 -0
  112. package/dist/workers/index.d.ts.map +1 -0
  113. package/dist/workers/index.js +25 -0
  114. package/dist/workers/native-worker.d.ts +76 -0
  115. package/dist/workers/native-worker.d.ts.map +1 -0
  116. package/dist/workers/native-worker.js +490 -0
  117. package/dist/workers/types.d.ts +69 -0
  118. package/dist/workers/types.d.ts.map +1 -0
  119. package/dist/workers/types.js +7 -0
  120. package/package.json +11 -9
@@ -0,0 +1,1026 @@
1
+ "use strict";
2
+ /**
3
+ * IntelligenceEngine - Full RuVector Intelligence Stack
4
+ *
5
+ * Integrates all RuVector capabilities for self-learning hooks:
6
+ * - VectorDB with HNSW for semantic memory (150x faster)
7
+ * - SONA for continual learning (Micro-LoRA, EWC++)
8
+ * - FastAgentDB for episode/trajectory storage
9
+ * - Attention mechanisms for pattern recognition
10
+ * - ReasoningBank for pattern clustering
11
+ *
12
+ * Replaces the simple Q-learning approach with real ML-powered intelligence.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.IntelligenceEngine = void 0;
16
+ exports.createIntelligenceEngine = createIntelligenceEngine;
17
+ exports.createHighPerformanceEngine = createHighPerformanceEngine;
18
+ exports.createLightweightEngine = createLightweightEngine;
19
+ const agentdb_fast_1 = require("./agentdb-fast");
20
+ const sona_wrapper_1 = require("./sona-wrapper");
21
+ const onnx_embedder_1 = require("./onnx-embedder");
22
+ const parallel_intelligence_1 = require("./parallel-intelligence");
23
+ // ============================================================================
24
+ // Lazy Loading
25
+ // ============================================================================
26
+ let VectorDB = null;
27
+ let vectorDbError = null;
28
+ function getVectorDB() {
29
+ if (VectorDB)
30
+ return VectorDB;
31
+ if (vectorDbError)
32
+ throw vectorDbError;
33
+ try {
34
+ const core = require('@ruvector/core');
35
+ VectorDB = core.VectorDb || core.VectorDB;
36
+ return VectorDB;
37
+ }
38
+ catch {
39
+ try {
40
+ const pkg = require('ruvector');
41
+ VectorDB = pkg.VectorDb || pkg.VectorDB;
42
+ return VectorDB;
43
+ }
44
+ catch (e) {
45
+ vectorDbError = new Error(`VectorDB not available: ${e.message}`);
46
+ throw vectorDbError;
47
+ }
48
+ }
49
+ }
50
+ let attentionModule = null;
51
+ let attentionError = null;
52
+ function getAttention() {
53
+ if (attentionModule)
54
+ return attentionModule;
55
+ if (attentionError)
56
+ return null; // Silently fail for optional module
57
+ try {
58
+ attentionModule = require('@ruvector/attention');
59
+ return attentionModule;
60
+ }
61
+ catch (e) {
62
+ attentionError = e;
63
+ return null;
64
+ }
65
+ }
66
+ // ============================================================================
67
+ // Intelligence Engine
68
+ // ============================================================================
69
+ /**
70
+ * Full-stack intelligence engine using all RuVector capabilities
71
+ */
72
+ class IntelligenceEngine {
73
+ constructor(config = {}) {
74
+ this.vectorDb = null;
75
+ this.sona = null;
76
+ this.attention = null;
77
+ this.onnxEmbedder = null;
78
+ this.onnxReady = false;
79
+ this.parallel = null;
80
+ // In-memory data structures
81
+ this.memories = new Map();
82
+ this.routingPatterns = new Map(); // state -> action -> value
83
+ this.errorPatterns = new Map(); // error -> fixes
84
+ this.coEditPatterns = new Map(); // file -> related files -> count
85
+ this.agentMappings = new Map(); // extension/dir -> agent
86
+ this.workerTriggerMappings = new Map(); // trigger -> agents
87
+ // Runtime state
88
+ this.currentTrajectoryId = null;
89
+ this.sessionStart = Date.now();
90
+ this.learningEnabled = true;
91
+ this.episodeBatchQueue = [];
92
+ // If ONNX is enabled, use 384 dimensions (MiniLM default)
93
+ const useOnnx = !!(config.enableOnnx && (0, onnx_embedder_1.isOnnxAvailable)());
94
+ const embeddingDim = useOnnx ? 384 : (config.embeddingDim ?? 256);
95
+ this.config = {
96
+ embeddingDim,
97
+ maxMemories: config.maxMemories ?? 100000,
98
+ maxEpisodes: config.maxEpisodes ?? 50000,
99
+ enableSona: config.enableSona ?? true,
100
+ enableAttention: config.enableAttention ?? true,
101
+ enableOnnx: useOnnx,
102
+ sonaConfig: config.sonaConfig ?? {},
103
+ storagePath: config.storagePath ?? '',
104
+ learningRate: config.learningRate ?? 0.1,
105
+ parallelConfig: config.parallelConfig ?? {},
106
+ };
107
+ // Initialize parallel workers (auto-enabled for MCP, disabled for CLI)
108
+ this.parallel = (0, parallel_intelligence_1.getParallelIntelligence)(this.config.parallelConfig);
109
+ this.initParallel();
110
+ // Initialize FastAgentDB for episode storage
111
+ this.agentDb = new agentdb_fast_1.FastAgentDB(this.config.embeddingDim, this.config.maxEpisodes);
112
+ // Initialize ONNX embedder if enabled
113
+ if (this.config.enableOnnx) {
114
+ this.onnxEmbedder = new onnx_embedder_1.OnnxEmbedder();
115
+ // Initialize async (don't block constructor)
116
+ this.initOnnx();
117
+ }
118
+ // Initialize SONA if enabled and available
119
+ if (this.config.enableSona && (0, sona_wrapper_1.isSonaAvailable)()) {
120
+ try {
121
+ this.sona = sona_wrapper_1.SonaEngine.withConfig({
122
+ hiddenDim: this.config.embeddingDim,
123
+ embeddingDim: this.config.embeddingDim,
124
+ microLoraRank: 2, // Fast adaptations
125
+ baseLoraRank: 8,
126
+ patternClusters: 100,
127
+ trajectoryCapacity: 10000,
128
+ ...this.config.sonaConfig,
129
+ });
130
+ }
131
+ catch (e) {
132
+ console.warn('SONA initialization failed, using fallback learning');
133
+ }
134
+ }
135
+ // Initialize attention if enabled (fallback if ONNX not available)
136
+ if (this.config.enableAttention && !this.config.enableOnnx) {
137
+ this.attention = getAttention();
138
+ }
139
+ // Initialize VectorDB for memory
140
+ this.initVectorDb();
141
+ }
142
+ async initOnnx() {
143
+ if (!this.onnxEmbedder)
144
+ return;
145
+ try {
146
+ await this.onnxEmbedder.init();
147
+ this.onnxReady = true;
148
+ }
149
+ catch (e) {
150
+ console.warn('ONNX initialization failed, using fallback embeddings');
151
+ this.onnxReady = false;
152
+ }
153
+ }
154
+ async initVectorDb() {
155
+ try {
156
+ const VDB = getVectorDB();
157
+ this.vectorDb = new VDB({
158
+ dimensions: this.config.embeddingDim,
159
+ distanceMetric: 'Cosine',
160
+ });
161
+ }
162
+ catch {
163
+ // VectorDB not available, use fallback
164
+ }
165
+ }
166
+ async initParallel() {
167
+ if (this.parallel) {
168
+ try {
169
+ await this.parallel.init();
170
+ }
171
+ catch {
172
+ // Parallel not available, use sequential
173
+ this.parallel = null;
174
+ }
175
+ }
176
+ }
177
+ // =========================================================================
178
+ // Embedding Generation
179
+ // =========================================================================
180
+ /**
181
+ * Generate embedding using attention or hash (sync). Use embedAsync() for ONNX.
182
+ */
183
+ embed(text) {
184
+ const dim = this.config.embeddingDim;
185
+ // Try to use attention-based embedding (best sync quality)
186
+ if (this.attention?.DotProductAttention) {
187
+ try {
188
+ return this.attentionEmbed(text, dim);
189
+ }
190
+ catch {
191
+ // Fall through to hash embedding
192
+ }
193
+ }
194
+ // Improved positional hash embedding
195
+ return this.hashEmbed(text, dim);
196
+ }
197
+ /**
198
+ * Async embedding with ONNX support (recommended for semantic quality)
199
+ */
200
+ async embedAsync(text) {
201
+ // Try ONNX first (best semantic quality)
202
+ if (this.onnxEmbedder) {
203
+ try {
204
+ if (!this.onnxReady) {
205
+ await this.onnxEmbedder.init();
206
+ this.onnxReady = true;
207
+ }
208
+ return await this.onnxEmbedder.embed(text);
209
+ }
210
+ catch {
211
+ // Fall through to sync methods
212
+ }
213
+ }
214
+ // Fall back to sync embedding
215
+ return this.embed(text);
216
+ }
217
+ /**
218
+ * Attention-based embedding using Flash or Multi-head attention
219
+ */
220
+ attentionEmbed(text, dim) {
221
+ const tokens = this.tokenize(text);
222
+ const tokenEmbeddings = tokens.map(t => this.tokenEmbed(t, dim));
223
+ if (tokenEmbeddings.length === 0) {
224
+ return new Array(dim).fill(0);
225
+ }
226
+ try {
227
+ // Try FlashAttention first (fastest)
228
+ if (this.attention?.FlashAttention) {
229
+ const flash = new this.attention.FlashAttention(dim);
230
+ const query = new Float32Array(this.meanPool(tokenEmbeddings));
231
+ const keys = tokenEmbeddings.map(e => new Float32Array(e));
232
+ const values = tokenEmbeddings.map(e => new Float32Array(e));
233
+ const result = flash.forward(query, keys, values);
234
+ return Array.from(result);
235
+ }
236
+ // Try MultiHeadAttention (better quality)
237
+ if (this.attention?.MultiHeadAttention) {
238
+ const numHeads = Math.min(8, Math.floor(dim / 32)); // 8 heads max
239
+ const mha = new this.attention.MultiHeadAttention(dim, numHeads);
240
+ const query = new Float32Array(this.meanPool(tokenEmbeddings));
241
+ const keys = tokenEmbeddings.map(e => new Float32Array(e));
242
+ const values = tokenEmbeddings.map(e => new Float32Array(e));
243
+ const result = mha.forward(query, keys, values);
244
+ return Array.from(result);
245
+ }
246
+ // Fall back to DotProductAttention
247
+ if (this.attention?.DotProductAttention) {
248
+ const attn = new this.attention.DotProductAttention();
249
+ const query = this.meanPool(tokenEmbeddings);
250
+ const result = attn.forward(new Float32Array(query), tokenEmbeddings.map(e => new Float32Array(e)), tokenEmbeddings.map(e => new Float32Array(e)));
251
+ return Array.from(result);
252
+ }
253
+ }
254
+ catch {
255
+ // Fall through to hash embedding
256
+ }
257
+ // Ultimate fallback
258
+ return this.hashEmbed(text, dim);
259
+ }
260
+ /**
261
+ * Improved hash-based embedding with positional encoding
262
+ */
263
+ hashEmbed(text, dim) {
264
+ const embedding = new Array(dim).fill(0);
265
+ const tokens = this.tokenize(text);
266
+ for (let t = 0; t < tokens.length; t++) {
267
+ const token = tokens[t];
268
+ const posWeight = 1 / (1 + t * 0.1); // Positional decay
269
+ for (let i = 0; i < token.length; i++) {
270
+ const charCode = token.charCodeAt(i);
271
+ // Multiple hash functions for better distribution
272
+ const h1 = (charCode * 31 + i * 17 + t * 7) % dim;
273
+ const h2 = (charCode * 37 + i * 23 + t * 11) % dim;
274
+ const h3 = (charCode * 41 + i * 29 + t * 13) % dim;
275
+ embedding[h1] += posWeight;
276
+ embedding[h2] += posWeight * 0.5;
277
+ embedding[h3] += posWeight * 0.25;
278
+ }
279
+ }
280
+ // L2 normalize
281
+ const norm = Math.sqrt(embedding.reduce((a, b) => a + b * b, 0));
282
+ if (norm > 0) {
283
+ for (let i = 0; i < dim; i++)
284
+ embedding[i] /= norm;
285
+ }
286
+ return embedding;
287
+ }
288
+ tokenize(text) {
289
+ return text.toLowerCase()
290
+ .replace(/[^\w\s]/g, ' ')
291
+ .split(/\s+/)
292
+ .filter(t => t.length > 0);
293
+ }
294
+ tokenEmbed(token, dim) {
295
+ const embedding = new Array(dim).fill(0);
296
+ for (let i = 0; i < token.length; i++) {
297
+ const idx = (token.charCodeAt(i) * 31 + i * 17) % dim;
298
+ embedding[idx] += 1;
299
+ }
300
+ const norm = Math.sqrt(embedding.reduce((a, b) => a + b * b, 0));
301
+ if (norm > 0)
302
+ for (let i = 0; i < dim; i++)
303
+ embedding[i] /= norm;
304
+ return embedding;
305
+ }
306
+ meanPool(embeddings) {
307
+ if (embeddings.length === 0)
308
+ return [];
309
+ const dim = embeddings[0].length;
310
+ const result = new Array(dim).fill(0);
311
+ for (const emb of embeddings) {
312
+ for (let i = 0; i < dim; i++)
313
+ result[i] += emb[i];
314
+ }
315
+ for (let i = 0; i < dim; i++)
316
+ result[i] /= embeddings.length;
317
+ return result;
318
+ }
319
+ // =========================================================================
320
+ // Memory Operations
321
+ // =========================================================================
322
+ /**
323
+ * Store content in vector memory (uses ONNX if available)
324
+ */
325
+ async remember(content, type = 'general') {
326
+ const id = `mem-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
327
+ // Use async ONNX embeddings if available for better semantic quality
328
+ const embedding = await this.embedAsync(content);
329
+ const entry = {
330
+ id,
331
+ content,
332
+ type,
333
+ embedding,
334
+ created: new Date().toISOString(),
335
+ accessed: 0,
336
+ };
337
+ this.memories.set(id, entry);
338
+ // Index in VectorDB if available
339
+ if (this.vectorDb) {
340
+ try {
341
+ await this.vectorDb.insert({
342
+ id,
343
+ vector: new Float32Array(embedding),
344
+ metadata: JSON.stringify({ content, type, created: entry.created }),
345
+ });
346
+ }
347
+ catch {
348
+ // Ignore indexing errors
349
+ }
350
+ }
351
+ return entry;
352
+ }
353
+ /**
354
+ * Semantic search of memories (uses ONNX if available)
355
+ */
356
+ async recall(query, topK = 5) {
357
+ // Use async ONNX embeddings if available for better semantic quality
358
+ const queryEmbed = await this.embedAsync(query);
359
+ // Try VectorDB search first (HNSW - 150x faster)
360
+ if (this.vectorDb) {
361
+ try {
362
+ const results = await this.vectorDb.search({
363
+ vector: new Float32Array(queryEmbed),
364
+ k: topK,
365
+ });
366
+ return results.map((r) => {
367
+ const entry = this.memories.get(r.id);
368
+ if (entry) {
369
+ entry.accessed++;
370
+ entry.score = 1 - r.score; // Convert distance to similarity
371
+ }
372
+ return entry;
373
+ }).filter((e) => e !== null);
374
+ }
375
+ catch {
376
+ // Fall through to brute force
377
+ }
378
+ }
379
+ // Fallback: brute-force cosine similarity
380
+ const scored = Array.from(this.memories.values()).map(m => ({
381
+ ...m,
382
+ score: this.cosineSimilarity(queryEmbed, m.embedding),
383
+ }));
384
+ return scored
385
+ .sort((a, b) => (b.score || 0) - (a.score || 0))
386
+ .slice(0, topK);
387
+ }
388
+ cosineSimilarity(a, b) {
389
+ if (a.length !== b.length)
390
+ return 0;
391
+ let dot = 0, normA = 0, normB = 0;
392
+ for (let i = 0; i < a.length; i++) {
393
+ dot += a[i] * b[i];
394
+ normA += a[i] * a[i];
395
+ normB += b[i] * b[i];
396
+ }
397
+ const denom = Math.sqrt(normA) * Math.sqrt(normB);
398
+ return denom > 0 ? dot / denom : 0;
399
+ }
400
+ // =========================================================================
401
+ // Agent Routing with SONA
402
+ // =========================================================================
403
+ /**
404
+ * Route a task to the best agent using learned patterns
405
+ */
406
+ async route(task, file) {
407
+ const ext = file ? this.getExtension(file) : '';
408
+ const state = this.getState(task, ext);
409
+ // Use async ONNX embeddings for semantic routing (critical fix)
410
+ const taskEmbed = await this.embedAsync(task + ' ' + (file || ''));
411
+ // Apply SONA micro-LoRA transformation if available
412
+ let adaptedEmbed = taskEmbed;
413
+ if (this.sona) {
414
+ try {
415
+ adaptedEmbed = this.sona.applyMicroLora(taskEmbed);
416
+ }
417
+ catch {
418
+ // Use original embedding
419
+ }
420
+ }
421
+ // Find similar patterns using ReasoningBank
422
+ let patterns = [];
423
+ if (this.sona) {
424
+ try {
425
+ patterns = this.sona.findPatterns(adaptedEmbed, 5);
426
+ }
427
+ catch {
428
+ // No patterns
429
+ }
430
+ }
431
+ // Default agent mappings
432
+ const defaults = {
433
+ '.rs': 'rust-developer',
434
+ '.ts': 'typescript-developer',
435
+ '.tsx': 'react-developer',
436
+ '.js': 'javascript-developer',
437
+ '.jsx': 'react-developer',
438
+ '.py': 'python-developer',
439
+ '.go': 'go-developer',
440
+ '.sql': 'database-specialist',
441
+ '.md': 'documentation-specialist',
442
+ '.yml': 'devops-engineer',
443
+ '.yaml': 'devops-engineer',
444
+ '.json': 'coder',
445
+ '.toml': 'coder',
446
+ };
447
+ // Check learned patterns first
448
+ const statePatterns = this.routingPatterns.get(state);
449
+ let bestAgent = defaults[ext] || 'coder';
450
+ let bestScore = 0.5;
451
+ let reason = 'default mapping';
452
+ if (statePatterns && statePatterns.size > 0) {
453
+ for (const [agent, score] of statePatterns) {
454
+ if (score > bestScore) {
455
+ bestAgent = agent;
456
+ bestScore = score;
457
+ reason = 'learned from patterns';
458
+ }
459
+ }
460
+ }
461
+ // Check custom agent mappings
462
+ if (this.agentMappings.has(ext)) {
463
+ const mapped = this.agentMappings.get(ext);
464
+ if (bestScore < 0.8) {
465
+ bestAgent = mapped;
466
+ bestScore = 0.8;
467
+ reason = 'custom mapping';
468
+ }
469
+ }
470
+ // Boost confidence if SONA patterns match
471
+ if (patterns.length > 0 && patterns[0].avgQuality > 0.7) {
472
+ bestScore = Math.min(1.0, bestScore + 0.1);
473
+ reason += ' + SONA pattern match';
474
+ }
475
+ return {
476
+ agent: bestAgent,
477
+ confidence: Math.min(1.0, bestScore),
478
+ reason,
479
+ patterns: patterns.length > 0 ? patterns : undefined,
480
+ alternates: this.getAlternates(statePatterns, bestAgent),
481
+ };
482
+ }
483
+ getExtension(file) {
484
+ const idx = file.lastIndexOf('.');
485
+ return idx >= 0 ? file.slice(idx).toLowerCase() : '';
486
+ }
487
+ getState(task, ext) {
488
+ const taskType = task.includes('fix') ? 'fix' :
489
+ task.includes('test') ? 'test' :
490
+ task.includes('refactor') ? 'refactor' :
491
+ task.includes('document') ? 'docs' : 'edit';
492
+ return `${taskType}:${ext || 'unknown'}`;
493
+ }
494
+ getAlternates(patterns, exclude) {
495
+ if (!patterns)
496
+ return [];
497
+ return Array.from(patterns.entries())
498
+ .filter(([a]) => a !== exclude)
499
+ .sort((a, b) => b[1] - a[1])
500
+ .slice(0, 3)
501
+ .map(([agent, confidence]) => ({ agent, confidence: Math.min(1.0, confidence) }));
502
+ }
503
+ // =========================================================================
504
+ // Trajectory Learning
505
+ // =========================================================================
506
+ /**
507
+ * Begin recording a trajectory (before edit/command)
508
+ */
509
+ beginTrajectory(context, file) {
510
+ const embed = this.embed(context + ' ' + (file || ''));
511
+ if (this.sona) {
512
+ try {
513
+ this.currentTrajectoryId = this.sona.beginTrajectory(embed);
514
+ if (file) {
515
+ this.sona.addContext(this.currentTrajectoryId, file);
516
+ }
517
+ }
518
+ catch {
519
+ this.currentTrajectoryId = null;
520
+ }
521
+ }
522
+ }
523
+ /**
524
+ * Add a step to the current trajectory
525
+ */
526
+ addTrajectoryStep(activations, reward) {
527
+ if (this.sona && this.currentTrajectoryId !== null) {
528
+ try {
529
+ const attentionWeights = new Array(activations.length).fill(1 / activations.length);
530
+ this.sona.addStep(this.currentTrajectoryId, activations, attentionWeights, reward);
531
+ }
532
+ catch {
533
+ // Ignore step errors
534
+ }
535
+ }
536
+ }
537
+ /**
538
+ * End the current trajectory with a quality score
539
+ */
540
+ endTrajectory(success, quality) {
541
+ const q = quality ?? (success ? 0.9 : 0.3);
542
+ if (this.sona && this.currentTrajectoryId !== null) {
543
+ try {
544
+ this.sona.endTrajectory(this.currentTrajectoryId, q);
545
+ }
546
+ catch {
547
+ // Ignore end errors
548
+ }
549
+ }
550
+ this.currentTrajectoryId = null;
551
+ }
552
+ /**
553
+ * Set the agent route for current trajectory
554
+ */
555
+ setTrajectoryRoute(agent) {
556
+ if (this.sona && this.currentTrajectoryId !== null) {
557
+ try {
558
+ this.sona.setRoute(this.currentTrajectoryId, agent);
559
+ }
560
+ catch {
561
+ // Ignore route errors
562
+ }
563
+ }
564
+ }
565
+ // =========================================================================
566
+ // Episode Learning (Q-learning compatible)
567
+ // =========================================================================
568
+ /**
569
+ * Record an episode for learning
570
+ */
571
+ async recordEpisode(state, action, reward, nextState, done, metadata) {
572
+ const stateEmbed = this.embed(state);
573
+ const nextStateEmbed = this.embed(nextState);
574
+ // Store in FastAgentDB
575
+ await this.agentDb.storeEpisode({
576
+ state: stateEmbed,
577
+ action,
578
+ reward,
579
+ nextState: nextStateEmbed,
580
+ done,
581
+ metadata,
582
+ });
583
+ // Update routing patterns (Q-learning style)
584
+ if (!this.routingPatterns.has(state)) {
585
+ this.routingPatterns.set(state, new Map());
586
+ }
587
+ const patterns = this.routingPatterns.get(state);
588
+ const oldValue = patterns.get(action) || 0.5;
589
+ const newValue = oldValue + this.config.learningRate * (reward - oldValue);
590
+ patterns.set(action, newValue);
591
+ }
592
+ /**
593
+ * Queue episode for batch processing (3-4x faster with workers)
594
+ */
595
+ queueEpisode(episode) {
596
+ this.episodeBatchQueue.push(episode);
597
+ }
598
+ /**
599
+ * Process queued episodes in parallel batch
600
+ */
601
+ async flushEpisodeBatch() {
602
+ if (this.episodeBatchQueue.length === 0)
603
+ return 0;
604
+ const count = this.episodeBatchQueue.length;
605
+ if (this.parallel) {
606
+ // Use parallel workers for batch processing
607
+ await this.parallel.recordEpisodesBatch(this.episodeBatchQueue);
608
+ }
609
+ else {
610
+ // Sequential fallback
611
+ for (const ep of this.episodeBatchQueue) {
612
+ await this.recordEpisode(ep.state, ep.action, ep.reward, ep.nextState, ep.done, ep.metadata);
613
+ }
614
+ }
615
+ this.episodeBatchQueue = [];
616
+ return count;
617
+ }
618
+ /**
619
+ * Learn from similar past episodes
620
+ */
621
+ async learnFromSimilar(state, k = 5) {
622
+ const stateEmbed = this.embed(state);
623
+ return this.agentDb.searchByState(stateEmbed, k);
624
+ }
625
+ // =========================================================================
626
+ // Worker-Agent Mappings
627
+ // =========================================================================
628
+ /**
629
+ * Register worker trigger to agent mappings
630
+ */
631
+ registerWorkerTrigger(trigger, priority, agents) {
632
+ this.workerTriggerMappings.set(trigger, { priority, agents });
633
+ }
634
+ /**
635
+ * Get agents for a worker trigger
636
+ */
637
+ getAgentsForTrigger(trigger) {
638
+ return this.workerTriggerMappings.get(trigger);
639
+ }
640
+ /**
641
+ * Route a task using worker trigger patterns first, then fall back to regular routing
642
+ */
643
+ async routeWithWorkers(task, file) {
644
+ // Check if task matches any worker trigger patterns
645
+ const taskLower = task.toLowerCase();
646
+ for (const [trigger, config] of this.workerTriggerMappings) {
647
+ if (taskLower.includes(trigger)) {
648
+ const primaryAgent = config.agents[0] || 'coder';
649
+ const alternates = config.agents.slice(1).map(a => ({ agent: a, confidence: 0.7 }));
650
+ return {
651
+ agent: primaryAgent,
652
+ confidence: config.priority === 'critical' ? 0.95 :
653
+ config.priority === 'high' ? 0.85 :
654
+ config.priority === 'medium' ? 0.75 : 0.65,
655
+ reason: `worker trigger: ${trigger}`,
656
+ alternates,
657
+ };
658
+ }
659
+ }
660
+ // Fall back to regular routing
661
+ return this.route(task, file);
662
+ }
663
+ /**
664
+ * Initialize default worker trigger mappings
665
+ */
666
+ initDefaultWorkerMappings() {
667
+ const defaults = [
668
+ ['ultralearn', 'high', ['researcher', 'coder']],
669
+ ['optimize', 'high', ['performance-analyzer']],
670
+ ['audit', 'critical', ['security-analyst', 'tester']],
671
+ ['map', 'medium', ['architect']],
672
+ ['security', 'critical', ['security-analyst']],
673
+ ['benchmark', 'low', ['performance-analyzer']],
674
+ ['document', 'medium', ['documenter']],
675
+ ['refactor', 'medium', ['coder', 'reviewer']],
676
+ ['testgaps', 'high', ['tester']],
677
+ ['deepdive', 'low', ['researcher']],
678
+ ['predict', 'medium', ['analyst']],
679
+ ['consolidate', 'low', ['architect']],
680
+ ];
681
+ for (const [trigger, priority, agents] of defaults) {
682
+ this.workerTriggerMappings.set(trigger, { priority, agents });
683
+ }
684
+ }
685
+ // =========================================================================
686
+ // Co-edit Pattern Learning
687
+ // =========================================================================
688
+ /**
689
+ * Record a co-edit pattern
690
+ */
691
+ recordCoEdit(file1, file2) {
692
+ if (!this.coEditPatterns.has(file1)) {
693
+ this.coEditPatterns.set(file1, new Map());
694
+ }
695
+ if (!this.coEditPatterns.has(file2)) {
696
+ this.coEditPatterns.set(file2, new Map());
697
+ }
698
+ const count1 = this.coEditPatterns.get(file1).get(file2) || 0;
699
+ this.coEditPatterns.get(file1).set(file2, count1 + 1);
700
+ const count2 = this.coEditPatterns.get(file2).get(file1) || 0;
701
+ this.coEditPatterns.get(file2).set(file1, count2 + 1);
702
+ }
703
+ /**
704
+ * Get likely next files to edit
705
+ */
706
+ getLikelyNextFiles(file, topK = 5) {
707
+ const related = this.coEditPatterns.get(file);
708
+ if (!related)
709
+ return [];
710
+ return Array.from(related.entries())
711
+ .sort((a, b) => b[1] - a[1])
712
+ .slice(0, topK)
713
+ .map(([f, count]) => ({ file: f, count }));
714
+ }
715
+ // =========================================================================
716
+ // Error Pattern Learning
717
+ // =========================================================================
718
+ /**
719
+ * Record an error pattern with fixes
720
+ */
721
+ recordErrorFix(errorPattern, fix) {
722
+ if (!this.errorPatterns.has(errorPattern)) {
723
+ this.errorPatterns.set(errorPattern, []);
724
+ }
725
+ const fixes = this.errorPatterns.get(errorPattern);
726
+ if (!fixes.includes(fix)) {
727
+ fixes.push(fix);
728
+ }
729
+ }
730
+ /**
731
+ * Get suggested fixes for an error
732
+ */
733
+ getSuggestedFixes(error) {
734
+ // Exact match
735
+ if (this.errorPatterns.has(error)) {
736
+ return this.errorPatterns.get(error);
737
+ }
738
+ // Fuzzy match by embedding similarity
739
+ const errorEmbed = this.embed(error);
740
+ const matches = [];
741
+ for (const [pattern, fixes] of this.errorPatterns) {
742
+ const patternEmbed = this.embed(pattern);
743
+ const similarity = this.cosineSimilarity(errorEmbed, patternEmbed);
744
+ if (similarity > 0.7) {
745
+ matches.push({ pattern, similarity, fixes });
746
+ }
747
+ }
748
+ if (matches.length === 0)
749
+ return [];
750
+ // Return fixes from most similar pattern
751
+ matches.sort((a, b) => b.similarity - a.similarity);
752
+ return matches[0].fixes;
753
+ }
754
+ // =========================================================================
755
+ // Tick / Background Learning
756
+ // =========================================================================
757
+ /**
758
+ * Run background learning cycle
759
+ */
760
+ tick() {
761
+ if (this.sona) {
762
+ try {
763
+ return this.sona.tick();
764
+ }
765
+ catch {
766
+ return null;
767
+ }
768
+ }
769
+ return null;
770
+ }
771
+ /**
772
+ * Force immediate learning
773
+ */
774
+ forceLearn() {
775
+ if (this.sona) {
776
+ try {
777
+ return this.sona.forceLearn();
778
+ }
779
+ catch {
780
+ return null;
781
+ }
782
+ }
783
+ return null;
784
+ }
785
+ // =========================================================================
786
+ // Statistics
787
+ // =========================================================================
788
+ /**
789
+ * Get comprehensive learning statistics
790
+ */
791
+ getStats() {
792
+ const agentDbStats = this.agentDb.getStats();
793
+ let sonaStats = null;
794
+ if (this.sona) {
795
+ try {
796
+ sonaStats = this.sona.getStats();
797
+ }
798
+ catch {
799
+ // No SONA stats
800
+ }
801
+ }
802
+ // Calculate average reward from patterns
803
+ let totalReward = 0;
804
+ let rewardCount = 0;
805
+ for (const patterns of this.routingPatterns.values()) {
806
+ for (const reward of patterns.values()) {
807
+ totalReward += reward;
808
+ rewardCount++;
809
+ }
810
+ }
811
+ const parallelStats = this.parallel?.getStats() ?? { enabled: false, workers: 0, busy: 0, queued: 0 };
812
+ return {
813
+ totalMemories: this.memories.size,
814
+ memoryDimensions: this.config.embeddingDim,
815
+ totalEpisodes: agentDbStats.episodeCount,
816
+ totalTrajectories: agentDbStats.trajectoryCount,
817
+ avgReward: rewardCount > 0 ? totalReward / rewardCount : 0,
818
+ sonaEnabled: this.sona !== null,
819
+ trajectoriesRecorded: sonaStats?.trajectoriesRecorded ?? 0,
820
+ patternsLearned: sonaStats?.patternsLearned ?? 0,
821
+ microLoraUpdates: sonaStats?.microLoraUpdates ?? 0,
822
+ baseLoraUpdates: sonaStats?.baseLoraUpdates ?? 0,
823
+ ewcConsolidations: sonaStats?.ewcConsolidations ?? 0,
824
+ routingPatterns: this.routingPatterns.size,
825
+ errorPatterns: this.errorPatterns.size,
826
+ coEditPatterns: this.coEditPatterns.size,
827
+ workerTriggers: this.workerTriggerMappings.size,
828
+ attentionEnabled: this.attention !== null,
829
+ onnxEnabled: this.onnxReady,
830
+ parallelEnabled: parallelStats.enabled,
831
+ parallelWorkers: parallelStats.workers,
832
+ parallelBusy: parallelStats.busy,
833
+ parallelQueued: parallelStats.queued,
834
+ };
835
+ }
836
+ // =========================================================================
837
+ // Persistence
838
+ // =========================================================================
839
+ /**
840
+ * Export all data for persistence
841
+ */
842
+ export() {
843
+ return {
844
+ version: '2.0.0',
845
+ exported: new Date().toISOString(),
846
+ config: this.config,
847
+ memories: Array.from(this.memories.values()),
848
+ routingPatterns: Object.fromEntries(Array.from(this.routingPatterns.entries()).map(([k, v]) => [
849
+ k,
850
+ Object.fromEntries(v),
851
+ ])),
852
+ errorPatterns: Object.fromEntries(this.errorPatterns),
853
+ coEditPatterns: Object.fromEntries(Array.from(this.coEditPatterns.entries()).map(([k, v]) => [
854
+ k,
855
+ Object.fromEntries(v),
856
+ ])),
857
+ agentMappings: Object.fromEntries(this.agentMappings),
858
+ workerTriggerMappings: Object.fromEntries(Array.from(this.workerTriggerMappings.entries()).map(([k, v]) => [k, v])),
859
+ stats: this.getStats(),
860
+ };
861
+ }
862
+ /**
863
+ * Import data from persistence
864
+ */
865
+ import(data, merge = false) {
866
+ if (!merge) {
867
+ this.memories.clear();
868
+ this.routingPatterns.clear();
869
+ this.errorPatterns.clear();
870
+ this.coEditPatterns.clear();
871
+ this.agentMappings.clear();
872
+ }
873
+ // Import memories and rebuild HNSW index so recall() returns results (#315)
874
+ if (data.memories) {
875
+ for (const mem of data.memories) {
876
+ this.memories.set(mem.id, mem);
877
+ if (this.vectorDb && mem.embedding?.length) {
878
+ this.vectorDb.insert({
879
+ id: mem.id,
880
+ vector: new Float32Array(mem.embedding),
881
+ metadata: JSON.stringify({ content: mem.content, type: mem.type, created: mem.created }),
882
+ }).catch(() => { });
883
+ }
884
+ }
885
+ }
886
+ // Import routing patterns
887
+ if (data.routingPatterns) {
888
+ for (const [state, actions] of Object.entries(data.routingPatterns)) {
889
+ const map = new Map(Object.entries(actions));
890
+ if (merge && this.routingPatterns.has(state)) {
891
+ const existing = this.routingPatterns.get(state);
892
+ for (const [action, value] of map) {
893
+ existing.set(action, Math.max(existing.get(action) || 0, value));
894
+ }
895
+ }
896
+ else {
897
+ this.routingPatterns.set(state, map);
898
+ }
899
+ }
900
+ }
901
+ // Import error patterns
902
+ if (data.errorPatterns) {
903
+ for (const [pattern, fixes] of Object.entries(data.errorPatterns)) {
904
+ if (merge && this.errorPatterns.has(pattern)) {
905
+ const existing = this.errorPatterns.get(pattern);
906
+ for (const fix of fixes) {
907
+ if (!existing.includes(fix))
908
+ existing.push(fix);
909
+ }
910
+ }
911
+ else {
912
+ this.errorPatterns.set(pattern, fixes);
913
+ }
914
+ }
915
+ }
916
+ // Import co-edit patterns
917
+ if (data.coEditPatterns) {
918
+ for (const [file, related] of Object.entries(data.coEditPatterns)) {
919
+ const map = new Map(Object.entries(related));
920
+ if (merge && this.coEditPatterns.has(file)) {
921
+ const existing = this.coEditPatterns.get(file);
922
+ for (const [f, count] of map) {
923
+ existing.set(f, (existing.get(f) || 0) + count);
924
+ }
925
+ }
926
+ else {
927
+ this.coEditPatterns.set(file, map);
928
+ }
929
+ }
930
+ }
931
+ // Import agent mappings
932
+ if (data.agentMappings) {
933
+ for (const [ext, agent] of Object.entries(data.agentMappings)) {
934
+ this.agentMappings.set(ext, agent);
935
+ }
936
+ }
937
+ // Import worker trigger mappings
938
+ if (data.workerTriggerMappings) {
939
+ for (const [trigger, config] of Object.entries(data.workerTriggerMappings)) {
940
+ const typedConfig = config;
941
+ this.workerTriggerMappings.set(trigger, typedConfig);
942
+ }
943
+ }
944
+ }
945
+ /**
946
+ * Clear all data
947
+ */
948
+ clear() {
949
+ this.memories.clear();
950
+ this.routingPatterns.clear();
951
+ this.errorPatterns.clear();
952
+ this.coEditPatterns.clear();
953
+ this.agentMappings.clear();
954
+ this.workerTriggerMappings.clear();
955
+ this.agentDb.clear();
956
+ }
957
+ // =========================================================================
958
+ // Compatibility with existing Intelligence class
959
+ // =========================================================================
960
+ /** Legacy: patterns object */
961
+ get patterns() {
962
+ const result = {};
963
+ for (const [state, actions] of this.routingPatterns) {
964
+ result[state] = Object.fromEntries(actions);
965
+ }
966
+ return result;
967
+ }
968
+ /** Legacy: file_sequences array */
969
+ get file_sequences() {
970
+ const sequences = [];
971
+ for (const [file, related] of this.coEditPatterns) {
972
+ const sorted = Array.from(related.entries())
973
+ .sort((a, b) => b[1] - a[1])
974
+ .map(([f]) => f);
975
+ if (sorted.length > 0) {
976
+ sequences.push([file, ...sorted.slice(0, 3)]);
977
+ }
978
+ }
979
+ return sequences;
980
+ }
981
+ /** Legacy: errors object */
982
+ get errors() {
983
+ return Object.fromEntries(this.errorPatterns);
984
+ }
985
+ }
986
+ exports.IntelligenceEngine = IntelligenceEngine;
987
+ // ============================================================================
988
+ // Factory Functions
989
+ // ============================================================================
990
+ /**
991
+ * Create a new IntelligenceEngine with default settings
992
+ */
993
+ function createIntelligenceEngine(config) {
994
+ return new IntelligenceEngine(config);
995
+ }
996
+ /**
997
+ * Create a high-performance engine with all features enabled
998
+ */
999
+ function createHighPerformanceEngine() {
1000
+ return new IntelligenceEngine({
1001
+ embeddingDim: 512,
1002
+ maxMemories: 200000,
1003
+ maxEpisodes: 100000,
1004
+ enableSona: true,
1005
+ enableAttention: true,
1006
+ sonaConfig: {
1007
+ hiddenDim: 512,
1008
+ microLoraRank: 2,
1009
+ baseLoraRank: 16,
1010
+ patternClusters: 200,
1011
+ },
1012
+ });
1013
+ }
1014
+ /**
1015
+ * Create a lightweight engine for fast startup
1016
+ */
1017
+ function createLightweightEngine() {
1018
+ return new IntelligenceEngine({
1019
+ embeddingDim: 128,
1020
+ maxMemories: 10000,
1021
+ maxEpisodes: 5000,
1022
+ enableSona: false,
1023
+ enableAttention: false,
1024
+ });
1025
+ }
1026
+ exports.default = IntelligenceEngine;