@claude-flow/memory 3.0.0-alpha.17 → 3.0.0-alpha.19
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.
- package/README.md +858 -647
- package/dist/agentdb-adapter.d.ts +60 -1
- package/dist/agentdb-adapter.d.ts.map +1 -1
- package/dist/agentdb-adapter.js +253 -9
- package/dist/agentdb-adapter.js.map +1 -1
- package/dist/agentdb-backend.js +26 -26
- package/dist/auto-memory-bridge.d.ts +12 -1
- package/dist/auto-memory-bridge.d.ts.map +1 -1
- package/dist/auto-memory-bridge.js +45 -5
- package/dist/auto-memory-bridge.js.map +1 -1
- package/dist/auto-memory-bridge.test.js +92 -33
- package/dist/auto-memory-bridge.test.js.map +1 -1
- package/dist/consolidator.d.ts +96 -0
- package/dist/consolidator.d.ts.map +1 -0
- package/dist/consolidator.js +209 -0
- package/dist/consolidator.js.map +1 -0
- package/dist/consolidator.test.d.ts +17 -0
- package/dist/consolidator.test.d.ts.map +1 -0
- package/dist/consolidator.test.js +239 -0
- package/dist/consolidator.test.js.map +1 -0
- package/dist/controller-registry.d.ts +7 -0
- package/dist/controller-registry.d.ts.map +1 -1
- package/dist/controller-registry.js +92 -5
- package/dist/controller-registry.js.map +1 -1
- package/dist/database-provider.d.ts +13 -2
- package/dist/database-provider.d.ts.map +1 -1
- package/dist/database-provider.js +37 -2
- package/dist/database-provider.js.map +1 -1
- package/dist/database-provider.test.js +41 -0
- package/dist/database-provider.test.js.map +1 -1
- package/dist/fts5.test.d.ts +13 -0
- package/dist/fts5.test.d.ts.map +1 -0
- package/dist/fts5.test.js +144 -0
- package/dist/fts5.test.js.map +1 -0
- package/dist/graceful-retrieval.test.d.ts +14 -0
- package/dist/graceful-retrieval.test.d.ts.map +1 -0
- package/dist/graceful-retrieval.test.js +144 -0
- package/dist/graceful-retrieval.test.js.map +1 -0
- package/dist/hnsw-index.d.ts +51 -0
- package/dist/hnsw-index.d.ts.map +1 -1
- package/dist/hnsw-index.js +217 -0
- package/dist/hnsw-index.js.map +1 -1
- package/dist/hnsw-persistence.test.d.ts +13 -0
- package/dist/hnsw-persistence.test.d.ts.map +1 -0
- package/dist/hnsw-persistence.test.js +208 -0
- package/dist/hnsw-persistence.test.js.map +1 -0
- package/dist/index.d.ts +149 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +260 -32
- package/dist/index.js.map +1 -1
- package/dist/index.test.d.ts +10 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +71 -0
- package/dist/index.test.js.map +1 -0
- package/dist/rvf-backend.d.ts.map +1 -1
- package/dist/rvf-backend.js +155 -1
- package/dist/rvf-backend.js.map +1 -1
- package/dist/smart-retrieval.d.ts +24 -0
- package/dist/smart-retrieval.d.ts.map +1 -1
- package/dist/smart-retrieval.js +19 -0
- package/dist/smart-retrieval.js.map +1 -1
- package/dist/sqlite-backend.d.ts +10 -0
- package/dist/sqlite-backend.d.ts.map +1 -1
- package/dist/sqlite-backend.js +156 -69
- package/dist/sqlite-backend.js.map +1 -1
- package/dist/sqljs-backend.d.ts +9 -0
- package/dist/sqljs-backend.d.ts.map +1 -1
- package/dist/sqljs-backend.js +113 -26
- package/dist/sqljs-backend.js.map +1 -1
- package/package.json +48 -48
- package/dist/hnsw-lite.d.ts +0 -23
- package/dist/hnsw-lite.d.ts.map +0 -1
- package/dist/hnsw-lite.js +0 -168
- package/dist/hnsw-lite.js.map +0 -1
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MemoryConsolidator — ADR-125 Phase 4
|
|
3
|
+
*
|
|
4
|
+
* Periodic maintenance for the in-memory state owned by {@link UnifiedMemoryService}.
|
|
5
|
+
*
|
|
6
|
+
* Operations:
|
|
7
|
+
* - `sweepExpired()` — drop entries past `expiresAt` from all indexes (including HNSW).
|
|
8
|
+
* - `dedup(strategy)` — collapse content-hash duplicates per strategy.
|
|
9
|
+
* - `compactHnsw()` — rebuild the HNSW index from current `entries`.
|
|
10
|
+
* - `runAll()` — sweep → dedup → compact in order.
|
|
11
|
+
*
|
|
12
|
+
* Invoked from two paths:
|
|
13
|
+
* 1. {@link UnifiedMemoryService}'s lifecycle (background timer when
|
|
14
|
+
* `consolidator.autoRun === true`, plus `close()`).
|
|
15
|
+
* 2. The AgentDB `nightlyLearner` controller (`src/controller-registry.ts`)
|
|
16
|
+
* delegates to `runAll()` instead of hitting AgentDB directly.
|
|
17
|
+
*
|
|
18
|
+
* Phase 3 placeholder lives in this file too — it provides the typed
|
|
19
|
+
* surface that {@link UnifiedMemoryService.getConsolidator} resolves to.
|
|
20
|
+
* The real implementation lands with Phase 4.
|
|
21
|
+
*
|
|
22
|
+
* @module v3/memory/consolidator
|
|
23
|
+
*/
|
|
24
|
+
import { createHash } from 'node:crypto';
|
|
25
|
+
import { HNSWIndex } from './hnsw-index.js';
|
|
26
|
+
export class MemoryConsolidator {
|
|
27
|
+
service;
|
|
28
|
+
opts;
|
|
29
|
+
constructor(service, opts = {}) {
|
|
30
|
+
this.service = service;
|
|
31
|
+
this.opts = opts;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Drop all entries whose `expiresAt` is in the past.
|
|
35
|
+
*/
|
|
36
|
+
async sweepExpired() {
|
|
37
|
+
const adapter = this.service.getAdapter();
|
|
38
|
+
const entries = adapter.entries;
|
|
39
|
+
const namespaceIndex = adapter.namespaceIndex;
|
|
40
|
+
const keyIndex = adapter.keyIndex;
|
|
41
|
+
const tagIndex = adapter.tagIndex;
|
|
42
|
+
const index = adapter.index;
|
|
43
|
+
const now = Date.now();
|
|
44
|
+
const toRemove = [];
|
|
45
|
+
for (const entry of entries.values()) {
|
|
46
|
+
if (entry.expiresAt != null && entry.expiresAt < now) {
|
|
47
|
+
toRemove.push(entry);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
let hnswRemoved = 0;
|
|
51
|
+
for (const entry of toRemove) {
|
|
52
|
+
entries.delete(entry.id);
|
|
53
|
+
namespaceIndex.get(entry.namespace)?.delete(entry.id);
|
|
54
|
+
keyIndex.delete(`${entry.namespace}:${entry.key}`);
|
|
55
|
+
for (const tag of entry.tags)
|
|
56
|
+
tagIndex.get(tag)?.delete(entry.id);
|
|
57
|
+
if (entry.embedding) {
|
|
58
|
+
const removed = await index.removePoint(entry.id);
|
|
59
|
+
if (removed)
|
|
60
|
+
hnswRemoved += 1;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Clean up empty namespace/tag sets to keep memory bounded
|
|
64
|
+
for (const [ns, ids] of namespaceIndex) {
|
|
65
|
+
if (ids.size === 0)
|
|
66
|
+
namespaceIndex.delete(ns);
|
|
67
|
+
}
|
|
68
|
+
for (const [tag, ids] of tagIndex) {
|
|
69
|
+
if (ids.size === 0)
|
|
70
|
+
tagIndex.delete(tag);
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
removed: toRemove.length,
|
|
74
|
+
remaining: entries.size,
|
|
75
|
+
hnswRemoved,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Collapse content-hash duplicates across all namespaces per `strategy`.
|
|
80
|
+
*
|
|
81
|
+
* - `keep-newest`: keep the entry with the highest `updatedAt`, drop the rest.
|
|
82
|
+
* - `keep-oldest`: keep the entry with the lowest `createdAt`, drop the rest.
|
|
83
|
+
* - `merge-tags`: keep newest, but union the tag sets of the duplicates first.
|
|
84
|
+
*/
|
|
85
|
+
async dedup(strategy) {
|
|
86
|
+
const adapter = this.service.getAdapter();
|
|
87
|
+
const entries = adapter.entries;
|
|
88
|
+
const namespaceIndex = adapter.namespaceIndex;
|
|
89
|
+
const keyIndex = adapter.keyIndex;
|
|
90
|
+
const tagIndex = adapter.tagIndex;
|
|
91
|
+
const index = adapter.index;
|
|
92
|
+
const effective = strategy ?? this.opts.dedupStrategy ?? 'keep-newest';
|
|
93
|
+
// Bucket by content hash
|
|
94
|
+
const buckets = new Map();
|
|
95
|
+
for (const entry of entries.values()) {
|
|
96
|
+
const hash = createHash('sha256').update(entry.content).digest('hex');
|
|
97
|
+
const bucket = buckets.get(hash);
|
|
98
|
+
if (bucket)
|
|
99
|
+
bucket.push(entry);
|
|
100
|
+
else
|
|
101
|
+
buckets.set(hash, [entry]);
|
|
102
|
+
}
|
|
103
|
+
let merged = 0;
|
|
104
|
+
let dupGroups = 0;
|
|
105
|
+
for (const bucket of buckets.values()) {
|
|
106
|
+
if (bucket.length <= 1)
|
|
107
|
+
continue;
|
|
108
|
+
dupGroups += 1;
|
|
109
|
+
// Choose keeper
|
|
110
|
+
let keeper;
|
|
111
|
+
if (effective === 'keep-oldest') {
|
|
112
|
+
keeper = bucket.reduce((acc, e) => e.createdAt < acc.createdAt ? e : acc);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// keep-newest + merge-tags share this branch
|
|
116
|
+
keeper = bucket.reduce((acc, e) => e.updatedAt > acc.updatedAt ? e : acc);
|
|
117
|
+
}
|
|
118
|
+
if (effective === 'merge-tags') {
|
|
119
|
+
const tagSet = new Set(keeper.tags);
|
|
120
|
+
for (const e of bucket)
|
|
121
|
+
for (const t of e.tags)
|
|
122
|
+
tagSet.add(t);
|
|
123
|
+
const oldTags = keeper.tags;
|
|
124
|
+
keeper.tags = [...tagSet];
|
|
125
|
+
// Update tagIndex membership for newly-added tags
|
|
126
|
+
for (const t of keeper.tags) {
|
|
127
|
+
if (!oldTags.includes(t)) {
|
|
128
|
+
if (!tagIndex.has(t))
|
|
129
|
+
tagIndex.set(t, new Set());
|
|
130
|
+
tagIndex.get(t).add(keeper.id);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Drop everyone except the keeper
|
|
135
|
+
for (const e of bucket) {
|
|
136
|
+
if (e.id === keeper.id)
|
|
137
|
+
continue;
|
|
138
|
+
entries.delete(e.id);
|
|
139
|
+
namespaceIndex.get(e.namespace)?.delete(e.id);
|
|
140
|
+
const compositeKey = `${e.namespace}:${e.key}`;
|
|
141
|
+
if (keyIndex.get(compositeKey) === e.id) {
|
|
142
|
+
keyIndex.delete(compositeKey);
|
|
143
|
+
}
|
|
144
|
+
for (const tag of e.tags)
|
|
145
|
+
tagIndex.get(tag)?.delete(e.id);
|
|
146
|
+
if (e.embedding) {
|
|
147
|
+
await index.removePoint(e.id);
|
|
148
|
+
}
|
|
149
|
+
merged += 1;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return { merged, groups: dupGroups };
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Rebuild the HNSW index from the current set of entries with embeddings.
|
|
156
|
+
* Returns a count snapshot + duration.
|
|
157
|
+
*/
|
|
158
|
+
async compactHnsw() {
|
|
159
|
+
const adapter = this.service.getAdapter();
|
|
160
|
+
const entries = adapter.entries;
|
|
161
|
+
const index = adapter.index;
|
|
162
|
+
const before = index.size;
|
|
163
|
+
const t0 = Date.now();
|
|
164
|
+
// Build a fresh HNSW from current entries that have embeddings.
|
|
165
|
+
const cfg = index.getConfig();
|
|
166
|
+
const fresh = new HNSWIndex({
|
|
167
|
+
dimensions: cfg.dimensions,
|
|
168
|
+
M: cfg.M,
|
|
169
|
+
efConstruction: cfg.efConstruction,
|
|
170
|
+
maxElements: cfg.maxElements,
|
|
171
|
+
metric: cfg.metric,
|
|
172
|
+
});
|
|
173
|
+
for (const entry of entries.values()) {
|
|
174
|
+
if (entry.embedding) {
|
|
175
|
+
try {
|
|
176
|
+
await fresh.addPoint(entry.id, entry.embedding);
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
// Tolerate dimension mismatches in malformed datasets.
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Swap pointers atomically and re-forward events
|
|
184
|
+
adapter.index = fresh;
|
|
185
|
+
if (typeof adapter.emit === 'function') {
|
|
186
|
+
fresh.on('point:added', (data) => adapter.emit('index:added', data));
|
|
187
|
+
}
|
|
188
|
+
const durationMs = Date.now() - t0;
|
|
189
|
+
return { before, after: fresh.size, durationMs };
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Sweep → dedup → compact. Used by the background timer and by the
|
|
193
|
+
* `nightlyLearner` AgentDB controller.
|
|
194
|
+
*/
|
|
195
|
+
async runAll() {
|
|
196
|
+
const start = Date.now();
|
|
197
|
+
const sweep = await this.sweepExpired();
|
|
198
|
+
const dedup = await this.dedup();
|
|
199
|
+
const compact = await this.compactHnsw();
|
|
200
|
+
return {
|
|
201
|
+
sweep,
|
|
202
|
+
dedup,
|
|
203
|
+
compact,
|
|
204
|
+
totalDurationMs: Date.now() - start,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
export default MemoryConsolidator;
|
|
209
|
+
//# sourceMappingURL=consolidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidator.js","sourceRoot":"","sources":["../src/consolidator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=consolidator.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidator.test.d.ts","sourceRoot":"","sources":["../src/consolidator.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
|
|
@@ -0,0 +1,239 @@
|
|
|
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 { ControllerRegistry } from './controller-registry.js';
|
|
20
|
+
import { createDefaultEntry } from './types.js';
|
|
21
|
+
function randomVec(dim, seed) {
|
|
22
|
+
const out = new Float32Array(dim);
|
|
23
|
+
let s = seed | 0 || 1;
|
|
24
|
+
for (let i = 0; i < dim; i++) {
|
|
25
|
+
s ^= s << 13;
|
|
26
|
+
s ^= s >>> 17;
|
|
27
|
+
s ^= s << 5;
|
|
28
|
+
out[i] = ((s | 0) / 2 ** 31);
|
|
29
|
+
}
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
async function newService(opts = {}) {
|
|
33
|
+
const svc = new MemoryService({
|
|
34
|
+
dimensions: 8,
|
|
35
|
+
persistenceEnabled: false,
|
|
36
|
+
snapshotInterval: 0,
|
|
37
|
+
...opts,
|
|
38
|
+
});
|
|
39
|
+
await svc.initialize();
|
|
40
|
+
return svc;
|
|
41
|
+
}
|
|
42
|
+
describe('Phase 4 — MemoryConsolidator.sweepExpired', () => {
|
|
43
|
+
it('Acceptance Criterion #4 — 1000 expired entries → 0 remaining + HNSW emptied', async () => {
|
|
44
|
+
const svc = await newService();
|
|
45
|
+
const consolidator = new MemoryConsolidator(svc);
|
|
46
|
+
const past = Date.now() - 1;
|
|
47
|
+
for (let i = 0; i < 1000; i++) {
|
|
48
|
+
const entry = createDefaultEntry({
|
|
49
|
+
key: `expired-${i}`,
|
|
50
|
+
content: `content-${i}`,
|
|
51
|
+
expiresAt: past,
|
|
52
|
+
});
|
|
53
|
+
entry.embedding = randomVec(8, i + 1);
|
|
54
|
+
await svc.store(entry);
|
|
55
|
+
}
|
|
56
|
+
const adapter = svc.getAdapter();
|
|
57
|
+
expect(adapter.entries.size).toBe(1000);
|
|
58
|
+
expect(adapter.index.size).toBe(1000);
|
|
59
|
+
const result = await consolidator.sweepExpired();
|
|
60
|
+
expect(result.removed).toBe(1000);
|
|
61
|
+
expect(result.remaining).toBe(0);
|
|
62
|
+
expect(result.hnswRemoved).toBe(1000);
|
|
63
|
+
expect(adapter.entries.size).toBe(0);
|
|
64
|
+
expect(adapter.index.size).toBe(0);
|
|
65
|
+
await svc.close();
|
|
66
|
+
});
|
|
67
|
+
it('leaves non-expired entries untouched', async () => {
|
|
68
|
+
const svc = await newService();
|
|
69
|
+
const consolidator = new MemoryConsolidator(svc);
|
|
70
|
+
// 5 expired + 5 fresh
|
|
71
|
+
for (let i = 0; i < 5; i++) {
|
|
72
|
+
const entry = createDefaultEntry({
|
|
73
|
+
key: `e-${i}`,
|
|
74
|
+
content: `e-${i}`,
|
|
75
|
+
expiresAt: Date.now() - 1,
|
|
76
|
+
});
|
|
77
|
+
entry.embedding = randomVec(8, i + 1);
|
|
78
|
+
await svc.store(entry);
|
|
79
|
+
}
|
|
80
|
+
for (let i = 0; i < 5; i++) {
|
|
81
|
+
const entry = createDefaultEntry({ key: `f-${i}`, content: `f-${i}` });
|
|
82
|
+
entry.embedding = randomVec(8, i + 100);
|
|
83
|
+
await svc.store(entry);
|
|
84
|
+
}
|
|
85
|
+
const result = await consolidator.sweepExpired();
|
|
86
|
+
expect(result.removed).toBe(5);
|
|
87
|
+
expect(result.remaining).toBe(5);
|
|
88
|
+
await svc.close();
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
describe('Phase 4 — MemoryConsolidator.dedup', () => {
|
|
92
|
+
it('keep-newest: drops 10 duplicates and keeps newest by updatedAt', async () => {
|
|
93
|
+
const svc = await newService();
|
|
94
|
+
const consolidator = new MemoryConsolidator(svc);
|
|
95
|
+
// 40 unique + 10 dupes of the same content as entry 0
|
|
96
|
+
const dupContent = 'duplicate-marker';
|
|
97
|
+
const newestTimestamps = [];
|
|
98
|
+
for (let i = 0; i < 40; i++) {
|
|
99
|
+
const entry = createDefaultEntry({ key: `u-${i}`, content: `unique-${i}` });
|
|
100
|
+
entry.embedding = randomVec(8, i + 1);
|
|
101
|
+
await svc.store(entry);
|
|
102
|
+
}
|
|
103
|
+
// The first dup has the OLDEST updatedAt; the last dup has the NEWEST.
|
|
104
|
+
for (let i = 0; i < 10; i++) {
|
|
105
|
+
const entry = createDefaultEntry({ key: `dup-${i}`, content: dupContent });
|
|
106
|
+
entry.embedding = randomVec(8, i + 500);
|
|
107
|
+
entry.updatedAt = 1_000_000_000 + i; // monotonic, last is newest
|
|
108
|
+
await svc.store(entry);
|
|
109
|
+
newestTimestamps.push(entry.updatedAt);
|
|
110
|
+
}
|
|
111
|
+
const result = await consolidator.dedup('keep-newest');
|
|
112
|
+
expect(result.merged).toBe(9);
|
|
113
|
+
expect(result.groups).toBe(1);
|
|
114
|
+
// Survivor's updatedAt should equal the max of the dup timestamps
|
|
115
|
+
const adapter = svc.getAdapter();
|
|
116
|
+
const survivors = [...adapter.entries.values()].filter((e) => e.content === dupContent);
|
|
117
|
+
expect(survivors.length).toBe(1);
|
|
118
|
+
expect(survivors[0].updatedAt).toBe(Math.max(...newestTimestamps));
|
|
119
|
+
await svc.close();
|
|
120
|
+
});
|
|
121
|
+
it('keep-oldest: keeps the entry with the lowest createdAt', async () => {
|
|
122
|
+
const svc = await newService();
|
|
123
|
+
const consolidator = new MemoryConsolidator(svc);
|
|
124
|
+
const ids = [];
|
|
125
|
+
for (let i = 0; i < 3; i++) {
|
|
126
|
+
const entry = createDefaultEntry({ key: `o-${i}`, content: 'same' });
|
|
127
|
+
entry.embedding = randomVec(8, i + 1);
|
|
128
|
+
entry.createdAt = 1000 + i; // i=0 is oldest
|
|
129
|
+
await svc.store(entry);
|
|
130
|
+
ids.push(entry.id);
|
|
131
|
+
}
|
|
132
|
+
const result = await consolidator.dedup('keep-oldest');
|
|
133
|
+
expect(result.merged).toBe(2);
|
|
134
|
+
const adapter = svc.getAdapter();
|
|
135
|
+
expect(adapter.entries.size).toBe(1);
|
|
136
|
+
expect(adapter.entries.has(ids[0])).toBe(true);
|
|
137
|
+
await svc.close();
|
|
138
|
+
});
|
|
139
|
+
it('merge-tags: unions tag sets across the duplicates and keeps newest', async () => {
|
|
140
|
+
const svc = await newService();
|
|
141
|
+
const consolidator = new MemoryConsolidator(svc);
|
|
142
|
+
for (let i = 0; i < 3; i++) {
|
|
143
|
+
const entry = createDefaultEntry({
|
|
144
|
+
key: `t-${i}`,
|
|
145
|
+
content: 'same',
|
|
146
|
+
tags: [`tag-${i}`, 'common'],
|
|
147
|
+
});
|
|
148
|
+
entry.embedding = randomVec(8, i + 1);
|
|
149
|
+
entry.updatedAt = 1000 + i;
|
|
150
|
+
await svc.store(entry);
|
|
151
|
+
}
|
|
152
|
+
const result = await consolidator.dedup('merge-tags');
|
|
153
|
+
expect(result.merged).toBe(2);
|
|
154
|
+
const adapter = svc.getAdapter();
|
|
155
|
+
const survivors = [...adapter.entries.values()];
|
|
156
|
+
expect(survivors.length).toBe(1);
|
|
157
|
+
const survivor = survivors[0];
|
|
158
|
+
expect(new Set(survivor.tags)).toEqual(new Set(['tag-0', 'tag-1', 'tag-2', 'common']));
|
|
159
|
+
await svc.close();
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
describe('Phase 4 — MemoryConsolidator.compactHnsw', () => {
|
|
163
|
+
it('rebuilds the HNSW index so size matches entries.size after sweep', async () => {
|
|
164
|
+
const svc = await newService();
|
|
165
|
+
const consolidator = new MemoryConsolidator(svc);
|
|
166
|
+
// Insert + expire half
|
|
167
|
+
const half = 20;
|
|
168
|
+
for (let i = 0; i < half * 2; i++) {
|
|
169
|
+
const entry = createDefaultEntry({
|
|
170
|
+
key: `c-${i}`,
|
|
171
|
+
content: `c-${i}`,
|
|
172
|
+
expiresAt: i < half ? Date.now() - 1 : undefined,
|
|
173
|
+
});
|
|
174
|
+
entry.embedding = randomVec(8, i + 1);
|
|
175
|
+
await svc.store(entry);
|
|
176
|
+
}
|
|
177
|
+
await consolidator.sweepExpired();
|
|
178
|
+
const result = await consolidator.compactHnsw();
|
|
179
|
+
expect(result.before).toBeGreaterThanOrEqual(half);
|
|
180
|
+
expect(result.after).toBe(half);
|
|
181
|
+
const adapter = svc.getAdapter();
|
|
182
|
+
expect(adapter.index.size).toBe(adapter.entries.size);
|
|
183
|
+
await svc.close();
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
describe('Phase 4 — MemoryService auto-run timer', () => {
|
|
187
|
+
it('invokes consolidator.runAll() at the configured interval', async () => {
|
|
188
|
+
const svc = new MemoryService({
|
|
189
|
+
dimensions: 8,
|
|
190
|
+
persistenceEnabled: false,
|
|
191
|
+
snapshotInterval: 0,
|
|
192
|
+
consolidator: { autoRun: true, intervalMs: 50 },
|
|
193
|
+
});
|
|
194
|
+
await svc.initialize();
|
|
195
|
+
// Spy on the lazily-loaded consolidator. getConsolidator() returns a
|
|
196
|
+
// singleton, so swap its runAll for a spy after first construction.
|
|
197
|
+
const consolidator = await svc.getConsolidator();
|
|
198
|
+
const spy = vi.spyOn(consolidator, 'runAll');
|
|
199
|
+
// Wait long enough for at least one tick.
|
|
200
|
+
await new Promise((r) => setTimeout(r, 180));
|
|
201
|
+
expect(spy).toHaveBeenCalled();
|
|
202
|
+
await svc.close();
|
|
203
|
+
});
|
|
204
|
+
it('close() clears the consolidator timer', async () => {
|
|
205
|
+
const svc = new MemoryService({
|
|
206
|
+
dimensions: 8,
|
|
207
|
+
persistenceEnabled: false,
|
|
208
|
+
snapshotInterval: 0,
|
|
209
|
+
consolidator: { autoRun: true, intervalMs: 50 },
|
|
210
|
+
});
|
|
211
|
+
await svc.initialize();
|
|
212
|
+
const consolidator = await svc.getConsolidator();
|
|
213
|
+
const spy = vi.spyOn(consolidator, 'runAll');
|
|
214
|
+
await svc.close();
|
|
215
|
+
await new Promise((r) => setTimeout(r, 150));
|
|
216
|
+
// No new calls after close()
|
|
217
|
+
const callCountAtClose = spy.mock.calls.length;
|
|
218
|
+
await new Promise((r) => setTimeout(r, 150));
|
|
219
|
+
expect(spy.mock.calls.length).toBe(callCountAtClose);
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
describe('Phase 4 — nightlyLearner controller delegates to MemoryConsolidator', () => {
|
|
223
|
+
it('returns a wrapper bound to consolidator.runAll when memoryService is registered', async () => {
|
|
224
|
+
const svc = await newService();
|
|
225
|
+
const registry = new ControllerRegistry();
|
|
226
|
+
await registry.initialize({ memoryService: svc });
|
|
227
|
+
const inst = registry.get('nightlyLearner');
|
|
228
|
+
expect(inst).toBeTruthy();
|
|
229
|
+
expect(inst.source).toBe('memory-consolidator');
|
|
230
|
+
expect(typeof inst.runAll).toBe('function');
|
|
231
|
+
const result = await inst.runAll();
|
|
232
|
+
expect(result).toHaveProperty('sweep');
|
|
233
|
+
expect(result).toHaveProperty('dedup');
|
|
234
|
+
expect(result).toHaveProperty('compact');
|
|
235
|
+
await registry.shutdown();
|
|
236
|
+
await svc.close();
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
//# 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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"}
|
|
@@ -90,6 +90,13 @@ export interface RuntimeConfig {
|
|
|
90
90
|
* on this injection point.
|
|
91
91
|
*/
|
|
92
92
|
agentdb?: unknown;
|
|
93
|
+
/**
|
|
94
|
+
* `MemoryService` (or compatible) used to back the `nightlyLearner`
|
|
95
|
+
* controller. When provided, ADR-125 Phase 4 wraps it with
|
|
96
|
+
* `MemoryConsolidator.runAll()` instead of delegating directly to AgentDB's
|
|
97
|
+
* `NightlyLearner`. Accepts `any` to avoid a circular import.
|
|
98
|
+
*/
|
|
99
|
+
memoryService?: any;
|
|
93
100
|
}
|
|
94
101
|
/**
|
|
95
102
|
* Level-based initialization order per ADR-053.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller-registry.d.ts","sourceRoot":"","sources":["../src/controller-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EACV,cAAc,EAId,kBAAkB,EAClB,QAAQ,EACT,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI9C;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAC7B,eAAe,GACf,QAAQ,GACR,WAAW,GACX,aAAa,GACb,cAAc,GACd,gBAAgB,GAChB,mBAAmB,GACnB,gBAAgB,GAChB,kBAAkB,GAClB,eAAe,GACf,gBAAgB,GAChB,eAAe,GACf,cAAc,CAAC;AAEnB;;GAEG;AACH,MAAM,MAAM,iBAAiB,GACzB,gBAAgB,GAChB,aAAa,GACb,kBAAkB,GAClB,aAAa,GACb,cAAc,GACd,kBAAkB,GAClB,gBAAgB,GAChB,gBAAgB,GAChB,oBAAoB,GACpB,qBAAqB,GACrB,iBAAiB,GACjB,oBAAoB,GACpB,YAAY,GACZ,cAAc,GACd,oBAAoB,GACpB,sBAAsB,CAAC;AAE3B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,qBAAqB,GAAG,iBAAiB,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,aAAa,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;IAC7C,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,gCAAgC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,mCAAmC;IACnC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IAExC,4BAA4B;IAC5B,MAAM,CAAC,EAAE;QACP,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,cAAc,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC/C,WAAW,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACzC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;KACpC,CAAC;IAEF,oBAAoB;IACpB,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,QAAQ,CAAC;KACrB,CAAC;IAEF,+CAA+C;IAC/C,WAAW,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;IAEvD,+CAA+C;IAC/C,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"controller-registry.d.ts","sourceRoot":"","sources":["../src/controller-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EACV,cAAc,EAId,kBAAkB,EAClB,QAAQ,EACT,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI9C;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAC7B,eAAe,GACf,QAAQ,GACR,WAAW,GACX,aAAa,GACb,cAAc,GACd,gBAAgB,GAChB,mBAAmB,GACnB,gBAAgB,GAChB,kBAAkB,GAClB,eAAe,GACf,gBAAgB,GAChB,eAAe,GACf,cAAc,CAAC;AAEnB;;GAEG;AACH,MAAM,MAAM,iBAAiB,GACzB,gBAAgB,GAChB,aAAa,GACb,kBAAkB,GAClB,aAAa,GACb,cAAc,GACd,kBAAkB,GAClB,gBAAgB,GAChB,gBAAgB,GAChB,oBAAoB,GACpB,qBAAqB,GACrB,iBAAiB,GACjB,oBAAoB,GACpB,YAAY,GACZ,cAAc,GACd,oBAAoB,GACpB,sBAAsB,CAAC;AAE3B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,qBAAqB,GAAG,iBAAiB,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,aAAa,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;IAC7C,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,gCAAgC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,mCAAmC;IACnC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IAExC,4BAA4B;IAC5B,MAAM,CAAC,EAAE;QACP,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,cAAc,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC/C,WAAW,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACzC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;KACpC,CAAC;IAEF,oBAAoB;IACpB,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,QAAQ,CAAC;KACrB,CAAC;IAEF,+CAA+C;IAC/C,WAAW,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;IAEvD,+CAA+C;IAC/C,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,GAAG,CAAC;CACrB;AAgBD;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,EAelC,CAAC;AAIF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;IAClD,OAAO,CAAC,WAAW,CAAmD;IACtE,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAK;IAEvB;;;;;;OAMG;IACG,UAAU,CAAC,MAAM,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IA0D3D;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAmC/B;;;OAGG;IACH,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,GAAG,CAAC,GAAG,IAAI;IA2BtC;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO;IAoBxC;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,oBAAoB,CAAC;IA+ClD;;OAEG;IACH,UAAU,IAAI,GAAG;IAIjB;;OAEG;IACH,UAAU,IAAI,cAAc,GAAG,IAAI;IAInC;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,cAAc,IAAI,MAAM;IAQxB;;OAEG;IACH,eAAe,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAUnF;;OAEG;YACW,WAAW;IA0DzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAuE3B;;OAEG;YACW,cAAc;IAqC5B;;;;OAIG;YACW,gBAAgB;IAyZ9B;;OAEG;YACW,kBAAkB;IAuBhC;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAiB9B;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IAuC9B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;CAOhC;AAED,eAAe,kBAAkB,CAAC"}
|
|
@@ -387,7 +387,6 @@ export class ControllerRegistry extends EventEmitter {
|
|
|
387
387
|
case 'causalRecall':
|
|
388
388
|
case 'learningSystem':
|
|
389
389
|
case 'explainableRecall':
|
|
390
|
-
case 'nightlyLearner':
|
|
391
390
|
case 'graphTransformer':
|
|
392
391
|
case 'graphAdapter':
|
|
393
392
|
case 'gnnService':
|
|
@@ -397,11 +396,20 @@ export class ControllerRegistry extends EventEmitter {
|
|
|
397
396
|
case 'rvfOptimizer':
|
|
398
397
|
case 'mmrDiversityRanker':
|
|
399
398
|
return this.agentdb !== null;
|
|
399
|
+
// ADR-125 Phase 4 — nightlyLearner is enabled when EITHER an AgentDB
|
|
400
|
+
// is present (legacy path) OR a MemoryService is registered (new path
|
|
401
|
+
// backed by MemoryConsolidator.runAll).
|
|
402
|
+
case 'nightlyLearner':
|
|
403
|
+
return this.agentdb !== null || !!this.config.memoryService;
|
|
400
404
|
// SemanticRouter — auto-enable if agentdb available (exported since alpha.10)
|
|
401
405
|
case 'semanticRouter':
|
|
402
406
|
return this.agentdb !== null;
|
|
403
|
-
//
|
|
407
|
+
// ADR-125 Phase 5 — hybridSearch auto-enables when a MemoryService is
|
|
408
|
+
// registered. Replaces the prior "placeholder, require explicit enable"
|
|
409
|
+
// posture.
|
|
404
410
|
case 'hybridSearch':
|
|
411
|
+
return !!this.config.memoryService;
|
|
412
|
+
// Optional controllers
|
|
405
413
|
case 'agentMemoryScope':
|
|
406
414
|
case 'sonaTrajectory':
|
|
407
415
|
case 'federatedSession':
|
|
@@ -494,9 +502,69 @@ export class ControllerRegistry extends EventEmitter {
|
|
|
494
502
|
});
|
|
495
503
|
return cache;
|
|
496
504
|
}
|
|
497
|
-
case 'hybridSearch':
|
|
498
|
-
//
|
|
499
|
-
|
|
505
|
+
case 'hybridSearch': {
|
|
506
|
+
// ADR-125 Phase 5 — real RRF + MMR hybrid search.
|
|
507
|
+
// Calls semanticSearch() (which degrades gracefully when embedder is
|
|
508
|
+
// unavailable) AND searchKeyword() independently, fuses via RRF, then
|
|
509
|
+
// diversifies via MMR (lambda=0.7).
|
|
510
|
+
const memSvc = this.config.memoryService;
|
|
511
|
+
if (!memSvc)
|
|
512
|
+
return null;
|
|
513
|
+
const adapter = typeof memSvc.getAdapter === 'function' ? memSvc.getAdapter() : null;
|
|
514
|
+
if (!adapter)
|
|
515
|
+
return null;
|
|
516
|
+
const { applyRRF, applyMMR } = await import('./smart-retrieval.js');
|
|
517
|
+
return {
|
|
518
|
+
/**
|
|
519
|
+
* Run a fused hybrid search.
|
|
520
|
+
* @param query Free-form query string.
|
|
521
|
+
* @param opts.limit Final result count (default 10).
|
|
522
|
+
* @param opts.fanOutK Per-arm fanout before fusion (default = limit * 3).
|
|
523
|
+
* @param opts.mmrLambda MMR relevance/diversity balance (default 0.7).
|
|
524
|
+
*/
|
|
525
|
+
search: async (query, opts = {}) => {
|
|
526
|
+
const limit = opts.limit ?? 10;
|
|
527
|
+
const fanOutK = opts.fanOutK ?? Math.max(limit * 3, 20);
|
|
528
|
+
const mmrLambda = opts.mmrLambda ?? 0.7;
|
|
529
|
+
// Dense arm — may internally fall back to keyword if embedder is
|
|
530
|
+
// missing, but that's still a valid signal to fuse.
|
|
531
|
+
let dense = [];
|
|
532
|
+
try {
|
|
533
|
+
dense = await adapter.semanticSearch(query, fanOutK);
|
|
534
|
+
}
|
|
535
|
+
catch {
|
|
536
|
+
dense = [];
|
|
537
|
+
}
|
|
538
|
+
// Sparse arm — FTS5 / keyword search.
|
|
539
|
+
let sparse = [];
|
|
540
|
+
try {
|
|
541
|
+
sparse = await adapter.searchKeyword(query, { k: fanOutK });
|
|
542
|
+
}
|
|
543
|
+
catch {
|
|
544
|
+
sparse = [];
|
|
545
|
+
}
|
|
546
|
+
// Adapt SearchResult[] → SearchCandidate[] expected by RRF
|
|
547
|
+
const toCands = (results) => results.map((r) => ({
|
|
548
|
+
id: r.entry.id,
|
|
549
|
+
key: r.entry.key,
|
|
550
|
+
content: r.entry.content,
|
|
551
|
+
namespace: r.entry.namespace,
|
|
552
|
+
metadata: r.entry.metadata,
|
|
553
|
+
createdAt: r.entry.createdAt,
|
|
554
|
+
updatedAt: r.entry.updatedAt,
|
|
555
|
+
score: r.score,
|
|
556
|
+
_entry: r.entry,
|
|
557
|
+
}));
|
|
558
|
+
const fused = applyRRF([toCands(dense), toCands(sparse)], 60);
|
|
559
|
+
const diverse = applyMMR(fused, mmrLambda, limit);
|
|
560
|
+
return diverse.map((s) => ({
|
|
561
|
+
entry: s.candidate._entry,
|
|
562
|
+
score: s.score,
|
|
563
|
+
}));
|
|
564
|
+
},
|
|
565
|
+
source: 'hybrid-rrf-mmr',
|
|
566
|
+
};
|
|
567
|
+
}
|
|
500
568
|
case 'agentMemoryScope':
|
|
501
569
|
// Agent memory scope — placeholder, activated when explicitly enabled
|
|
502
570
|
return null;
|
|
@@ -646,6 +714,25 @@ export class ControllerRegistry extends EventEmitter {
|
|
|
646
714
|
}
|
|
647
715
|
}
|
|
648
716
|
case 'nightlyLearner': {
|
|
717
|
+
// ADR-125 Phase 4 — prefer the MemoryConsolidator when a
|
|
718
|
+
// MemoryService is registered. The consolidator's `runAll()` is the
|
|
719
|
+
// documented entry point for sweep + dedup + compact and replaces the
|
|
720
|
+
// thin delegate to AgentDB's NightlyLearner.
|
|
721
|
+
const memSvc = this.config.memoryService;
|
|
722
|
+
if (memSvc && typeof memSvc.getConsolidator === 'function') {
|
|
723
|
+
try {
|
|
724
|
+
const consolidator = await memSvc.getConsolidator();
|
|
725
|
+
return {
|
|
726
|
+
run: () => consolidator.runAll(),
|
|
727
|
+
runAll: () => consolidator.runAll(),
|
|
728
|
+
sweepExpired: () => consolidator.sweepExpired(),
|
|
729
|
+
dedup: (s) => consolidator.dedup(s),
|
|
730
|
+
compactHnsw: () => consolidator.compactHnsw(),
|
|
731
|
+
source: 'memory-consolidator',
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
catch { /* fall through to AgentDB */ }
|
|
735
|
+
}
|
|
649
736
|
if (!this.agentdb)
|
|
650
737
|
return null;
|
|
651
738
|
try {
|