@aman_asmuei/amem 0.19.0 → 0.20.0
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/cli.js +6 -7
- package/dist/cli.js.map +1 -1
- package/dist/dashboard.d.ts +1 -1
- package/dist/dashboard.js +1 -1
- package/dist/dashboard.js.map +1 -1
- package/dist/index.js +3 -7
- package/dist/index.js.map +1 -1
- package/dist/tools/advanced.d.ts +1 -1
- package/dist/tools/advanced.js +1 -5
- package/dist/tools/advanced.js.map +1 -1
- package/dist/tools/graph.d.ts +1 -1
- package/dist/tools/graph.js +1 -2
- package/dist/tools/graph.js.map +1 -1
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.js +2 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/log.d.ts +1 -1
- package/dist/tools/log.js +1 -2
- package/dist/tools/log.js.map +1 -1
- package/dist/tools/memory.d.ts +1 -2
- package/dist/tools/memory.js +16 -22
- package/dist/tools/memory.js.map +1 -1
- package/dist/tools/reminders.d.ts +1 -1
- package/dist/tools/reminders.js +4 -5
- package/dist/tools/reminders.js.map +1 -1
- package/dist/tools/versions.d.ts +1 -1
- package/dist/tools/versions.js +3 -4
- package/dist/tools/versions.js.map +1 -1
- package/dist/tools.test.js +1 -2
- package/dist/tools.test.js.map +1 -1
- package/package.json +3 -9
- package/dist/ann.d.ts +0 -26
- package/dist/ann.js +0 -155
- package/dist/ann.js.map +0 -1
- package/dist/auto-relate.d.ts +0 -14
- package/dist/auto-relate.js +0 -47
- package/dist/auto-relate.js.map +0 -1
- package/dist/config.d.ts +0 -51
- package/dist/config.js +0 -130
- package/dist/config.js.map +0 -1
- package/dist/database.d.ts +0 -165
- package/dist/database.js +0 -831
- package/dist/database.js.map +0 -1
- package/dist/database.test.d.ts +0 -1
- package/dist/database.test.js +0 -275
- package/dist/database.test.js.map +0 -1
- package/dist/doctor.d.ts +0 -23
- package/dist/doctor.js +0 -107
- package/dist/doctor.js.map +0 -1
- package/dist/embeddings.d.ts +0 -38
- package/dist/embeddings.js +0 -251
- package/dist/embeddings.js.map +0 -1
- package/dist/embeddings.test.d.ts +0 -1
- package/dist/embeddings.test.js +0 -106
- package/dist/embeddings.test.js.map +0 -1
- package/dist/extractor.d.ts +0 -13
- package/dist/extractor.js +0 -89
- package/dist/extractor.js.map +0 -1
- package/dist/memory.d.ts +0 -134
- package/dist/memory.js +0 -432
- package/dist/memory.js.map +0 -1
- package/dist/memory.test.d.ts +0 -1
- package/dist/memory.test.js +0 -172
- package/dist/memory.test.js.map +0 -1
- package/dist/query-expand.d.ts +0 -9
- package/dist/query-expand.js +0 -71
- package/dist/query-expand.js.map +0 -1
- package/dist/reflection.d.ts +0 -82
- package/dist/reflection.js +0 -414
- package/dist/reflection.js.map +0 -1
- package/dist/reflection.test.d.ts +0 -1
- package/dist/reflection.test.js +0 -453
- package/dist/reflection.test.js.map +0 -1
- package/dist/repair.d.ts +0 -8
- package/dist/repair.js +0 -90
- package/dist/repair.js.map +0 -1
- package/dist/schemas.d.ts +0 -1075
- package/dist/schemas.js +0 -311
- package/dist/schemas.js.map +0 -1
- package/dist/sync.d.ts +0 -85
- package/dist/sync.js +0 -304
- package/dist/sync.js.map +0 -1
- package/dist/tools/helpers.d.ts +0 -7
- package/dist/tools/helpers.js +0 -23
- package/dist/tools/helpers.js.map +0 -1
package/dist/memory.js
DELETED
|
@@ -1,432 +0,0 @@
|
|
|
1
|
-
import { cosineSimilarity, rerankWithCrossEncoder } from "./embeddings.js";
|
|
2
|
-
import { expandQuery } from "./query-expand.js";
|
|
3
|
-
import { VectorIndex } from "./ann.js";
|
|
4
|
-
export const MemoryType = {
|
|
5
|
-
CORRECTION: "correction",
|
|
6
|
-
DECISION: "decision",
|
|
7
|
-
PATTERN: "pattern",
|
|
8
|
-
PREFERENCE: "preference",
|
|
9
|
-
TOPOLOGY: "topology",
|
|
10
|
-
FACT: "fact",
|
|
11
|
-
};
|
|
12
|
-
export const IMPORTANCE_WEIGHTS = {
|
|
13
|
-
correction: 1.0,
|
|
14
|
-
decision: 0.85,
|
|
15
|
-
pattern: 0.7,
|
|
16
|
-
preference: 0.7,
|
|
17
|
-
topology: 0.5,
|
|
18
|
-
fact: 0.4,
|
|
19
|
-
};
|
|
20
|
-
export function computeScore(input) {
|
|
21
|
-
const hoursSinceAccess = (input.now - input.lastAccessed) / (1000 * 60 * 60);
|
|
22
|
-
const recency = Math.pow(0.995, Math.max(0, hoursSinceAccess));
|
|
23
|
-
return (input.relevance * 0.45 +
|
|
24
|
-
recency * 0.2 +
|
|
25
|
-
input.confidence * 0.2 +
|
|
26
|
-
input.importance * 0.15);
|
|
27
|
-
}
|
|
28
|
-
export function detectConflict(newContent, existingContent, similarity) {
|
|
29
|
-
if (newContent === existingContent) {
|
|
30
|
-
return { isConflict: false, similarity };
|
|
31
|
-
}
|
|
32
|
-
return {
|
|
33
|
-
isConflict: similarity > 0.85,
|
|
34
|
-
similarity,
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
export function recallMemories(db, options) {
|
|
38
|
-
const { query, queryEmbedding, limit, type, tag, minConfidence, scope, explain, filterExpired = true, tier } = options;
|
|
39
|
-
const now = Date.now();
|
|
40
|
-
let candidates;
|
|
41
|
-
if (type) {
|
|
42
|
-
candidates = db.searchByType(type);
|
|
43
|
-
if (scope) {
|
|
44
|
-
candidates = candidates.filter(m => m.scope === "global" || m.scope === scope);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
else if (tag) {
|
|
48
|
-
candidates = db.searchByTag(tag);
|
|
49
|
-
if (scope) {
|
|
50
|
-
candidates = candidates.filter(m => m.scope === "global" || m.scope === scope);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
else if (scope) {
|
|
54
|
-
candidates = db.getAllForProject(scope);
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
candidates = db.getAll();
|
|
58
|
-
}
|
|
59
|
-
// Filter out expired memories (temporal validity)
|
|
60
|
-
if (filterExpired) {
|
|
61
|
-
candidates = candidates.filter(m => m.validUntil === null || m.validUntil > now);
|
|
62
|
-
}
|
|
63
|
-
// Filter by tier
|
|
64
|
-
if (tier) {
|
|
65
|
-
candidates = candidates.filter(m => m.tier === tier);
|
|
66
|
-
}
|
|
67
|
-
if (minConfidence) {
|
|
68
|
-
candidates = candidates.filter((m) => m.confidence >= minConfidence);
|
|
69
|
-
}
|
|
70
|
-
// When query exists but no embeddings, filter to keyword matches only
|
|
71
|
-
if (query && !queryEmbedding) {
|
|
72
|
-
const expanded = expandQuery(query);
|
|
73
|
-
const keywordMatches = candidates.filter((m) => {
|
|
74
|
-
const lower = m.content.toLowerCase();
|
|
75
|
-
const tagStr = m.tags.join(" ").toLowerCase();
|
|
76
|
-
return expanded.some(term => lower.includes(term) || tagStr.includes(term));
|
|
77
|
-
});
|
|
78
|
-
if (keywordMatches.length > 0) {
|
|
79
|
-
candidates = keywordMatches;
|
|
80
|
-
}
|
|
81
|
-
// If no keyword matches, keep all candidates (broad fallback)
|
|
82
|
-
}
|
|
83
|
-
const scored = candidates.map((memory) => {
|
|
84
|
-
let relevance = 0.5;
|
|
85
|
-
let relevanceSource = "default";
|
|
86
|
-
if (queryEmbedding && memory.embedding) {
|
|
87
|
-
relevance = Math.max(0, cosineSimilarity(queryEmbedding, memory.embedding));
|
|
88
|
-
relevanceSource = "semantic";
|
|
89
|
-
}
|
|
90
|
-
else if (query && memory.content.toLowerCase().includes(query.toLowerCase())) {
|
|
91
|
-
relevance = 0.75;
|
|
92
|
-
relevanceSource = "keyword";
|
|
93
|
-
}
|
|
94
|
-
const importance = IMPORTANCE_WEIGHTS[memory.type] ?? 0.4;
|
|
95
|
-
const hoursSinceAccess = (now - memory.lastAccessed) / (1000 * 60 * 60);
|
|
96
|
-
const recency = Math.pow(0.995, Math.max(0, hoursSinceAccess));
|
|
97
|
-
const score = computeScore({
|
|
98
|
-
relevance,
|
|
99
|
-
confidence: memory.confidence,
|
|
100
|
-
lastAccessed: memory.lastAccessed,
|
|
101
|
-
importance,
|
|
102
|
-
now,
|
|
103
|
-
});
|
|
104
|
-
if (explain) {
|
|
105
|
-
return {
|
|
106
|
-
...memory,
|
|
107
|
-
score,
|
|
108
|
-
explanation: {
|
|
109
|
-
relevance,
|
|
110
|
-
relevanceSource,
|
|
111
|
-
recency: Number(recency.toFixed(4)),
|
|
112
|
-
hoursSinceAccess: Number(hoursSinceAccess.toFixed(1)),
|
|
113
|
-
confidence: memory.confidence,
|
|
114
|
-
importance,
|
|
115
|
-
importanceLabel: memory.type,
|
|
116
|
-
finalScore: Number(score.toFixed(4)),
|
|
117
|
-
},
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
return { ...memory, score };
|
|
121
|
-
});
|
|
122
|
-
scored.sort((a, b) => b.score - a.score);
|
|
123
|
-
return scored.slice(0, limit);
|
|
124
|
-
}
|
|
125
|
-
export function consolidateMemories(db, cosineSim, options) {
|
|
126
|
-
const now = Date.now();
|
|
127
|
-
const msPerDay = 1000 * 60 * 60 * 24;
|
|
128
|
-
const allMemories = db.getAllWithEmbeddings();
|
|
129
|
-
const all = db.getAll();
|
|
130
|
-
const beforeTotal = all.length;
|
|
131
|
-
const actions = [];
|
|
132
|
-
const toDelete = new Set();
|
|
133
|
-
let promoted = 0;
|
|
134
|
-
// 1. MERGE: find near-duplicate pairs (>0.85 similarity)
|
|
135
|
-
// Batch by type to reduce O(n²) — only compare within same type, skip corrections.
|
|
136
|
-
// Sort by recency and cap group size to keep O(n²) bounded.
|
|
137
|
-
const MAX_MERGE_GROUP = 500;
|
|
138
|
-
const byType = new Map();
|
|
139
|
-
for (const mem of allMemories) {
|
|
140
|
-
if (!mem.embedding)
|
|
141
|
-
continue;
|
|
142
|
-
if (mem.type === "correction")
|
|
143
|
-
continue;
|
|
144
|
-
const group = byType.get(mem.type) ?? [];
|
|
145
|
-
group.push(mem);
|
|
146
|
-
byType.set(mem.type, group);
|
|
147
|
-
}
|
|
148
|
-
for (const [, group] of byType) {
|
|
149
|
-
// Sort most recently accessed first — duplicates are most likely among recent memories
|
|
150
|
-
group.sort((a, b) => b.lastAccessed - a.lastAccessed);
|
|
151
|
-
const capped = group.slice(0, MAX_MERGE_GROUP);
|
|
152
|
-
for (let i = 0; i < capped.length; i++) {
|
|
153
|
-
if (toDelete.has(capped[i].id))
|
|
154
|
-
continue;
|
|
155
|
-
for (let j = i + 1; j < capped.length; j++) {
|
|
156
|
-
if (toDelete.has(capped[j].id))
|
|
157
|
-
continue;
|
|
158
|
-
const sim = cosineSim(capped[i].embedding, capped[j].embedding);
|
|
159
|
-
if (sim > 0.85) {
|
|
160
|
-
const [keep, discard] = capped[i].confidence >= capped[j].confidence
|
|
161
|
-
? [capped[i], capped[j]]
|
|
162
|
-
: [capped[j], capped[i]];
|
|
163
|
-
toDelete.add(discard.id);
|
|
164
|
-
actions.push({
|
|
165
|
-
action: "merged",
|
|
166
|
-
memoryIds: [keep.id, discard.id],
|
|
167
|
-
description: `Merged "${discard.content}" into "${keep.content}" (${(sim * 100).toFixed(0)}% similar)`,
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
// 2. PRUNE: stale, low-confidence, rarely-accessed (NEVER corrections)
|
|
174
|
-
for (const mem of all) {
|
|
175
|
-
if (toDelete.has(mem.id))
|
|
176
|
-
continue;
|
|
177
|
-
if (mem.type === "correction")
|
|
178
|
-
continue;
|
|
179
|
-
const daysSinceAccess = (now - mem.lastAccessed) / msPerDay;
|
|
180
|
-
if (daysSinceAccess > options.maxStaleDays &&
|
|
181
|
-
mem.confidence < options.minConfidence &&
|
|
182
|
-
mem.accessCount < options.minAccessCount) {
|
|
183
|
-
toDelete.add(mem.id);
|
|
184
|
-
actions.push({
|
|
185
|
-
action: "pruned",
|
|
186
|
-
memoryIds: [mem.id],
|
|
187
|
-
description: `Pruned "${mem.content}" (${daysSinceAccess.toFixed(0)}d stale, ${(mem.confidence * 100).toFixed(0)}% confidence, ${mem.accessCount} accesses)`,
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
// 3. PROMOTE: frequently-accessed memories with low confidence
|
|
192
|
-
const toPromote = [];
|
|
193
|
-
for (const mem of all) {
|
|
194
|
-
if (toDelete.has(mem.id))
|
|
195
|
-
continue;
|
|
196
|
-
if (mem.accessCount >= 5 && mem.confidence < 0.8) {
|
|
197
|
-
toPromote.push({ id: mem.id });
|
|
198
|
-
promoted++;
|
|
199
|
-
actions.push({
|
|
200
|
-
action: "promoted",
|
|
201
|
-
memoryIds: [mem.id],
|
|
202
|
-
description: `Promoted "${mem.content}" to 90% confidence (accessed ${mem.accessCount} times)`,
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
// 4. DECAY: gradually reduce confidence of stale, non-correction memories
|
|
207
|
-
let decayed = 0;
|
|
208
|
-
const toDecay = [];
|
|
209
|
-
if (options.enableDecay) {
|
|
210
|
-
const factor = options.decayFactor ?? 0.95;
|
|
211
|
-
for (const mem of all) {
|
|
212
|
-
if (toDelete.has(mem.id))
|
|
213
|
-
continue;
|
|
214
|
-
if (mem.type === "correction")
|
|
215
|
-
continue;
|
|
216
|
-
const daysSinceAccess = (now - mem.lastAccessed) / msPerDay;
|
|
217
|
-
if (daysSinceAccess > 30 && mem.confidence > 0.3) {
|
|
218
|
-
const newConf = Number((mem.confidence * factor).toFixed(3));
|
|
219
|
-
if (newConf < mem.confidence) {
|
|
220
|
-
toDecay.push({ id: mem.id, newConfidence: Math.max(0.1, newConf) });
|
|
221
|
-
decayed++;
|
|
222
|
-
actions.push({
|
|
223
|
-
action: "decayed",
|
|
224
|
-
memoryIds: [mem.id],
|
|
225
|
-
description: `Decayed "${mem.content}" from ${(mem.confidence * 100).toFixed(0)}% to ${(newConf * 100).toFixed(0)}% confidence (${daysSinceAccess.toFixed(0)}d idle)`,
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
// Apply all mutations inside a single transaction for atomicity
|
|
232
|
-
if (!options.dryRun) {
|
|
233
|
-
db.transaction(() => {
|
|
234
|
-
for (const action of actions) {
|
|
235
|
-
if (action.action === "merged") {
|
|
236
|
-
const keepId = action.memoryIds[0];
|
|
237
|
-
const discardId = action.memoryIds[1];
|
|
238
|
-
const keep = allMemories.find(m => m.id === keepId) ?? all.find(m => m.id === keepId);
|
|
239
|
-
if (keep) {
|
|
240
|
-
db.updateConfidence(keepId, Math.min(1.0, keep.confidence + 0.1));
|
|
241
|
-
}
|
|
242
|
-
db.deleteMemory(discardId);
|
|
243
|
-
}
|
|
244
|
-
else if (action.action === "pruned") {
|
|
245
|
-
db.deleteMemory(action.memoryIds[0]);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
for (const { id } of toPromote) {
|
|
249
|
-
db.updateConfidence(id, 0.9);
|
|
250
|
-
}
|
|
251
|
-
for (const d of toDecay) {
|
|
252
|
-
db.updateConfidence(d.id, d.newConfidence);
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
const afterTotal = beforeTotal - toDelete.size;
|
|
257
|
-
const signalCount = all.filter(m => !toDelete.has(m.id) && (m.confidence >= 0.8 || m.type === "correction")).length;
|
|
258
|
-
const healthScore = afterTotal === 0 ? 100 : Math.round((signalCount / afterTotal) * 100);
|
|
259
|
-
return {
|
|
260
|
-
merged: actions.filter(a => a.action === "merged").length,
|
|
261
|
-
pruned: actions.filter(a => a.action === "pruned").length,
|
|
262
|
-
promoted,
|
|
263
|
-
decayed,
|
|
264
|
-
actions,
|
|
265
|
-
healthScore,
|
|
266
|
-
before: { total: beforeTotal },
|
|
267
|
-
after: { total: afterTotal },
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
// ── Vector Index ─────────────────────────────────────
|
|
271
|
-
let vectorIndex = null;
|
|
272
|
-
export function buildVectorIndex(db) {
|
|
273
|
-
const index = new VectorIndex(384);
|
|
274
|
-
const memories = db.getAllWithEmbeddings();
|
|
275
|
-
index.buildFrom(memories
|
|
276
|
-
.filter(m => m.embedding !== null)
|
|
277
|
-
.map(m => ({ id: m.id, embedding: m.embedding })));
|
|
278
|
-
vectorIndex = index;
|
|
279
|
-
return index;
|
|
280
|
-
}
|
|
281
|
-
export function getVectorIndex() {
|
|
282
|
-
return vectorIndex;
|
|
283
|
-
}
|
|
284
|
-
/**
|
|
285
|
-
* Multi-strategy retrieval: combines semantic search, FTS5, knowledge graph traversal,
|
|
286
|
-
* and temporal recency into a unified ranking. Each strategy votes independently,
|
|
287
|
-
* then scores are merged with configurable weights.
|
|
288
|
-
*/
|
|
289
|
-
export async function multiStrategyRecall(db, options) {
|
|
290
|
-
const { query, queryEmbedding, limit, scope } = options;
|
|
291
|
-
const weights = options.weights ?? { semantic: 0.4, fts: 0.3, graph: 0.15, temporal: 0.15 };
|
|
292
|
-
const now = Date.now();
|
|
293
|
-
const scoreMap = new Map();
|
|
294
|
-
const initEntry = (m) => {
|
|
295
|
-
if (!scoreMap.has(m.id)) {
|
|
296
|
-
scoreMap.set(m.id, { memory: m, scores: { semantic: 0, fts: 0, graph: 0, temporal: 0 } });
|
|
297
|
-
}
|
|
298
|
-
return scoreMap.get(m.id);
|
|
299
|
-
};
|
|
300
|
-
// Strategy 1: Semantic search via vector index (or full scan fallback)
|
|
301
|
-
if (queryEmbedding) {
|
|
302
|
-
const index = getVectorIndex();
|
|
303
|
-
if (index && index.size() > 0) {
|
|
304
|
-
// Fast path: in-memory vector index lookup
|
|
305
|
-
const vectorResults = index.search(queryEmbedding, limit * 3, 0.2);
|
|
306
|
-
for (const r of vectorResults) {
|
|
307
|
-
const mem = db.getById(r.id);
|
|
308
|
-
if (!mem)
|
|
309
|
-
continue;
|
|
310
|
-
if (mem.validUntil !== null && mem.validUntil <= now)
|
|
311
|
-
continue;
|
|
312
|
-
if (scope && mem.scope !== "global" && mem.scope !== scope)
|
|
313
|
-
continue;
|
|
314
|
-
const entry = initEntry(mem);
|
|
315
|
-
entry.scores.semantic = r.similarity;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
else {
|
|
319
|
-
// Fallback: full scan when index isn't built yet
|
|
320
|
-
const candidates = scope ? db.getAllForProject(scope) : db.getAll();
|
|
321
|
-
const validCandidates = candidates.filter(m => m.validUntil === null || m.validUntil > now);
|
|
322
|
-
for (const m of validCandidates) {
|
|
323
|
-
if (!m.embedding)
|
|
324
|
-
continue;
|
|
325
|
-
const sim = Math.max(0, cosineSimilarity(queryEmbedding, m.embedding));
|
|
326
|
-
if (sim > 0.2) {
|
|
327
|
-
const entry = initEntry(m);
|
|
328
|
-
entry.scores.semantic = sim;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
// Strategy 2: Full-text search (FTS5 exact matching)
|
|
334
|
-
try {
|
|
335
|
-
const ftsResults = db.fullTextSearch(query, limit * 2, scope);
|
|
336
|
-
const validFts = ftsResults.filter(m => m.validUntil === null || m.validUntil > now);
|
|
337
|
-
for (let i = 0; i < validFts.length; i++) {
|
|
338
|
-
const m = validFts[i];
|
|
339
|
-
const entry = initEntry(m);
|
|
340
|
-
// FTS rank: highest rank for first result, decaying
|
|
341
|
-
entry.scores.fts = Math.max(entry.scores.fts, 1.0 - (i / validFts.length) * 0.5);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
catch {
|
|
345
|
-
// FTS may fail — skip this strategy
|
|
346
|
-
}
|
|
347
|
-
// Strategy 3: Knowledge graph traversal
|
|
348
|
-
// Find memories that are related to high-scoring candidates
|
|
349
|
-
const topSemanticIds = [...scoreMap.entries()]
|
|
350
|
-
.sort((a, b) => b[1].scores.semantic - a[1].scores.semantic)
|
|
351
|
-
.slice(0, 10)
|
|
352
|
-
.map(([id]) => id);
|
|
353
|
-
for (const id of topSemanticIds) {
|
|
354
|
-
const related = db.getRelatedMemories(id);
|
|
355
|
-
for (const m of related) {
|
|
356
|
-
if (m.validUntil !== null && m.validUntil <= now)
|
|
357
|
-
continue;
|
|
358
|
-
const entry = initEntry(m);
|
|
359
|
-
const parentScore = scoreMap.get(id)?.scores.semantic ?? 0;
|
|
360
|
-
// Graph neighbors get a fraction of the parent's score
|
|
361
|
-
entry.scores.graph = Math.max(entry.scores.graph, parentScore * 0.6);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
// Strategy 4: Temporal boost (recently accessed/created memories score higher)
|
|
365
|
-
for (const [, entry] of scoreMap) {
|
|
366
|
-
const hoursSinceAccess = (now - entry.memory.lastAccessed) / (1000 * 60 * 60);
|
|
367
|
-
entry.scores.temporal = Math.pow(0.995, Math.max(0, hoursSinceAccess));
|
|
368
|
-
}
|
|
369
|
-
// Merge scores with weights
|
|
370
|
-
const results = [];
|
|
371
|
-
for (const [, entry] of scoreMap) {
|
|
372
|
-
const { semantic, fts, graph, temporal } = entry.scores;
|
|
373
|
-
const importance = IMPORTANCE_WEIGHTS[entry.memory.type] ?? 0.4;
|
|
374
|
-
const combined = (semantic * weights.semantic +
|
|
375
|
-
fts * weights.fts +
|
|
376
|
-
graph * weights.graph +
|
|
377
|
-
temporal * weights.temporal) * entry.memory.confidence * importance;
|
|
378
|
-
results.push({ ...entry.memory, score: combined });
|
|
379
|
-
}
|
|
380
|
-
results.sort((a, b) => b.score - a.score);
|
|
381
|
-
// Optional cross-encoder reranking — the final pass for highest accuracy
|
|
382
|
-
const shouldRerank = options.rerank ?? false;
|
|
383
|
-
if (shouldRerank && results.length > 1) {
|
|
384
|
-
const rerankerTopK = options.rerankerTopK ?? 20;
|
|
385
|
-
const candidatesForRerank = results.slice(0, rerankerTopK);
|
|
386
|
-
const reranked = await rerankWithCrossEncoder(query, candidatesForRerank.map(r => ({ id: r.id, content: r.content, score: r.score })), limit);
|
|
387
|
-
// Map reranked scores back to full RecalledMemory objects
|
|
388
|
-
const rerankedMap = new Map(reranked.map(r => [r.id, r.score]));
|
|
389
|
-
const finalResults = [];
|
|
390
|
-
for (const r of candidatesForRerank) {
|
|
391
|
-
const newScore = rerankedMap.get(r.id);
|
|
392
|
-
if (newScore !== undefined) {
|
|
393
|
-
finalResults.push({ ...r, score: newScore });
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
finalResults.sort((a, b) => b.score - a.score);
|
|
397
|
-
return finalResults.slice(0, limit);
|
|
398
|
-
}
|
|
399
|
-
return results.slice(0, limit);
|
|
400
|
-
}
|
|
401
|
-
// ── Auto-expire contradictions ─────────────────────────
|
|
402
|
-
/**
|
|
403
|
-
* When storing a new memory that contradicts an existing one,
|
|
404
|
-
* auto-expire the old memory instead of requiring manual consolidation.
|
|
405
|
-
*/
|
|
406
|
-
export function autoExpireContradictions(db, newContent, newEmbedding, newType) {
|
|
407
|
-
if (!newEmbedding)
|
|
408
|
-
return { expired: [], reason: "no embedding" };
|
|
409
|
-
const existing = db.getRecentWithEmbeddings(50000);
|
|
410
|
-
const expired = [];
|
|
411
|
-
for (const mem of existing) {
|
|
412
|
-
if (!mem.embedding)
|
|
413
|
-
continue;
|
|
414
|
-
if (mem.type !== newType)
|
|
415
|
-
continue; // Only expire same-type memories
|
|
416
|
-
if (mem.validUntil !== null)
|
|
417
|
-
continue; // Already expired
|
|
418
|
-
const sim = cosineSimilarity(newEmbedding, mem.embedding);
|
|
419
|
-
if (sim > 0.75 && sim < 0.95) {
|
|
420
|
-
// High similarity but not exact match = likely contradicting/superseding
|
|
421
|
-
const conflict = detectConflict(newContent, mem.content, sim);
|
|
422
|
-
if (conflict.isConflict) {
|
|
423
|
-
db.expireMemory(mem.id);
|
|
424
|
-
expired.push(mem.id);
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
return { expired, reason: expired.length > 0 ? `auto-expired ${expired.length} contradicting memories` : "no contradictions" };
|
|
429
|
-
}
|
|
430
|
-
// ── Privacy helper (re-exported for tools) ─────────────
|
|
431
|
-
export { sanitizeContent } from "./config.js";
|
|
432
|
-
//# sourceMappingURL=memory.js.map
|
package/dist/memory.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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"}
|
package/dist/memory.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/memory.test.js
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import { MemoryType, IMPORTANCE_WEIGHTS, computeScore, detectConflict, recallMemories, } from "./memory.js";
|
|
3
|
-
import { createDatabase } from "./database.js";
|
|
4
|
-
describe("MemoryType constants", () => {
|
|
5
|
-
it("has the expected types", () => {
|
|
6
|
-
expect(MemoryType.CORRECTION).toBe("correction");
|
|
7
|
-
expect(MemoryType.DECISION).toBe("decision");
|
|
8
|
-
expect(MemoryType.PATTERN).toBe("pattern");
|
|
9
|
-
expect(MemoryType.PREFERENCE).toBe("preference");
|
|
10
|
-
expect(MemoryType.TOPOLOGY).toBe("topology");
|
|
11
|
-
expect(MemoryType.FACT).toBe("fact");
|
|
12
|
-
});
|
|
13
|
-
});
|
|
14
|
-
describe("IMPORTANCE_WEIGHTS", () => {
|
|
15
|
-
it("correction has highest weight (1.0)", () => {
|
|
16
|
-
expect(IMPORTANCE_WEIGHTS.correction).toBe(1.0);
|
|
17
|
-
});
|
|
18
|
-
it("decision has weight 0.85", () => {
|
|
19
|
-
expect(IMPORTANCE_WEIGHTS.decision).toBe(0.85);
|
|
20
|
-
});
|
|
21
|
-
it("pattern and preference have weight 0.7", () => {
|
|
22
|
-
expect(IMPORTANCE_WEIGHTS.pattern).toBe(0.7);
|
|
23
|
-
expect(IMPORTANCE_WEIGHTS.preference).toBe(0.7);
|
|
24
|
-
});
|
|
25
|
-
it("topology has weight 0.5", () => {
|
|
26
|
-
expect(IMPORTANCE_WEIGHTS.topology).toBe(0.5);
|
|
27
|
-
});
|
|
28
|
-
it("fact has lowest weight (0.4)", () => {
|
|
29
|
-
expect(IMPORTANCE_WEIGHTS.fact).toBe(0.4);
|
|
30
|
-
});
|
|
31
|
-
it("weights are ordered: correction > decision > pattern = preference > topology > fact", () => {
|
|
32
|
-
expect(IMPORTANCE_WEIGHTS.correction).toBeGreaterThan(IMPORTANCE_WEIGHTS.decision);
|
|
33
|
-
expect(IMPORTANCE_WEIGHTS.decision).toBeGreaterThan(IMPORTANCE_WEIGHTS.pattern);
|
|
34
|
-
expect(IMPORTANCE_WEIGHTS.pattern).toBe(IMPORTANCE_WEIGHTS.preference);
|
|
35
|
-
expect(IMPORTANCE_WEIGHTS.preference).toBeGreaterThan(IMPORTANCE_WEIGHTS.topology);
|
|
36
|
-
expect(IMPORTANCE_WEIGHTS.topology).toBeGreaterThan(IMPORTANCE_WEIGHTS.fact);
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
describe("computeScore", () => {
|
|
40
|
-
it("returns higher score for recently accessed memories", () => {
|
|
41
|
-
const now = Date.now();
|
|
42
|
-
const recentScore = computeScore({
|
|
43
|
-
relevance: 0.8,
|
|
44
|
-
confidence: 0.9,
|
|
45
|
-
lastAccessed: now - 1000 * 60 * 60, // 1 hour ago
|
|
46
|
-
importance: 1.0,
|
|
47
|
-
now,
|
|
48
|
-
});
|
|
49
|
-
const oldScore = computeScore({
|
|
50
|
-
relevance: 0.8,
|
|
51
|
-
confidence: 0.9,
|
|
52
|
-
lastAccessed: now - 1000 * 60 * 60 * 24 * 30, // 30 days ago
|
|
53
|
-
importance: 1.0,
|
|
54
|
-
now,
|
|
55
|
-
});
|
|
56
|
-
expect(recentScore).toBeGreaterThan(oldScore);
|
|
57
|
-
});
|
|
58
|
-
it("returns higher score for higher confidence", () => {
|
|
59
|
-
const now = Date.now();
|
|
60
|
-
const highConf = computeScore({ relevance: 0.8, confidence: 1.0, lastAccessed: now, importance: 1.0, now });
|
|
61
|
-
const lowConf = computeScore({ relevance: 0.8, confidence: 0.3, lastAccessed: now, importance: 1.0, now });
|
|
62
|
-
expect(highConf).toBeGreaterThan(lowConf);
|
|
63
|
-
});
|
|
64
|
-
it("returns higher score for higher importance", () => {
|
|
65
|
-
const now = Date.now();
|
|
66
|
-
const highImp = computeScore({ relevance: 0.8, confidence: 0.9, lastAccessed: now, importance: 1.0, now });
|
|
67
|
-
const lowImp = computeScore({ relevance: 0.8, confidence: 0.9, lastAccessed: now, importance: 0.4, now });
|
|
68
|
-
expect(highImp).toBeGreaterThan(lowImp);
|
|
69
|
-
});
|
|
70
|
-
it("returns higher score for higher relevance", () => {
|
|
71
|
-
const now = Date.now();
|
|
72
|
-
const highRel = computeScore({ relevance: 1.0, confidence: 0.9, lastAccessed: now, importance: 1.0, now });
|
|
73
|
-
const lowRel = computeScore({ relevance: 0.2, confidence: 0.9, lastAccessed: now, importance: 1.0, now });
|
|
74
|
-
expect(highRel).toBeGreaterThan(lowRel);
|
|
75
|
-
});
|
|
76
|
-
it("returns low score when relevance is 0", () => {
|
|
77
|
-
const now = Date.now();
|
|
78
|
-
const score = computeScore({ relevance: 0, confidence: 1.0, lastAccessed: now, importance: 1.0, now });
|
|
79
|
-
// With additive scoring, zero relevance still gets recency+confidence+importance contributions
|
|
80
|
-
expect(score).toBeCloseTo(0.55, 1);
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
describe("detectConflict", () => {
|
|
84
|
-
it("detects conflict when similarity > 0.85 and content differs", () => {
|
|
85
|
-
const result = detectConflict("Use pnpm", "Use npm", 0.9);
|
|
86
|
-
expect(result.isConflict).toBe(true);
|
|
87
|
-
expect(result.similarity).toBe(0.9);
|
|
88
|
-
});
|
|
89
|
-
it("no conflict when similarity <= 0.85", () => {
|
|
90
|
-
const result = detectConflict("Use pnpm", "Use npm", 0.7);
|
|
91
|
-
expect(result.isConflict).toBe(false);
|
|
92
|
-
});
|
|
93
|
-
it("no conflict when content is identical (even with high similarity)", () => {
|
|
94
|
-
const result = detectConflict("same text", "same text", 1.0);
|
|
95
|
-
expect(result.isConflict).toBe(false);
|
|
96
|
-
});
|
|
97
|
-
it("conflict at boundary (0.86)", () => {
|
|
98
|
-
const result = detectConflict("a", "b", 0.86);
|
|
99
|
-
expect(result.isConflict).toBe(true);
|
|
100
|
-
});
|
|
101
|
-
it("no conflict at boundary (0.85)", () => {
|
|
102
|
-
const result = detectConflict("a", "b", 0.85);
|
|
103
|
-
expect(result.isConflict).toBe(false);
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
describe("recallMemories", () => {
|
|
107
|
-
let db;
|
|
108
|
-
beforeEach(() => {
|
|
109
|
-
db = createDatabase(":memory:");
|
|
110
|
-
});
|
|
111
|
-
afterEach(() => {
|
|
112
|
-
db.close();
|
|
113
|
-
});
|
|
114
|
-
it("returns all memories ranked by score when no filter", () => {
|
|
115
|
-
db.insertMemory({ content: "fact one", type: "fact", tags: [], confidence: 0.5, source: "t", embedding: null, scope: "global" });
|
|
116
|
-
db.insertMemory({ content: "correction one", type: "correction", tags: [], confidence: 1.0, source: "t", embedding: null, scope: "global" });
|
|
117
|
-
const results = recallMemories(db, { query: null, limit: 10 });
|
|
118
|
-
expect(results).toHaveLength(2);
|
|
119
|
-
// Correction should score higher due to higher importance + confidence
|
|
120
|
-
expect(results[0].type).toBe("correction");
|
|
121
|
-
});
|
|
122
|
-
it("filters by type", () => {
|
|
123
|
-
db.insertMemory({ content: "a", type: "fact", tags: [], confidence: 0.5, source: "t", embedding: null, scope: "global" });
|
|
124
|
-
db.insertMemory({ content: "b", type: "decision", tags: [], confidence: 0.9, source: "t", embedding: null, scope: "global" });
|
|
125
|
-
const results = recallMemories(db, { query: null, limit: 10, type: "decision" });
|
|
126
|
-
expect(results).toHaveLength(1);
|
|
127
|
-
expect(results[0].type).toBe("decision");
|
|
128
|
-
});
|
|
129
|
-
it("filters by tag", () => {
|
|
130
|
-
db.insertMemory({ content: "ts thing", type: "fact", tags: ["typescript"], confidence: 0.5, source: "t", embedding: null, scope: "global" });
|
|
131
|
-
db.insertMemory({ content: "rust thing", type: "fact", tags: ["rust"], confidence: 0.5, source: "t", embedding: null, scope: "global" });
|
|
132
|
-
const results = recallMemories(db, { query: null, limit: 10, tag: "typescript" });
|
|
133
|
-
expect(results).toHaveLength(1);
|
|
134
|
-
expect(results[0].content).toBe("ts thing");
|
|
135
|
-
});
|
|
136
|
-
it("filters by minConfidence", () => {
|
|
137
|
-
db.insertMemory({ content: "low", type: "fact", tags: [], confidence: 0.2, source: "t", embedding: null, scope: "global" });
|
|
138
|
-
db.insertMemory({ content: "high", type: "fact", tags: [], confidence: 0.9, source: "t", embedding: null, scope: "global" });
|
|
139
|
-
const results = recallMemories(db, { query: null, limit: 10, minConfidence: 0.5 });
|
|
140
|
-
expect(results).toHaveLength(1);
|
|
141
|
-
expect(results[0].content).toBe("high");
|
|
142
|
-
});
|
|
143
|
-
it("respects limit", () => {
|
|
144
|
-
for (let i = 0; i < 5; i++) {
|
|
145
|
-
db.insertMemory({ content: `mem ${i}`, type: "fact", tags: [], confidence: 0.5, source: "t", embedding: null, scope: "global" });
|
|
146
|
-
}
|
|
147
|
-
const results = recallMemories(db, { query: null, limit: 3 });
|
|
148
|
-
expect(results).toHaveLength(3);
|
|
149
|
-
});
|
|
150
|
-
it("keyword matching narrows results to matches and boosts relevance", () => {
|
|
151
|
-
db.insertMemory({ content: "TypeScript compiler config", type: "fact", tags: [], confidence: 0.8, source: "t", embedding: null, scope: "global" });
|
|
152
|
-
db.insertMemory({ content: "Rust build system", type: "fact", tags: [], confidence: 0.8, source: "t", embedding: null, scope: "global" });
|
|
153
|
-
const results = recallMemories(db, { query: "TypeScript", limit: 10 });
|
|
154
|
-
// Only the TypeScript memory should match when using keyword-only (no embeddings)
|
|
155
|
-
expect(results).toHaveLength(1);
|
|
156
|
-
expect(results[0].content).toContain("TypeScript");
|
|
157
|
-
// Keyword match gives relevance of 0.75 (higher than default 0.5)
|
|
158
|
-
expect(results[0].score).toBeGreaterThan(0);
|
|
159
|
-
});
|
|
160
|
-
it("filters by scope", () => {
|
|
161
|
-
db.insertMemory({ content: "global mem", type: "fact", tags: [], confidence: 0.5, source: "t", embedding: null, scope: "global" });
|
|
162
|
-
db.insertMemory({ content: "project mem", type: "fact", tags: [], confidence: 0.5, source: "t", embedding: null, scope: "project:foo" });
|
|
163
|
-
db.insertMemory({ content: "other project", type: "fact", tags: [], confidence: 0.5, source: "t", embedding: null, scope: "project:bar" });
|
|
164
|
-
const results = recallMemories(db, { query: null, limit: 10, scope: "project:foo" });
|
|
165
|
-
// Should include global + project:foo, but not project:bar
|
|
166
|
-
const scopes = results.map(r => r.scope);
|
|
167
|
-
expect(scopes).toContain("global");
|
|
168
|
-
expect(scopes).toContain("project:foo");
|
|
169
|
-
expect(scopes).not.toContain("project:bar");
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
//# sourceMappingURL=memory.test.js.map
|