@sparkleideas/neural 3.5.2-patch.1

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 (122) hide show
  1. package/README.md +260 -0
  2. package/__tests__/README.md +235 -0
  3. package/__tests__/algorithms.test.ts +582 -0
  4. package/__tests__/patterns.test.ts +549 -0
  5. package/__tests__/sona.test.ts +445 -0
  6. package/docs/SONA_INTEGRATION.md +460 -0
  7. package/docs/SONA_QUICKSTART.md +168 -0
  8. package/examples/sona-usage.ts +318 -0
  9. package/package.json +23 -0
  10. package/src/algorithms/a2c.d.ts +86 -0
  11. package/src/algorithms/a2c.d.ts.map +1 -0
  12. package/src/algorithms/a2c.js +361 -0
  13. package/src/algorithms/a2c.js.map +1 -0
  14. package/src/algorithms/a2c.ts +478 -0
  15. package/src/algorithms/curiosity.d.ts +82 -0
  16. package/src/algorithms/curiosity.d.ts.map +1 -0
  17. package/src/algorithms/curiosity.js +392 -0
  18. package/src/algorithms/curiosity.js.map +1 -0
  19. package/src/algorithms/curiosity.ts +509 -0
  20. package/src/algorithms/decision-transformer.d.ts +82 -0
  21. package/src/algorithms/decision-transformer.d.ts.map +1 -0
  22. package/src/algorithms/decision-transformer.js +415 -0
  23. package/src/algorithms/decision-transformer.js.map +1 -0
  24. package/src/algorithms/decision-transformer.ts +521 -0
  25. package/src/algorithms/dqn.d.ts +72 -0
  26. package/src/algorithms/dqn.d.ts.map +1 -0
  27. package/src/algorithms/dqn.js +303 -0
  28. package/src/algorithms/dqn.js.map +1 -0
  29. package/src/algorithms/dqn.ts +382 -0
  30. package/src/algorithms/index.d.ts +32 -0
  31. package/src/algorithms/index.d.ts.map +1 -0
  32. package/src/algorithms/index.js +74 -0
  33. package/src/algorithms/index.js.map +1 -0
  34. package/src/algorithms/index.ts +122 -0
  35. package/src/algorithms/ppo.d.ts +72 -0
  36. package/src/algorithms/ppo.d.ts.map +1 -0
  37. package/src/algorithms/ppo.js +331 -0
  38. package/src/algorithms/ppo.js.map +1 -0
  39. package/src/algorithms/ppo.ts +429 -0
  40. package/src/algorithms/q-learning.d.ts +77 -0
  41. package/src/algorithms/q-learning.d.ts.map +1 -0
  42. package/src/algorithms/q-learning.js +259 -0
  43. package/src/algorithms/q-learning.js.map +1 -0
  44. package/src/algorithms/q-learning.ts +333 -0
  45. package/src/algorithms/sarsa.d.ts +82 -0
  46. package/src/algorithms/sarsa.d.ts.map +1 -0
  47. package/src/algorithms/sarsa.js +297 -0
  48. package/src/algorithms/sarsa.js.map +1 -0
  49. package/src/algorithms/sarsa.ts +383 -0
  50. package/src/algorithms/tmp.json +0 -0
  51. package/src/application/index.ts +11 -0
  52. package/src/application/services/neural-application-service.ts +217 -0
  53. package/src/domain/entities/pattern.ts +169 -0
  54. package/src/domain/index.ts +18 -0
  55. package/src/domain/services/learning-service.ts +256 -0
  56. package/src/index.d.ts +118 -0
  57. package/src/index.d.ts.map +1 -0
  58. package/src/index.js +201 -0
  59. package/src/index.js.map +1 -0
  60. package/src/index.ts +363 -0
  61. package/src/modes/balanced.d.ts +60 -0
  62. package/src/modes/balanced.d.ts.map +1 -0
  63. package/src/modes/balanced.js +234 -0
  64. package/src/modes/balanced.js.map +1 -0
  65. package/src/modes/balanced.ts +299 -0
  66. package/src/modes/base.ts +163 -0
  67. package/src/modes/batch.d.ts +82 -0
  68. package/src/modes/batch.d.ts.map +1 -0
  69. package/src/modes/batch.js +316 -0
  70. package/src/modes/batch.js.map +1 -0
  71. package/src/modes/batch.ts +434 -0
  72. package/src/modes/edge.d.ts +85 -0
  73. package/src/modes/edge.d.ts.map +1 -0
  74. package/src/modes/edge.js +310 -0
  75. package/src/modes/edge.js.map +1 -0
  76. package/src/modes/edge.ts +409 -0
  77. package/src/modes/index.d.ts +55 -0
  78. package/src/modes/index.d.ts.map +1 -0
  79. package/src/modes/index.js +83 -0
  80. package/src/modes/index.js.map +1 -0
  81. package/src/modes/index.ts +16 -0
  82. package/src/modes/real-time.d.ts +58 -0
  83. package/src/modes/real-time.d.ts.map +1 -0
  84. package/src/modes/real-time.js +196 -0
  85. package/src/modes/real-time.js.map +1 -0
  86. package/src/modes/real-time.ts +257 -0
  87. package/src/modes/research.d.ts +79 -0
  88. package/src/modes/research.d.ts.map +1 -0
  89. package/src/modes/research.js +389 -0
  90. package/src/modes/research.js.map +1 -0
  91. package/src/modes/research.ts +486 -0
  92. package/src/modes/tmp.json +0 -0
  93. package/src/pattern-learner.d.ts +117 -0
  94. package/src/pattern-learner.d.ts.map +1 -0
  95. package/src/pattern-learner.js +603 -0
  96. package/src/pattern-learner.js.map +1 -0
  97. package/src/pattern-learner.ts +757 -0
  98. package/src/reasoning-bank.d.ts +259 -0
  99. package/src/reasoning-bank.d.ts.map +1 -0
  100. package/src/reasoning-bank.js +993 -0
  101. package/src/reasoning-bank.js.map +1 -0
  102. package/src/reasoning-bank.ts +1279 -0
  103. package/src/reasoningbank-adapter.ts +697 -0
  104. package/src/sona-integration.d.ts +168 -0
  105. package/src/sona-integration.d.ts.map +1 -0
  106. package/src/sona-integration.js +316 -0
  107. package/src/sona-integration.js.map +1 -0
  108. package/src/sona-integration.ts +432 -0
  109. package/src/sona-manager.d.ts +147 -0
  110. package/src/sona-manager.d.ts.map +1 -0
  111. package/src/sona-manager.js +695 -0
  112. package/src/sona-manager.js.map +1 -0
  113. package/src/sona-manager.ts +835 -0
  114. package/src/tmp.json +0 -0
  115. package/src/types.d.ts +431 -0
  116. package/src/types.d.ts.map +1 -0
  117. package/src/types.js +11 -0
  118. package/src/types.js.map +1 -0
  119. package/src/types.ts +590 -0
  120. package/tmp.json +0 -0
  121. package/tsconfig.json +9 -0
  122. package/vitest.config.ts +19 -0
@@ -0,0 +1,445 @@
1
+ /**
2
+ * SONA Learning Engine Tests
3
+ *
4
+ * Tests for SONA integration with @ruvector/sona package.
5
+ * Covers initialization, learning, adaptation, mode switching, and performance.
6
+ *
7
+ * Performance targets:
8
+ * - learn(): <0.05ms
9
+ * - adapt(): <0.1ms
10
+ * - Full learning cycle: <10ms
11
+ */
12
+
13
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
14
+ import {
15
+ SONALearningEngine,
16
+ createSONALearningEngine,
17
+ type Context,
18
+ type AdaptedBehavior,
19
+ } from '../src/sona-integration.js';
20
+ import type { Trajectory, SONAMode, SONAModeConfig } from '../src/types.js';
21
+
22
+ // Create a reusable mock engine factory
23
+ function createMockEngine() {
24
+ let enabled = true;
25
+ return {
26
+ beginTrajectory: vi.fn().mockReturnValue(1),
27
+ addTrajectoryStep: vi.fn(),
28
+ addTrajectoryContext: vi.fn(),
29
+ endTrajectory: vi.fn(),
30
+ flush: vi.fn(),
31
+ applyMicroLora: vi.fn((arr: number[]) => arr),
32
+ findPatterns: vi.fn().mockReturnValue([
33
+ {
34
+ patternType: 'test-pattern',
35
+ avgQuality: 0.85,
36
+ embedding: new Float32Array(768),
37
+ usageCount: 5,
38
+ },
39
+ ]),
40
+ forceLearn: vi.fn().mockReturnValue('Learning complete'),
41
+ tick: vi.fn().mockReturnValue(null),
42
+ getStats: vi.fn().mockReturnValue(JSON.stringify({
43
+ total_trajectories: 10,
44
+ patterns_learned: 5,
45
+ avg_quality: 0.75,
46
+ })),
47
+ isEnabled: vi.fn(() => enabled),
48
+ setEnabled: vi.fn((value: boolean) => { enabled = value; }),
49
+ };
50
+ }
51
+
52
+ // Mock @ruvector/sona
53
+ vi.mock('@ruvector/sona', () => {
54
+ return {
55
+ SonaEngine: {
56
+ withConfig: vi.fn(() => createMockEngine()),
57
+ },
58
+ };
59
+ });
60
+
61
+ describe('SONALearningEngine', () => {
62
+ let engine: SONALearningEngine;
63
+ let modeConfig: SONAModeConfig;
64
+
65
+ beforeEach(() => {
66
+ modeConfig = {
67
+ mode: 'balanced',
68
+ loraRank: 4,
69
+ learningRate: 0.002,
70
+ batchSize: 32,
71
+ trajectoryCapacity: 3000,
72
+ patternClusters: 50,
73
+ qualityThreshold: 0.5,
74
+ maxLatencyMs: 18,
75
+ memoryBudgetMb: 50,
76
+ ewcLambda: 2000,
77
+ };
78
+ engine = new SONALearningEngine('balanced', modeConfig);
79
+ });
80
+
81
+ describe('Initialization', () => {
82
+ it('should initialize with balanced mode', () => {
83
+ expect(engine).toBeDefined();
84
+ expect(engine.isEnabled()).toBe(true);
85
+ });
86
+
87
+ it('should initialize with real-time mode', () => {
88
+ const rtEngine = createSONALearningEngine('real-time', {
89
+ mode: 'real-time',
90
+ loraRank: 2,
91
+ learningRate: 0.001,
92
+ batchSize: 32,
93
+ trajectoryCapacity: 1000,
94
+ patternClusters: 25,
95
+ qualityThreshold: 0.7,
96
+ maxLatencyMs: 0.5,
97
+ memoryBudgetMb: 25,
98
+ ewcLambda: 2000,
99
+ });
100
+ expect(rtEngine).toBeDefined();
101
+ expect(rtEngine.isEnabled()).toBe(true);
102
+ });
103
+
104
+ it('should initialize with research mode', () => {
105
+ const researchEngine = createSONALearningEngine('research', {
106
+ mode: 'research',
107
+ loraRank: 16,
108
+ learningRate: 0.002,
109
+ batchSize: 64,
110
+ trajectoryCapacity: 10000,
111
+ patternClusters: 100,
112
+ qualityThreshold: 0.2,
113
+ maxLatencyMs: 100,
114
+ memoryBudgetMb: 100,
115
+ ewcLambda: 2500,
116
+ });
117
+ expect(researchEngine).toBeDefined();
118
+ });
119
+
120
+ it('should initialize with edge mode', () => {
121
+ const edgeEngine = createSONALearningEngine('edge', {
122
+ mode: 'edge',
123
+ loraRank: 1,
124
+ learningRate: 0.001,
125
+ batchSize: 16,
126
+ trajectoryCapacity: 200,
127
+ patternClusters: 15,
128
+ qualityThreshold: 0.8,
129
+ maxLatencyMs: 1,
130
+ memoryBudgetMb: 5,
131
+ ewcLambda: 1500,
132
+ });
133
+ expect(edgeEngine).toBeDefined();
134
+ });
135
+
136
+ it('should initialize with batch mode', () => {
137
+ const batchEngine = createSONALearningEngine('batch', {
138
+ mode: 'batch',
139
+ loraRank: 8,
140
+ learningRate: 0.002,
141
+ batchSize: 128,
142
+ trajectoryCapacity: 5000,
143
+ patternClusters: 75,
144
+ qualityThreshold: 0.4,
145
+ maxLatencyMs: 50,
146
+ memoryBudgetMb: 75,
147
+ ewcLambda: 2000,
148
+ });
149
+ expect(batchEngine).toBeDefined();
150
+ });
151
+ });
152
+
153
+ describe('Learning from Trajectories', () => {
154
+ it('should learn from a complete trajectory', async () => {
155
+ const trajectory: Trajectory = {
156
+ trajectoryId: 'test-traj-1',
157
+ context: 'Test task',
158
+ domain: 'code',
159
+ steps: [
160
+ {
161
+ stepId: 'step-1',
162
+ timestamp: Date.now(),
163
+ action: 'analyze',
164
+ stateBefore: new Float32Array(768).fill(0.1),
165
+ stateAfter: new Float32Array(768).fill(0.2),
166
+ reward: 0.8,
167
+ },
168
+ {
169
+ stepId: 'step-2',
170
+ timestamp: Date.now(),
171
+ action: 'implement',
172
+ stateBefore: new Float32Array(768).fill(0.2),
173
+ stateAfter: new Float32Array(768).fill(0.3),
174
+ reward: 0.9,
175
+ },
176
+ ],
177
+ qualityScore: 0.85,
178
+ isComplete: true,
179
+ startTime: Date.now() - 1000,
180
+ endTime: Date.now(),
181
+ };
182
+
183
+ await expect(engine.learn(trajectory)).resolves.not.toThrow();
184
+ });
185
+
186
+ it('should complete learning under performance target (<0.05ms)', async () => {
187
+ const trajectory: Trajectory = {
188
+ trajectoryId: 'perf-test',
189
+ context: 'Performance test',
190
+ domain: 'code',
191
+ steps: [
192
+ {
193
+ stepId: 'step-1',
194
+ timestamp: Date.now(),
195
+ action: 'test',
196
+ stateBefore: new Float32Array(768).fill(0.5),
197
+ stateAfter: new Float32Array(768).fill(0.6),
198
+ reward: 0.7,
199
+ },
200
+ ],
201
+ qualityScore: 0.7,
202
+ isComplete: true,
203
+ startTime: Date.now(),
204
+ };
205
+
206
+ const startTime = performance.now();
207
+ await engine.learn(trajectory);
208
+ const elapsed = performance.now() - startTime;
209
+
210
+ // Note: This is the JS call overhead, actual SONA is <0.05ms
211
+ expect(elapsed).toBeLessThan(10); // Allow overhead for mocking
212
+ expect(engine.getLearningTime()).toBeDefined();
213
+ });
214
+
215
+ it('should handle empty trajectories gracefully', async () => {
216
+ const emptyTrajectory: Trajectory = {
217
+ trajectoryId: 'empty-traj',
218
+ context: 'Empty test',
219
+ domain: 'general',
220
+ steps: [],
221
+ qualityScore: 0,
222
+ isComplete: true,
223
+ startTime: Date.now(),
224
+ };
225
+
226
+ await expect(engine.learn(emptyTrajectory)).resolves.not.toThrow();
227
+ });
228
+
229
+ it('should learn from multi-step trajectories', async () => {
230
+ const multiStepTrajectory: Trajectory = {
231
+ trajectoryId: 'multi-step',
232
+ context: 'Complex task',
233
+ domain: 'reasoning',
234
+ steps: Array.from({ length: 10 }, (_, i) => ({
235
+ stepId: `step-${i}`,
236
+ timestamp: Date.now() + i * 100,
237
+ action: `action-${i}`,
238
+ stateBefore: new Float32Array(768).fill(i * 0.1),
239
+ stateAfter: new Float32Array(768).fill((i + 1) * 0.1),
240
+ reward: 0.5 + i * 0.05,
241
+ })),
242
+ qualityScore: 0.9,
243
+ isComplete: true,
244
+ startTime: Date.now(),
245
+ endTime: Date.now() + 1000,
246
+ };
247
+
248
+ await expect(engine.learn(multiStepTrajectory)).resolves.not.toThrow();
249
+ });
250
+ });
251
+
252
+ describe('Adaptation', () => {
253
+ it('should adapt behavior based on context', async () => {
254
+ const context: Context = {
255
+ domain: 'code',
256
+ queryEmbedding: new Float32Array(768).fill(0.5),
257
+ metadata: { task: 'implementation' },
258
+ };
259
+
260
+ const result = await engine.adapt(context);
261
+
262
+ expect(result).toBeDefined();
263
+ expect(result.transformedQuery).toBeInstanceOf(Float32Array);
264
+ expect(result.patterns).toBeDefined();
265
+ expect(result.confidence).toBeGreaterThanOrEqual(0);
266
+ expect(result.confidence).toBeLessThanOrEqual(1);
267
+ });
268
+
269
+ it('should complete adaptation under performance target (<0.1ms)', async () => {
270
+ const context: Context = {
271
+ domain: 'code',
272
+ queryEmbedding: new Float32Array(768).fill(0.5),
273
+ };
274
+
275
+ const startTime = performance.now();
276
+ await engine.adapt(context);
277
+ const elapsed = performance.now() - startTime;
278
+
279
+ expect(elapsed).toBeLessThan(10); // Allow overhead for mocking
280
+ expect(engine.getAdaptationTime()).toBeDefined();
281
+ });
282
+
283
+ it('should find similar patterns during adaptation', async () => {
284
+ const context: Context = {
285
+ domain: 'code',
286
+ queryEmbedding: new Float32Array(768).fill(0.7),
287
+ };
288
+
289
+ const result = await engine.adapt(context);
290
+
291
+ expect(result.patterns).toHaveLength(1);
292
+ expect(result.patterns[0].patternType).toBe('test-pattern');
293
+ expect(result.patterns[0].avgQuality).toBeCloseTo(0.85);
294
+ });
295
+
296
+ it('should infer suggested route from patterns', async () => {
297
+ const context: Context = {
298
+ domain: 'creative',
299
+ queryEmbedding: new Float32Array(768).fill(0.3),
300
+ };
301
+
302
+ const result = await engine.adapt(context);
303
+
304
+ expect(result.suggestedRoute).toBeDefined();
305
+ expect(typeof result.suggestedRoute).toBe('string');
306
+ });
307
+
308
+ it('should handle adaptation with no patterns found', async () => {
309
+ const { SonaEngine } = await import('@ruvector/sona');
310
+ // Create a complete mock with findPatterns returning empty array
311
+ const emptyPatternsEngine = {
312
+ beginTrajectory: vi.fn().mockReturnValue(1),
313
+ addTrajectoryStep: vi.fn(),
314
+ addTrajectoryContext: vi.fn(),
315
+ endTrajectory: vi.fn(),
316
+ flush: vi.fn(),
317
+ applyMicroLora: vi.fn((arr: number[]) => arr),
318
+ findPatterns: vi.fn().mockReturnValue([]),
319
+ forceLearn: vi.fn().mockReturnValue('Learning complete'),
320
+ tick: vi.fn().mockReturnValue(null),
321
+ getStats: vi.fn().mockReturnValue(JSON.stringify({
322
+ total_trajectories: 0,
323
+ patterns_learned: 0,
324
+ avg_quality: 0,
325
+ })),
326
+ isEnabled: vi.fn().mockReturnValue(true),
327
+ setEnabled: vi.fn(),
328
+ };
329
+ vi.mocked(SonaEngine.withConfig).mockReturnValueOnce(emptyPatternsEngine as any);
330
+
331
+ const freshEngine = new SONALearningEngine('balanced', modeConfig);
332
+ const context: Context = {
333
+ domain: 'code',
334
+ queryEmbedding: new Float32Array(768).fill(0.5),
335
+ };
336
+
337
+ const result = await freshEngine.adapt(context);
338
+
339
+ expect(result.patterns).toHaveLength(0);
340
+ expect(result.confidence).toBeCloseTo(0.5); // Default confidence
341
+ });
342
+ });
343
+
344
+ describe('Mode Switching', () => {
345
+ it('should switch between modes correctly', () => {
346
+ const modes: SONAMode[] = ['real-time', 'balanced', 'research', 'edge', 'batch'];
347
+
348
+ modes.forEach(mode => {
349
+ const testEngine = createSONALearningEngine(mode, {
350
+ mode,
351
+ loraRank: 4,
352
+ learningRate: 0.002,
353
+ batchSize: 32,
354
+ trajectoryCapacity: 3000,
355
+ patternClusters: 50,
356
+ qualityThreshold: 0.5,
357
+ maxLatencyMs: 18,
358
+ memoryBudgetMb: 50,
359
+ ewcLambda: 2000,
360
+ });
361
+ expect(testEngine).toBeDefined();
362
+ });
363
+ });
364
+
365
+ it('should reset learning state', () => {
366
+ expect(() => engine.resetLearning()).not.toThrow();
367
+ expect(engine.getLearningTime()).toBe(0);
368
+ expect(engine.getAdaptationTime()).toBe(0);
369
+ });
370
+ });
371
+
372
+ describe('Statistics and Monitoring', () => {
373
+ it('should return engine statistics', () => {
374
+ const stats = engine.getStats();
375
+
376
+ expect(stats).toBeDefined();
377
+ expect(stats.totalTrajectories).toBe(10);
378
+ expect(stats.patternsLearned).toBe(5);
379
+ expect(stats.avgQuality).toBeCloseTo(0.75);
380
+ expect(stats.enabled).toBe(true);
381
+ });
382
+
383
+ it('should track learning time', async () => {
384
+ const trajectory: Trajectory = {
385
+ trajectoryId: 'timing-test',
386
+ context: 'Timing test',
387
+ domain: 'code',
388
+ steps: [
389
+ {
390
+ stepId: 'step-1',
391
+ timestamp: Date.now(),
392
+ action: 'test',
393
+ stateBefore: new Float32Array(768).fill(0.5),
394
+ stateAfter: new Float32Array(768).fill(0.6),
395
+ reward: 0.7,
396
+ },
397
+ ],
398
+ qualityScore: 0.7,
399
+ isComplete: true,
400
+ startTime: Date.now(),
401
+ };
402
+
403
+ await engine.learn(trajectory);
404
+ expect(engine.getLearningTime()).toBeGreaterThan(0);
405
+ });
406
+
407
+ it('should track adaptation time', async () => {
408
+ const context: Context = {
409
+ domain: 'code',
410
+ queryEmbedding: new Float32Array(768).fill(0.5),
411
+ };
412
+
413
+ await engine.adapt(context);
414
+ expect(engine.getAdaptationTime()).toBeGreaterThan(0);
415
+ });
416
+ });
417
+
418
+ describe('Engine Control', () => {
419
+ it('should enable and disable engine', () => {
420
+ engine.setEnabled(false);
421
+ expect(engine.isEnabled()).toBe(false);
422
+
423
+ engine.setEnabled(true);
424
+ expect(engine.isEnabled()).toBe(true);
425
+ });
426
+
427
+ it('should force immediate learning', () => {
428
+ const result = engine.forceLearning();
429
+ expect(result).toBe('Learning complete');
430
+ });
431
+
432
+ it('should tick background learning', () => {
433
+ const result = engine.tick();
434
+ expect(result).toBeNull(); // No learning needed yet
435
+ });
436
+
437
+ it('should find patterns by query embedding', () => {
438
+ const queryEmbedding = new Float32Array(768).fill(0.5);
439
+ const patterns = engine.findPatterns(queryEmbedding, 5);
440
+
441
+ expect(patterns).toBeDefined();
442
+ expect(Array.isArray(patterns)).toBe(true);
443
+ });
444
+ });
445
+ });