@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,549 @@
1
+ /**
2
+ * Pattern Learning and ReasoningBank Tests
3
+ *
4
+ * Tests for pattern extraction, memory distillation, and trajectory tracking:
5
+ * - Pattern extraction from trajectories
6
+ * - Memory distillation (4-step pipeline)
7
+ * - Trajectory tracking and judgment
8
+ * - Pattern evolution and consolidation
9
+ *
10
+ * Performance target: <10ms for learning operations
11
+ */
12
+
13
+ import { describe, it, expect, beforeEach } from 'vitest';
14
+ import {
15
+ ReasoningBank,
16
+ createReasoningBank,
17
+ type RetrievalResult,
18
+ type ConsolidationResult,
19
+ } from '../src/reasoning-bank.js';
20
+ import type {
21
+ Trajectory,
22
+ TrajectoryVerdict,
23
+ DistilledMemory,
24
+ Pattern,
25
+ } from '../src/types.js';
26
+
27
+ // Helper function to create test trajectories
28
+ function createTestTrajectory(
29
+ quality: number = 0.75,
30
+ domain: 'code' | 'creative' | 'reasoning' | 'chat' | 'math' | 'general' = 'code',
31
+ steps: number = 5
32
+ ): Trajectory {
33
+ return {
34
+ trajectoryId: `test-traj-${Date.now()}-${Math.random()}`,
35
+ context: `Test task for ${domain}`,
36
+ domain,
37
+ steps: Array.from({ length: steps }, (_, i) => ({
38
+ stepId: `step-${i}`,
39
+ timestamp: Date.now() + i * 100,
40
+ action: `action-${i}`,
41
+ stateBefore: new Float32Array(768).fill(i * 0.1),
42
+ stateAfter: new Float32Array(768).fill((i + 1) * 0.1),
43
+ reward: 0.5 + (i / steps) * (quality - 0.5) * 2,
44
+ })),
45
+ qualityScore: quality,
46
+ isComplete: true,
47
+ startTime: Date.now() - 1000,
48
+ endTime: Date.now(),
49
+ };
50
+ }
51
+
52
+ describe('ReasoningBank - Pattern Extraction', () => {
53
+ let bank: ReasoningBank;
54
+
55
+ beforeEach(() => {
56
+ bank = createReasoningBank({
57
+ maxTrajectories: 1000,
58
+ distillationThreshold: 0.6,
59
+ retrievalK: 3,
60
+ mmrLambda: 0.7,
61
+ });
62
+ });
63
+
64
+ it('should initialize correctly', () => {
65
+ expect(bank).toBeDefined();
66
+ const stats = bank.getStats();
67
+ expect(stats.trajectoryCount).toBe(0);
68
+ expect(stats.memoryCount).toBe(0);
69
+ expect(stats.patternCount).toBe(0);
70
+ });
71
+
72
+ it('should store trajectories', () => {
73
+ const trajectory = createTestTrajectory(0.8);
74
+ bank.storeTrajectory(trajectory);
75
+
76
+ const stats = bank.getStats();
77
+ expect(stats.trajectoryCount).toBe(1);
78
+
79
+ const retrieved = bank.getTrajectory(trajectory.trajectoryId);
80
+ expect(retrieved).toBeDefined();
81
+ expect(retrieved?.trajectoryId).toBe(trajectory.trajectoryId);
82
+ });
83
+
84
+ it('should retrieve all trajectories', () => {
85
+ for (let i = 0; i < 5; i++) {
86
+ bank.storeTrajectory(createTestTrajectory(0.7 + i * 0.05));
87
+ }
88
+
89
+ const trajectories = bank.getTrajectories();
90
+ expect(trajectories).toHaveLength(5);
91
+ });
92
+
93
+ it('should judge successful trajectories correctly', async () => {
94
+ const trajectory = createTestTrajectory(0.85, 'code', 10);
95
+ const verdict = await bank.judge(trajectory);
96
+
97
+ expect(verdict).toBeDefined();
98
+ expect(verdict.success).toBe(true);
99
+ expect(verdict.confidence).toBeGreaterThan(0);
100
+ expect(verdict.strengths).toBeDefined();
101
+ expect(verdict.weaknesses).toBeDefined();
102
+ expect(verdict.improvements).toBeDefined();
103
+ });
104
+
105
+ it('should judge failed trajectories correctly', async () => {
106
+ const trajectory = createTestTrajectory(0.3, 'code', 10);
107
+ const verdict = await bank.judge(trajectory);
108
+
109
+ expect(verdict.success).toBe(false);
110
+ expect(verdict.weaknesses.length).toBeGreaterThan(0);
111
+ });
112
+
113
+ it('should identify strengths in high-quality trajectories', async () => {
114
+ const trajectory = createTestTrajectory(0.95, 'code', 8);
115
+ const verdict = await bank.judge(trajectory);
116
+
117
+ expect(verdict.strengths.length).toBeGreaterThan(0);
118
+ expect(verdict.strengths.some(s => s.includes('quality'))).toBe(true);
119
+ });
120
+
121
+ it('should identify weaknesses in low-quality trajectories', async () => {
122
+ const trajectory = createTestTrajectory(0.2, 'code', 15);
123
+ const verdict = await bank.judge(trajectory);
124
+
125
+ expect(verdict.weaknesses.length).toBeGreaterThan(0);
126
+ });
127
+
128
+ it('should generate improvement suggestions', async () => {
129
+ const trajectory = createTestTrajectory(0.4, 'code', 12);
130
+ const verdict = await bank.judge(trajectory);
131
+
132
+ expect(verdict.improvements).toBeDefined();
133
+ if (verdict.weaknesses.length > 0) {
134
+ expect(verdict.improvements.length).toBeGreaterThan(0);
135
+ }
136
+ });
137
+
138
+ it('should throw on judging incomplete trajectory', async () => {
139
+ const incompleteTrajectory: Trajectory = {
140
+ ...createTestTrajectory(0.8),
141
+ isComplete: false,
142
+ };
143
+
144
+ await expect(bank.judge(incompleteTrajectory)).rejects.toThrow('incomplete');
145
+ });
146
+ });
147
+
148
+ describe('ReasoningBank - Memory Distillation', () => {
149
+ let bank: ReasoningBank;
150
+
151
+ beforeEach(() => {
152
+ bank = createReasoningBank({
153
+ distillationThreshold: 0.6,
154
+ });
155
+ });
156
+
157
+ it('should distill successful trajectories', async () => {
158
+ const trajectory = createTestTrajectory(0.8);
159
+ const memory = await bank.distill(trajectory);
160
+
161
+ expect(memory).toBeDefined();
162
+ expect(memory?.memoryId).toBeDefined();
163
+ expect(memory?.strategy).toBeDefined();
164
+ expect(memory?.keyLearnings).toBeDefined();
165
+ expect(memory?.embedding).toBeInstanceOf(Float32Array);
166
+ expect(memory?.quality).toBeCloseTo(0.8);
167
+ });
168
+
169
+ it('should not distill low-quality trajectories', async () => {
170
+ const trajectory = createTestTrajectory(0.3);
171
+ const memory = await bank.distill(trajectory);
172
+
173
+ expect(memory).toBeNull();
174
+ });
175
+
176
+ it('should automatically judge before distillation', async () => {
177
+ const trajectory = createTestTrajectory(0.85);
178
+ expect(trajectory.verdict).toBeUndefined();
179
+
180
+ const memory = await bank.distill(trajectory);
181
+
182
+ expect(trajectory.verdict).toBeDefined();
183
+ expect(memory).not.toBeNull();
184
+ });
185
+
186
+ it('should extract meaningful strategy', async () => {
187
+ const trajectory = createTestTrajectory(0.9, 'code', 8);
188
+ const memory = await bank.distill(trajectory);
189
+
190
+ expect(memory).not.toBeNull();
191
+ expect(memory!.strategy).toBeTruthy();
192
+ expect(typeof memory!.strategy).toBe('string');
193
+ });
194
+
195
+ it('should extract key learnings', async () => {
196
+ const trajectory = createTestTrajectory(0.85, 'reasoning', 10);
197
+ const memory = await bank.distill(trajectory);
198
+
199
+ expect(memory).not.toBeNull();
200
+ expect(memory!.keyLearnings).toBeDefined();
201
+ expect(Array.isArray(memory!.keyLearnings)).toBe(true);
202
+ expect(memory!.keyLearnings.length).toBeGreaterThan(0);
203
+ });
204
+
205
+ it('should compute aggregate embedding', async () => {
206
+ const trajectory = createTestTrajectory(0.8, 'code', 10);
207
+ const memory = await bank.distill(trajectory);
208
+
209
+ expect(memory).not.toBeNull();
210
+ expect(memory!.embedding).toBeInstanceOf(Float32Array);
211
+ expect(memory!.embedding.length).toBe(768);
212
+ });
213
+
214
+ it('should track distillation performance', async () => {
215
+ const trajectory = createTestTrajectory(0.8);
216
+ await bank.distill(trajectory);
217
+
218
+ const stats = bank.getStats();
219
+ expect(stats.avgDistillationTimeMs).toBeGreaterThanOrEqual(0);
220
+ });
221
+
222
+ it('should link distilled memory to trajectory', async () => {
223
+ const trajectory = createTestTrajectory(0.9);
224
+ const memory = await bank.distill(trajectory);
225
+
226
+ expect(trajectory.distilledMemory).toBeDefined();
227
+ expect(trajectory.distilledMemory?.memoryId).toBe(memory?.memoryId);
228
+ });
229
+ });
230
+
231
+ describe('ReasoningBank - Retrieval (MMR)', () => {
232
+ let bank: ReasoningBank;
233
+
234
+ beforeEach(async () => {
235
+ bank = createReasoningBank({
236
+ retrievalK: 3,
237
+ mmrLambda: 0.7,
238
+ });
239
+
240
+ // Add some diverse memories
241
+ for (let i = 0; i < 10; i++) {
242
+ const trajectory = createTestTrajectory(0.7 + i * 0.02, 'code', 8);
243
+ await bank.distill(trajectory);
244
+ }
245
+ });
246
+
247
+ it('should retrieve top-k similar memories', async () => {
248
+ const queryEmbedding = new Float32Array(768).fill(0.5);
249
+ const results = await bank.retrieve(queryEmbedding, 3);
250
+
251
+ expect(results).toBeDefined();
252
+ expect(results.length).toBeLessThanOrEqual(3);
253
+ });
254
+
255
+ it('should apply MMR for diversity', async () => {
256
+ const queryEmbedding = new Float32Array(768).fill(0.5);
257
+ const results = await bank.retrieve(queryEmbedding, 5);
258
+
259
+ // Check that results have diversity scores
260
+ for (const result of results) {
261
+ expect(result.relevanceScore).toBeGreaterThanOrEqual(0);
262
+ expect(result.diversityScore).toBeGreaterThanOrEqual(0);
263
+ expect(result.combinedScore).toBeDefined();
264
+ }
265
+ });
266
+
267
+ it('should return retrieval results with proper structure', async () => {
268
+ const queryEmbedding = new Float32Array(768).fill(0.3);
269
+ const results = await bank.retrieve(queryEmbedding);
270
+
271
+ for (const result of results) {
272
+ expect(result.memory).toBeDefined();
273
+ expect(result.memory.memoryId).toBeTruthy();
274
+ expect(result.relevanceScore).toBeGreaterThanOrEqual(0);
275
+ expect(result.relevanceScore).toBeLessThanOrEqual(1);
276
+ }
277
+ });
278
+
279
+ it('should track retrieval performance', async () => {
280
+ const queryEmbedding = new Float32Array(768).fill(0.5);
281
+ await bank.retrieve(queryEmbedding);
282
+
283
+ const stats = bank.getStats();
284
+ expect(stats.avgRetrievalTimeMs).toBeGreaterThanOrEqual(0);
285
+ });
286
+
287
+ it('should handle retrieval with no memories', async () => {
288
+ const emptyBank = createReasoningBank();
289
+ const queryEmbedding = new Float32Array(768).fill(0.5);
290
+ const results = await emptyBank.retrieve(queryEmbedding);
291
+
292
+ expect(results).toHaveLength(0);
293
+ });
294
+
295
+ it('should respect retrieval k parameter', async () => {
296
+ const queryEmbedding = new Float32Array(768).fill(0.5);
297
+ const results = await bank.retrieve(queryEmbedding, 2);
298
+
299
+ expect(results.length).toBeLessThanOrEqual(2);
300
+ });
301
+ });
302
+
303
+ describe('ReasoningBank - Consolidation', () => {
304
+ let bank: ReasoningBank;
305
+
306
+ beforeEach(async () => {
307
+ bank = createReasoningBank({
308
+ dedupThreshold: 0.95,
309
+ enableContradictionDetection: true,
310
+ maxPatternAgeDays: 30,
311
+ });
312
+ });
313
+
314
+ it('should deduplicate similar memories', async () => {
315
+ // Add very similar trajectories
316
+ for (let i = 0; i < 5; i++) {
317
+ const trajectory = createTestTrajectory(0.8, 'code', 5);
318
+ await bank.distill(trajectory);
319
+ }
320
+
321
+ const beforeStats = bank.getStats();
322
+ const result = await bank.consolidate();
323
+
324
+ expect(result.removedDuplicates).toBeGreaterThanOrEqual(0);
325
+ });
326
+
327
+ it('should detect contradictions', async () => {
328
+ // Add similar contexts with different outcomes
329
+ const highQualityTraj = createTestTrajectory(0.95, 'code', 5);
330
+ const lowQualityTraj = createTestTrajectory(0.2, 'code', 5);
331
+
332
+ await bank.distill(highQualityTraj);
333
+ await bank.distill(lowQualityTraj);
334
+
335
+ const result = await bank.consolidate();
336
+
337
+ expect(result.contradictionsDetected).toBeGreaterThanOrEqual(0);
338
+ });
339
+
340
+ it('should merge similar patterns', async () => {
341
+ // Create some patterns first
342
+ for (let i = 0; i < 5; i++) {
343
+ const trajectory = createTestTrajectory(0.75, 'code', 5);
344
+ const memory = await bank.distill(trajectory);
345
+ if (memory) {
346
+ bank.memoryToPattern(memory);
347
+ }
348
+ }
349
+
350
+ const result = await bank.consolidate();
351
+ expect(result.mergedPatterns).toBeGreaterThanOrEqual(0);
352
+ });
353
+
354
+ it('should prune old patterns', async () => {
355
+ const result = await bank.consolidate();
356
+ expect(result.prunedPatterns).toBeGreaterThanOrEqual(0);
357
+ });
358
+
359
+ it('should return consolidation result', async () => {
360
+ const result = await bank.consolidate();
361
+
362
+ expect(result).toBeDefined();
363
+ expect(result.removedDuplicates).toBeGreaterThanOrEqual(0);
364
+ expect(result.contradictionsDetected).toBeGreaterThanOrEqual(0);
365
+ expect(result.prunedPatterns).toBeGreaterThanOrEqual(0);
366
+ expect(result.mergedPatterns).toBeGreaterThanOrEqual(0);
367
+ });
368
+
369
+ it('should emit consolidation event', async () => {
370
+ let eventEmitted = false;
371
+ bank.addEventListener((event) => {
372
+ if (event.type === 'memory_consolidated') {
373
+ eventEmitted = true;
374
+ }
375
+ });
376
+
377
+ await bank.consolidate();
378
+ expect(eventEmitted).toBe(true);
379
+ });
380
+ });
381
+
382
+ describe('Pattern Management', () => {
383
+ let bank: ReasoningBank;
384
+
385
+ beforeEach(() => {
386
+ bank = createReasoningBank();
387
+ });
388
+
389
+ it('should convert memory to pattern', async () => {
390
+ const trajectory = createTestTrajectory(0.85, 'code', 8);
391
+ const memory = await bank.distill(trajectory);
392
+
393
+ expect(memory).not.toBeNull();
394
+ const pattern = bank.memoryToPattern(memory!);
395
+
396
+ expect(pattern).toBeDefined();
397
+ expect(pattern.patternId).toBeTruthy();
398
+ expect(pattern.name).toBeTruthy();
399
+ expect(pattern.domain).toBe('code');
400
+ expect(pattern.strategy).toBe(memory!.strategy);
401
+ expect(pattern.successRate).toBe(memory!.quality);
402
+ });
403
+
404
+ it('should evolve pattern based on new experience', async () => {
405
+ const trajectory1 = createTestTrajectory(0.8, 'code', 5);
406
+ const memory = await bank.distill(trajectory1);
407
+ const pattern = bank.memoryToPattern(memory!);
408
+
409
+ const trajectory2 = createTestTrajectory(0.9, 'code', 5);
410
+ bank.evolvePattern(pattern.patternId, trajectory2);
411
+
412
+ const patterns = bank.getPatterns();
413
+ const evolvedPattern = patterns.find(p => p.patternId === pattern.patternId);
414
+
415
+ expect(evolvedPattern).toBeDefined();
416
+ expect(evolvedPattern!.usageCount).toBe(1);
417
+ expect(evolvedPattern!.qualityHistory.length).toBeGreaterThan(1);
418
+ expect(evolvedPattern!.evolutionHistory.length).toBeGreaterThan(0);
419
+ });
420
+
421
+ it('should track pattern usage', async () => {
422
+ const trajectory = createTestTrajectory(0.85, 'code', 5);
423
+ const memory = await bank.distill(trajectory);
424
+ const pattern = bank.memoryToPattern(memory!);
425
+
426
+ // Evolve multiple times
427
+ for (let i = 0; i < 3; i++) {
428
+ const newTraj = createTestTrajectory(0.7 + i * 0.05, 'code', 5);
429
+ bank.evolvePattern(pattern.patternId, newTraj);
430
+ }
431
+
432
+ const patterns = bank.getPatterns();
433
+ const usedPattern = patterns.find(p => p.patternId === pattern.patternId);
434
+
435
+ expect(usedPattern!.usageCount).toBe(3);
436
+ });
437
+
438
+ it('should update success rate on evolution', async () => {
439
+ const trajectory1 = createTestTrajectory(0.7, 'code', 5);
440
+ const memory = await bank.distill(trajectory1);
441
+ const pattern = bank.memoryToPattern(memory!);
442
+
443
+ const initialSuccessRate = pattern.successRate;
444
+
445
+ const trajectory2 = createTestTrajectory(0.9, 'code', 5);
446
+ bank.evolvePattern(pattern.patternId, trajectory2);
447
+
448
+ const patterns = bank.getPatterns();
449
+ const evolvedPattern = patterns.find(p => p.patternId === pattern.patternId);
450
+
451
+ expect(evolvedPattern!.successRate).not.toBe(initialSuccessRate);
452
+ });
453
+
454
+ it('should maintain quality history (max 100)', async () => {
455
+ const trajectory = createTestTrajectory(0.8, 'code', 5);
456
+ const memory = await bank.distill(trajectory);
457
+ const pattern = bank.memoryToPattern(memory!);
458
+
459
+ // Evolve many times
460
+ for (let i = 0; i < 150; i++) {
461
+ const newTraj = createTestTrajectory(0.6 + (i % 40) * 0.01, 'code', 3);
462
+ bank.evolvePattern(pattern.patternId, newTraj);
463
+ }
464
+
465
+ const patterns = bank.getPatterns();
466
+ const evolvedPattern = patterns.find(p => p.patternId === pattern.patternId);
467
+
468
+ expect(evolvedPattern!.qualityHistory.length).toBeLessThanOrEqual(100);
469
+ });
470
+
471
+ it('should emit pattern evolution event', async () => {
472
+ let eventEmitted = false;
473
+ bank.addEventListener((event) => {
474
+ if (event.type === 'pattern_evolved') {
475
+ eventEmitted = true;
476
+ }
477
+ });
478
+
479
+ const trajectory1 = createTestTrajectory(0.8, 'code', 5);
480
+ const memory = await bank.distill(trajectory1);
481
+ const pattern = bank.memoryToPattern(memory!);
482
+
483
+ const trajectory2 = createTestTrajectory(0.85, 'code', 5);
484
+ bank.evolvePattern(pattern.patternId, trajectory2);
485
+
486
+ expect(eventEmitted).toBe(true);
487
+ });
488
+
489
+ it('should get all patterns', async () => {
490
+ for (let i = 0; i < 5; i++) {
491
+ const trajectory = createTestTrajectory(0.75 + i * 0.02, 'code', 5);
492
+ const memory = await bank.distill(trajectory);
493
+ if (memory) {
494
+ bank.memoryToPattern(memory);
495
+ }
496
+ }
497
+
498
+ const patterns = bank.getPatterns();
499
+ expect(patterns.length).toBeGreaterThan(0);
500
+ });
501
+ });
502
+
503
+ describe('Event System', () => {
504
+ let bank: ReasoningBank;
505
+
506
+ beforeEach(() => {
507
+ bank = createReasoningBank();
508
+ });
509
+
510
+ it('should add and remove event listeners', () => {
511
+ const listener = () => {};
512
+
513
+ expect(() => bank.addEventListener(listener)).not.toThrow();
514
+ expect(() => bank.removeEventListener(listener)).not.toThrow();
515
+ });
516
+
517
+ it('should emit consolidation events', async () => {
518
+ let eventReceived = false;
519
+
520
+ bank.addEventListener((event) => {
521
+ if (event.type === 'memory_consolidated') {
522
+ eventReceived = true;
523
+ }
524
+ });
525
+
526
+ await bank.consolidate();
527
+ expect(eventReceived).toBe(true);
528
+ });
529
+
530
+ it('should emit pattern evolution events', async () => {
531
+ let evolutionEvent: any = null;
532
+
533
+ bank.addEventListener((event) => {
534
+ if (event.type === 'pattern_evolved') {
535
+ evolutionEvent = event;
536
+ }
537
+ });
538
+
539
+ const trajectory1 = createTestTrajectory(0.8, 'code', 5);
540
+ const memory = await bank.distill(trajectory1);
541
+ const pattern = bank.memoryToPattern(memory!);
542
+
543
+ const trajectory2 = createTestTrajectory(0.9, 'code', 5);
544
+ bank.evolvePattern(pattern.patternId, trajectory2);
545
+
546
+ expect(evolutionEvent).not.toBeNull();
547
+ expect(evolutionEvent.patternId).toBe(pattern.patternId);
548
+ });
549
+ });