@aman_asmuei/amem 0.8.2 → 0.9.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/README.md +190 -27
- package/dist/cli.js +36 -0
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +51 -0
- package/dist/config.js +130 -0
- package/dist/config.js.map +1 -0
- package/dist/dashboard.js +62 -1
- package/dist/dashboard.js.map +1 -1
- package/dist/database.d.ts +31 -0
- package/dist/database.js +121 -22
- package/dist/database.js.map +1 -1
- package/dist/embeddings.d.ts +18 -0
- package/dist/embeddings.js +79 -0
- package/dist/embeddings.js.map +1 -1
- package/dist/hooks.d.ts +21 -0
- package/dist/hooks.js +264 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.js +44 -10
- package/dist/index.js.map +1 -1
- package/dist/memory.d.ts +38 -0
- package/dist/memory.js +139 -2
- package/dist/memory.js.map +1 -1
- package/dist/tools/advanced.d.ts +3 -0
- package/dist/tools/advanced.js +318 -0
- package/dist/tools/advanced.js.map +1 -0
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/memory.js +21 -4
- package/dist/tools/memory.js.map +1 -1
- package/package.json +1 -1
package/dist/config.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
const DEFAULT_CONFIG = {
|
|
5
|
+
embeddingModel: "Xenova/all-MiniLM-L6-v2",
|
|
6
|
+
embeddingDimensions: 384,
|
|
7
|
+
embeddingCacheSize: 128,
|
|
8
|
+
retrieval: {
|
|
9
|
+
semanticWeight: 0.4,
|
|
10
|
+
ftsWeight: 0.3,
|
|
11
|
+
graphWeight: 0.15,
|
|
12
|
+
temporalWeight: 0.15,
|
|
13
|
+
maxCandidates: 50000,
|
|
14
|
+
rerankerEnabled: false,
|
|
15
|
+
rerankerTopK: 20,
|
|
16
|
+
},
|
|
17
|
+
consolidation: {
|
|
18
|
+
maxStaleDays: 60,
|
|
19
|
+
minConfidence: 0.3,
|
|
20
|
+
minAccessCount: 2,
|
|
21
|
+
enableDecay: false,
|
|
22
|
+
decayFactor: 0.95,
|
|
23
|
+
},
|
|
24
|
+
privacy: {
|
|
25
|
+
enablePrivateTags: true,
|
|
26
|
+
redactPatterns: [
|
|
27
|
+
"(?:api[_-]?key|secret|token|password|passwd|credential)\\s*[:=]\\s*['\"]?[A-Za-z0-9_\\-\\.]{8,}",
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
hooks: {
|
|
31
|
+
enabled: true,
|
|
32
|
+
captureToolUse: true,
|
|
33
|
+
captureSessionEnd: true,
|
|
34
|
+
autoExtractInterval: 0,
|
|
35
|
+
},
|
|
36
|
+
tiers: {
|
|
37
|
+
coreMaxTokens: 500,
|
|
38
|
+
workingMaxTokens: 2000,
|
|
39
|
+
},
|
|
40
|
+
team: {
|
|
41
|
+
enabled: false,
|
|
42
|
+
syncPath: null,
|
|
43
|
+
syncInterval: 30,
|
|
44
|
+
userId: null,
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
let loadedConfig = null;
|
|
48
|
+
export function getConfigPath() {
|
|
49
|
+
const amemDir = process.env.AMEM_DIR || path.join(os.homedir(), ".amem");
|
|
50
|
+
return path.join(amemDir, "config.json");
|
|
51
|
+
}
|
|
52
|
+
export function loadConfig() {
|
|
53
|
+
if (loadedConfig)
|
|
54
|
+
return loadedConfig;
|
|
55
|
+
const configPath = getConfigPath();
|
|
56
|
+
try {
|
|
57
|
+
if (fs.existsSync(configPath)) {
|
|
58
|
+
const raw = fs.readFileSync(configPath, "utf-8").trim();
|
|
59
|
+
if (raw) {
|
|
60
|
+
const userConfig = JSON.parse(raw);
|
|
61
|
+
loadedConfig = deepMerge(DEFAULT_CONFIG, userConfig);
|
|
62
|
+
return loadedConfig;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.error("[amem] Failed to load config, using defaults:", error instanceof Error ? error.message : String(error));
|
|
68
|
+
}
|
|
69
|
+
loadedConfig = { ...DEFAULT_CONFIG };
|
|
70
|
+
return loadedConfig;
|
|
71
|
+
}
|
|
72
|
+
export function saveConfig(config) {
|
|
73
|
+
const configPath = getConfigPath();
|
|
74
|
+
const dir = path.dirname(configPath);
|
|
75
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
76
|
+
// Merge with existing config
|
|
77
|
+
const existing = loadConfig();
|
|
78
|
+
const merged = deepMerge(existing, config);
|
|
79
|
+
fs.writeFileSync(configPath, JSON.stringify(merged, null, 2) + "\n");
|
|
80
|
+
loadedConfig = merged;
|
|
81
|
+
}
|
|
82
|
+
export function getDefaultConfig() {
|
|
83
|
+
return { ...DEFAULT_CONFIG };
|
|
84
|
+
}
|
|
85
|
+
export function resetConfigCache() {
|
|
86
|
+
loadedConfig = null;
|
|
87
|
+
}
|
|
88
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
89
|
+
function deepMerge(base, override) {
|
|
90
|
+
const result = { ...base };
|
|
91
|
+
for (const key of Object.keys(override)) {
|
|
92
|
+
const val = override[key];
|
|
93
|
+
if (val !== undefined && val !== null) {
|
|
94
|
+
if (typeof val === "object" && !Array.isArray(val) && typeof result[key] === "object" && !Array.isArray(result[key])) {
|
|
95
|
+
result[key] = deepMerge(result[key], val);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
result[key] = val;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
// ── Privacy helpers ─────────────────────────────────────
|
|
105
|
+
/**
|
|
106
|
+
* Strip <private>...</private> tags and redact patterns from content before storage.
|
|
107
|
+
* Returns cleaned content, or null if the entire content is private.
|
|
108
|
+
*/
|
|
109
|
+
export function sanitizeContent(content, config) {
|
|
110
|
+
const cfg = config ?? loadConfig();
|
|
111
|
+
if (!cfg.privacy.enablePrivateTags)
|
|
112
|
+
return content;
|
|
113
|
+
// Strip <private>...</private> blocks
|
|
114
|
+
let cleaned = content.replace(/<private>[\s\S]*?<\/private>/gi, "[REDACTED]");
|
|
115
|
+
// If entire content was private, return null (don't store)
|
|
116
|
+
if (cleaned.trim() === "[REDACTED]" || cleaned.trim() === "")
|
|
117
|
+
return null;
|
|
118
|
+
// Apply regex redaction patterns
|
|
119
|
+
for (const pattern of cfg.privacy.redactPatterns) {
|
|
120
|
+
try {
|
|
121
|
+
const regex = new RegExp(pattern, "g");
|
|
122
|
+
cleaned = cleaned.replace(regex, "[REDACTED]");
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// Invalid regex pattern — skip
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return cleaned;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/dashboard.js
CHANGED
|
@@ -133,6 +133,12 @@ a{color:var(--decision);text-decoration:none}
|
|
|
133
133
|
<option value="topology">topology</option>
|
|
134
134
|
<option value="fact">fact</option>
|
|
135
135
|
</select>
|
|
136
|
+
<select id="mem-tier">
|
|
137
|
+
<option value="">All tiers</option>
|
|
138
|
+
<option value="core">core</option>
|
|
139
|
+
<option value="working">working</option>
|
|
140
|
+
<option value="archival">archival</option>
|
|
141
|
+
</select>
|
|
136
142
|
</div>
|
|
137
143
|
<div class="mem-list" id="mem-list"></div>
|
|
138
144
|
</div>
|
|
@@ -149,6 +155,12 @@ a{color:var(--decision);text-decoration:none}
|
|
|
149
155
|
<div class="reminder-list" id="reminder-list"></div>
|
|
150
156
|
</div>
|
|
151
157
|
|
|
158
|
+
<!-- Session summaries -->
|
|
159
|
+
<div class="card full" id="summary-card">
|
|
160
|
+
<h2>Session Summaries</h2>
|
|
161
|
+
<div class="summary-list" id="summary-list"></div>
|
|
162
|
+
</div>
|
|
163
|
+
|
|
152
164
|
<!-- Recent log -->
|
|
153
165
|
<div class="card full" id="log-card">
|
|
154
166
|
<h2>Recent Log</h2>
|
|
@@ -220,9 +232,13 @@ a{color:var(--decision);text-decoration:none}
|
|
|
220
232
|
setHTML(el, memories.slice(0,50).map(function(m){
|
|
221
233
|
var color=TYPE_COLORS[m.type]||'#8b949e';
|
|
222
234
|
var tags=(m.tags||[]).map(function(t){return '<span class="tag">#'+esc(t)+'</span>'}).join(' ');
|
|
223
|
-
|
|
235
|
+
var tierBadge = m.tier && m.tier !== 'archival' ? '<span class="type-badge" style="background:'+(m.tier==='core'?'#f0883e':'#58a6ff')+'">'+esc(m.tier)+'</span>' : '';
|
|
236
|
+
var expiredBadge = m.validUntil ? '<span class="type-badge" style="background:#f85149;opacity:0.7">expired</span>' : '';
|
|
237
|
+
var validInfo = m.validFrom ? '<span>Valid: '+new Date(m.validFrom).toISOString().slice(0,10)+(m.validUntil?' → '+new Date(m.validUntil).toISOString().slice(0,10):' → now')+'</span>' : '';
|
|
238
|
+
return '<div class="mem-card"'+(m.validUntil?' style="opacity:0.6"':'')+'>'+
|
|
224
239
|
'<div class="mem-head">'+
|
|
225
240
|
'<span class="type-badge" style="background:'+color+'">'+esc(m.type)+'</span>'+
|
|
241
|
+
tierBadge+expiredBadge+
|
|
226
242
|
'<code class="mono" style="color:var(--muted);font-size:0.7rem">'+esc(m.id.slice(0,8))+'</code>'+
|
|
227
243
|
'</div>'+
|
|
228
244
|
'<div class="mem-content">'+esc(m.content)+'</div>'+
|
|
@@ -231,6 +247,7 @@ a{color:var(--decision);text-decoration:none}
|
|
|
231
247
|
'<span>'+timeAgo(m.createdAt)+'</span>'+
|
|
232
248
|
'<span>Accessed '+m.accessCount+'x</span>'+
|
|
233
249
|
(m.scope?'<span>Scope: '+esc(m.scope)+'</span>':'')+
|
|
250
|
+
validInfo+
|
|
234
251
|
(tags?' '+tags:'')+
|
|
235
252
|
'</div></div>';
|
|
236
253
|
}).join(''));
|
|
@@ -239,9 +256,11 @@ a{color:var(--decision);text-decoration:none}
|
|
|
239
256
|
function filterMemories(){
|
|
240
257
|
var q=($('mem-search').value||'').toLowerCase();
|
|
241
258
|
var t=$('mem-type').value;
|
|
259
|
+
var tier=$('mem-tier')?$('mem-tier').value:'';
|
|
242
260
|
var list=allMemories;
|
|
243
261
|
if(q) list=list.filter(function(m){return m.content.toLowerCase().indexOf(q)!==-1});
|
|
244
262
|
if(t) list=list.filter(function(m){return m.type===t});
|
|
263
|
+
if(tier) list=list.filter(function(m){return m.tier===tier});
|
|
245
264
|
renderMemories(list);
|
|
246
265
|
}
|
|
247
266
|
|
|
@@ -367,6 +386,27 @@ a{color:var(--decision);text-decoration:none}
|
|
|
367
386
|
fetchJSON('/api/graph').then(renderGraph).catch(function(){});
|
|
368
387
|
fetchJSON('/api/reminders').then(renderReminders).catch(function(){});
|
|
369
388
|
fetchJSON('/api/log?limit=30').then(renderLog).catch(function(){});
|
|
389
|
+
fetchJSON('/api/summaries?limit=10').then(renderSummaries).catch(function(){});
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
function renderSummaries(summaries){
|
|
393
|
+
var el=$('summary-list');
|
|
394
|
+
if(!el) return;
|
|
395
|
+
if(!summaries||!summaries.length){setHTML(el,'<div class="empty">No session summaries yet. Use memory_summarize at session end.</div>');return}
|
|
396
|
+
setHTML(el, summaries.map(function(s){
|
|
397
|
+
var decisions=(s.keyDecisions||[]).map(function(d){return '<li>'+esc(d)+'</li>'}).join('');
|
|
398
|
+
var corrections=(s.keyCorrections||[]).map(function(c){return '<li style="color:var(--correction)">'+esc(c)+'</li>'}).join('');
|
|
399
|
+
return '<div class="mem-card">'+
|
|
400
|
+
'<div class="mem-head">'+
|
|
401
|
+
'<span class="type-badge" style="background:var(--decision)">session</span>'+
|
|
402
|
+
'<code class="mono" style="color:var(--muted);font-size:0.7rem">'+esc(s.sessionId.slice(0,16))+'</code>'+
|
|
403
|
+
'<span style="color:var(--muted);font-size:0.75rem;margin-left:auto">'+timeAgo(s.createdAt)+' | '+s.memoriesExtracted+' memories extracted</span>'+
|
|
404
|
+
'</div>'+
|
|
405
|
+
'<div class="mem-content">'+esc(s.summary)+'</div>'+
|
|
406
|
+
(decisions?'<div class="mem-meta"><strong>Decisions:</strong></div><ul style="margin:4px 0 8px 20px;font-size:0.85rem">'+decisions+'</ul>':'')+
|
|
407
|
+
(corrections?'<div class="mem-meta"><strong>Corrections:</strong></div><ul style="margin:4px 0 8px 20px;font-size:0.85rem">'+corrections+'</ul>':'')+
|
|
408
|
+
'</div>';
|
|
409
|
+
}).join(''));
|
|
370
410
|
}
|
|
371
411
|
|
|
372
412
|
// -- Event listeners --
|
|
@@ -376,6 +416,7 @@ a{color:var(--decision);text-decoration:none}
|
|
|
376
416
|
debounce=setTimeout(filterMemories,300);
|
|
377
417
|
});
|
|
378
418
|
$('mem-type').addEventListener('change',filterMemories);
|
|
419
|
+
if($('mem-tier')) $('mem-tier').addEventListener('change',filterMemories);
|
|
379
420
|
|
|
380
421
|
// -- Init --
|
|
381
422
|
loadAll();
|
|
@@ -460,6 +501,9 @@ function handleMemories(db, res, query) {
|
|
|
460
501
|
createdAt: m.createdAt,
|
|
461
502
|
lastAccessed: m.lastAccessed,
|
|
462
503
|
scope: m.scope,
|
|
504
|
+
tier: m.tier,
|
|
505
|
+
validFrom: m.validFrom,
|
|
506
|
+
validUntil: m.validUntil,
|
|
463
507
|
}));
|
|
464
508
|
jsonResponse(res, result);
|
|
465
509
|
}
|
|
@@ -509,6 +553,20 @@ function handleLog(db, res, query) {
|
|
|
509
553
|
sessionId: e.sessionId,
|
|
510
554
|
})));
|
|
511
555
|
}
|
|
556
|
+
function handleSummaries(db, res, query) {
|
|
557
|
+
const limit = Math.min(50, Math.max(1, parseInt(query.limit || "10", 10) || 10));
|
|
558
|
+
const project = query.project || "global";
|
|
559
|
+
const summaries = db.getRecentSummaries(project, limit);
|
|
560
|
+
jsonResponse(res, summaries.map((s) => ({
|
|
561
|
+
id: s.id,
|
|
562
|
+
sessionId: s.sessionId,
|
|
563
|
+
summary: s.summary,
|
|
564
|
+
keyDecisions: s.keyDecisions,
|
|
565
|
+
keyCorrections: s.keyCorrections,
|
|
566
|
+
memoriesExtracted: s.memoriesExtracted,
|
|
567
|
+
createdAt: s.createdAt,
|
|
568
|
+
})));
|
|
569
|
+
}
|
|
512
570
|
// ---------------------------------------------------------------------------
|
|
513
571
|
// Public API
|
|
514
572
|
// ---------------------------------------------------------------------------
|
|
@@ -537,6 +595,9 @@ export function startDashboard(db, port) {
|
|
|
537
595
|
case "/api/log":
|
|
538
596
|
handleLog(db, res, query);
|
|
539
597
|
break;
|
|
598
|
+
case "/api/summaries":
|
|
599
|
+
handleSummaries(db, res, query);
|
|
600
|
+
break;
|
|
540
601
|
default:
|
|
541
602
|
errorResponse(res, "Not found", 404);
|
|
542
603
|
}
|
package/dist/dashboard.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,8EAA8E;AAC9E,0DAA0D;AAC1D,sEAAsE;AACtE,sEAAsE;AACtE,8EAA8E;AAE9E,MAAM,cAAc,GAAG
|
|
1
|
+
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"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"}
|
package/dist/database.d.ts
CHANGED
|
@@ -7,6 +7,19 @@ export interface MemoryInput {
|
|
|
7
7
|
source: string;
|
|
8
8
|
embedding: Float32Array | null;
|
|
9
9
|
scope: string;
|
|
10
|
+
validFrom?: number;
|
|
11
|
+
validUntil?: number;
|
|
12
|
+
tier?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface SessionSummary {
|
|
15
|
+
id: string;
|
|
16
|
+
sessionId: string;
|
|
17
|
+
summary: string;
|
|
18
|
+
keyDecisions: string[];
|
|
19
|
+
keyCorrections: string[];
|
|
20
|
+
memoriesExtracted: number;
|
|
21
|
+
project: string;
|
|
22
|
+
createdAt: number;
|
|
10
23
|
}
|
|
11
24
|
export interface MemoryStats {
|
|
12
25
|
total: number;
|
|
@@ -43,6 +56,8 @@ export interface MemoryRelation {
|
|
|
43
56
|
relationshipType: string;
|
|
44
57
|
strength: number;
|
|
45
58
|
createdAt: number;
|
|
59
|
+
validFrom?: number | null;
|
|
60
|
+
validUntil?: number | null;
|
|
46
61
|
}
|
|
47
62
|
export interface PatchInput {
|
|
48
63
|
field: "content" | "confidence" | "tags" | "type";
|
|
@@ -111,5 +126,21 @@ export interface AmemDatabase {
|
|
|
111
126
|
resolveId(partialId: string): string | null;
|
|
112
127
|
resolveReminderId(partialId: string): string | null;
|
|
113
128
|
getAllRelations(): MemoryRelation[];
|
|
129
|
+
expireMemory(id: string, timestamp?: number): void;
|
|
130
|
+
getValidMemories(asOf?: number): Memory[];
|
|
131
|
+
updateTier(id: string, tier: string): void;
|
|
132
|
+
getByTier(tier: string, scope?: string): Memory[];
|
|
133
|
+
insertSummary(input: {
|
|
134
|
+
sessionId: string;
|
|
135
|
+
summary: string;
|
|
136
|
+
keyDecisions: string[];
|
|
137
|
+
keyCorrections: string[];
|
|
138
|
+
memoriesExtracted: number;
|
|
139
|
+
project: string;
|
|
140
|
+
}): string;
|
|
141
|
+
getSummaryBySession(sessionId: string): SessionSummary | null;
|
|
142
|
+
getRecentSummaries(project: string, limit?: number): SessionSummary[];
|
|
143
|
+
expireRelation(relationId: string, timestamp?: number): void;
|
|
144
|
+
getValidRelations(asOf?: number): MemoryRelation[];
|
|
114
145
|
}
|
|
115
146
|
export declare function createDatabase(dbPath: string): AmemDatabase;
|
package/dist/database.js
CHANGED
|
@@ -15,6 +15,33 @@ function rowToMemory(row) {
|
|
|
15
15
|
? new Float32Array(row.embedding.buffer, row.embedding.byteOffset, row.embedding.byteLength / 4)
|
|
16
16
|
: null,
|
|
17
17
|
scope: row.scope,
|
|
18
|
+
validFrom: row.valid_from ?? row.created_at,
|
|
19
|
+
validUntil: row.valid_until ?? null,
|
|
20
|
+
tier: (row.tier ?? 'archival'),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function rowToSummary(row) {
|
|
24
|
+
return {
|
|
25
|
+
id: row.id,
|
|
26
|
+
sessionId: row.session_id,
|
|
27
|
+
summary: row.summary,
|
|
28
|
+
keyDecisions: JSON.parse(row.key_decisions),
|
|
29
|
+
keyCorrections: JSON.parse(row.key_corrections),
|
|
30
|
+
memoriesExtracted: row.memories_extracted,
|
|
31
|
+
project: row.project,
|
|
32
|
+
createdAt: row.created_at,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function rowToRelation(r) {
|
|
36
|
+
return {
|
|
37
|
+
id: r.id,
|
|
38
|
+
fromId: r.from_id,
|
|
39
|
+
toId: r.to_id,
|
|
40
|
+
relationshipType: r.relationship_type,
|
|
41
|
+
strength: r.strength,
|
|
42
|
+
createdAt: r.created_at,
|
|
43
|
+
validFrom: r.valid_from ?? null,
|
|
44
|
+
validUntil: r.valid_until ?? null,
|
|
18
45
|
};
|
|
19
46
|
}
|
|
20
47
|
export function createDatabase(dbPath) {
|
|
@@ -112,6 +139,21 @@ export function createDatabase(dbPath) {
|
|
|
112
139
|
);
|
|
113
140
|
CREATE INDEX IF NOT EXISTS idx_reminders_due ON reminders(due_at);
|
|
114
141
|
CREATE INDEX IF NOT EXISTS idx_reminders_completed ON reminders(completed);
|
|
142
|
+
|
|
143
|
+
-- Session summaries
|
|
144
|
+
CREATE TABLE IF NOT EXISTS session_summaries (
|
|
145
|
+
id TEXT PRIMARY KEY,
|
|
146
|
+
session_id TEXT NOT NULL,
|
|
147
|
+
summary TEXT NOT NULL,
|
|
148
|
+
key_decisions TEXT NOT NULL DEFAULT '[]',
|
|
149
|
+
key_corrections TEXT NOT NULL DEFAULT '[]',
|
|
150
|
+
memories_extracted INTEGER NOT NULL DEFAULT 0,
|
|
151
|
+
project TEXT NOT NULL DEFAULT 'global',
|
|
152
|
+
created_at INTEGER NOT NULL,
|
|
153
|
+
UNIQUE(session_id)
|
|
154
|
+
);
|
|
155
|
+
CREATE INDEX IF NOT EXISTS idx_summaries_session ON session_summaries(session_id);
|
|
156
|
+
CREATE INDEX IF NOT EXISTS idx_summaries_project ON session_summaries(project);
|
|
115
157
|
`);
|
|
116
158
|
// Migration: add scope column if not present
|
|
117
159
|
const columns = db.pragma('table_info(memories)');
|
|
@@ -132,10 +174,28 @@ export function createDatabase(dbPath) {
|
|
|
132
174
|
}
|
|
133
175
|
}
|
|
134
176
|
db.exec(`CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash)`);
|
|
177
|
+
// Migration: add temporal validity + tiers
|
|
178
|
+
const hasValidFrom = columns.some(c => c.name === 'valid_from');
|
|
179
|
+
if (!hasValidFrom) {
|
|
180
|
+
db.exec(`ALTER TABLE memories ADD COLUMN valid_from INTEGER`);
|
|
181
|
+
db.exec(`ALTER TABLE memories ADD COLUMN valid_until INTEGER`);
|
|
182
|
+
db.exec(`ALTER TABLE memories ADD COLUMN tier TEXT NOT NULL DEFAULT 'archival'`);
|
|
183
|
+
db.exec(`UPDATE memories SET valid_from = created_at WHERE valid_from IS NULL`);
|
|
184
|
+
}
|
|
185
|
+
db.exec(`CREATE INDEX IF NOT EXISTS idx_memories_valid_until ON memories(valid_until)`);
|
|
186
|
+
db.exec(`CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier)`);
|
|
187
|
+
// Migration: add temporal validity to relations
|
|
188
|
+
const relColumns = db.pragma('table_info(memory_relations)');
|
|
189
|
+
const relHasValidFrom = relColumns.some(c => c.name === 'valid_from');
|
|
190
|
+
if (!relHasValidFrom) {
|
|
191
|
+
db.exec(`ALTER TABLE memory_relations ADD COLUMN valid_from INTEGER`);
|
|
192
|
+
db.exec(`ALTER TABLE memory_relations ADD COLUMN valid_until INTEGER`);
|
|
193
|
+
db.exec(`UPDATE memory_relations SET valid_from = created_at WHERE valid_from IS NULL`);
|
|
194
|
+
}
|
|
135
195
|
const stmts = {
|
|
136
196
|
insert: db.prepare(`
|
|
137
|
-
INSERT INTO memories (id, content, type, tags, confidence, access_count, created_at, last_accessed, source, embedding, scope, content_hash)
|
|
138
|
-
VALUES (?, ?, ?, ?, ?, 0, ?, ?, ?, ?, ?, ?)
|
|
197
|
+
INSERT INTO memories (id, content, type, tags, confidence, access_count, created_at, last_accessed, source, embedding, scope, content_hash, valid_from, valid_until, tier)
|
|
198
|
+
VALUES (?, ?, ?, ?, ?, 0, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
139
199
|
`),
|
|
140
200
|
getById: db.prepare(`SELECT * FROM memories WHERE id = ?`),
|
|
141
201
|
searchByType: db.prepare(`SELECT * FROM memories WHERE type = ? ORDER BY last_accessed DESC`),
|
|
@@ -183,8 +243,8 @@ export function createDatabase(dbPath) {
|
|
|
183
243
|
getVersions: db.prepare(`SELECT * FROM memory_versions WHERE memory_id = ? ORDER BY edited_at DESC`),
|
|
184
244
|
// Relations
|
|
185
245
|
insertRelation: db.prepare(`
|
|
186
|
-
INSERT OR REPLACE INTO memory_relations (id, from_id, to_id, relationship_type, strength, created_at)
|
|
187
|
-
VALUES (?, ?, ?, ?, ?, ?)
|
|
246
|
+
INSERT OR REPLACE INTO memory_relations (id, from_id, to_id, relationship_type, strength, created_at, valid_from)
|
|
247
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
188
248
|
`),
|
|
189
249
|
getRelationsFrom: db.prepare(`SELECT * FROM memory_relations WHERE from_id = ?`),
|
|
190
250
|
getRelationsTo: db.prepare(`SELECT * FROM memory_relations WHERE to_id = ?`),
|
|
@@ -203,6 +263,19 @@ export function createDatabase(dbPath) {
|
|
|
203
263
|
resolveReminderIdPrefix: db.prepare("SELECT id FROM reminders WHERE id LIKE ? LIMIT 2"),
|
|
204
264
|
// Batch relation loading
|
|
205
265
|
getAllRelations: db.prepare("SELECT * FROM memory_relations ORDER BY created_at DESC"),
|
|
266
|
+
// Temporal validity
|
|
267
|
+
getValidMemories: db.prepare(`SELECT * FROM memories WHERE (valid_until IS NULL OR valid_until > ?) ORDER BY last_accessed DESC`),
|
|
268
|
+
expireMemory: db.prepare(`UPDATE memories SET valid_until = ? WHERE id = ?`),
|
|
269
|
+
updateTier: db.prepare(`UPDATE memories SET tier = ?, last_accessed = ? WHERE id = ?`),
|
|
270
|
+
getByTier: db.prepare(`SELECT * FROM memories WHERE tier = ? ORDER BY last_accessed DESC`),
|
|
271
|
+
getByTierAndScope: db.prepare(`SELECT * FROM memories WHERE tier = ? AND (scope = 'global' OR scope = ?) ORDER BY last_accessed DESC`),
|
|
272
|
+
// Session summaries
|
|
273
|
+
insertSummary: db.prepare(`INSERT OR REPLACE INTO session_summaries (id, session_id, summary, key_decisions, key_corrections, memories_extracted, project, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`),
|
|
274
|
+
getSummaryBySession: db.prepare(`SELECT * FROM session_summaries WHERE session_id = ?`),
|
|
275
|
+
getRecentSummaries: db.prepare(`SELECT * FROM session_summaries WHERE project = ? ORDER BY created_at DESC LIMIT ?`),
|
|
276
|
+
// Temporal relations
|
|
277
|
+
expireRelation: db.prepare(`UPDATE memory_relations SET valid_until = ? WHERE id = ?`),
|
|
278
|
+
getValidRelations: db.prepare(`SELECT * FROM memory_relations WHERE (valid_until IS NULL OR valid_until > ?) ORDER BY created_at DESC`),
|
|
206
279
|
};
|
|
207
280
|
// Keep FTS index in sync via triggers.
|
|
208
281
|
// External-content FTS5 tables require explicit rowid in all operations.
|
|
@@ -244,7 +317,7 @@ export function createDatabase(dbPath) {
|
|
|
244
317
|
? Buffer.from(input.embedding.buffer, input.embedding.byteOffset, input.embedding.byteLength)
|
|
245
318
|
: null;
|
|
246
319
|
const contentHash = createHash("sha256").update(input.content).digest("hex").slice(0, 16);
|
|
247
|
-
stmts.insert.run(id, input.content, input.type, JSON.stringify(input.tags), input.confidence, now, now, input.source, embeddingBuffer, input.scope, contentHash);
|
|
320
|
+
stmts.insert.run(id, input.content, input.type, JSON.stringify(input.tags), input.confidence, now, now, input.source, embeddingBuffer, input.scope, contentHash, input.validFrom ?? now, input.validUntil ?? null, input.tier ?? "archival");
|
|
248
321
|
return id;
|
|
249
322
|
},
|
|
250
323
|
findByContentHash(content) {
|
|
@@ -444,20 +517,14 @@ export function createDatabase(dbPath) {
|
|
|
444
517
|
// ── Relations ────────────────────────────────────────────
|
|
445
518
|
addRelation(fromId, toId, type, strength = 0.8) {
|
|
446
519
|
const id = randomUUID();
|
|
447
|
-
|
|
520
|
+
const now = Date.now();
|
|
521
|
+
stmts.insertRelation.run(id, fromId, toId, type, strength, now, now);
|
|
448
522
|
return id;
|
|
449
523
|
},
|
|
450
524
|
getRelations(memoryId) {
|
|
451
525
|
const from = stmts.getRelationsFrom.all(memoryId);
|
|
452
526
|
const to = stmts.getRelationsTo.all(memoryId);
|
|
453
|
-
return [...from, ...to].map(
|
|
454
|
-
id: r.id,
|
|
455
|
-
fromId: r.from_id,
|
|
456
|
-
toId: r.to_id,
|
|
457
|
-
relationshipType: r.relationship_type,
|
|
458
|
-
strength: r.strength,
|
|
459
|
-
createdAt: r.created_at,
|
|
460
|
-
}));
|
|
527
|
+
return [...from, ...to].map(rowToRelation);
|
|
461
528
|
},
|
|
462
529
|
removeRelation(relationId) {
|
|
463
530
|
stmts.deleteRelation.run(relationId);
|
|
@@ -586,14 +653,46 @@ export function createDatabase(dbPath) {
|
|
|
586
653
|
},
|
|
587
654
|
getAllRelations() {
|
|
588
655
|
const rows = stmts.getAllRelations.all();
|
|
589
|
-
return rows.map(
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
656
|
+
return rows.map(rowToRelation);
|
|
657
|
+
},
|
|
658
|
+
// ── Temporal validity ───────────────────────────────────
|
|
659
|
+
expireMemory(id, timestamp) {
|
|
660
|
+
stmts.expireMemory.run(timestamp ?? Date.now(), id);
|
|
661
|
+
},
|
|
662
|
+
getValidMemories(asOf) {
|
|
663
|
+
const rows = stmts.getValidMemories.all(asOf ?? Date.now());
|
|
664
|
+
return rows.map(rowToMemory);
|
|
665
|
+
},
|
|
666
|
+
updateTier(id, tier) {
|
|
667
|
+
stmts.updateTier.run(tier, Date.now(), id);
|
|
668
|
+
},
|
|
669
|
+
getByTier(tier, scope) {
|
|
670
|
+
const rows = scope
|
|
671
|
+
? stmts.getByTierAndScope.all(tier, scope)
|
|
672
|
+
: stmts.getByTier.all(tier);
|
|
673
|
+
return rows.map(rowToMemory);
|
|
674
|
+
},
|
|
675
|
+
// ── Session summaries ───────────────────────────────────
|
|
676
|
+
insertSummary(input) {
|
|
677
|
+
const id = randomUUID();
|
|
678
|
+
stmts.insertSummary.run(id, input.sessionId, input.summary, JSON.stringify(input.keyDecisions), JSON.stringify(input.keyCorrections), input.memoriesExtracted, input.project, Date.now());
|
|
679
|
+
return id;
|
|
680
|
+
},
|
|
681
|
+
getSummaryBySession(sessionId) {
|
|
682
|
+
const row = stmts.getSummaryBySession.get(sessionId);
|
|
683
|
+
return row ? rowToSummary(row) : null;
|
|
684
|
+
},
|
|
685
|
+
getRecentSummaries(project, limit = 10) {
|
|
686
|
+
const rows = stmts.getRecentSummaries.all(project, limit);
|
|
687
|
+
return rows.map(rowToSummary);
|
|
688
|
+
},
|
|
689
|
+
// ── Temporal relations ──────────────────────────────────
|
|
690
|
+
expireRelation(relationId, timestamp) {
|
|
691
|
+
stmts.expireRelation.run(timestamp ?? Date.now(), relationId);
|
|
692
|
+
},
|
|
693
|
+
getValidRelations(asOf) {
|
|
694
|
+
const rows = stmts.getValidRelations.all(asOf ?? Date.now());
|
|
695
|
+
return rows.map(rowToRelation);
|
|
597
696
|
},
|
|
598
697
|
};
|
|
599
698
|
}
|