@claude-flow/memory 3.0.0-alpha.16 → 3.0.0-alpha.18
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 +60 -0
- 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/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 +87 -0
- 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 +87 -0
- package/dist/sqljs-backend.js.map +1 -1
- package/package.json +4 -4
- 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,96 @@
|
|
|
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 type { MemoryEntry } from './types.js';
|
|
25
|
+
/**
|
|
26
|
+
* Strategy for resolving content-hash duplicates inside {@link MemoryConsolidator.dedup}.
|
|
27
|
+
*/
|
|
28
|
+
export type DedupStrategy = 'keep-newest' | 'keep-oldest' | 'merge-tags';
|
|
29
|
+
export interface ConsolidatorOptions {
|
|
30
|
+
/** Default strategy when `dedup()` is invoked with no argument. */
|
|
31
|
+
dedupStrategy?: DedupStrategy;
|
|
32
|
+
/** Used by `MemoryService` when scheduling automatic runs (ms). */
|
|
33
|
+
intervalMs?: number;
|
|
34
|
+
}
|
|
35
|
+
export interface SweepResult {
|
|
36
|
+
removed: number;
|
|
37
|
+
remaining: number;
|
|
38
|
+
hnswRemoved: number;
|
|
39
|
+
}
|
|
40
|
+
export interface DedupResult {
|
|
41
|
+
merged: number;
|
|
42
|
+
groups: number;
|
|
43
|
+
}
|
|
44
|
+
export interface CompactResult {
|
|
45
|
+
before: number;
|
|
46
|
+
after: number;
|
|
47
|
+
durationMs: number;
|
|
48
|
+
}
|
|
49
|
+
export interface ConsolidationResult {
|
|
50
|
+
sweep: SweepResult;
|
|
51
|
+
dedup: DedupResult;
|
|
52
|
+
compact: CompactResult;
|
|
53
|
+
totalDurationMs: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Minimal surface the consolidator needs from `UnifiedMemoryService`. Avoids
|
|
57
|
+
* a circular type import.
|
|
58
|
+
*/
|
|
59
|
+
interface ServiceLike {
|
|
60
|
+
getAdapter(): {
|
|
61
|
+
entries: Map<string, MemoryEntry>;
|
|
62
|
+
namespaceIndex: Map<string, Set<string>>;
|
|
63
|
+
keyIndex: Map<string, string>;
|
|
64
|
+
tagIndex: Map<string, Set<string>>;
|
|
65
|
+
[key: string]: any;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export declare class MemoryConsolidator {
|
|
69
|
+
private readonly service;
|
|
70
|
+
private readonly opts;
|
|
71
|
+
constructor(service: ServiceLike, opts?: ConsolidatorOptions);
|
|
72
|
+
/**
|
|
73
|
+
* Drop all entries whose `expiresAt` is in the past.
|
|
74
|
+
*/
|
|
75
|
+
sweepExpired(): Promise<SweepResult>;
|
|
76
|
+
/**
|
|
77
|
+
* Collapse content-hash duplicates across all namespaces per `strategy`.
|
|
78
|
+
*
|
|
79
|
+
* - `keep-newest`: keep the entry with the highest `updatedAt`, drop the rest.
|
|
80
|
+
* - `keep-oldest`: keep the entry with the lowest `createdAt`, drop the rest.
|
|
81
|
+
* - `merge-tags`: keep newest, but union the tag sets of the duplicates first.
|
|
82
|
+
*/
|
|
83
|
+
dedup(strategy?: DedupStrategy): Promise<DedupResult>;
|
|
84
|
+
/**
|
|
85
|
+
* Rebuild the HNSW index from the current set of entries with embeddings.
|
|
86
|
+
* Returns a count snapshot + duration.
|
|
87
|
+
*/
|
|
88
|
+
compactHnsw(): Promise<CompactResult>;
|
|
89
|
+
/**
|
|
90
|
+
* Sweep → dedup → compact. Used by the background timer and by the
|
|
91
|
+
* `nightlyLearner` AgentDB controller.
|
|
92
|
+
*/
|
|
93
|
+
runAll(): Promise<ConsolidationResult>;
|
|
94
|
+
}
|
|
95
|
+
export default MemoryConsolidator;
|
|
96
|
+
//# sourceMappingURL=consolidator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidator.d.ts","sourceRoot":"","sources":["../src/consolidator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,aAAa,GAAG,YAAY,CAAC;AAEzE,MAAM,WAAW,mBAAmB;IAClC,mEAAmE;IACnE,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,UAAU,WAAW;IACnB,UAAU,IAAI;QAEZ,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAClC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QACzC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QAEnC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,CAAC;CACH;AAED,qBAAa,kBAAkB;IAE3B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBADJ,OAAO,EAAE,WAAW,EACpB,IAAI,GAAE,mBAAwB;IAGjD;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,WAAW,CAAC;IA2C1C;;;;;;OAMG;IACG,KAAK,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC;IAwE3D;;;OAGG;IACG,WAAW,IAAI,OAAO,CAAC,aAAa,CAAC;IAsC3C;;;OAGG;IACG,MAAM,IAAI,OAAO,CAAC,mBAAmB,CAAC;CAY7C;AAED,eAAe,kBAAkB,CAAC"}
|
|
@@ -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":"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"}
|