@monoes/memory 1.0.5 → 1.0.6
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 +72 -840
- package/dist/atomic-file.d.ts +17 -0
- package/dist/atomic-file.d.ts.map +1 -0
- package/dist/atomic-file.js +27 -0
- package/dist/atomic-file.js.map +1 -0
- package/dist/cache-manager.d.ts +0 -0
- package/dist/cache-manager.d.ts.map +1 -1
- package/dist/cache-manager.js +0 -0
- package/dist/cache-manager.js.map +1 -1
- package/dist/checkpointer.d.ts +13 -0
- package/dist/checkpointer.d.ts.map +1 -1
- package/dist/checkpointer.js +69 -6
- package/dist/checkpointer.js.map +1 -1
- package/dist/controller-registry.d.ts +2 -8
- package/dist/controller-registry.d.ts.map +1 -1
- package/dist/controller-registry.js +4 -49
- package/dist/controller-registry.js.map +1 -1
- package/dist/database-provider.d.ts +0 -0
- package/dist/database-provider.d.ts.map +0 -0
- package/dist/database-provider.js +0 -0
- package/dist/database-provider.js.map +1 -1
- package/dist/hnsw-index.d.ts +0 -0
- package/dist/hnsw-index.d.ts.map +1 -1
- package/dist/hnsw-index.js +0 -0
- package/dist/hnsw-index.js.map +1 -1
- package/dist/index.d.ts +0 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -17
- package/dist/index.js.map +1 -1
- package/dist/knowledge/document-chunker.d.ts +0 -0
- package/dist/knowledge/document-chunker.d.ts.map +0 -0
- package/dist/knowledge/document-chunker.js +0 -0
- package/dist/knowledge/document-chunker.js.map +1 -1
- package/dist/knowledge/index.d.ts +0 -0
- package/dist/knowledge/index.d.ts.map +0 -0
- package/dist/knowledge/index.js +0 -0
- package/dist/knowledge/index.js.map +0 -0
- package/dist/knowledge/knowledge-retriever.d.ts +0 -0
- package/dist/knowledge/knowledge-retriever.d.ts.map +1 -1
- package/dist/knowledge/knowledge-retriever.js +0 -0
- package/dist/knowledge/knowledge-retriever.js.map +1 -1
- package/dist/knowledge/knowledge-store.d.ts +0 -0
- package/dist/knowledge/knowledge-store.d.ts.map +1 -1
- package/dist/knowledge/knowledge-store.js +0 -0
- package/dist/knowledge/knowledge-store.js.map +0 -0
- package/dist/lancedb-backend.d.ts +5 -0
- package/dist/lancedb-backend.d.ts.map +1 -1
- package/dist/lancedb-backend.js +70 -12
- package/dist/lancedb-backend.js.map +1 -1
- package/dist/math-utils.d.ts +0 -0
- package/dist/math-utils.d.ts.map +0 -0
- package/dist/math-utils.js +0 -0
- package/dist/math-utils.js.map +0 -0
- package/dist/migration.d.ts +1 -0
- package/dist/migration.d.ts.map +1 -1
- package/dist/migration.js +50 -21
- package/dist/migration.js.map +1 -1
- package/dist/prompt-version-store.d.ts +0 -0
- package/dist/prompt-version-store.d.ts.map +1 -1
- package/dist/prompt-version-store.js +0 -0
- package/dist/prompt-version-store.js.map +0 -0
- package/dist/query-builder.d.ts +0 -0
- package/dist/query-builder.d.ts.map +1 -1
- package/dist/query-builder.js +0 -0
- package/dist/query-builder.js.map +1 -1
- package/dist/sqlite-backend.d.ts +0 -0
- package/dist/sqlite-backend.d.ts.map +1 -1
- package/dist/sqlite-backend.js +38 -9
- package/dist/sqlite-backend.js.map +1 -1
- package/dist/sqljs-backend.d.ts +1 -0
- package/dist/sqljs-backend.d.ts.map +1 -1
- package/dist/sqljs-backend.js +64 -13
- package/dist/sqljs-backend.js.map +1 -1
- package/dist/types/checkpoint.d.ts +0 -0
- package/dist/types/checkpoint.d.ts.map +0 -0
- package/dist/types/checkpoint.js +0 -0
- package/dist/types/checkpoint.js.map +0 -0
- package/dist/types.d.ts +1 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -0
- package/dist/types.js.map +1 -1
- package/package.json +12 -13
- package/dist/agent-memory-scope.d.ts +0 -131
- package/dist/agent-memory-scope.d.ts.map +0 -1
- package/dist/agent-memory-scope.js +0 -230
- package/dist/agent-memory-scope.js.map +0 -1
- package/dist/auto-memory-bridge.d.ts +0 -230
- package/dist/auto-memory-bridge.d.ts.map +0 -1
- package/dist/auto-memory-bridge.js +0 -736
- package/dist/auto-memory-bridge.js.map +0 -1
- package/dist/episodic-store.d.ts +0 -58
- package/dist/episodic-store.d.ts.map +0 -1
- package/dist/episodic-store.js +0 -160
- package/dist/episodic-store.js.map +0 -1
- package/dist/learning-bridge.d.ts +0 -180
- package/dist/learning-bridge.d.ts.map +0 -1
- package/dist/learning-bridge.js +0 -566
- package/dist/learning-bridge.js.map +0 -1
- package/dist/memory-graph.d.ts +0 -125
- package/dist/memory-graph.d.ts.map +0 -1
- package/dist/memory-graph.js +0 -429
- package/dist/memory-graph.js.map +0 -1
- package/dist/procedural/action-record.d.ts +0 -19
- package/dist/procedural/action-record.d.ts.map +0 -1
- package/dist/procedural/action-record.js +0 -51
- package/dist/procedural/action-record.js.map +0 -1
- package/dist/procedural/action-sequence-extractor.d.ts +0 -25
- package/dist/procedural/action-sequence-extractor.d.ts.map +0 -1
- package/dist/procedural/action-sequence-extractor.js +0 -91
- package/dist/procedural/action-sequence-extractor.js.map +0 -1
- package/dist/procedural/index.d.ts +0 -14
- package/dist/procedural/index.d.ts.map +0 -1
- package/dist/procedural/index.js +0 -13
- package/dist/procedural/index.js.map +0 -1
- package/dist/procedural/learned-skill.d.ts +0 -17
- package/dist/procedural/learned-skill.d.ts.map +0 -1
- package/dist/procedural/learned-skill.js +0 -73
- package/dist/procedural/learned-skill.js.map +0 -1
- package/dist/procedural/skill-registry.d.ts +0 -25
- package/dist/procedural/skill-registry.d.ts.map +0 -1
- package/dist/procedural/skill-registry.js +0 -56
- package/dist/procedural/skill-registry.js.map +0 -1
- package/dist/procedural/types.d.ts +0 -67
- package/dist/procedural/types.d.ts.map +0 -1
- package/dist/procedural/types.js +0 -15
- package/dist/procedural/types.js.map +0 -1
- package/dist/tiers/contextual.d.ts +0 -45
- package/dist/tiers/contextual.d.ts.map +0 -1
- package/dist/tiers/contextual.js +0 -109
- package/dist/tiers/contextual.js.map +0 -1
- package/dist/tiers/entity.d.ts +0 -46
- package/dist/tiers/entity.d.ts.map +0 -1
- package/dist/tiers/entity.js +0 -106
- package/dist/tiers/entity.js.map +0 -1
- package/dist/tiers/index.d.ts +0 -4
- package/dist/tiers/index.d.ts.map +0 -1
- package/dist/tiers/index.js +0 -4
- package/dist/tiers/index.js.map +0 -1
- package/dist/tiers/short-term.d.ts +0 -42
- package/dist/tiers/short-term.d.ts.map +0 -1
- package/dist/tiers/short-term.js +0 -90
- package/dist/tiers/short-term.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,891 +1,123 @@
|
|
|
1
|
-
# @
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/@monomind/memory)
|
|
4
|
-
[](https://www.npmjs.com/package/@monomind/memory)
|
|
5
|
-
[](https://opensource.org/licenses/MIT)
|
|
6
|
-
[](https://www.typescriptlang.org/)
|
|
7
|
-
|
|
8
|
-
> High-performance memory module for Monomind V1 - LanceDB unification, HNSW indexing, vector search, self-learning knowledge graph, and hybrid SQLite+LanceDB backend (ADR-009).
|
|
9
|
-
|
|
10
|
-
## Features
|
|
11
|
-
|
|
12
|
-
- **Indexed Vector Search** - HNSW (Hierarchical Navigable Small World) vector index for fast similarity search
|
|
13
|
-
- **Hybrid Backend** - SQLite for structured data + LanceDB for vectors (ADR-009)
|
|
14
|
-
- **Auto Memory Bridge** - Bidirectional sync between Claude Code auto memory and LanceDB (ADR-048)
|
|
15
|
-
- **Self-Learning** - LearningBridge connects insights to the ReasoningBank pattern store (ADR-049)
|
|
16
|
-
- **Knowledge Graph** - PageRank + label propagation community detection + HippoRAG PPR re-ranking (ADR-049)
|
|
17
|
-
- **Agent-Scoped Memory** - 3-scope agent memory (project/local/user) with cross-agent knowledge transfer (ADR-049)
|
|
18
|
-
- **Vector Quantization** - Binary, scalar, and product quantization for 4-32x memory reduction
|
|
19
|
-
- **Multiple Distance Metrics** - Cosine, Euclidean, dot product, and Manhattan distance
|
|
20
|
-
- **Query Builder** - Fluent API for building complex memory queries
|
|
21
|
-
- **Cache Manager** - LRU caching with configurable size and TTL
|
|
22
|
-
- **Migration Tools** - Seamless migration from V2 memory systems
|
|
23
|
-
- **DiskANN Backend** - SSD-resident Vamana ANN graph for million-scale entry search (arXiv:2305.04359)
|
|
24
|
-
- **A-MEM Auto-Linking** - Bidirectional reference edges auto-created on store (arXiv:2409.11987)
|
|
25
|
-
- **GraphRAG Community Retrieval** - Community-level summaries annotate semantic search results (arXiv:2404.16130)
|
|
26
|
-
- **HippoRAG PPR Re-ranking** - Personalised PageRank re-ranks semantic results via knowledge graph (arXiv:2405.14831)
|
|
27
|
-
- **Collaborative Memory Promotion** - Entries auto-promoted to team scope after 3+ agent reads/24 h (arXiv:2505.18279)
|
|
28
|
-
- **Temporal Knowledge Graph** - Causal/temporal edge typing inspired by Zep/Graphiti (arXiv:2501.13956)
|
|
29
|
-
- **Injection Filter** - Structural prompt-injection detection on semantic search results (arXiv:2302.12173, arXiv:2310.12815)
|
|
30
|
-
|
|
31
|
-
## Installation
|
|
1
|
+
# @monoes/memory
|
|
32
2
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
```
|
|
3
|
+
[](https://github.com/monoes/monomind/blob/main/LICENSE)
|
|
4
|
+
[](https://nodejs.org)
|
|
36
5
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
```typescript
|
|
40
|
-
import { HNSWIndex, LanceDBAdapter, CacheManager } from '@monomind/memory';
|
|
41
|
-
|
|
42
|
-
// Create HNSW index for vector search
|
|
43
|
-
const index = new HNSWIndex({
|
|
44
|
-
dimensions: 1536, // OpenAI embedding size
|
|
45
|
-
M: 16, // Max connections per node
|
|
46
|
-
efConstruction: 200,
|
|
47
|
-
metric: 'cosine'
|
|
48
|
-
});
|
|
6
|
+
**Persistent memory backends for Monomind agents** — SQLite (native or WASM) key-value storage, an optional LanceDB vector backend, a pure-JS HNSW index, JSONL episodic memory, and a chunked knowledge store.
|
|
49
7
|
|
|
50
|
-
|
|
51
|
-
await index.addPoint('memory-1', new Float32Array(embedding));
|
|
52
|
-
await index.addPoint('memory-2', new Float32Array(embedding2));
|
|
8
|
+
> Part of the [Monomind](https://github.com/monoes/monomind) ecosystem. The only hard dependency is `sql.js` (WASM); `better-sqlite3` and `@lancedb/lancedb` are optional and loaded dynamically when installed.
|
|
53
9
|
|
|
54
|
-
|
|
55
|
-
const results = await index.search(queryVector, 10);
|
|
56
|
-
// [{ id: 'memory-1', distance: 0.05 }, { id: 'memory-2', distance: 0.12 }]
|
|
57
|
-
```
|
|
10
|
+
## Install
|
|
58
11
|
|
|
59
|
-
|
|
12
|
+
```bash
|
|
13
|
+
npm install @monoes/memory
|
|
60
14
|
|
|
61
|
-
|
|
15
|
+
# optional: native SQLite and vector search
|
|
16
|
+
npm install better-sqlite3 @lancedb/lancedb apache-arrow
|
|
17
|
+
```
|
|
62
18
|
|
|
63
|
-
|
|
64
|
-
import { HNSWIndex } from '@monomind/memory';
|
|
19
|
+
## What's in the box
|
|
65
20
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
21
|
+
| Export | What it does |
|
|
22
|
+
|---|---|
|
|
23
|
+
| `UnifiedMemoryService` | High-level store/get/search facade backed by `LanceDBBackend` |
|
|
24
|
+
| `SQLiteBackend` / `SqlJsBackend` | Structured key-value memory (native SQLite or zero-compile WASM) |
|
|
25
|
+
| `LanceDBBackend` | Vector memory via `@lancedb/lancedb` (optional dependency, loaded lazily) |
|
|
26
|
+
| `HNSWIndex` | Pure-JS approximate nearest-neighbor index with quantization support |
|
|
27
|
+
| `EpisodicStore` | JSON-lines episodic memory — accumulates agent runs into summarized episodes |
|
|
28
|
+
| `chunkDocument`, `KnowledgeStore`, `KnowledgeRetriever` | Document chunking + retrieval for knowledge bases |
|
|
29
|
+
| `QueryBuilder` / `query()` | Fluent query construction (namespace, tags, threshold, sort) |
|
|
30
|
+
| `CacheManager`, `TieredCacheManager` | LRU caching with size/TTL limits |
|
|
31
|
+
| `createDatabase`, `getPlatformInfo` | Platform-aware provider selection (better-sqlite3 → sql.js → JSON fallback) |
|
|
32
|
+
| `SwarmCheckpointer` | Persist/restore swarm agent state snapshots |
|
|
33
|
+
| `MemoryMigrator` | Import from SQLite, JSON, or Markdown sources |
|
|
34
|
+
| `PromptVersionStore`, `ControllerRegistry` | Prompt version history; init-level controller registry |
|
|
77
35
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
// Search
|
|
82
|
-
const results = await index.search(
|
|
83
|
-
query: Float32Array,
|
|
84
|
-
k: number,
|
|
85
|
-
ef?: number // Search-time depth (higher = more accurate)
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
// Search with filters
|
|
89
|
-
const filtered = await index.searchWithFilters(
|
|
90
|
-
query,
|
|
91
|
-
k,
|
|
92
|
-
(id) => id.startsWith('session-')
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
// Remove vectors
|
|
96
|
-
await index.removePoint(id);
|
|
97
|
-
|
|
98
|
-
// Get statistics
|
|
99
|
-
const stats = index.getStats();
|
|
100
|
-
// { vectorCount, memoryUsage, avgSearchTime, compressionRatio }
|
|
101
|
-
```
|
|
36
|
+
Note: Monomind's live hook/routing hot path uses plain JSON pattern files and
|
|
37
|
+
keyword-based episodic recall — the vector backends here are opt-in, used when
|
|
38
|
+
an embedding generator and the optional native dependencies are provided.
|
|
102
39
|
|
|
103
|
-
|
|
40
|
+
## Quick start — key-value memory
|
|
104
41
|
|
|
105
42
|
```typescript
|
|
106
|
-
import {
|
|
107
|
-
|
|
108
|
-
const adapter = new LanceDBAdapter({
|
|
109
|
-
dimensions: 1536, // vector dimensions
|
|
110
|
-
hnswM: 16, // max connections per HNSW layer
|
|
111
|
-
hnswEfConstruction: 200, // construction-time search depth
|
|
112
|
-
cacheEnabled: true, // LRU result cache
|
|
113
|
-
cacheSize: 10000, // max cached entries
|
|
114
|
-
cacheTtl: 300000, // 5 minutes
|
|
115
|
-
defaultNamespace: 'default',
|
|
116
|
-
embeddingGenerator: async (text) => myEmbedder.embed(text),
|
|
117
|
-
});
|
|
43
|
+
import { SQLiteBackend } from '@monoes/memory';
|
|
118
44
|
|
|
119
|
-
|
|
45
|
+
const backend = new SQLiteBackend({ databasePath: './data/memory.db' });
|
|
46
|
+
await backend.initialize();
|
|
120
47
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
id: 'mem-123',
|
|
48
|
+
await backend.store({
|
|
49
|
+
id: 'mem-1',
|
|
124
50
|
key: 'user-preference',
|
|
125
51
|
content: 'User prefers dark mode',
|
|
126
52
|
type: 'semantic',
|
|
127
53
|
namespace: 'preferences',
|
|
128
54
|
tags: ['ui'],
|
|
129
|
-
metadata: {},
|
|
130
|
-
accessLevel: 'private',
|
|
131
|
-
createdAt: Date.now(),
|
|
132
|
-
updatedAt: Date.now(),
|
|
133
|
-
version: 1,
|
|
134
|
-
references: [],
|
|
135
|
-
accessCount: 0,
|
|
136
|
-
lastAccessedAt: Date.now(),
|
|
137
55
|
});
|
|
138
56
|
|
|
139
|
-
|
|
140
|
-
const results = await adapter.semanticSearch('dark mode preference', 10, 0.7);
|
|
141
|
-
// [{ entry: MemoryEntry, score: number, distance: number }, ...]
|
|
142
|
-
|
|
143
|
-
// Convenience: store from plain input (auto-generates id, timestamps)
|
|
144
|
-
const entry = await adapter.storeEntry({
|
|
145
|
-
key: 'my-fact',
|
|
146
|
-
content: 'TypeScript 5+ required',
|
|
147
|
-
namespace: 'learnings',
|
|
148
|
-
type: 'semantic',
|
|
149
|
-
tags: ['setup'],
|
|
150
|
-
metadata: {},
|
|
151
|
-
});
|
|
57
|
+
const entry = await backend.getByKey('preferences', 'user-preference');
|
|
152
58
|
```
|
|
153
59
|
|
|
154
|
-
|
|
60
|
+
## Vector search (optional)
|
|
155
61
|
|
|
156
62
|
```typescript
|
|
157
|
-
import {
|
|
158
|
-
|
|
159
|
-
const cache = new CacheManager<MemoryEntry>({
|
|
160
|
-
maxSize: 1000, // max entries before LRU eviction
|
|
161
|
-
ttl: 3_600_000, // entry TTL in ms (1 hour)
|
|
162
|
-
maxMemory: 50 * 1024 * 1024, // optional memory cap (50 MB)
|
|
163
|
-
lruEnabled: true, // enable LRU ordering (default: true)
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
// Cache operations
|
|
167
|
-
cache.set('key', entry);
|
|
168
|
-
const entry = cache.get('key'); // null if missing or expired
|
|
169
|
-
const exists = cache.has('key');
|
|
170
|
-
cache.delete('key');
|
|
171
|
-
cache.clear(); // emits 'cache:cleared' with correct previousSize
|
|
172
|
-
|
|
173
|
-
// Batch prefetch
|
|
174
|
-
await cache.prefetch(['k1', 'k2'], async (keys) => loadFromDB(keys));
|
|
175
|
-
|
|
176
|
-
// Statistics
|
|
177
|
-
const stats = cache.getStats();
|
|
178
|
-
// { size, hits, misses, hitRate, evictions, memoryUsage }
|
|
63
|
+
import { UnifiedMemoryService } from '@monoes/memory';
|
|
179
64
|
|
|
180
|
-
//
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
### Query Builder
|
|
185
|
-
|
|
186
|
-
```typescript
|
|
187
|
-
import { query, QueryTemplates } from '@monomind/memory';
|
|
188
|
-
|
|
189
|
-
// Fluent query construction — produces a MemoryQuery object
|
|
190
|
-
const q = query()
|
|
191
|
-
.semantic('authentication patterns') // type = semantic, embeds content
|
|
192
|
-
.inNamespace('security')
|
|
193
|
-
.withTags(['auth', 'patterns'])
|
|
194
|
-
.ofType('semantic')
|
|
195
|
-
.threshold(0.7)
|
|
196
|
-
.limit(20)
|
|
197
|
-
.sortByNewest() // sortField: createdAt, sortDirection: desc
|
|
198
|
-
.build();
|
|
199
|
-
|
|
200
|
-
// Exact-key lookup
|
|
201
|
-
const exact = query().exact('my-key', 'my-namespace').build();
|
|
202
|
-
|
|
203
|
-
// Prefix search
|
|
204
|
-
const prefix = query().prefix('session-').inNamespace('sessions').build();
|
|
205
|
-
|
|
206
|
-
// Sorting options
|
|
207
|
-
query().semantic('...').sortBy('accessCount', 'desc').build(); // most-accessed first
|
|
208
|
-
query().semantic('...').oldestFirst().build(); // createdAt asc
|
|
209
|
-
query().semantic('...').recentlyAccessed().build(); // lastAccessedAt desc
|
|
210
|
-
|
|
211
|
-
// sortField and sortDirection are passed through to all backends that support them
|
|
212
|
-
// (lancedb-adapter, sqlite-backend, sqljs-backend, JsonBackend)
|
|
213
|
-
|
|
214
|
-
// Predefined templates
|
|
215
|
-
const recent = QueryTemplates.recentInNamespace('learnings', 10);
|
|
216
|
-
const stale = QueryTemplates.staleEntries('session-cache', 10);
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
### Migration
|
|
220
|
-
|
|
221
|
-
```typescript
|
|
222
|
-
import { MemoryMigrator, createMigrator } from '@monomind/memory';
|
|
223
|
-
|
|
224
|
-
// Migrate from a legacy SQLite, JSON, or Markdown source
|
|
225
|
-
const migrator = createMigrator(targetAdapter, {
|
|
226
|
-
source: 'sqlite', // 'sqlite' | 'json' | 'markdown' | 'memory-manager' | 'swarm-memory'
|
|
227
|
-
sourcePath: './data/v2-memory.db',
|
|
228
|
-
batchSize: 100,
|
|
229
|
-
generateEmbeddings: true, // generate vector embeddings for each entry
|
|
230
|
-
continueOnError: true, // skip bad entries instead of aborting
|
|
231
|
-
validateData: true,
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
const result = await migrator.migrate();
|
|
235
|
-
console.log(`Migrated ${result.progress.migrated} entries`);
|
|
236
|
-
console.log(`Failed: ${result.progress.failed}`);
|
|
237
|
-
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
## Quantization Options
|
|
241
|
-
|
|
242
|
-
```typescript
|
|
243
|
-
// Binary quantization (32x compression)
|
|
244
|
-
const binaryIndex = new HNSWIndex({
|
|
65
|
+
// Requires @lancedb/lancedb + apache-arrow installed
|
|
66
|
+
const memory = new UnifiedMemoryService({
|
|
67
|
+
persistencePath: './data/lancedb',
|
|
245
68
|
dimensions: 1536,
|
|
246
|
-
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
// Scalar quantization (4x compression)
|
|
250
|
-
const scalarIndex = new HNSWIndex({
|
|
251
|
-
dimensions: 1536,
|
|
252
|
-
quantization: { type: 'scalar', bits: 8 }
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
// Product quantization (8x compression)
|
|
256
|
-
const productIndex = new HNSWIndex({
|
|
257
|
-
dimensions: 1536,
|
|
258
|
-
quantization: { type: 'product', subquantizers: 8 }
|
|
259
|
-
});
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
## Auto Memory Bridge (ADR-048)
|
|
263
|
-
|
|
264
|
-
Bidirectional sync between Claude Code's [auto memory](https://code.claude.com/docs/en/memory) files and LanceDB. Auto memory is a persistent directory (`~/.claude/projects/<project>/memory/`) where Claude writes learnings as markdown. `MEMORY.md` (first 200 lines) is loaded into the system prompt; topic files are read on demand.
|
|
265
|
-
|
|
266
|
-
### Quick Start
|
|
267
|
-
|
|
268
|
-
```typescript
|
|
269
|
-
import { AutoMemoryBridge } from '@monomind/memory';
|
|
270
|
-
|
|
271
|
-
const bridge = new AutoMemoryBridge(memoryBackend, {
|
|
272
|
-
workingDir: '/workspaces/my-project',
|
|
273
|
-
syncMode: 'on-session-end', // 'on-write' | 'on-session-end' | 'periodic'
|
|
274
|
-
pruneStrategy: 'confidence-weighted', // 'confidence-weighted' | 'fifo' | 'lru'
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
// Record an insight (stores in LanceDB + optionally writes to files)
|
|
278
|
-
await bridge.recordInsight({
|
|
279
|
-
category: 'debugging',
|
|
280
|
-
summary: 'HNSW index requires initialization before search',
|
|
281
|
-
source: 'agent:tester',
|
|
282
|
-
confidence: 0.95,
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
// Sync buffered insights to auto memory files
|
|
286
|
-
const syncResult = await bridge.syncToAutoMemory();
|
|
287
|
-
|
|
288
|
-
// Import existing auto memory files into LanceDB (on session start)
|
|
289
|
-
const importResult = await bridge.importFromAutoMemory();
|
|
290
|
-
|
|
291
|
-
// Curate MEMORY.md index (stays under 200-line limit)
|
|
292
|
-
await bridge.curateIndex();
|
|
293
|
-
|
|
294
|
-
// Check status
|
|
295
|
-
const status = bridge.getStatus();
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
### Sync Modes
|
|
299
|
-
|
|
300
|
-
| Mode | Behavior |
|
|
301
|
-
|------|----------|
|
|
302
|
-
| `on-write` | Writes to files immediately on `recordInsight()` |
|
|
303
|
-
| `on-session-end` | Buffers insights, flushes on `syncToAutoMemory()` |
|
|
304
|
-
| `periodic` | Auto-syncs on a configurable interval |
|
|
305
|
-
|
|
306
|
-
### Insight Categories
|
|
307
|
-
|
|
308
|
-
| Category | Topic File | Description |
|
|
309
|
-
|----------|-----------|-------------|
|
|
310
|
-
| `project-patterns` | `patterns.md` | Code patterns and conventions |
|
|
311
|
-
| `debugging` | `debugging.md` | Bug fixes and debugging insights |
|
|
312
|
-
| `architecture` | `architecture.md` | Design decisions and module relationships |
|
|
313
|
-
| `performance` | `performance.md` | Benchmarks and optimization results |
|
|
314
|
-
| `security` | `security.md` | Security findings and CVE notes |
|
|
315
|
-
| `preferences` | `preferences.md` | User and project preferences |
|
|
316
|
-
| `swarm-results` | `swarm-results.md` | Multi-agent swarm outcomes |
|
|
317
|
-
|
|
318
|
-
### Key Optimizations
|
|
319
|
-
|
|
320
|
-
- **Batch import** - `bulkInsert()` instead of individual `store()` calls
|
|
321
|
-
- **Pre-fetched hashes** - Single query for content-hash dedup during import
|
|
322
|
-
- **Async I/O** - `node:fs/promises` for non-blocking writes
|
|
323
|
-
- **Exact dedup** - `hasSummaryLine()` uses bullet-prefix matching, not substring
|
|
324
|
-
- **O(1) sync tracking** - `syncedInsightKeys` Set prevents double-write race
|
|
325
|
-
- **Prune-before-build** - Avoids O(n^2) index rebuild loop
|
|
326
|
-
|
|
327
|
-
### Utility Functions
|
|
328
|
-
|
|
329
|
-
```typescript
|
|
330
|
-
import {
|
|
331
|
-
resolveAutoMemoryDir, // Derive auto memory path from working dir
|
|
332
|
-
findGitRoot, // Walk up to find .git root
|
|
333
|
-
parseMarkdownEntries, // Parse ## headings into structured entries
|
|
334
|
-
extractSummaries, // Extract bullet summaries, strip metadata
|
|
335
|
-
formatInsightLine, // Format insight as markdown bullet
|
|
336
|
-
hashContent, // SHA-256 truncated to 16 hex chars
|
|
337
|
-
pruneTopicFile, // Keep topic files under line limit
|
|
338
|
-
hasSummaryLine, // Exact bullet-prefix dedup check
|
|
339
|
-
} from '@monomind/memory';
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
### Types
|
|
343
|
-
|
|
344
|
-
```typescript
|
|
345
|
-
import type {
|
|
346
|
-
AutoMemoryBridgeConfig,
|
|
347
|
-
MemoryInsight,
|
|
348
|
-
InsightCategory,
|
|
349
|
-
SyncDirection,
|
|
350
|
-
SyncMode,
|
|
351
|
-
PruneStrategy,
|
|
352
|
-
SyncResult,
|
|
353
|
-
ImportResult,
|
|
354
|
-
} from '@monomind/memory';
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
## Self-Learning Bridge (ADR-049)
|
|
358
|
-
|
|
359
|
-
Connects insights to the ReasoningBank pattern store. The optional neural learning system can be injected via `neuralLoader`; when none is provided, learning operations degrade to no-ops while pattern storage and retrieval continue to work.
|
|
360
|
-
|
|
361
|
-
### Quick Start
|
|
362
|
-
|
|
363
|
-
```typescript
|
|
364
|
-
import { AutoMemoryBridge, LearningBridge } from '@monomind/memory';
|
|
365
|
-
|
|
366
|
-
const bridge = new AutoMemoryBridge(backend, {
|
|
367
|
-
workingDir: '/workspaces/my-project',
|
|
368
|
-
learning: {
|
|
369
|
-
sonaMode: 'balanced',
|
|
370
|
-
confidenceDecayRate: 0.005, // Per-hour decay
|
|
371
|
-
accessBoostAmount: 0.03, // Boost per access
|
|
372
|
-
consolidationThreshold: 10, // Min insights before consolidation
|
|
373
|
-
},
|
|
374
|
-
});
|
|
375
|
-
|
|
376
|
-
// Insights now trigger learning trajectories automatically
|
|
377
|
-
await bridge.recordInsight({
|
|
378
|
-
category: 'debugging',
|
|
379
|
-
summary: 'Connection pool exhaustion on high load',
|
|
380
|
-
source: 'agent:tester',
|
|
381
|
-
confidence: 0.9,
|
|
382
|
-
});
|
|
383
|
-
|
|
384
|
-
// Consolidation runs JUDGE/DISTILL/CONSOLIDATE pipeline
|
|
385
|
-
await bridge.syncToAutoMemory(); // Calls consolidate() first
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
### Standalone Usage
|
|
389
|
-
|
|
390
|
-
```typescript
|
|
391
|
-
import { LearningBridge } from '@monomind/memory';
|
|
392
|
-
|
|
393
|
-
const lb = new LearningBridge(backend, {
|
|
394
|
-
// Optional: inject a custom neural learning system (structural interface).
|
|
395
|
-
// Without a neuralLoader, learning degrades to no-ops; pattern storage
|
|
396
|
-
// and ReasoningBank retrieval still work.
|
|
397
|
-
neuralLoader: async () => myNeuralLearningSystem,
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
// Boost confidence when insight is accessed
|
|
401
|
-
await lb.onInsightAccessed('entry-123'); // +0.03 confidence
|
|
402
|
-
|
|
403
|
-
// Apply time-based decay
|
|
404
|
-
const decayed = await lb.decayConfidences('default'); // -0.005/hour
|
|
405
|
-
|
|
406
|
-
// Find similar patterns via ReasoningBank
|
|
407
|
-
const patterns = await lb.findSimilarPatterns('connection pooling');
|
|
408
|
-
|
|
409
|
-
// Get learning statistics
|
|
410
|
-
const stats = lb.getStats();
|
|
411
|
-
// { totalTrajectories, activeTrajectories, completedTrajectories,
|
|
412
|
-
// totalConsolidations, accessBoosts, ... }
|
|
413
|
-
```
|
|
414
|
-
|
|
415
|
-
### Confidence Lifecycle
|
|
416
|
-
|
|
417
|
-
| Event | Effect | Range |
|
|
418
|
-
|-------|--------|-------|
|
|
419
|
-
| Insight recorded | Initial confidence from source | 0.1 - 1.0 |
|
|
420
|
-
| Insight accessed | +0.03 per access | Capped at 1.0 |
|
|
421
|
-
| Time decay | -0.005 per hour since last access | Floored at 0.1 |
|
|
422
|
-
| Consolidation | Neural pipeline may adjust | 0.1 - 1.0 |
|
|
423
|
-
|
|
424
|
-
## Knowledge Graph (ADR-049)
|
|
425
|
-
|
|
426
|
-
Pure TypeScript knowledge graph with PageRank and community detection. No external graph libraries required.
|
|
427
|
-
|
|
428
|
-
### Quick Start
|
|
429
|
-
|
|
430
|
-
```typescript
|
|
431
|
-
import { AutoMemoryBridge, MemoryGraph } from '@monomind/memory';
|
|
432
|
-
|
|
433
|
-
const bridge = new AutoMemoryBridge(backend, {
|
|
434
|
-
workingDir: '/workspaces/my-project',
|
|
435
|
-
graph: {
|
|
436
|
-
similarityThreshold: 0.8,
|
|
437
|
-
pageRankDamping: 0.85,
|
|
438
|
-
maxNodes: 5000,
|
|
439
|
-
},
|
|
440
|
-
});
|
|
441
|
-
|
|
442
|
-
// Graph builds automatically on import
|
|
443
|
-
await bridge.importFromAutoMemory();
|
|
444
|
-
|
|
445
|
-
// Curation uses PageRank to prioritize influential insights
|
|
446
|
-
await bridge.curateIndex();
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
### Standalone Usage
|
|
450
|
-
|
|
451
|
-
```typescript
|
|
452
|
-
import { MemoryGraph } from '@monomind/memory';
|
|
453
|
-
|
|
454
|
-
const graph = new MemoryGraph({
|
|
455
|
-
pageRankDamping: 0.85,
|
|
456
|
-
pageRankIterations: 50,
|
|
457
|
-
pageRankConvergence: 1e-6,
|
|
458
|
-
maxNodes: 5000,
|
|
459
|
-
});
|
|
460
|
-
|
|
461
|
-
// Build from backend entries
|
|
462
|
-
await graph.buildFromBackend(backend, 'my-namespace');
|
|
463
|
-
|
|
464
|
-
// Or build manually
|
|
465
|
-
graph.addNode(entry);
|
|
466
|
-
graph.addEdge('entry-1', 'entry-2', 'reference', 1.0);
|
|
467
|
-
graph.addEdge('entry-1', 'entry-3', 'similar', 0.9);
|
|
468
|
-
|
|
469
|
-
// Compute PageRank (power iteration)
|
|
470
|
-
const ranks = graph.computePageRank();
|
|
471
|
-
|
|
472
|
-
// Detect communities (label propagation)
|
|
473
|
-
const communities = graph.detectCommunities();
|
|
474
|
-
|
|
475
|
-
// Graph-aware ranking: blend vector score + PageRank
|
|
476
|
-
const ranked = graph.rankWithGraph(searchResults, 0.7);
|
|
477
|
-
// alpha=0.7 means 70% vector score + 30% PageRank
|
|
478
|
-
|
|
479
|
-
// Get most influential insights for MEMORY.md
|
|
480
|
-
const topNodes = graph.getTopNodes(20);
|
|
481
|
-
|
|
482
|
-
// BFS traversal for related insights
|
|
483
|
-
const neighbors = graph.getNeighbors('entry-1', 2); // depth=2
|
|
484
|
-
```
|
|
485
|
-
|
|
486
|
-
### Edge Types
|
|
487
|
-
|
|
488
|
-
| Type | Source | Description |
|
|
489
|
-
|------|--------|-------------|
|
|
490
|
-
| `reference` | `MemoryEntry.references` | Explicit cross-references between entries |
|
|
491
|
-
| `similar` | HNSW search | Auto-created when similarity > threshold |
|
|
492
|
-
| `temporal` | Timestamps | Entries created in same time window |
|
|
493
|
-
| `co-accessed` | Access patterns | Entries frequently accessed together |
|
|
494
|
-
| `causal` | Learning pipeline | Cause-effect relationships |
|
|
495
|
-
|
|
496
|
-
### Performance
|
|
497
|
-
|
|
498
|
-
| Operation | Result | Target |
|
|
499
|
-
|-----------|--------|--------|
|
|
500
|
-
| Graph build (1k nodes) | 2.78 ms | <200 ms |
|
|
501
|
-
| PageRank (1k nodes) | 12.21 ms | <100 ms |
|
|
502
|
-
| Community detection (1k) | 19.62 ms | — |
|
|
503
|
-
| `rankWithGraph(10)` | 0.006 ms | — |
|
|
504
|
-
| `getTopNodes(20)` | 0.308 ms | — |
|
|
505
|
-
| `getNeighbors(d=2)` | 0.005 ms | — |
|
|
506
|
-
|
|
507
|
-
## Agent-Scoped Memory (ADR-049)
|
|
508
|
-
|
|
509
|
-
Maps Claude Code's 3-scope agent memory directories for per-agent knowledge isolation and cross-agent transfer.
|
|
510
|
-
|
|
511
|
-
### Quick Start
|
|
512
|
-
|
|
513
|
-
```typescript
|
|
514
|
-
import { createAgentBridge, transferKnowledge } from '@monomind/memory';
|
|
515
|
-
|
|
516
|
-
// Create a bridge for a specific agent scope
|
|
517
|
-
const agentBridge = createAgentBridge(backend, {
|
|
518
|
-
agentName: 'my-coder',
|
|
519
|
-
scope: 'project', // 'project' | 'local' | 'user'
|
|
520
|
-
workingDir: '/workspaces/my-project',
|
|
521
|
-
});
|
|
522
|
-
|
|
523
|
-
// Record insights scoped to this agent
|
|
524
|
-
await agentBridge.recordInsight({
|
|
525
|
-
category: 'debugging',
|
|
526
|
-
summary: 'Use connection pooling for DB calls',
|
|
527
|
-
source: 'agent:my-coder',
|
|
528
|
-
confidence: 0.95,
|
|
529
|
-
});
|
|
530
|
-
|
|
531
|
-
// Transfer high-confidence insights between agents
|
|
532
|
-
const result = await transferKnowledge(sourceBackend, targetBridge, {
|
|
533
|
-
sourceNamespace: 'learnings',
|
|
534
|
-
minConfidence: 0.8, // Only transfer confident insights
|
|
535
|
-
maxEntries: 20,
|
|
536
|
-
categories: ['debugging', 'architecture'],
|
|
537
|
-
});
|
|
538
|
-
// { transferred: 15, skipped: 5 }
|
|
539
|
-
```
|
|
540
|
-
|
|
541
|
-
### Scope Paths
|
|
542
|
-
|
|
543
|
-
| Scope | Directory | Use Case |
|
|
544
|
-
|-------|-----------|----------|
|
|
545
|
-
| `project` | `<gitRoot>/.claude/agent-memory/<agent>/` | Project-specific learnings |
|
|
546
|
-
| `local` | `<gitRoot>/.claude/agent-memory-local/<agent>/` | Machine-local data |
|
|
547
|
-
| `user` | `~/.claude/agent-memory/<agent>/` | Cross-project user knowledge |
|
|
548
|
-
|
|
549
|
-
### Utilities
|
|
550
|
-
|
|
551
|
-
```typescript
|
|
552
|
-
import {
|
|
553
|
-
resolveAgentMemoryDir, // Get scope directory path
|
|
554
|
-
createAgentBridge, // Create scoped AutoMemoryBridge
|
|
555
|
-
transferKnowledge, // Cross-agent knowledge sharing
|
|
556
|
-
listAgentScopes, // Discover existing agent scopes
|
|
557
|
-
} from '@monomind/memory';
|
|
558
|
-
|
|
559
|
-
// Resolve path for an agent scope
|
|
560
|
-
const dir = resolveAgentMemoryDir('my-agent', 'project');
|
|
561
|
-
// → /workspaces/my-project/.claude/agent-memory/my-agent/
|
|
562
|
-
|
|
563
|
-
// List all agent scopes in a directory
|
|
564
|
-
const scopes = await listAgentScopes('/workspaces/my-project');
|
|
565
|
-
// [{ agentName: 'coder', scope: 'project', path: '...' }, ...]
|
|
566
|
-
```
|
|
567
|
-
|
|
568
|
-
## A-MEM Auto-Linking (arXiv:2409.11987)
|
|
569
|
-
|
|
570
|
-
When `HybridBackend` is configured with an `embeddingGenerator`, every stored entry
|
|
571
|
-
automatically discovers its top-3 semantic neighbors and creates bidirectional
|
|
572
|
-
`references` edges — implementing the Zettelkasten note-linking structure from A-MEM.
|
|
573
|
-
|
|
574
|
-
```typescript
|
|
575
|
-
const backend = new HybridBackend({
|
|
576
|
-
embeddingGenerator: async (text) => myEmbeddingModel.embed(text),
|
|
577
|
-
// A-MEM auto-linking is automatically active when embeddingGenerator is set
|
|
578
|
-
});
|
|
579
|
-
|
|
580
|
-
// Store any entry — references are linked asynchronously, best-effort
|
|
581
|
-
await backend.store(entry);
|
|
582
|
-
|
|
583
|
-
// After linking, querySemantic PPR re-ranking propagates scores through the
|
|
584
|
-
// newly created reference graph, improving recall for connected knowledge.
|
|
585
|
-
backend.on('amem:linked', ({ id, linkedTo }) =>
|
|
586
|
-
console.log(`Linked ${id} to ${linkedTo.join(', ')}`));
|
|
587
|
-
```
|
|
588
|
-
|
|
589
|
-
## Injection-Safe Semantic Search
|
|
590
|
-
|
|
591
|
-
Set `filterInjection: true` to remove entries containing prompt-injection patterns
|
|
592
|
-
from semantic search results before they reach the agent context:
|
|
593
|
-
|
|
594
|
-
```typescript
|
|
595
|
-
const backend = new HybridBackend({
|
|
596
|
-
embeddingGenerator: myEmbedder,
|
|
597
|
-
filterInjection: true, // Screen RAG results for indirect injection
|
|
598
|
-
});
|
|
599
|
-
|
|
600
|
-
// Filtered result — entries matching injection patterns are silently dropped
|
|
601
|
-
const entries = await backend.querySemantic({ content: 'OAuth patterns', k: 10 });
|
|
602
|
-
|
|
603
|
-
// Blocked entries are observable via event
|
|
604
|
-
backend.on('injection:blocked', ({ id, namespace }) =>
|
|
605
|
-
securityLogger.warn(`Injection blocked from entry ${id}`));
|
|
606
|
-
```
|
|
607
|
-
|
|
608
|
-
Source: arXiv:2302.12173, arXiv:2310.12815 — indirect prompt injection in RAG pipelines.
|
|
609
|
-
|
|
610
|
-
## GraphRAG Community Retrieval (arXiv:2404.16130)
|
|
611
|
-
|
|
612
|
-
`querySemantic()` now captures community summaries from `MemoryGraph.getCommunitySummaries()`
|
|
613
|
-
and annotates each returned entry with its GraphRAG community metadata. This implements
|
|
614
|
-
the community-level summarisation strategy from Microsoft GraphRAG.
|
|
615
|
-
|
|
616
|
-
```typescript
|
|
617
|
-
const entries = await backend.querySemantic({ content: 'authentication patterns', k: 10 });
|
|
618
|
-
// Each entry now carries:
|
|
619
|
-
// entry.community — community ID string
|
|
620
|
-
// entry.communityNodeCount — number of nodes in that community
|
|
621
|
-
// entry.communityAvgPageRank — mean PageRank of community members
|
|
622
|
-
```
|
|
623
|
-
|
|
624
|
-
PPR re-ranking is handled by HippoRAG-style personalised PageRank (arXiv:2405.14831),
|
|
625
|
-
which propagates query-node scores through the knowledge graph before returning results.
|
|
626
|
-
|
|
627
|
-
## Collaborative Memory Promotion (arXiv:2505.18279)
|
|
628
|
-
|
|
629
|
-
`HybridBackend.get(id, agentId?)` accepts an optional `agentId` parameter. When
|
|
630
|
-
provided, it fires a read-tracking call to the SQLite backend, which promotes the
|
|
631
|
-
entry's `AccessLevel` from `'private'` to `'team'` once **3 or more distinct agents**
|
|
632
|
-
have accessed it within a 24-hour window.
|
|
633
|
-
|
|
634
|
-
```typescript
|
|
635
|
-
// Each agent reads with its own ID — no other change required
|
|
636
|
-
const entry = await backend.get('entry-id-123', 'coder-agent');
|
|
637
|
-
|
|
638
|
-
// After the third distinct agent reads it within 24 h:
|
|
639
|
-
// entry.accessLevel === 'team'
|
|
640
|
-
// (auto-promoted, visible to peer agents in the same namespace)
|
|
641
|
-
```
|
|
642
|
-
|
|
643
|
-
Collaborative promotion is transparent to callers that don't pass `agentId` —
|
|
644
|
-
`get(id)` continues to work exactly as before (backwards-compatible).
|
|
645
|
-
|
|
646
|
-
## Knowledge Graph & Temporal Edges (arXiv:2501.13956)
|
|
647
|
-
|
|
648
|
-
`MemoryGraph` models causal and temporal relationships between entries as typed
|
|
649
|
-
edges, inspired by the Zep/Graphiti episodic knowledge graph (arXiv:2501.13956).
|
|
650
|
-
Edge types include `REFERENCES`, `CAUSES`, `PRECEDED_BY`, `RELATED_TO`, and
|
|
651
|
-
`CONTRADICTS`, enabling episodic reasoning over the agent's memory history.
|
|
652
|
-
|
|
653
|
-
```typescript
|
|
654
|
-
import { MemoryGraph, type EdgeType } from '@monomind/memory';
|
|
655
|
-
|
|
656
|
-
const graph = new MemoryGraph();
|
|
657
|
-
graph.addEdge('plan-123', 'code-456', EdgeType.CAUSES, 0.9);
|
|
658
|
-
graph.addEdge('code-456', 'test-789', EdgeType.PRECEDED_BY, 1.0);
|
|
659
|
-
|
|
660
|
-
const ranked = graph.pprRerank(['plan-123'], candidates, 0.85);
|
|
661
|
-
// Entries causally downstream of 'plan-123' score higher in PPR
|
|
662
|
-
```
|
|
663
|
-
|
|
664
|
-
## μACP Learning-Bridge Integration (arXiv:2601.03938)
|
|
665
|
-
|
|
666
|
-
`LearningBridge` integrates with the μACP coordination substrate: when consolidation
|
|
667
|
-
detects a pattern conflict between agents, it initiates a μACP round to resolve which
|
|
668
|
-
variant to promote. The result is stored as a causal edge in `MemoryGraph`.
|
|
669
|
-
|
|
670
|
-
```typescript
|
|
671
|
-
// Conflict resolution is automatic during consolidation:
|
|
672
|
-
await learningBridge.consolidate();
|
|
673
|
-
// Internally calls MuACP.coordinate() when divergent patterns are detected,
|
|
674
|
-
// then records the winning pattern as a CAUSES edge.
|
|
675
|
-
```
|
|
676
|
-
|
|
677
|
-
Source: arXiv:2601.03938.
|
|
678
|
-
|
|
679
|
-
## Bi-Temporal Query Filtering (arXiv:2501.13956)
|
|
680
|
-
|
|
681
|
-
`MemoryQuery` now supports `eventAfter` and `eventBefore` filters that operate on the
|
|
682
|
-
`eventAt` field — the timestamp of *when the event occurred* (T), as opposed to
|
|
683
|
-
`createdAt` which records *when the entry was ingested* (T'). This is the bi-temporal
|
|
684
|
-
model from Zep/Graphiti that prevents retrieval failures when data arrives out-of-order
|
|
685
|
-
or is backdated.
|
|
686
|
-
|
|
687
|
-
```typescript
|
|
688
|
-
const entries = await backend.query({
|
|
689
|
-
type: 'hybrid',
|
|
690
|
-
namespace: 'incidents',
|
|
691
|
-
limit: 50,
|
|
692
|
-
// Filter by WHEN THE INCIDENT HAPPENED — not when it was logged
|
|
693
|
-
eventAfter: new Date('2026-01-01').getTime(),
|
|
694
|
-
eventBefore: new Date('2026-04-01').getTime(),
|
|
695
|
-
});
|
|
696
|
-
|
|
697
|
-
// Store with explicit event time (e.g. a past incident being recorded now)
|
|
698
|
-
await backend.store({
|
|
699
|
-
key: 'outage-2026-02-14',
|
|
700
|
-
content: 'DB connection pool exhausted during peak traffic',
|
|
701
|
-
type: 'episodic',
|
|
702
|
-
namespace: 'incidents',
|
|
703
|
-
eventAt: new Date('2026-02-14T03:22:00Z').getTime(), // event time
|
|
704
|
-
// createdAt is auto-set to Date.now() (ingestion time)
|
|
705
|
-
// ...
|
|
69
|
+
embeddingGenerator: async (text) => myEmbedder.embed(text),
|
|
706
70
|
});
|
|
71
|
+
await memory.initialize();
|
|
707
72
|
```
|
|
708
73
|
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
## MemoRAG Query Rewriting (arXiv:2409.05591)
|
|
712
|
-
|
|
713
|
-
`HybridBackend` supports a `memoragRewriter` configuration option that adds a
|
|
714
|
-
"draft clue" query-expansion stage before HNSW search. When configured, `querySemantic()`
|
|
715
|
-
calls the rewriter to generate 2-3 reformulated sub-queries, searches HNSW independently
|
|
716
|
-
for each, then fuses all ranked result lists using **Reciprocal Rank Fusion (RRF)** before
|
|
717
|
-
continuing with HippoRAG PPR re-ranking and GraphRAG community annotation.
|
|
718
|
-
|
|
719
|
-
This addresses the MemoRAG insight that naive RAG fails when the user query does not
|
|
720
|
-
directly match any retrievable chunk — paraphrased sub-queries dramatically improve recall.
|
|
74
|
+
Or use the standalone pure-JS index directly:
|
|
721
75
|
|
|
722
76
|
```typescript
|
|
723
|
-
import {
|
|
724
|
-
|
|
725
|
-
const backend = new HybridBackend({
|
|
726
|
-
embeddingGenerator: myEmbedder,
|
|
727
|
-
memoragRewriter: async (query) => {
|
|
728
|
-
// Use a cheap LLM (Haiku) or deterministic rules to produce sub-queries
|
|
729
|
-
const reformulated = await callClaude({
|
|
730
|
-
model: 'claude-haiku-4-5',
|
|
731
|
-
prompt: `Generate 3 alternative search queries for: "${query}"\nRespond with a JSON array of strings.`,
|
|
732
|
-
});
|
|
733
|
-
return JSON.parse(reformulated); // e.g. ["...", "...", "..."]
|
|
734
|
-
},
|
|
735
|
-
});
|
|
77
|
+
import { HNSWIndex } from '@monoes/memory';
|
|
736
78
|
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
79
|
+
const index = new HNSWIndex({ dimensions: 1536, M: 16, efConstruction: 200, metric: 'cosine' });
|
|
80
|
+
await index.addPoint('mem-1', new Float32Array(embedding));
|
|
81
|
+
const results = await index.search(queryVector, 10);
|
|
82
|
+
// [{ id: 'mem-1', distance: 0.05 }, ...]
|
|
740
83
|
```
|
|
741
84
|
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
## DiskANN Backend — Large-Scale ANN at Disk Scale (arXiv:2305.04359)
|
|
745
|
-
|
|
746
|
-
`DiskAnnBackend` is an `IMemoryBackend` decorator that activates SSD-resident Vamana ANN search above entry-count thresholds. Wraps any existing backend (typically the long-term SQLite/LanceDB backend in `TierManager`).
|
|
747
|
-
|
|
748
|
-
### Architecture
|
|
749
|
-
|
|
750
|
-
- **Disk-persisted adjacency list** — Vamana graph written to `graphPath` as JSON
|
|
751
|
-
- **In-memory Int8-quantised vectors** — `Map<string, Int8Array>` for fast beam search
|
|
752
|
-
- **Beam search** — BFS traversal using Int8 dot-product as the candidate scorer
|
|
753
|
-
- **Full-precision cosine re-ranking** — fetches raw embeddings from the delegate backend
|
|
754
|
-
|
|
755
|
-
### Quick Start
|
|
85
|
+
## Episodic memory
|
|
756
86
|
|
|
757
87
|
```typescript
|
|
758
|
-
import {
|
|
759
|
-
|
|
760
|
-
// Wrap any IMemoryBackend
|
|
761
|
-
const diskann = new DiskAnnBackend(existingBackend, {
|
|
762
|
-
graphPath: './data/diskann.graph.json',
|
|
763
|
-
R: 32, // Max graph degree (default: 32)
|
|
764
|
-
L: 64, // Beam width (default: 64)
|
|
765
|
-
beamWidth: 10, // Search beam candidates (default: 10)
|
|
766
|
-
dimensions: 128, // Vector dimensions (default: 128)
|
|
767
|
-
});
|
|
768
|
-
|
|
769
|
-
// All CRUD proxies through to the wrapped backend
|
|
770
|
-
await diskann.store(entry);
|
|
771
|
-
await diskann.get(id);
|
|
88
|
+
import { EpisodicStore } from '@monoes/memory';
|
|
772
89
|
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
// [{ entry: MemoryEntry, score: number }, ...]
|
|
90
|
+
const store = new EpisodicStore({ filePath: './data/episodes.jsonl', maxRunsPerEpisode: 20 });
|
|
91
|
+
// Accumulates agent runs into episodes, one JSON object per line
|
|
776
92
|
```
|
|
777
93
|
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
Pass `diskAnnConfig` to activate DiskANN on the long-term backend:
|
|
781
|
-
|
|
782
|
-
```typescript
|
|
783
|
-
import { TierManager } from '@monomind/memory';
|
|
784
|
-
|
|
785
|
-
const tier = new TierManager(
|
|
786
|
-
longTermBackend,
|
|
787
|
-
{ shortTermCapacity: 1000 },
|
|
788
|
-
{}, // PartitionedHNSW config
|
|
789
|
-
{ // DiskAnnBackendConfig — activates DiskANN
|
|
790
|
-
graphPath: './data/diskann.graph.json',
|
|
791
|
-
R: 32,
|
|
792
|
-
beamWidth: 12,
|
|
793
|
-
},
|
|
794
|
-
);
|
|
795
|
-
|
|
796
|
-
// tier.diskann is now populated — search() includes DiskANN results
|
|
797
|
-
const results = await tier.search('authentication patterns', 10);
|
|
798
|
-
```
|
|
799
|
-
|
|
800
|
-
### DiskAnnBackendConfig
|
|
801
|
-
|
|
802
|
-
| Field | Default | Description |
|
|
803
|
-
|-------|---------|-------------|
|
|
804
|
-
| `graphPath` | `'./diskann.graph.json'` | Path for persisted Vamana adjacency list |
|
|
805
|
-
| `R` | `32` | Max out-degree per node |
|
|
806
|
-
| `L` | `64` | Beam width during construction |
|
|
807
|
-
| `beamWidth` | `10` | Beam width during search |
|
|
808
|
-
| `dimensions` | `128` | Vector dimensions |
|
|
809
|
-
|
|
810
|
-
## Performance Benchmarks
|
|
811
|
-
|
|
812
|
-
| Operation | V2 Performance | V1 Performance | Improvement |
|
|
813
|
-
|-----------|---------------|----------------|-------------|
|
|
814
|
-
| Vector Search | 150ms | <1ms | **150x** |
|
|
815
|
-
| Bulk Insert | 500ms | 5ms | **100x** |
|
|
816
|
-
| Memory Write | 50ms | <5ms | **10x** |
|
|
817
|
-
| Cache Hit | 5ms | <0.1ms | **50x** |
|
|
818
|
-
| Index Build | 10s | 800ms | **12.5x** |
|
|
819
|
-
|
|
820
|
-
### ADR-049 Benchmarks
|
|
821
|
-
|
|
822
|
-
| Operation | Actual | Target | Headroom |
|
|
823
|
-
|-----------|--------|--------|----------|
|
|
824
|
-
| Graph build (1k nodes) | 2.78 ms | <200 ms | **71.9x** |
|
|
825
|
-
| PageRank (1k nodes) | 12.21 ms | <100 ms | **8.2x** |
|
|
826
|
-
| Insight recording | 0.12 ms/each | <5 ms/each | **41.0x** |
|
|
827
|
-
| Consolidation | 0.26 ms | <500 ms | **1,955x** |
|
|
828
|
-
| Confidence decay (1k) | 0.23 ms | <50 ms | **215x** |
|
|
829
|
-
| Knowledge transfer | 1.25 ms | <100 ms | **80.0x** |
|
|
830
|
-
|
|
831
|
-
## TypeScript Types
|
|
94
|
+
## Query builder
|
|
832
95
|
|
|
833
96
|
```typescript
|
|
834
|
-
import
|
|
835
|
-
// Core entry and query types
|
|
836
|
-
MemoryEntry, MemoryEntryInput, MemoryEntryUpdate,
|
|
837
|
-
MemoryQuery, MemoryType, AccessLevel,
|
|
838
|
-
SearchResult, SearchOptions,
|
|
97
|
+
import { query } from '@monoes/memory';
|
|
839
98
|
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
IMemoryBackend, BackendStats, HealthCheckResult,
|
|
849
|
-
|
|
850
|
-
// Cache
|
|
851
|
-
CacheConfig, CacheStats,
|
|
852
|
-
|
|
853
|
-
// Auto Memory Bridge (ADR-048)
|
|
854
|
-
AutoMemoryBridgeConfig, MemoryInsight, InsightCategory,
|
|
855
|
-
SyncMode, SyncResult, ImportResult,
|
|
856
|
-
|
|
857
|
-
// Agent Scope (ADR-049)
|
|
858
|
-
AgentMemoryScope, AgentScopedConfig,
|
|
859
|
-
TransferOptions, TransferResult,
|
|
860
|
-
|
|
861
|
-
// Learning Bridge (ADR-049)
|
|
862
|
-
LearningBridgeConfig, ConsolidateResult, PatternMatch,
|
|
863
|
-
|
|
864
|
-
// Knowledge Graph (ADR-049)
|
|
865
|
-
MemoryGraphConfig, GraphNode, GraphEdge,
|
|
866
|
-
GraphStats, RankedResult,
|
|
867
|
-
|
|
868
|
-
// Tiers
|
|
869
|
-
MemoryTier, EntityFact, SessionSummary,
|
|
870
|
-
|
|
871
|
-
// Migration
|
|
872
|
-
MigrationSource, MigrationConfig, MigrationResult,
|
|
873
|
-
|
|
874
|
-
// Checkpointing
|
|
875
|
-
AgentState, SwarmCheckpoint, CheckpointMeta,
|
|
876
|
-
} from '@monomind/memory';
|
|
99
|
+
const q = query()
|
|
100
|
+
.semantic('authentication patterns')
|
|
101
|
+
.inNamespace('security')
|
|
102
|
+
.withTags(['auth'])
|
|
103
|
+
.threshold(0.7)
|
|
104
|
+
.limit(20)
|
|
105
|
+
.sortByNewest()
|
|
106
|
+
.build();
|
|
877
107
|
```
|
|
878
108
|
|
|
879
|
-
##
|
|
109
|
+
## Cross-platform notes
|
|
880
110
|
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
111
|
+
`createDatabase()` picks the best available provider per platform:
|
|
112
|
+
`better-sqlite3` (native, fastest) → `sql.js` (WASM, zero compilation, works
|
|
113
|
+
everywhere including Windows without a toolchain) → JSON file fallback. See
|
|
114
|
+
`docs/CROSS_PLATFORM.md` and `docs/WINDOWS_SUPPORT.md`.
|
|
884
115
|
|
|
885
|
-
##
|
|
116
|
+
## Links
|
|
886
117
|
|
|
887
|
-
- [
|
|
888
|
-
- [
|
|
118
|
+
- [GitHub](https://github.com/monoes/monomind)
|
|
119
|
+
- [Documentation](https://monoes.github.io/monomind/)
|
|
120
|
+
- [Issues](https://github.com/monoes/monomind/issues)
|
|
889
121
|
|
|
890
122
|
## License
|
|
891
123
|
|