universal-agent-memory 0.6.3 → 0.7.1
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/benchmarks/benchmark.d.ts +12 -12
- package/dist/benchmarks/execution-verifier.d.ts.map +1 -1
- package/dist/benchmarks/execution-verifier.js +51 -10
- package/dist/benchmarks/execution-verifier.js.map +1 -1
- package/dist/bin/cli.js +4 -1
- package/dist/bin/cli.js.map +1 -1
- package/dist/cli/update.d.ts +3 -0
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +136 -11
- package/dist/cli/update.js.map +1 -1
- package/dist/index.d.ts +17 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/dist/memory/backends/qdrant-cloud.d.ts +12 -1
- package/dist/memory/backends/qdrant-cloud.d.ts.map +1 -1
- package/dist/memory/backends/qdrant-cloud.js +39 -3
- package/dist/memory/backends/qdrant-cloud.js.map +1 -1
- package/dist/memory/context-compressor.d.ts +66 -0
- package/dist/memory/context-compressor.d.ts.map +1 -0
- package/dist/memory/context-compressor.js +250 -0
- package/dist/memory/context-compressor.js.map +1 -0
- package/dist/memory/dynamic-retrieval.d.ts +62 -1
- package/dist/memory/dynamic-retrieval.d.ts.map +1 -1
- package/dist/memory/dynamic-retrieval.js +154 -32
- package/dist/memory/dynamic-retrieval.js.map +1 -1
- package/dist/memory/embeddings.d.ts +38 -4
- package/dist/memory/embeddings.d.ts.map +1 -1
- package/dist/memory/embeddings.js +173 -9
- package/dist/memory/embeddings.js.map +1 -1
- package/dist/memory/hierarchical-memory.d.ts +116 -0
- package/dist/memory/hierarchical-memory.d.ts.map +1 -0
- package/dist/memory/hierarchical-memory.js +299 -0
- package/dist/memory/hierarchical-memory.js.map +1 -0
- package/dist/memory/memory-consolidator.d.ts +124 -0
- package/dist/memory/memory-consolidator.d.ts.map +1 -0
- package/dist/memory/memory-consolidator.js +514 -0
- package/dist/memory/memory-consolidator.js.map +1 -0
- package/dist/memory/multi-view-memory.d.ts +134 -0
- package/dist/memory/multi-view-memory.d.ts.map +1 -0
- package/dist/memory/multi-view-memory.js +420 -0
- package/dist/memory/multi-view-memory.js.map +1 -0
- package/dist/memory/semantic-compression.d.ts +77 -0
- package/dist/memory/semantic-compression.d.ts.map +1 -0
- package/dist/memory/semantic-compression.js +344 -0
- package/dist/memory/semantic-compression.js.map +1 -0
- package/dist/memory/speculative-cache.d.ts +92 -0
- package/dist/memory/speculative-cache.d.ts.map +1 -0
- package/dist/memory/speculative-cache.js +261 -0
- package/dist/memory/speculative-cache.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Consolidation Service for UAM
|
|
3
|
+
*
|
|
4
|
+
* Implements the consolidation rules from CLAUDE.md:
|
|
5
|
+
* - Trigger: Every 10 working memory entries
|
|
6
|
+
* - Action: Summarize → session_memories, Extract lessons → semantic memory
|
|
7
|
+
* - Dedup: Skip if content_hash exists OR similarity > 0.92
|
|
8
|
+
*
|
|
9
|
+
* Enhanced with SimpleMem-style recursive consolidation:
|
|
10
|
+
* - Background async consolidation process
|
|
11
|
+
* - Hierarchical abstraction (memories → summaries → meta-summaries)
|
|
12
|
+
* - Quality scoring and automatic pruning
|
|
13
|
+
*/
|
|
14
|
+
import { createHash } from 'crypto';
|
|
15
|
+
import { existsSync } from 'fs';
|
|
16
|
+
import Database from 'better-sqlite3';
|
|
17
|
+
import { summarizeMemories, compressMemoryEntry } from './context-compressor.js';
|
|
18
|
+
import { getEmbeddingService } from './embeddings.js';
|
|
19
|
+
import { createSemanticUnit } from './semantic-compression.js';
|
|
20
|
+
const DEFAULT_CONFIG = {
|
|
21
|
+
triggerThreshold: 10,
|
|
22
|
+
minImportanceForLongTerm: 7,
|
|
23
|
+
similarityThreshold: 0.92,
|
|
24
|
+
maxSummaryLength: 500,
|
|
25
|
+
backgroundIntervalMs: 60000, // 1 minute
|
|
26
|
+
recursiveDepth: 3, // memories → summaries → meta-summaries
|
|
27
|
+
qualityDecayRate: 0.95, // 5% decay per day unused
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Memory Consolidation Service
|
|
31
|
+
*/
|
|
32
|
+
export class MemoryConsolidator {
|
|
33
|
+
config;
|
|
34
|
+
db = null;
|
|
35
|
+
contentHashes = new Set();
|
|
36
|
+
lastConsolidationId = 0;
|
|
37
|
+
backgroundInterval = null;
|
|
38
|
+
isRunning = false;
|
|
39
|
+
memoryQualityScores = new Map();
|
|
40
|
+
constructor(config = {}) {
|
|
41
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Initialize with database connection
|
|
45
|
+
*/
|
|
46
|
+
initialize(dbPath) {
|
|
47
|
+
if (!existsSync(dbPath)) {
|
|
48
|
+
throw new Error(`Database not found: ${dbPath}`);
|
|
49
|
+
}
|
|
50
|
+
this.db = new Database(dbPath);
|
|
51
|
+
this.loadContentHashes();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Load existing content hashes for deduplication
|
|
55
|
+
*/
|
|
56
|
+
loadContentHashes() {
|
|
57
|
+
if (!this.db)
|
|
58
|
+
return;
|
|
59
|
+
try {
|
|
60
|
+
const stmt = this.db.prepare(`
|
|
61
|
+
SELECT content FROM memories
|
|
62
|
+
UNION
|
|
63
|
+
SELECT content FROM session_memories
|
|
64
|
+
`);
|
|
65
|
+
const rows = stmt.all();
|
|
66
|
+
for (const row of rows) {
|
|
67
|
+
this.contentHashes.add(this.hashContent(row.content));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// Tables might not exist yet
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Hash content for deduplication
|
|
76
|
+
*/
|
|
77
|
+
hashContent(content) {
|
|
78
|
+
return createHash('md5')
|
|
79
|
+
.update(content.toLowerCase().trim())
|
|
80
|
+
.digest('hex');
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Check if consolidation should run
|
|
84
|
+
*/
|
|
85
|
+
shouldConsolidate() {
|
|
86
|
+
if (!this.db)
|
|
87
|
+
return false;
|
|
88
|
+
try {
|
|
89
|
+
const stmt = this.db.prepare(`
|
|
90
|
+
SELECT COUNT(*) as count, MAX(id) as maxId
|
|
91
|
+
FROM memories
|
|
92
|
+
WHERE id > ?
|
|
93
|
+
`);
|
|
94
|
+
const result = stmt.get(this.lastConsolidationId);
|
|
95
|
+
return result.count >= this.config.triggerThreshold;
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Run consolidation process
|
|
103
|
+
*/
|
|
104
|
+
async consolidate() {
|
|
105
|
+
if (!this.db) {
|
|
106
|
+
throw new Error('Database not initialized');
|
|
107
|
+
}
|
|
108
|
+
const result = {
|
|
109
|
+
memoriesProcessed: 0,
|
|
110
|
+
summariesCreated: 0,
|
|
111
|
+
lessonsExtracted: 0,
|
|
112
|
+
duplicatesSkipped: 0,
|
|
113
|
+
tokensReduced: 0,
|
|
114
|
+
};
|
|
115
|
+
// Get memories since last consolidation
|
|
116
|
+
const stmt = this.db.prepare(`
|
|
117
|
+
SELECT id, timestamp, type, content
|
|
118
|
+
FROM memories
|
|
119
|
+
WHERE id > ?
|
|
120
|
+
ORDER BY id ASC
|
|
121
|
+
LIMIT 100
|
|
122
|
+
`);
|
|
123
|
+
const memories = stmt.all(this.lastConsolidationId);
|
|
124
|
+
if (memories.length === 0)
|
|
125
|
+
return result;
|
|
126
|
+
result.memoriesProcessed = memories.length;
|
|
127
|
+
const originalTokens = memories.reduce((sum, m) => sum + m.content.length / 4, 0);
|
|
128
|
+
// Group by type for summarization
|
|
129
|
+
const byType = {};
|
|
130
|
+
for (const mem of memories) {
|
|
131
|
+
if (!byType[mem.type])
|
|
132
|
+
byType[mem.type] = [];
|
|
133
|
+
byType[mem.type].push(mem);
|
|
134
|
+
}
|
|
135
|
+
// Create summaries for each type
|
|
136
|
+
for (const [_type, typeMemories] of Object.entries(byType)) {
|
|
137
|
+
if (typeMemories.length >= 3) {
|
|
138
|
+
const summary = summarizeMemories(typeMemories.map(m => ({
|
|
139
|
+
content: m.content,
|
|
140
|
+
timestamp: m.timestamp,
|
|
141
|
+
type: m.type,
|
|
142
|
+
})), this.config.maxSummaryLength);
|
|
143
|
+
const summaryHash = this.hashContent(summary);
|
|
144
|
+
if (!this.contentHashes.has(summaryHash)) {
|
|
145
|
+
// Store in session_memories
|
|
146
|
+
await this.storeSessionMemory(summary, 'summary', 6);
|
|
147
|
+
this.contentHashes.add(summaryHash);
|
|
148
|
+
result.summariesCreated++;
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
result.duplicatesSkipped++;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Extract lessons from high-importance observations
|
|
156
|
+
const lessons = memories.filter(m => m.type === 'observation' &&
|
|
157
|
+
this.detectLesson(m.content));
|
|
158
|
+
for (const lesson of lessons) {
|
|
159
|
+
const compressed = compressMemoryEntry(lesson.content, { compressionLevel: 'medium' });
|
|
160
|
+
const hash = this.hashContent(compressed.compressed);
|
|
161
|
+
if (!this.contentHashes.has(hash)) {
|
|
162
|
+
// Check semantic similarity
|
|
163
|
+
const isDuplicate = await this.checkSemanticDuplicate(compressed.compressed);
|
|
164
|
+
if (!isDuplicate) {
|
|
165
|
+
await this.storeLesson(compressed.compressed, lesson.timestamp);
|
|
166
|
+
this.contentHashes.add(hash);
|
|
167
|
+
result.lessonsExtracted++;
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
result.duplicatesSkipped++;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
result.duplicatesSkipped++;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Calculate token reduction
|
|
178
|
+
const summaryTokens = result.summariesCreated * (this.config.maxSummaryLength / 4);
|
|
179
|
+
const lessonTokens = result.lessonsExtracted * 100; // Approximate
|
|
180
|
+
result.tokensReduced = Math.max(0, originalTokens - summaryTokens - lessonTokens);
|
|
181
|
+
// Update last consolidation pointer
|
|
182
|
+
this.lastConsolidationId = memories[memories.length - 1].id;
|
|
183
|
+
return result;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Detect if content contains a lesson/insight
|
|
187
|
+
*/
|
|
188
|
+
detectLesson(content) {
|
|
189
|
+
const lessonIndicators = [
|
|
190
|
+
/learned that/i,
|
|
191
|
+
/important to/i,
|
|
192
|
+
/mistake was/i,
|
|
193
|
+
/better to/i,
|
|
194
|
+
/should always/i,
|
|
195
|
+
/should never/i,
|
|
196
|
+
/key insight/i,
|
|
197
|
+
/gotcha/i,
|
|
198
|
+
/watch out for/i,
|
|
199
|
+
/best practice/i,
|
|
200
|
+
/pattern/i,
|
|
201
|
+
/tip:/i,
|
|
202
|
+
];
|
|
203
|
+
return lessonIndicators.some(pattern => pattern.test(content));
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Check for semantic duplicates using embeddings
|
|
207
|
+
*/
|
|
208
|
+
async checkSemanticDuplicate(content) {
|
|
209
|
+
if (!this.db)
|
|
210
|
+
return false;
|
|
211
|
+
try {
|
|
212
|
+
const embeddingService = getEmbeddingService();
|
|
213
|
+
const newEmbedding = await embeddingService.embed(content);
|
|
214
|
+
// Get recent session memories for comparison
|
|
215
|
+
const stmt = this.db.prepare(`
|
|
216
|
+
SELECT content FROM session_memories
|
|
217
|
+
ORDER BY id DESC
|
|
218
|
+
LIMIT 50
|
|
219
|
+
`);
|
|
220
|
+
const existing = stmt.all();
|
|
221
|
+
for (const { content: existingContent } of existing) {
|
|
222
|
+
const existingEmbedding = await embeddingService.embed(existingContent);
|
|
223
|
+
const similarity = embeddingService.cosineSimilarity(newEmbedding, existingEmbedding);
|
|
224
|
+
if (similarity > this.config.similarityThreshold) {
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
// Fall back to text comparison
|
|
232
|
+
const normalizedNew = content.toLowerCase().trim();
|
|
233
|
+
const stmt = this.db.prepare(`
|
|
234
|
+
SELECT content FROM session_memories
|
|
235
|
+
WHERE LOWER(TRIM(content)) = ?
|
|
236
|
+
LIMIT 1
|
|
237
|
+
`);
|
|
238
|
+
const match = stmt.get(normalizedNew);
|
|
239
|
+
return !!match;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Store session memory
|
|
244
|
+
*/
|
|
245
|
+
async storeSessionMemory(content, type, importance) {
|
|
246
|
+
if (!this.db)
|
|
247
|
+
return;
|
|
248
|
+
const stmt = this.db.prepare(`
|
|
249
|
+
INSERT OR IGNORE INTO session_memories (session_id, timestamp, type, content, importance)
|
|
250
|
+
VALUES ('consolidation', ?, ?, ?, ?)
|
|
251
|
+
`);
|
|
252
|
+
stmt.run(new Date().toISOString(), type, content, importance);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Store lesson in long-term memory
|
|
256
|
+
*/
|
|
257
|
+
async storeLesson(content, timestamp) {
|
|
258
|
+
if (!this.db)
|
|
259
|
+
return;
|
|
260
|
+
const stmt = this.db.prepare(`
|
|
261
|
+
INSERT OR IGNORE INTO session_memories (session_id, timestamp, type, content, importance)
|
|
262
|
+
VALUES ('lessons', ?, 'lesson', ?, ?)
|
|
263
|
+
`);
|
|
264
|
+
stmt.run(timestamp, content, this.config.minImportanceForLongTerm);
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Run decay on old memories
|
|
268
|
+
* Formula: effective_importance = importance × (0.95 ^ days_since_access)
|
|
269
|
+
*/
|
|
270
|
+
async runDecay() {
|
|
271
|
+
if (!this.db)
|
|
272
|
+
return 0;
|
|
273
|
+
try {
|
|
274
|
+
// SQLite doesn't have POW, so we do this in application code
|
|
275
|
+
const stmt = this.db.prepare(`
|
|
276
|
+
SELECT id, importance, timestamp
|
|
277
|
+
FROM session_memories
|
|
278
|
+
WHERE importance > 1
|
|
279
|
+
`);
|
|
280
|
+
const rows = stmt.all();
|
|
281
|
+
let updated = 0;
|
|
282
|
+
const now = Date.now();
|
|
283
|
+
const updateStmt = this.db.prepare(`
|
|
284
|
+
UPDATE session_memories
|
|
285
|
+
SET importance = ?
|
|
286
|
+
WHERE id = ?
|
|
287
|
+
`);
|
|
288
|
+
for (const row of rows) {
|
|
289
|
+
const daysSince = (now - new Date(row.timestamp).getTime()) / (1000 * 60 * 60 * 24);
|
|
290
|
+
const decayed = Math.round(row.importance * Math.pow(0.95, daysSince));
|
|
291
|
+
if (decayed !== row.importance && decayed >= 1) {
|
|
292
|
+
updateStmt.run(decayed, row.id);
|
|
293
|
+
updated++;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return updated;
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
return 0;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Get consolidation stats
|
|
304
|
+
*/
|
|
305
|
+
getStats() {
|
|
306
|
+
if (!this.db) {
|
|
307
|
+
return {
|
|
308
|
+
totalMemories: 0,
|
|
309
|
+
totalSessionMemories: 0,
|
|
310
|
+
totalLessons: 0,
|
|
311
|
+
lastConsolidationId: this.lastConsolidationId,
|
|
312
|
+
uniqueHashes: this.contentHashes.size,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
try {
|
|
316
|
+
const memoriesStmt = this.db.prepare('SELECT COUNT(*) as count FROM memories');
|
|
317
|
+
const sessionStmt = this.db.prepare('SELECT COUNT(*) as count FROM session_memories');
|
|
318
|
+
const lessonsStmt = this.db.prepare(`
|
|
319
|
+
SELECT COUNT(*) as count FROM session_memories WHERE type = 'lesson'
|
|
320
|
+
`);
|
|
321
|
+
const memories = memoriesStmt.get().count;
|
|
322
|
+
const session = sessionStmt.get().count;
|
|
323
|
+
const lessons = lessonsStmt.get().count;
|
|
324
|
+
return {
|
|
325
|
+
totalMemories: memories,
|
|
326
|
+
totalSessionMemories: session,
|
|
327
|
+
totalLessons: lessons,
|
|
328
|
+
lastConsolidationId: this.lastConsolidationId,
|
|
329
|
+
uniqueHashes: this.contentHashes.size,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
catch {
|
|
333
|
+
return {
|
|
334
|
+
totalMemories: 0,
|
|
335
|
+
totalSessionMemories: 0,
|
|
336
|
+
totalLessons: 0,
|
|
337
|
+
lastConsolidationId: this.lastConsolidationId,
|
|
338
|
+
uniqueHashes: this.contentHashes.size,
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Start background consolidation process (SimpleMem-style async)
|
|
344
|
+
*/
|
|
345
|
+
startBackgroundConsolidation() {
|
|
346
|
+
if (this.backgroundInterval)
|
|
347
|
+
return;
|
|
348
|
+
this.isRunning = true;
|
|
349
|
+
this.backgroundInterval = setInterval(async () => {
|
|
350
|
+
if (!this.isRunning)
|
|
351
|
+
return;
|
|
352
|
+
try {
|
|
353
|
+
// Run consolidation if threshold met
|
|
354
|
+
if (this.shouldConsolidate()) {
|
|
355
|
+
await this.consolidate();
|
|
356
|
+
}
|
|
357
|
+
// Run recursive consolidation on summaries
|
|
358
|
+
await this.recursiveConsolidate();
|
|
359
|
+
// Apply quality decay
|
|
360
|
+
await this.applyQualityDecay();
|
|
361
|
+
}
|
|
362
|
+
catch (error) {
|
|
363
|
+
console.error('[MemoryConsolidator] Background error:', error);
|
|
364
|
+
}
|
|
365
|
+
}, this.config.backgroundIntervalMs);
|
|
366
|
+
console.log(`[MemoryConsolidator] Background consolidation started (interval: ${this.config.backgroundIntervalMs}ms)`);
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Stop background consolidation
|
|
370
|
+
*/
|
|
371
|
+
stopBackgroundConsolidation() {
|
|
372
|
+
this.isRunning = false;
|
|
373
|
+
if (this.backgroundInterval) {
|
|
374
|
+
clearInterval(this.backgroundInterval);
|
|
375
|
+
this.backgroundInterval = null;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Recursive consolidation - merge summaries into meta-summaries
|
|
380
|
+
* Based on SimpleMem's hierarchical abstraction
|
|
381
|
+
*/
|
|
382
|
+
async recursiveConsolidate(depth = 0) {
|
|
383
|
+
if (!this.db || depth >= this.config.recursiveDepth)
|
|
384
|
+
return 0;
|
|
385
|
+
let consolidated = 0;
|
|
386
|
+
try {
|
|
387
|
+
// Find summaries that can be merged (same type, adjacent time periods)
|
|
388
|
+
const stmt = this.db.prepare(`
|
|
389
|
+
SELECT id, timestamp, type, content, importance
|
|
390
|
+
FROM session_memories
|
|
391
|
+
WHERE type = 'summary'
|
|
392
|
+
ORDER BY timestamp ASC
|
|
393
|
+
LIMIT 20
|
|
394
|
+
`);
|
|
395
|
+
const summaries = stmt.all();
|
|
396
|
+
// Group adjacent summaries (within 24 hours)
|
|
397
|
+
const groups = [];
|
|
398
|
+
let currentGroup = [];
|
|
399
|
+
for (const summary of summaries) {
|
|
400
|
+
if (currentGroup.length === 0) {
|
|
401
|
+
currentGroup.push(summary);
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
const lastTime = new Date(currentGroup[currentGroup.length - 1].timestamp).getTime();
|
|
405
|
+
const thisTime = new Date(summary.timestamp).getTime();
|
|
406
|
+
const hoursDiff = (thisTime - lastTime) / (1000 * 60 * 60);
|
|
407
|
+
if (hoursDiff <= 24) {
|
|
408
|
+
currentGroup.push(summary);
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
if (currentGroup.length >= 3)
|
|
412
|
+
groups.push(currentGroup);
|
|
413
|
+
currentGroup = [summary];
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
if (currentGroup.length >= 3)
|
|
418
|
+
groups.push(currentGroup);
|
|
419
|
+
// Create meta-summaries from groups
|
|
420
|
+
for (const group of groups) {
|
|
421
|
+
const unit = createSemanticUnit(group.map(s => ({ content: s.content, importance: s.importance })));
|
|
422
|
+
if (unit.compressionRatio > 1.2) {
|
|
423
|
+
const metaSummary = unit.atomicFacts.map(f => f.content).join(' ');
|
|
424
|
+
const hash = this.hashContent(metaSummary);
|
|
425
|
+
if (!this.contentHashes.has(hash)) {
|
|
426
|
+
await this.storeSessionMemory(metaSummary, 'meta-summary', 8);
|
|
427
|
+
this.contentHashes.add(hash);
|
|
428
|
+
consolidated++;
|
|
429
|
+
// Remove original summaries
|
|
430
|
+
const ids = group.map(s => s.id);
|
|
431
|
+
this.db.prepare(`DELETE FROM session_memories WHERE id IN (${ids.join(',')})`).run();
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
catch {
|
|
437
|
+
// Ignore errors
|
|
438
|
+
}
|
|
439
|
+
return consolidated;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Apply quality decay to unused memories (Memory-R1 style)
|
|
443
|
+
*/
|
|
444
|
+
async applyQualityDecay() {
|
|
445
|
+
if (!this.db)
|
|
446
|
+
return 0;
|
|
447
|
+
const now = Date.now();
|
|
448
|
+
let updated = 0;
|
|
449
|
+
try {
|
|
450
|
+
const stmt = this.db.prepare(`
|
|
451
|
+
SELECT id, importance, timestamp
|
|
452
|
+
FROM session_memories
|
|
453
|
+
WHERE importance > 1
|
|
454
|
+
`);
|
|
455
|
+
const rows = stmt.all();
|
|
456
|
+
const updateStmt = this.db.prepare(`
|
|
457
|
+
UPDATE session_memories SET importance = ? WHERE id = ?
|
|
458
|
+
`);
|
|
459
|
+
for (const row of rows) {
|
|
460
|
+
const memKey = `session-${row.id}`;
|
|
461
|
+
const quality = this.memoryQualityScores.get(memKey);
|
|
462
|
+
// Calculate days since last access (or creation)
|
|
463
|
+
const lastAccess = quality?.lastAccessed || new Date(row.timestamp);
|
|
464
|
+
const daysSince = (now - lastAccess.getTime()) / (1000 * 60 * 60 * 24);
|
|
465
|
+
// Apply decay: importance * (decayRate ^ days)
|
|
466
|
+
const decayed = Math.round(row.importance * Math.pow(this.config.qualityDecayRate, daysSince));
|
|
467
|
+
if (decayed !== row.importance && decayed >= 1) {
|
|
468
|
+
updateStmt.run(decayed, row.id);
|
|
469
|
+
updated++;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
catch {
|
|
474
|
+
// Ignore errors
|
|
475
|
+
}
|
|
476
|
+
return updated;
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Record memory access (for quality scoring)
|
|
480
|
+
*/
|
|
481
|
+
recordAccess(memoryId) {
|
|
482
|
+
const existing = this.memoryQualityScores.get(memoryId);
|
|
483
|
+
this.memoryQualityScores.set(memoryId, {
|
|
484
|
+
score: (existing?.score || 5) + 0.5,
|
|
485
|
+
lastAccessed: new Date(),
|
|
486
|
+
accessCount: (existing?.accessCount || 0) + 1,
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Get memory quality score
|
|
491
|
+
*/
|
|
492
|
+
getQualityScore(memoryId) {
|
|
493
|
+
return this.memoryQualityScores.get(memoryId)?.score || 5;
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Close database connection
|
|
497
|
+
*/
|
|
498
|
+
close() {
|
|
499
|
+
this.stopBackgroundConsolidation();
|
|
500
|
+
if (this.db) {
|
|
501
|
+
this.db.close();
|
|
502
|
+
this.db = null;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
// Singleton instance
|
|
507
|
+
let globalConsolidator = null;
|
|
508
|
+
export function getMemoryConsolidator(config) {
|
|
509
|
+
if (!globalConsolidator) {
|
|
510
|
+
globalConsolidator = new MemoryConsolidator(config);
|
|
511
|
+
}
|
|
512
|
+
return globalConsolidator;
|
|
513
|
+
}
|
|
514
|
+
//# sourceMappingURL=memory-consolidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-consolidator.js","sourceRoot":"","sources":["../../src/memory/memory-consolidator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-View Memory System for UAM
|
|
3
|
+
*
|
|
4
|
+
* Implements:
|
|
5
|
+
* 1. Multi-view indexing (entity, temporal, semantic type views)
|
|
6
|
+
* 2. ENGRAM-style memory typing (episodic, semantic, procedural)
|
|
7
|
+
* 3. Async embedding generation
|
|
8
|
+
* 4. Speculative cache integration with task classifier
|
|
9
|
+
*
|
|
10
|
+
* Based on SimpleMem (2026) and ENGRAM (2025) research
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* ENGRAM-style memory types
|
|
14
|
+
*/
|
|
15
|
+
export type ENGRAMMemoryType = 'episodic' | 'semantic' | 'procedural';
|
|
16
|
+
/**
|
|
17
|
+
* Multi-view indexed memory entry
|
|
18
|
+
*/
|
|
19
|
+
export interface MultiViewMemory {
|
|
20
|
+
id: string;
|
|
21
|
+
content: string;
|
|
22
|
+
memoryType: ENGRAMMemoryType;
|
|
23
|
+
entities: string[];
|
|
24
|
+
temporalBucket: string;
|
|
25
|
+
semanticType: string;
|
|
26
|
+
embedding?: number[];
|
|
27
|
+
embeddingPending?: boolean;
|
|
28
|
+
importance: number;
|
|
29
|
+
accessCount: number;
|
|
30
|
+
lastAccessed: Date;
|
|
31
|
+
qualityScore: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Multi-view index structure
|
|
35
|
+
*/
|
|
36
|
+
export interface MultiViewIndex {
|
|
37
|
+
byEntity: Map<string, Set<string>>;
|
|
38
|
+
byTemporal: Map<string, Set<string>>;
|
|
39
|
+
bySemanticType: Map<string, Set<string>>;
|
|
40
|
+
byENGRAMType: Map<ENGRAMMemoryType, Set<string>>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Classify memory into ENGRAM type
|
|
44
|
+
*/
|
|
45
|
+
export declare function classifyENGRAMType(content: string, context?: {
|
|
46
|
+
type?: string;
|
|
47
|
+
}): ENGRAMMemoryType;
|
|
48
|
+
/**
|
|
49
|
+
* Extract temporal bucket from content/timestamp
|
|
50
|
+
*/
|
|
51
|
+
export declare function extractTemporalBucket(content: string, timestamp?: string): string;
|
|
52
|
+
/**
|
|
53
|
+
* Multi-View Memory Manager
|
|
54
|
+
*/
|
|
55
|
+
export declare class MultiViewMemoryManager {
|
|
56
|
+
private memories;
|
|
57
|
+
private index;
|
|
58
|
+
private embeddingQueue;
|
|
59
|
+
private isProcessingEmbeddings;
|
|
60
|
+
/**
|
|
61
|
+
* Add memory with multi-view indexing
|
|
62
|
+
*/
|
|
63
|
+
add(content: string, options?: {
|
|
64
|
+
id?: string;
|
|
65
|
+
semanticType?: string;
|
|
66
|
+
entities?: string[];
|
|
67
|
+
timestamp?: string;
|
|
68
|
+
importance?: number;
|
|
69
|
+
generateEmbedding?: boolean;
|
|
70
|
+
}): Promise<MultiViewMemory>;
|
|
71
|
+
/**
|
|
72
|
+
* Index memory in all views
|
|
73
|
+
*/
|
|
74
|
+
private indexMemory;
|
|
75
|
+
/**
|
|
76
|
+
* Query by entity
|
|
77
|
+
*/
|
|
78
|
+
queryByEntity(entity: string): MultiViewMemory[];
|
|
79
|
+
/**
|
|
80
|
+
* Query by ENGRAM type
|
|
81
|
+
*/
|
|
82
|
+
queryByENGRAMType(type: ENGRAMMemoryType): MultiViewMemory[];
|
|
83
|
+
/**
|
|
84
|
+
* Query by temporal bucket
|
|
85
|
+
*/
|
|
86
|
+
queryByTemporal(bucket: string): MultiViewMemory[];
|
|
87
|
+
/**
|
|
88
|
+
* Smart query using task classification to select best view
|
|
89
|
+
*/
|
|
90
|
+
smartQuery(query: string, limit?: number): Promise<MultiViewMemory[]>;
|
|
91
|
+
/**
|
|
92
|
+
* Get retrieval strategy based on task classification
|
|
93
|
+
*/
|
|
94
|
+
private getRetrievalStrategy;
|
|
95
|
+
/**
|
|
96
|
+
* Execute a single strategy step
|
|
97
|
+
*/
|
|
98
|
+
private executeStrategyStep;
|
|
99
|
+
/**
|
|
100
|
+
* Semantic search using embeddings
|
|
101
|
+
*/
|
|
102
|
+
semanticSearch(query: string, limit?: number): Promise<MultiViewMemory[]>;
|
|
103
|
+
/**
|
|
104
|
+
* Process embedding queue asynchronously
|
|
105
|
+
*/
|
|
106
|
+
private processEmbeddingQueue;
|
|
107
|
+
/**
|
|
108
|
+
* Extract entities from content
|
|
109
|
+
*/
|
|
110
|
+
private extractEntities;
|
|
111
|
+
/**
|
|
112
|
+
* Record memory access
|
|
113
|
+
*/
|
|
114
|
+
recordAccess(memoryId: string): void;
|
|
115
|
+
/**
|
|
116
|
+
* Get statistics
|
|
117
|
+
*/
|
|
118
|
+
getStats(): {
|
|
119
|
+
totalMemories: number;
|
|
120
|
+
byENGRAMType: Record<ENGRAMMemoryType, number>;
|
|
121
|
+
pendingEmbeddings: number;
|
|
122
|
+
entitiesIndexed: number;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Export all memories
|
|
126
|
+
*/
|
|
127
|
+
export(): MultiViewMemory[];
|
|
128
|
+
/**
|
|
129
|
+
* Import memories
|
|
130
|
+
*/
|
|
131
|
+
import(memories: MultiViewMemory[]): Promise<void>;
|
|
132
|
+
}
|
|
133
|
+
export declare function getMultiViewMemoryManager(): MultiViewMemoryManager;
|
|
134
|
+
//# sourceMappingURL=multi-view-memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-view-memory.d.ts","sourceRoot":"","sources":["../../src/memory/multi-view-memory.ts"],"names":[],"mappings":"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"}
|