@claude-flow/memory 3.0.0-alpha.9 → 3.0.0

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 (184) hide show
  1. package/README.md +308 -37
  2. package/dist/agent-memory-scope.d.ts.map +1 -1
  3. package/dist/agent-memory-scope.js +10 -2
  4. package/dist/agent-memory-scope.js.map +1 -1
  5. package/dist/agentdb-adapter-key-isolation.test.d.ts +2 -0
  6. package/dist/agentdb-adapter-key-isolation.test.d.ts.map +1 -0
  7. package/dist/agentdb-adapter-key-isolation.test.js +175 -0
  8. package/dist/agentdb-adapter-key-isolation.test.js.map +1 -0
  9. package/dist/agentdb-adapter-upsert.test.d.ts +2 -0
  10. package/dist/agentdb-adapter-upsert.test.d.ts.map +1 -0
  11. package/dist/agentdb-adapter-upsert.test.js +216 -0
  12. package/dist/agentdb-adapter-upsert.test.js.map +1 -0
  13. package/dist/agentdb-adapter.d.ts +70 -1
  14. package/dist/agentdb-adapter.d.ts.map +1 -1
  15. package/dist/agentdb-adapter.js +365 -32
  16. package/dist/agentdb-adapter.js.map +1 -1
  17. package/dist/agentdb-backend.d.ts +25 -0
  18. package/dist/agentdb-backend.d.ts.map +1 -1
  19. package/dist/agentdb-backend.js +113 -28
  20. package/dist/agentdb-backend.js.map +1 -1
  21. package/dist/agentdb-retrieval-guard.d.ts +76 -0
  22. package/dist/agentdb-retrieval-guard.d.ts.map +1 -0
  23. package/dist/agentdb-retrieval-guard.js +77 -0
  24. package/dist/agentdb-retrieval-guard.js.map +1 -0
  25. package/dist/agentdb-retrieval-guard.test.d.ts +12 -0
  26. package/dist/agentdb-retrieval-guard.test.d.ts.map +1 -0
  27. package/dist/agentdb-retrieval-guard.test.js +129 -0
  28. package/dist/agentdb-retrieval-guard.test.js.map +1 -0
  29. package/dist/auto-memory-bridge.d.ts +12 -1
  30. package/dist/auto-memory-bridge.d.ts.map +1 -1
  31. package/dist/auto-memory-bridge.js +101 -7
  32. package/dist/auto-memory-bridge.js.map +1 -1
  33. package/dist/auto-memory-bridge.test.js +121 -15
  34. package/dist/auto-memory-bridge.test.js.map +1 -1
  35. package/dist/auto-memory-index-3224.test.d.ts +2 -0
  36. package/dist/auto-memory-index-3224.test.d.ts.map +1 -0
  37. package/dist/auto-memory-index-3224.test.js +77 -0
  38. package/dist/auto-memory-index-3224.test.js.map +1 -0
  39. package/dist/consolidator-embedding-benchmark.test.d.ts +39 -0
  40. package/dist/consolidator-embedding-benchmark.test.d.ts.map +1 -0
  41. package/dist/consolidator-embedding-benchmark.test.js +366 -0
  42. package/dist/consolidator-embedding-benchmark.test.js.map +1 -0
  43. package/dist/consolidator.d.ts +131 -0
  44. package/dist/consolidator.d.ts.map +1 -0
  45. package/dist/consolidator.js +309 -0
  46. package/dist/consolidator.js.map +1 -0
  47. package/dist/consolidator.test.d.ts +17 -0
  48. package/dist/consolidator.test.d.ts.map +1 -0
  49. package/dist/consolidator.test.js +376 -0
  50. package/dist/consolidator.test.js.map +1 -0
  51. package/dist/controller-registry.d.ts +290 -0
  52. package/dist/controller-registry.d.ts.map +1 -0
  53. package/dist/controller-registry.js +1095 -0
  54. package/dist/controller-registry.js.map +1 -0
  55. package/dist/controller-registry.test.d.ts +14 -0
  56. package/dist/controller-registry.test.d.ts.map +1 -0
  57. package/dist/controller-registry.test.js +818 -0
  58. package/dist/controller-registry.test.js.map +1 -0
  59. package/dist/database-provider.d.ts +14 -2
  60. package/dist/database-provider.d.ts.map +1 -1
  61. package/dist/database-provider.js +63 -3
  62. package/dist/database-provider.js.map +1 -1
  63. package/dist/database-provider.test.js +56 -3
  64. package/dist/database-provider.test.js.map +1 -1
  65. package/dist/entity-tagger.d.ts +31 -0
  66. package/dist/entity-tagger.d.ts.map +1 -0
  67. package/dist/entity-tagger.js +80 -0
  68. package/dist/entity-tagger.js.map +1 -0
  69. package/dist/entity-tagger.test.d.ts +12 -0
  70. package/dist/entity-tagger.test.d.ts.map +1 -0
  71. package/dist/entity-tagger.test.js +70 -0
  72. package/dist/entity-tagger.test.js.map +1 -0
  73. package/dist/fts5.test.d.ts +13 -0
  74. package/dist/fts5.test.d.ts.map +1 -0
  75. package/dist/fts5.test.js +144 -0
  76. package/dist/fts5.test.js.map +1 -0
  77. package/dist/graceful-retrieval.test.d.ts +14 -0
  78. package/dist/graceful-retrieval.test.d.ts.map +1 -0
  79. package/dist/graceful-retrieval.test.js +251 -0
  80. package/dist/graceful-retrieval.test.js.map +1 -0
  81. package/dist/hnsw-index.d.ts +62 -0
  82. package/dist/hnsw-index.d.ts.map +1 -1
  83. package/dist/hnsw-index.js +461 -16
  84. package/dist/hnsw-index.js.map +1 -1
  85. package/dist/hnsw-persistence.test.d.ts +13 -0
  86. package/dist/hnsw-persistence.test.d.ts.map +1 -0
  87. package/dist/hnsw-persistence.test.js +208 -0
  88. package/dist/hnsw-persistence.test.js.map +1 -0
  89. package/dist/hnsw-quantization.test.d.ts +17 -0
  90. package/dist/hnsw-quantization.test.d.ts.map +1 -0
  91. package/dist/hnsw-quantization.test.js +140 -0
  92. package/dist/hnsw-quantization.test.js.map +1 -0
  93. package/dist/hybrid-backend.d.ts +46 -2
  94. package/dist/hybrid-backend.d.ts.map +1 -1
  95. package/dist/hybrid-backend.js +120 -21
  96. package/dist/hybrid-backend.js.map +1 -1
  97. package/dist/hybrid-backend.test.js +139 -5
  98. package/dist/hybrid-backend.test.js.map +1 -1
  99. package/dist/index.d.ts +164 -10
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +272 -30
  102. package/dist/index.js.map +1 -1
  103. package/dist/index.test.d.ts +10 -0
  104. package/dist/index.test.d.ts.map +1 -0
  105. package/dist/index.test.js +71 -0
  106. package/dist/index.test.js.map +1 -0
  107. package/dist/json-security.d.ts +12 -0
  108. package/dist/json-security.d.ts.map +1 -0
  109. package/dist/json-security.js +20 -0
  110. package/dist/json-security.js.map +1 -0
  111. package/dist/learning-bridge.d.ts +29 -0
  112. package/dist/learning-bridge.d.ts.map +1 -1
  113. package/dist/learning-bridge.js +71 -6
  114. package/dist/learning-bridge.js.map +1 -1
  115. package/dist/learning-bridge.test.js +181 -1
  116. package/dist/learning-bridge.test.js.map +1 -1
  117. package/dist/memory-key.d.ts +3 -0
  118. package/dist/memory-key.d.ts.map +1 -0
  119. package/dist/memory-key.js +5 -0
  120. package/dist/memory-key.js.map +1 -0
  121. package/dist/migration.d.ts +19 -4
  122. package/dist/migration.d.ts.map +1 -1
  123. package/dist/migration.js +99 -24
  124. package/dist/migration.js.map +1 -1
  125. package/dist/migration.test.d.ts +11 -0
  126. package/dist/migration.test.d.ts.map +1 -0
  127. package/dist/migration.test.js +141 -0
  128. package/dist/migration.test.js.map +1 -0
  129. package/dist/mmr-benchmark.test.d.ts +2 -0
  130. package/dist/mmr-benchmark.test.d.ts.map +1 -0
  131. package/dist/mmr-benchmark.test.js +286 -0
  132. package/dist/mmr-benchmark.test.js.map +1 -0
  133. package/dist/mmr-rerank-perf.test.d.ts +2 -0
  134. package/dist/mmr-rerank-perf.test.d.ts.map +1 -0
  135. package/dist/mmr-rerank-perf.test.js +191 -0
  136. package/dist/mmr-rerank-perf.test.js.map +1 -0
  137. package/dist/persistent-sona.d.ts +144 -0
  138. package/dist/persistent-sona.d.ts.map +1 -0
  139. package/dist/persistent-sona.js +332 -0
  140. package/dist/persistent-sona.js.map +1 -0
  141. package/dist/rvf-backend.d.ts +53 -0
  142. package/dist/rvf-backend.d.ts.map +1 -0
  143. package/dist/rvf-backend.js +643 -0
  144. package/dist/rvf-backend.js.map +1 -0
  145. package/dist/rvf-learning-store.d.ts +139 -0
  146. package/dist/rvf-learning-store.d.ts.map +1 -0
  147. package/dist/rvf-learning-store.js +295 -0
  148. package/dist/rvf-learning-store.js.map +1 -0
  149. package/dist/rvf-migration.d.ts +45 -0
  150. package/dist/rvf-migration.d.ts.map +1 -0
  151. package/dist/rvf-migration.js +254 -0
  152. package/dist/rvf-migration.js.map +1 -0
  153. package/dist/smart-retrieval-scores.test.d.ts +2 -0
  154. package/dist/smart-retrieval-scores.test.d.ts.map +1 -0
  155. package/dist/smart-retrieval-scores.test.js +75 -0
  156. package/dist/smart-retrieval-scores.test.js.map +1 -0
  157. package/dist/smart-retrieval.d.ts +141 -0
  158. package/dist/smart-retrieval.d.ts.map +1 -0
  159. package/dist/smart-retrieval.js +389 -0
  160. package/dist/smart-retrieval.js.map +1 -0
  161. package/dist/smart-retrieval.test.d.ts +2 -0
  162. package/dist/smart-retrieval.test.d.ts.map +1 -0
  163. package/dist/smart-retrieval.test.js +418 -0
  164. package/dist/smart-retrieval.test.js.map +1 -0
  165. package/dist/sqlite-backend.d.ts +10 -0
  166. package/dist/sqlite-backend.d.ts.map +1 -1
  167. package/dist/sqlite-backend.js +101 -5
  168. package/dist/sqlite-backend.js.map +1 -1
  169. package/dist/sqljs-backend.d.ts +9 -0
  170. package/dist/sqljs-backend.d.ts.map +1 -1
  171. package/dist/sqljs-backend.js +91 -3
  172. package/dist/sqljs-backend.js.map +1 -1
  173. package/dist/tiered-memory.d.ts +171 -0
  174. package/dist/tiered-memory.d.ts.map +1 -0
  175. package/dist/tiered-memory.js +350 -0
  176. package/dist/tiered-memory.js.map +1 -0
  177. package/dist/tiered-memory.test.d.ts +9 -0
  178. package/dist/tiered-memory.test.d.ts.map +1 -0
  179. package/dist/tiered-memory.test.js +220 -0
  180. package/dist/tiered-memory.test.js.map +1 -0
  181. package/dist/types.d.ts +17 -0
  182. package/dist/types.d.ts.map +1 -1
  183. package/dist/types.js.map +1 -1
  184. package/package.json +10 -8
@@ -0,0 +1,376 @@
1
+ /**
2
+ * Phase 4 — MemoryConsolidator (ADR-125)
3
+ *
4
+ * Verifies:
5
+ * - `sweepExpired()` after 1000 entries with `expiresAt` in the past →
6
+ * `entries.size === 0` AND `hnsw.size === 0` (Acceptance Criterion #4).
7
+ * - `dedup('keep-newest')` collapses content-hash duplicates and keeps the
8
+ * newest by `updatedAt`.
9
+ * - `dedup('keep-oldest')` keeps the oldest by `createdAt`.
10
+ * - `dedup('merge-tags')` unions tags and keeps the newest.
11
+ * - `compactHnsw` rebuilds the index so size matches `entries.size`.
12
+ * - Auto-run timer with a small interval calls `runAll()` at least once.
13
+ * - `nightlyLearner` controller delegates to `MemoryConsolidator.runAll()`
14
+ * when a `MemoryService` is registered.
15
+ */
16
+ import { describe, it, expect, vi } from 'vitest';
17
+ import { MemoryService } from './index.js';
18
+ import { MemoryConsolidator } from './consolidator.js';
19
+ import { HNSWIndex } from './hnsw-index.js';
20
+ import { ControllerRegistry } from './controller-registry.js';
21
+ import { createDefaultEntry } from './types.js';
22
+ function randomVec(dim, seed) {
23
+ const out = new Float32Array(dim);
24
+ let s = seed | 0 || 1;
25
+ for (let i = 0; i < dim; i++) {
26
+ s ^= s << 13;
27
+ s ^= s >>> 17;
28
+ s ^= s << 5;
29
+ out[i] = ((s | 0) / 2 ** 31);
30
+ }
31
+ return out;
32
+ }
33
+ async function newService(opts = {}) {
34
+ const svc = new MemoryService({
35
+ dimensions: 8,
36
+ persistenceEnabled: false,
37
+ snapshotInterval: 0,
38
+ ...opts,
39
+ });
40
+ await svc.initialize();
41
+ return svc;
42
+ }
43
+ describe('Phase 4 — MemoryConsolidator.sweepExpired', () => {
44
+ it('Acceptance Criterion #4 — 1000 expired entries → 0 remaining + HNSW emptied', async () => {
45
+ const svc = await newService();
46
+ const consolidator = new MemoryConsolidator(svc);
47
+ const past = Date.now() - 1;
48
+ for (let i = 0; i < 1000; i++) {
49
+ const entry = createDefaultEntry({
50
+ key: `expired-${i}`,
51
+ content: `content-${i}`,
52
+ expiresAt: past,
53
+ });
54
+ entry.embedding = randomVec(8, i + 1);
55
+ await svc.store(entry);
56
+ }
57
+ const adapter = svc.getAdapter();
58
+ expect(adapter.entries.size).toBe(1000);
59
+ expect(adapter.index.size).toBe(1000);
60
+ const result = await consolidator.sweepExpired();
61
+ expect(result.removed).toBe(1000);
62
+ expect(result.remaining).toBe(0);
63
+ expect(result.hnswRemoved).toBe(1000);
64
+ expect(adapter.entries.size).toBe(0);
65
+ expect(adapter.index.size).toBe(0);
66
+ await svc.close();
67
+ });
68
+ it('leaves non-expired entries untouched', async () => {
69
+ const svc = await newService();
70
+ const consolidator = new MemoryConsolidator(svc);
71
+ // 5 expired + 5 fresh
72
+ for (let i = 0; i < 5; i++) {
73
+ const entry = createDefaultEntry({
74
+ key: `e-${i}`,
75
+ content: `e-${i}`,
76
+ expiresAt: Date.now() - 1,
77
+ });
78
+ entry.embedding = randomVec(8, i + 1);
79
+ await svc.store(entry);
80
+ }
81
+ for (let i = 0; i < 5; i++) {
82
+ const entry = createDefaultEntry({ key: `f-${i}`, content: `f-${i}` });
83
+ entry.embedding = randomVec(8, i + 100);
84
+ await svc.store(entry);
85
+ }
86
+ const result = await consolidator.sweepExpired();
87
+ expect(result.removed).toBe(5);
88
+ expect(result.remaining).toBe(5);
89
+ await svc.close();
90
+ });
91
+ });
92
+ describe('Phase 4 — MemoryConsolidator.dedup', () => {
93
+ it('keep-newest: drops 10 duplicates and keeps newest by updatedAt', async () => {
94
+ const svc = await newService();
95
+ const consolidator = new MemoryConsolidator(svc);
96
+ // 40 unique + 10 dupes of the same content as entry 0
97
+ const dupContent = 'duplicate-marker';
98
+ const newestTimestamps = [];
99
+ for (let i = 0; i < 40; i++) {
100
+ const entry = createDefaultEntry({ key: `u-${i}`, content: `unique-${i}` });
101
+ entry.embedding = randomVec(8, i + 1);
102
+ await svc.store(entry);
103
+ }
104
+ // The first dup has the OLDEST updatedAt; the last dup has the NEWEST.
105
+ for (let i = 0; i < 10; i++) {
106
+ const entry = createDefaultEntry({ key: `dup-${i}`, content: dupContent });
107
+ entry.embedding = randomVec(8, i + 500);
108
+ entry.updatedAt = 1_000_000_000 + i; // monotonic, last is newest
109
+ await svc.store(entry);
110
+ newestTimestamps.push(entry.updatedAt);
111
+ }
112
+ const result = await consolidator.dedup('keep-newest');
113
+ expect(result.merged).toBe(9);
114
+ expect(result.groups).toBe(1);
115
+ // Survivor's updatedAt should equal the max of the dup timestamps
116
+ const adapter = svc.getAdapter();
117
+ const survivors = [...adapter.entries.values()].filter((e) => e.content === dupContent);
118
+ expect(survivors.length).toBe(1);
119
+ expect(survivors[0].updatedAt).toBe(Math.max(...newestTimestamps));
120
+ await svc.close();
121
+ });
122
+ it('keep-oldest: keeps the entry with the lowest createdAt', async () => {
123
+ const svc = await newService();
124
+ const consolidator = new MemoryConsolidator(svc);
125
+ const ids = [];
126
+ for (let i = 0; i < 3; i++) {
127
+ const entry = createDefaultEntry({ key: `o-${i}`, content: 'same' });
128
+ entry.embedding = randomVec(8, i + 1);
129
+ entry.createdAt = 1000 + i; // i=0 is oldest
130
+ await svc.store(entry);
131
+ ids.push(entry.id);
132
+ }
133
+ const result = await consolidator.dedup('keep-oldest');
134
+ expect(result.merged).toBe(2);
135
+ const adapter = svc.getAdapter();
136
+ expect(adapter.entries.size).toBe(1);
137
+ expect(adapter.entries.has(ids[0])).toBe(true);
138
+ await svc.close();
139
+ });
140
+ it('merge-tags: unions tag sets across the duplicates and keeps newest', async () => {
141
+ const svc = await newService();
142
+ const consolidator = new MemoryConsolidator(svc);
143
+ for (let i = 0; i < 3; i++) {
144
+ const entry = createDefaultEntry({
145
+ key: `t-${i}`,
146
+ content: 'same',
147
+ tags: [`tag-${i}`, 'common'],
148
+ });
149
+ entry.embedding = randomVec(8, i + 1);
150
+ entry.updatedAt = 1000 + i;
151
+ await svc.store(entry);
152
+ }
153
+ const result = await consolidator.dedup('merge-tags');
154
+ expect(result.merged).toBe(2);
155
+ const adapter = svc.getAdapter();
156
+ const survivors = [...adapter.entries.values()];
157
+ expect(survivors.length).toBe(1);
158
+ const survivor = survivors[0];
159
+ expect(new Set(survivor.tags)).toEqual(new Set(['tag-0', 'tag-1', 'tag-2', 'common']));
160
+ await svc.close();
161
+ });
162
+ });
163
+ describe('Phase 4.1 — MemoryConsolidator.dedup embedding near-duplicates', () => {
164
+ it('merges different-content entries whose embeddings are near-identical (cosine >= threshold)', async () => {
165
+ const svc = await newService();
166
+ const consolidator = new MemoryConsolidator(svc);
167
+ const base = randomVec(8, 42);
168
+ const a = createDefaultEntry({ key: 'a', content: 'paraphrase-one' });
169
+ a.embedding = base;
170
+ a.updatedAt = 1000;
171
+ await svc.store(a);
172
+ const b = createDefaultEntry({
173
+ key: 'b',
174
+ content: 'paraphrase-two-totally-different-text',
175
+ });
176
+ b.embedding = new Float32Array(base); // identical vector, different content/hash
177
+ b.updatedAt = 2000;
178
+ await svc.store(b);
179
+ const result = await consolidator.dedup('keep-newest');
180
+ expect(result.merged).toBe(1);
181
+ expect(result.groups).toBe(1);
182
+ const adapter = svc.getAdapter();
183
+ expect(adapter.entries.size).toBe(1);
184
+ expect(adapter.entries.has(b.id)).toBe(true); // newer of the pair survives
185
+ await svc.close();
186
+ });
187
+ it('does not merge entries whose embeddings fall below the similarity threshold', async () => {
188
+ const svc = await newService();
189
+ const consolidator = new MemoryConsolidator(svc);
190
+ const a = createDefaultEntry({ key: 'a', content: 'unrelated-one' });
191
+ a.embedding = randomVec(8, 1);
192
+ await svc.store(a);
193
+ const b = createDefaultEntry({ key: 'b', content: 'unrelated-two' });
194
+ b.embedding = randomVec(8, 999);
195
+ await svc.store(b);
196
+ const result = await consolidator.dedup();
197
+ expect(result.merged).toBe(0);
198
+ expect(result.groups).toBe(0);
199
+ const adapter = svc.getAdapter();
200
+ expect(adapter.entries.size).toBe(2);
201
+ await svc.close();
202
+ });
203
+ it('falls back to hash-only behavior for entries with no embedding', async () => {
204
+ const svc = await newService();
205
+ const consolidator = new MemoryConsolidator(svc);
206
+ const a = createDefaultEntry({ key: 'a', content: 'no-embedding-a' });
207
+ await svc.store(a);
208
+ const b = createDefaultEntry({ key: 'b', content: 'no-embedding-b' });
209
+ await svc.store(b);
210
+ const result = await consolidator.dedup();
211
+ expect(result.merged).toBe(0);
212
+ expect(result.groups).toBe(0);
213
+ await svc.close();
214
+ });
215
+ it('respects a custom similarityThreshold option', async () => {
216
+ const svc = await newService();
217
+ // A threshold below cosine's minimum (-1) means every pair is "similar".
218
+ const consolidator = new MemoryConsolidator(svc, { similarityThreshold: -1 });
219
+ const a = createDefaultEntry({ key: 'a', content: 'threshold-one' });
220
+ a.embedding = randomVec(8, 11);
221
+ await svc.store(a);
222
+ const b = createDefaultEntry({ key: 'b', content: 'threshold-two' });
223
+ b.embedding = randomVec(8, 22);
224
+ await svc.store(b);
225
+ const result = await consolidator.dedup();
226
+ expect(result.merged).toBe(1);
227
+ expect(result.groups).toBe(1);
228
+ await svc.close();
229
+ });
230
+ it('disables the embedding pass entirely when similarityThreshold >= 1', async () => {
231
+ const svc = await newService();
232
+ const consolidator = new MemoryConsolidator(svc, { similarityThreshold: 1 });
233
+ const embedding = randomVec(8, 5);
234
+ const a = createDefaultEntry({ key: 'a', content: 'disabled-one' });
235
+ a.embedding = embedding;
236
+ await svc.store(a);
237
+ const b = createDefaultEntry({ key: 'b', content: 'disabled-two' });
238
+ b.embedding = new Float32Array(embedding); // identical vector, still not merged
239
+ await svc.store(b);
240
+ const result = await consolidator.dedup();
241
+ expect(result.merged).toBe(0);
242
+ expect(result.groups).toBe(0);
243
+ await svc.close();
244
+ });
245
+ it('fully converges a near-duplicate cluster larger than the search neighborhood in one call', async () => {
246
+ // Adversarial-critique regression: a cluster wider than
247
+ // NEAR_DUP_SEARCH_K must still collapse to a single survivor from one
248
+ // dedup() call, not split into multiple leftover sub-group survivors.
249
+ const svc = await newService();
250
+ const consolidator = new MemoryConsolidator(svc);
251
+ const base = randomVec(8, 12345);
252
+ const n = 15; // > NEAR_DUP_SEARCH_K (8)
253
+ for (let i = 0; i < n; i++) {
254
+ const entry = createDefaultEntry({ key: `cluster-${i}`, content: `unique-content-${i}` });
255
+ entry.embedding = new Float32Array(base); // pairwise cosine similarity 1.0
256
+ entry.updatedAt = 1000 + i;
257
+ await svc.store(entry);
258
+ }
259
+ const result = await consolidator.dedup('keep-newest');
260
+ expect(result.merged).toBe(n - 1);
261
+ const adapter = svc.getAdapter();
262
+ expect(adapter.entries.size).toBe(1);
263
+ // The single survivor should be the newest of the cluster.
264
+ const survivor = [...adapter.entries.values()][0];
265
+ expect(survivor.updatedAt).toBe(1000 + n - 1);
266
+ await svc.close();
267
+ });
268
+ it('skips the near-duplicate pass entirely for a non-cosine-metric index', async () => {
269
+ const index = new HNSWIndex({ dimensions: 8, metric: 'euclidean' });
270
+ const embedding = randomVec(8, 7);
271
+ const a = createDefaultEntry({ key: 'a', content: 'euclid-one' });
272
+ a.embedding = embedding;
273
+ const b = createDefaultEntry({ key: 'b', content: 'euclid-two' });
274
+ b.embedding = new Float32Array(embedding); // identical vector, different content
275
+ await index.addPoint(a.id, a.embedding);
276
+ await index.addPoint(b.id, b.embedding);
277
+ const entries = new Map([
278
+ [a.id, a],
279
+ [b.id, b],
280
+ ]);
281
+ const namespaceIndex = new Map([
282
+ [a.namespace, new Set([a.id, b.id])],
283
+ ]);
284
+ const keyIndex = new Map([
285
+ [`${a.namespace}:${a.key}`, a.id],
286
+ [`${b.namespace}:${b.key}`, b.id],
287
+ ]);
288
+ const tagIndex = new Map();
289
+ const fakeService = {
290
+ getAdapter: () => ({ entries, namespaceIndex, keyIndex, tagIndex, index }),
291
+ };
292
+ const consolidator = new MemoryConsolidator(fakeService);
293
+ const result = await consolidator.dedup();
294
+ expect(result.merged).toBe(0);
295
+ expect(result.groups).toBe(0);
296
+ expect(entries.size).toBe(2);
297
+ });
298
+ });
299
+ describe('Phase 4 — MemoryConsolidator.compactHnsw', () => {
300
+ it('rebuilds the HNSW index so size matches entries.size after sweep', async () => {
301
+ const svc = await newService();
302
+ const consolidator = new MemoryConsolidator(svc);
303
+ // Insert + expire half
304
+ const half = 20;
305
+ for (let i = 0; i < half * 2; i++) {
306
+ const entry = createDefaultEntry({
307
+ key: `c-${i}`,
308
+ content: `c-${i}`,
309
+ expiresAt: i < half ? Date.now() - 1 : undefined,
310
+ });
311
+ entry.embedding = randomVec(8, i + 1);
312
+ await svc.store(entry);
313
+ }
314
+ await consolidator.sweepExpired();
315
+ const result = await consolidator.compactHnsw();
316
+ expect(result.before).toBeGreaterThanOrEqual(half);
317
+ expect(result.after).toBe(half);
318
+ const adapter = svc.getAdapter();
319
+ expect(adapter.index.size).toBe(adapter.entries.size);
320
+ await svc.close();
321
+ });
322
+ });
323
+ describe('Phase 4 — MemoryService auto-run timer', () => {
324
+ it('invokes consolidator.runAll() at the configured interval', async () => {
325
+ const svc = new MemoryService({
326
+ dimensions: 8,
327
+ persistenceEnabled: false,
328
+ snapshotInterval: 0,
329
+ consolidator: { autoRun: true, intervalMs: 50 },
330
+ });
331
+ await svc.initialize();
332
+ // Spy on the lazily-loaded consolidator. getConsolidator() returns a
333
+ // singleton, so swap its runAll for a spy after first construction.
334
+ const consolidator = await svc.getConsolidator();
335
+ const spy = vi.spyOn(consolidator, 'runAll');
336
+ // Wait long enough for at least one tick.
337
+ await new Promise((r) => setTimeout(r, 180));
338
+ expect(spy).toHaveBeenCalled();
339
+ await svc.close();
340
+ });
341
+ it('close() clears the consolidator timer', async () => {
342
+ const svc = new MemoryService({
343
+ dimensions: 8,
344
+ persistenceEnabled: false,
345
+ snapshotInterval: 0,
346
+ consolidator: { autoRun: true, intervalMs: 50 },
347
+ });
348
+ await svc.initialize();
349
+ const consolidator = await svc.getConsolidator();
350
+ const spy = vi.spyOn(consolidator, 'runAll');
351
+ await svc.close();
352
+ await new Promise((r) => setTimeout(r, 150));
353
+ // No new calls after close()
354
+ const callCountAtClose = spy.mock.calls.length;
355
+ await new Promise((r) => setTimeout(r, 150));
356
+ expect(spy.mock.calls.length).toBe(callCountAtClose);
357
+ });
358
+ });
359
+ describe('Phase 4 — nightlyLearner controller delegates to MemoryConsolidator', () => {
360
+ it('returns a wrapper bound to consolidator.runAll when memoryService is registered', async () => {
361
+ const svc = await newService();
362
+ const registry = new ControllerRegistry();
363
+ await registry.initialize({ memoryService: svc });
364
+ const inst = registry.get('nightlyLearner');
365
+ expect(inst).toBeTruthy();
366
+ expect(inst.source).toBe('memory-consolidator');
367
+ expect(typeof inst.runAll).toBe('function');
368
+ const result = await inst.runAll();
369
+ expect(result).toHaveProperty('sweep');
370
+ expect(result).toHaveProperty('dedup');
371
+ expect(result).toHaveProperty('compact');
372
+ await registry.shutdown();
373
+ await svc.close();
374
+ });
375
+ });
376
+ //# sourceMappingURL=consolidator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consolidator.test.js","sourceRoot":"","sources":["../src/consolidator.test.ts"],"names":[],"mappings":"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"}