@monoes/memory 1.0.3 → 1.0.5
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/dist/index.d.ts +1 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +1 -1
- package/dist/lancedb-backend.d.ts +6 -0
- package/dist/lancedb-backend.d.ts.map +1 -1
- package/dist/lancedb-backend.js +13 -0
- package/dist/lancedb-backend.js.map +1 -1
- package/package.json +1 -1
- package/dist/diskann-backend.d.ts +0 -126
- package/dist/diskann-backend.d.ts.map +0 -1
- package/dist/diskann-backend.js +0 -336
- package/dist/diskann-backend.js.map +0 -1
- package/dist/partitioned-hnsw.d.ts +0 -65
- package/dist/partitioned-hnsw.d.ts.map +0 -1
- package/dist/partitioned-hnsw.js +0 -209
- package/dist/partitioned-hnsw.js.map +0 -1
- package/dist/tier-manager.d.ts +0 -79
- package/dist/tier-manager.d.ts.map +0 -1
- package/dist/tier-manager.js +0 -173
- package/dist/tier-manager.js.map +0 -1
package/dist/tier-manager.d.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TierManager — Routes memory operations to the correct tier (Task 09)
|
|
3
|
-
*
|
|
4
|
-
* Coordinates short-term (in-memory), long-term (persistent backend),
|
|
5
|
-
* entity (JSON-lines KV), and contextual (session summaries) tiers.
|
|
6
|
-
*
|
|
7
|
-
* @module v1/memory/tier-manager
|
|
8
|
-
*/
|
|
9
|
-
import type { IMemoryBackend, MemoryEntry, MemoryEntryInput, MemoryTier, TierManagerConfig } from './types.js';
|
|
10
|
-
import { ShortTermMemory } from './tiers/short-term.js';
|
|
11
|
-
import { EntityMemory } from './tiers/entity.js';
|
|
12
|
-
import { ContextualMemory } from './tiers/contextual.js';
|
|
13
|
-
import { PartitionedHNSW, type PartitionedHNSWConfig } from './partitioned-hnsw.js';
|
|
14
|
-
import { DiskAnnBackend, type DiskAnnBackendConfig } from './diskann-backend.js';
|
|
15
|
-
export declare class TierManager {
|
|
16
|
-
readonly shortTerm: ShortTermMemory;
|
|
17
|
-
readonly entity: EntityMemory;
|
|
18
|
-
readonly contextual: ContextualMemory;
|
|
19
|
-
/** Timestamp-partitioned HNSW for temporally-local semantic search.
|
|
20
|
-
* Source: ICDE 2025 Timestamp-Partitioned HNSW */
|
|
21
|
-
readonly partitionedIndex: PartitionedHNSW;
|
|
22
|
-
/**
|
|
23
|
-
* Optional DiskANN backend for large-scale ANN search (Tier 4).
|
|
24
|
-
* Activated by passing `diskAnnConfig` to the constructor.
|
|
25
|
-
* Wraps the longTermBackend so all CRUD still flows through the delegate;
|
|
26
|
-
* `search()` uses the disk-resident graph + quantised beam search.
|
|
27
|
-
* Source: arXiv:2305.04359
|
|
28
|
-
*/
|
|
29
|
-
readonly diskann?: DiskAnnBackend;
|
|
30
|
-
private readonly longTermBackend;
|
|
31
|
-
private readonly config;
|
|
32
|
-
constructor(longTermBackend: IMemoryBackend, config?: Partial<TierManagerConfig>, partitionedHNSWConfig?: PartitionedHNSWConfig, diskAnnConfig?: DiskAnnBackendConfig);
|
|
33
|
-
/**
|
|
34
|
-
* Store a memory entry, routing to the correct tier.
|
|
35
|
-
*
|
|
36
|
-
* - `short-term` goes to the in-memory buffer
|
|
37
|
-
* - `long-term` (or unspecified) goes to the persistent backend
|
|
38
|
-
*
|
|
39
|
-
* All entries are also indexed in the timestamp-partitioned HNSW for
|
|
40
|
-
* temporally-local search (ICDE 2025).
|
|
41
|
-
*
|
|
42
|
-
* Returns the generated entry ID.
|
|
43
|
-
*/
|
|
44
|
-
store(input: MemoryEntryInput & {
|
|
45
|
-
tier?: MemoryTier;
|
|
46
|
-
}): Promise<string>;
|
|
47
|
-
/**
|
|
48
|
-
* Merged search across partitioned HNSW, short-term buffer, long-term backend,
|
|
49
|
-
* and (when configured) DiskANN beam search.
|
|
50
|
-
*
|
|
51
|
-
* Order of precedence:
|
|
52
|
-
* 1. Partitioned HNSW (newest buckets first — temporal locality)
|
|
53
|
-
* 2. Short-term in-memory buffer
|
|
54
|
-
* 3. Long-term persistent backend (metadata / hybrid query)
|
|
55
|
-
* 4. DiskANN ANN search — only when diskAnnConfig was supplied; uses a
|
|
56
|
-
* character-frequency proxy embedding as the query vector (approximation)
|
|
57
|
-
*
|
|
58
|
-
* Results are deduplicated by entry ID.
|
|
59
|
-
*/
|
|
60
|
-
search(query: string, limit?: number): Promise<MemoryEntry[]>;
|
|
61
|
-
/**
|
|
62
|
-
* Derive a fixed-length Float32 proxy embedding from plain text.
|
|
63
|
-
*
|
|
64
|
-
* Maps character byte values into a 128-dimensional L2-normalised vector.
|
|
65
|
-
* This is NOT a semantic embedding — it is solely used to drive DiskANN
|
|
66
|
-
* beam traversal when no real embedding generator is available at this
|
|
67
|
-
* call site. Quality of DiskANN results improves dramatically when entries
|
|
68
|
-
* are stored with real semantic embeddings.
|
|
69
|
-
*/
|
|
70
|
-
private static textToVec;
|
|
71
|
-
/**
|
|
72
|
-
* Flush the short-term buffer into the long-term backend.
|
|
73
|
-
* Promoted entries are also added to the partitioned HNSW index so they
|
|
74
|
-
* remain visible in partition-based searches after promotion.
|
|
75
|
-
* Returns the number of entries promoted.
|
|
76
|
-
*/
|
|
77
|
-
flushShortTerm(): Promise<number>;
|
|
78
|
-
}
|
|
79
|
-
//# sourceMappingURL=tier-manager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tier-manager.d.ts","sourceRoot":"","sources":["../src/tier-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjF,qBAAa,WAAW;IACtB,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IAEtC;uDACmD;IACnD,QAAQ,CAAC,gBAAgB,EAAE,eAAe,CAAC;IAE3C;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;IAElC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;gBAGzC,eAAe,EAAE,cAAc,EAC/B,MAAM,GAAE,OAAO,CAAC,iBAAiB,CAAM,EACvC,qBAAqB,GAAE,qBAA0B,EACjD,aAAa,CAAC,EAAE,oBAAoB;IA4BtC;;;;;;;;;;OAUG;IACG,KAAK,CAAC,KAAK,EAAE,gBAAgB,GAAG;QAAE,IAAI,CAAC,EAAE,UAAU,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAgB7E;;;;;;;;;;;;OAYG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAmD/D;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,CAAC,SAAS;IAYxB;;;;;OAKG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;CAUxC"}
|
package/dist/tier-manager.js
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TierManager — Routes memory operations to the correct tier (Task 09)
|
|
3
|
-
*
|
|
4
|
-
* Coordinates short-term (in-memory), long-term (persistent backend),
|
|
5
|
-
* entity (JSON-lines KV), and contextual (session summaries) tiers.
|
|
6
|
-
*
|
|
7
|
-
* @module v1/memory/tier-manager
|
|
8
|
-
*/
|
|
9
|
-
import { createDefaultEntry } from './types.js';
|
|
10
|
-
import { ShortTermMemory } from './tiers/short-term.js';
|
|
11
|
-
import { EntityMemory } from './tiers/entity.js';
|
|
12
|
-
import { ContextualMemory } from './tiers/contextual.js';
|
|
13
|
-
import { PartitionedHNSW } from './partitioned-hnsw.js';
|
|
14
|
-
import { DiskAnnBackend } from './diskann-backend.js';
|
|
15
|
-
export class TierManager {
|
|
16
|
-
shortTerm;
|
|
17
|
-
entity;
|
|
18
|
-
contextual;
|
|
19
|
-
/** Timestamp-partitioned HNSW for temporally-local semantic search.
|
|
20
|
-
* Source: ICDE 2025 Timestamp-Partitioned HNSW */
|
|
21
|
-
partitionedIndex;
|
|
22
|
-
/**
|
|
23
|
-
* Optional DiskANN backend for large-scale ANN search (Tier 4).
|
|
24
|
-
* Activated by passing `diskAnnConfig` to the constructor.
|
|
25
|
-
* Wraps the longTermBackend so all CRUD still flows through the delegate;
|
|
26
|
-
* `search()` uses the disk-resident graph + quantised beam search.
|
|
27
|
-
* Source: arXiv:2305.04359
|
|
28
|
-
*/
|
|
29
|
-
diskann;
|
|
30
|
-
longTermBackend;
|
|
31
|
-
config;
|
|
32
|
-
constructor(longTermBackend, config = {}, partitionedHNSWConfig = {}, diskAnnConfig) {
|
|
33
|
-
this.config = {
|
|
34
|
-
shortTermCapacity: config.shortTermCapacity ?? 500,
|
|
35
|
-
entityStorePath: config.entityStorePath ?? './data/memory/entities.jsonl',
|
|
36
|
-
contextualNamespace: config.contextualNamespace ?? 'contextual-summaries',
|
|
37
|
-
autoFlushOnSessionEnd: config.autoFlushOnSessionEnd ?? true,
|
|
38
|
-
};
|
|
39
|
-
// If diskAnnConfig is supplied, wrap longTermBackend in a DiskAnnBackend.
|
|
40
|
-
// All CRUD still delegates to the original backend; search() uses DiskANN.
|
|
41
|
-
if (diskAnnConfig) {
|
|
42
|
-
const diskannBackend = new DiskAnnBackend(longTermBackend, diskAnnConfig);
|
|
43
|
-
this.diskann = diskannBackend;
|
|
44
|
-
this.longTermBackend = diskannBackend;
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
this.longTermBackend = longTermBackend;
|
|
48
|
-
}
|
|
49
|
-
this.shortTerm = new ShortTermMemory(this.config.shortTermCapacity);
|
|
50
|
-
this.entity = new EntityMemory(this.config.entityStorePath);
|
|
51
|
-
this.contextual = new ContextualMemory(this.longTermBackend, this.config.contextualNamespace);
|
|
52
|
-
this.partitionedIndex = new PartitionedHNSW(partitionedHNSWConfig);
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Store a memory entry, routing to the correct tier.
|
|
56
|
-
*
|
|
57
|
-
* - `short-term` goes to the in-memory buffer
|
|
58
|
-
* - `long-term` (or unspecified) goes to the persistent backend
|
|
59
|
-
*
|
|
60
|
-
* All entries are also indexed in the timestamp-partitioned HNSW for
|
|
61
|
-
* temporally-local search (ICDE 2025).
|
|
62
|
-
*
|
|
63
|
-
* Returns the generated entry ID.
|
|
64
|
-
*/
|
|
65
|
-
async store(input) {
|
|
66
|
-
const entry = createDefaultEntry(input);
|
|
67
|
-
const tier = input.tier ?? 'long-term';
|
|
68
|
-
if (tier === 'short-term') {
|
|
69
|
-
this.shortTerm.store(entry);
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
await this.longTermBackend.store(entry);
|
|
73
|
-
}
|
|
74
|
-
// Index in partitioned HNSW for temporal-locality search
|
|
75
|
-
this.partitionedIndex.add(entry);
|
|
76
|
-
return entry.id;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Merged search across partitioned HNSW, short-term buffer, long-term backend,
|
|
80
|
-
* and (when configured) DiskANN beam search.
|
|
81
|
-
*
|
|
82
|
-
* Order of precedence:
|
|
83
|
-
* 1. Partitioned HNSW (newest buckets first — temporal locality)
|
|
84
|
-
* 2. Short-term in-memory buffer
|
|
85
|
-
* 3. Long-term persistent backend (metadata / hybrid query)
|
|
86
|
-
* 4. DiskANN ANN search — only when diskAnnConfig was supplied; uses a
|
|
87
|
-
* character-frequency proxy embedding as the query vector (approximation)
|
|
88
|
-
*
|
|
89
|
-
* Results are deduplicated by entry ID.
|
|
90
|
-
*/
|
|
91
|
-
async search(query, limit = 10) {
|
|
92
|
-
// 1. Partitioned HNSW — nearest neighbours in recent time buckets first
|
|
93
|
-
const partitionedResults = this.partitionedIndex.search(null, // no raw embedding at this call-site; uses text fallback
|
|
94
|
-
query, limit);
|
|
95
|
-
// 2. Short-term results (synchronous)
|
|
96
|
-
const shortResults = this.shortTerm.search(query, limit);
|
|
97
|
-
// 3. Long-term results via the backend query interface
|
|
98
|
-
const longResults = await this.longTermBackend.query({
|
|
99
|
-
type: 'hybrid',
|
|
100
|
-
content: query,
|
|
101
|
-
limit,
|
|
102
|
-
});
|
|
103
|
-
// 4. DiskANN ANN search (activated when diskann is configured)
|
|
104
|
-
// Uses a character-frequency proxy embedding to drive beam search.
|
|
105
|
-
// Re-ranking in DiskAnnBackend.search() uses the actual stored embeddings.
|
|
106
|
-
let annEntries = [];
|
|
107
|
-
if (this.diskann) {
|
|
108
|
-
try {
|
|
109
|
-
const proxyVec = TierManager.textToVec(query);
|
|
110
|
-
const annResults = await this.diskann.search(proxyVec, { k: limit });
|
|
111
|
-
annEntries = annResults.map(r => r.entry);
|
|
112
|
-
}
|
|
113
|
-
catch {
|
|
114
|
-
// Non-fatal; DiskANN is best-effort
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
// Deduplicate by id: partitioned > short-term > long-term > diskann
|
|
118
|
-
// Iterate each source directly to avoid allocating a combined array and to
|
|
119
|
-
// enable early-exit between sources once the limit is reached.
|
|
120
|
-
const seen = new Set();
|
|
121
|
-
const merged = [];
|
|
122
|
-
outer: for (const batch of [partitionedResults, shortResults, longResults, annEntries]) {
|
|
123
|
-
for (const entry of batch) {
|
|
124
|
-
if (!seen.has(entry.id)) {
|
|
125
|
-
seen.add(entry.id);
|
|
126
|
-
merged.push(entry);
|
|
127
|
-
}
|
|
128
|
-
if (merged.length >= limit)
|
|
129
|
-
break outer;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return merged;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Derive a fixed-length Float32 proxy embedding from plain text.
|
|
136
|
-
*
|
|
137
|
-
* Maps character byte values into a 128-dimensional L2-normalised vector.
|
|
138
|
-
* This is NOT a semantic embedding — it is solely used to drive DiskANN
|
|
139
|
-
* beam traversal when no real embedding generator is available at this
|
|
140
|
-
* call site. Quality of DiskANN results improves dramatically when entries
|
|
141
|
-
* are stored with real semantic embeddings.
|
|
142
|
-
*/
|
|
143
|
-
static textToVec(text, dims = 128) {
|
|
144
|
-
const vec = new Float32Array(dims);
|
|
145
|
-
for (let i = 0; i < text.length; i++) {
|
|
146
|
-
vec[i % dims] += text.charCodeAt(i) / 255;
|
|
147
|
-
}
|
|
148
|
-
let norm = 0;
|
|
149
|
-
for (const v of vec)
|
|
150
|
-
norm += v * v;
|
|
151
|
-
norm = Math.sqrt(norm) || 1;
|
|
152
|
-
for (let i = 0; i < dims; i++)
|
|
153
|
-
vec[i] /= norm;
|
|
154
|
-
return vec;
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Flush the short-term buffer into the long-term backend.
|
|
158
|
-
* Promoted entries are also added to the partitioned HNSW index so they
|
|
159
|
-
* remain visible in partition-based searches after promotion.
|
|
160
|
-
* Returns the number of entries promoted.
|
|
161
|
-
*/
|
|
162
|
-
async flushShortTerm() {
|
|
163
|
-
// Snapshot the entries before flush so we can index them afterwards.
|
|
164
|
-
// ShortTermMemory.flush() clears the buffer, so we must read first.
|
|
165
|
-
const toPromote = this.shortTerm.snapshot();
|
|
166
|
-
const count = await this.shortTerm.flush(this.longTermBackend);
|
|
167
|
-
for (const entry of toPromote) {
|
|
168
|
-
this.partitionedIndex.add(entry);
|
|
169
|
-
}
|
|
170
|
-
return count;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
//# sourceMappingURL=tier-manager.js.map
|
package/dist/tier-manager.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tier-manager.js","sourceRoot":"","sources":["../src/tier-manager.ts"],"names":[],"mappings":"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"}
|