agent-working-memory 0.5.4 → 0.5.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 +87 -46
- package/dist/api/routes.d.ts.map +1 -1
- package/dist/api/routes.js +21 -5
- package/dist/api/routes.js.map +1 -1
- package/dist/cli.js +67 -67
- package/dist/coordination/index.d.ts +11 -0
- package/dist/coordination/index.d.ts.map +1 -0
- package/dist/coordination/index.js +39 -0
- package/dist/coordination/index.js.map +1 -0
- package/dist/coordination/mcp-tools.d.ts +8 -0
- package/dist/coordination/mcp-tools.d.ts.map +1 -0
- package/dist/coordination/mcp-tools.js +216 -0
- package/dist/coordination/mcp-tools.js.map +1 -0
- package/dist/coordination/routes.d.ts +9 -0
- package/dist/coordination/routes.d.ts.map +1 -0
- package/dist/coordination/routes.js +434 -0
- package/dist/coordination/routes.js.map +1 -0
- package/dist/coordination/schema.d.ts +12 -0
- package/dist/coordination/schema.d.ts.map +1 -0
- package/dist/coordination/schema.js +91 -0
- package/dist/coordination/schema.js.map +1 -0
- package/dist/coordination/schemas.d.ts +208 -0
- package/dist/coordination/schemas.d.ts.map +1 -0
- package/dist/coordination/schemas.js +109 -0
- package/dist/coordination/schemas.js.map +1 -0
- package/dist/coordination/stale.d.ts +25 -0
- package/dist/coordination/stale.d.ts.map +1 -0
- package/dist/coordination/stale.js +53 -0
- package/dist/coordination/stale.js.map +1 -0
- package/dist/index.js +21 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +90 -79
- package/dist/mcp.js.map +1 -1
- package/dist/storage/sqlite.d.ts +3 -0
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +285 -281
- package/dist/storage/sqlite.js.map +1 -1
- package/package.json +55 -55
- package/src/api/index.ts +3 -3
- package/src/api/routes.ts +551 -536
- package/src/cli.ts +397 -397
- package/src/coordination/index.ts +47 -0
- package/src/coordination/mcp-tools.ts +313 -0
- package/src/coordination/routes.ts +656 -0
- package/src/coordination/schema.ts +94 -0
- package/src/coordination/schemas.ts +136 -0
- package/src/coordination/stale.ts +89 -0
- package/src/core/decay.ts +63 -63
- package/src/core/embeddings.ts +88 -88
- package/src/core/hebbian.ts +93 -93
- package/src/core/index.ts +5 -5
- package/src/core/logger.ts +36 -36
- package/src/core/query-expander.ts +66 -66
- package/src/core/reranker.ts +101 -101
- package/src/engine/activation.ts +656 -656
- package/src/engine/connections.ts +103 -103
- package/src/engine/consolidation-scheduler.ts +125 -125
- package/src/engine/eval.ts +102 -102
- package/src/engine/eviction.ts +101 -101
- package/src/engine/index.ts +8 -8
- package/src/engine/retraction.ts +100 -100
- package/src/engine/staging.ts +74 -74
- package/src/index.ts +137 -121
- package/src/mcp.ts +1024 -1013
- package/src/storage/index.ts +3 -3
- package/src/storage/sqlite.ts +968 -963
- package/src/types/agent.ts +67 -67
- package/src/types/checkpoint.ts +46 -46
- package/src/types/engram.ts +217 -217
- package/src/types/eval.ts +100 -100
- package/src/types/index.ts +6 -6
package/dist/storage/sqlite.js
CHANGED
|
@@ -27,119 +27,123 @@ export class EngramStore {
|
|
|
27
27
|
this.db.pragma('foreign_keys = ON');
|
|
28
28
|
this.init();
|
|
29
29
|
}
|
|
30
|
+
/** Expose the raw database handle for the coordination module. */
|
|
31
|
+
getDb() {
|
|
32
|
+
return this.db;
|
|
33
|
+
}
|
|
30
34
|
init() {
|
|
31
|
-
this.db.exec(`
|
|
32
|
-
CREATE TABLE IF NOT EXISTS engrams (
|
|
33
|
-
id TEXT PRIMARY KEY,
|
|
34
|
-
agent_id TEXT NOT NULL,
|
|
35
|
-
concept TEXT NOT NULL,
|
|
36
|
-
content TEXT NOT NULL,
|
|
37
|
-
embedding BLOB,
|
|
38
|
-
confidence REAL NOT NULL DEFAULT 0.5,
|
|
39
|
-
salience REAL NOT NULL DEFAULT 0.5,
|
|
40
|
-
access_count INTEGER NOT NULL DEFAULT 0,
|
|
41
|
-
last_accessed TEXT NOT NULL,
|
|
42
|
-
created_at TEXT NOT NULL,
|
|
43
|
-
salience_features TEXT NOT NULL DEFAULT '{}',
|
|
44
|
-
reason_codes TEXT NOT NULL DEFAULT '[]',
|
|
45
|
-
stage TEXT NOT NULL DEFAULT 'active',
|
|
46
|
-
ttl INTEGER,
|
|
47
|
-
retracted INTEGER NOT NULL DEFAULT 0,
|
|
48
|
-
retracted_by TEXT,
|
|
49
|
-
retracted_at TEXT,
|
|
50
|
-
tags TEXT NOT NULL DEFAULT '[]'
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
CREATE INDEX IF NOT EXISTS idx_engrams_agent ON engrams(agent_id);
|
|
54
|
-
CREATE INDEX IF NOT EXISTS idx_engrams_stage ON engrams(agent_id, stage);
|
|
55
|
-
CREATE INDEX IF NOT EXISTS idx_engrams_concept ON engrams(concept);
|
|
56
|
-
CREATE INDEX IF NOT EXISTS idx_engrams_retracted ON engrams(agent_id, retracted);
|
|
57
|
-
|
|
58
|
-
CREATE TABLE IF NOT EXISTS associations (
|
|
59
|
-
id TEXT PRIMARY KEY,
|
|
60
|
-
from_engram_id TEXT NOT NULL REFERENCES engrams(id) ON DELETE CASCADE,
|
|
61
|
-
to_engram_id TEXT NOT NULL REFERENCES engrams(id) ON DELETE CASCADE,
|
|
62
|
-
weight REAL NOT NULL DEFAULT 0.1,
|
|
63
|
-
confidence REAL NOT NULL DEFAULT 0.5,
|
|
64
|
-
type TEXT NOT NULL DEFAULT 'hebbian',
|
|
65
|
-
activation_count INTEGER NOT NULL DEFAULT 0,
|
|
66
|
-
created_at TEXT NOT NULL,
|
|
67
|
-
last_activated TEXT NOT NULL
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
CREATE INDEX IF NOT EXISTS idx_assoc_from ON associations(from_engram_id);
|
|
71
|
-
CREATE INDEX IF NOT EXISTS idx_assoc_to ON associations(to_engram_id);
|
|
72
|
-
CREATE UNIQUE INDEX IF NOT EXISTS idx_assoc_pair ON associations(from_engram_id, to_engram_id);
|
|
73
|
-
|
|
74
|
-
CREATE TABLE IF NOT EXISTS agents (
|
|
75
|
-
id TEXT PRIMARY KEY,
|
|
76
|
-
name TEXT NOT NULL,
|
|
77
|
-
created_at TEXT NOT NULL,
|
|
78
|
-
config TEXT NOT NULL DEFAULT '{}'
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
-- FTS5 for full-text search (BM25 ranking built in)
|
|
82
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS engrams_fts USING fts5(
|
|
83
|
-
concept, content, tags,
|
|
84
|
-
content=engrams,
|
|
85
|
-
content_rowid=rowid
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
-- Triggers to keep FTS in sync
|
|
89
|
-
CREATE TRIGGER IF NOT EXISTS engrams_ai AFTER INSERT ON engrams BEGIN
|
|
90
|
-
INSERT INTO engrams_fts(rowid, concept, content, tags) VALUES (new.rowid, new.concept, new.content, new.tags);
|
|
91
|
-
END;
|
|
92
|
-
CREATE TRIGGER IF NOT EXISTS engrams_ad AFTER DELETE ON engrams BEGIN
|
|
93
|
-
INSERT INTO engrams_fts(engrams_fts, rowid, concept, content, tags) VALUES('delete', old.rowid, old.concept, old.content, old.tags);
|
|
94
|
-
END;
|
|
95
|
-
CREATE TRIGGER IF NOT EXISTS engrams_au AFTER UPDATE ON engrams BEGIN
|
|
96
|
-
INSERT INTO engrams_fts(engrams_fts, rowid, concept, content, tags) VALUES('delete', old.rowid, old.concept, old.content, old.tags);
|
|
97
|
-
INSERT INTO engrams_fts(rowid, concept, content, tags) VALUES (new.rowid, new.concept, new.content, new.tags);
|
|
98
|
-
END;
|
|
99
|
-
|
|
100
|
-
-- Eval event logs
|
|
101
|
-
CREATE TABLE IF NOT EXISTS activation_events (
|
|
102
|
-
id TEXT PRIMARY KEY,
|
|
103
|
-
agent_id TEXT NOT NULL,
|
|
104
|
-
timestamp TEXT NOT NULL,
|
|
105
|
-
context TEXT NOT NULL,
|
|
106
|
-
results_returned INTEGER NOT NULL,
|
|
107
|
-
top_score REAL,
|
|
108
|
-
latency_ms REAL NOT NULL,
|
|
109
|
-
engram_ids TEXT NOT NULL DEFAULT '[]'
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
CREATE TABLE IF NOT EXISTS staging_events (
|
|
113
|
-
engram_id TEXT NOT NULL,
|
|
114
|
-
agent_id TEXT NOT NULL,
|
|
115
|
-
action TEXT NOT NULL,
|
|
116
|
-
resonance_score REAL,
|
|
117
|
-
timestamp TEXT NOT NULL,
|
|
118
|
-
age_ms INTEGER NOT NULL
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
CREATE TABLE IF NOT EXISTS retrieval_feedback (
|
|
122
|
-
id TEXT PRIMARY KEY,
|
|
123
|
-
activation_event_id TEXT,
|
|
124
|
-
engram_id TEXT NOT NULL,
|
|
125
|
-
useful INTEGER NOT NULL,
|
|
126
|
-
context TEXT,
|
|
127
|
-
timestamp TEXT NOT NULL
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
CREATE TABLE IF NOT EXISTS episodes (
|
|
131
|
-
id TEXT PRIMARY KEY,
|
|
132
|
-
agent_id TEXT NOT NULL,
|
|
133
|
-
label TEXT NOT NULL,
|
|
134
|
-
embedding BLOB,
|
|
135
|
-
engram_count INTEGER NOT NULL DEFAULT 0,
|
|
136
|
-
start_time TEXT NOT NULL,
|
|
137
|
-
end_time TEXT NOT NULL,
|
|
138
|
-
created_at TEXT NOT NULL
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
CREATE INDEX IF NOT EXISTS idx_episodes_agent ON episodes(agent_id);
|
|
142
|
-
CREATE INDEX IF NOT EXISTS idx_episodes_time ON episodes(agent_id, end_time);
|
|
35
|
+
this.db.exec(`
|
|
36
|
+
CREATE TABLE IF NOT EXISTS engrams (
|
|
37
|
+
id TEXT PRIMARY KEY,
|
|
38
|
+
agent_id TEXT NOT NULL,
|
|
39
|
+
concept TEXT NOT NULL,
|
|
40
|
+
content TEXT NOT NULL,
|
|
41
|
+
embedding BLOB,
|
|
42
|
+
confidence REAL NOT NULL DEFAULT 0.5,
|
|
43
|
+
salience REAL NOT NULL DEFAULT 0.5,
|
|
44
|
+
access_count INTEGER NOT NULL DEFAULT 0,
|
|
45
|
+
last_accessed TEXT NOT NULL,
|
|
46
|
+
created_at TEXT NOT NULL,
|
|
47
|
+
salience_features TEXT NOT NULL DEFAULT '{}',
|
|
48
|
+
reason_codes TEXT NOT NULL DEFAULT '[]',
|
|
49
|
+
stage TEXT NOT NULL DEFAULT 'active',
|
|
50
|
+
ttl INTEGER,
|
|
51
|
+
retracted INTEGER NOT NULL DEFAULT 0,
|
|
52
|
+
retracted_by TEXT,
|
|
53
|
+
retracted_at TEXT,
|
|
54
|
+
tags TEXT NOT NULL DEFAULT '[]'
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
CREATE INDEX IF NOT EXISTS idx_engrams_agent ON engrams(agent_id);
|
|
58
|
+
CREATE INDEX IF NOT EXISTS idx_engrams_stage ON engrams(agent_id, stage);
|
|
59
|
+
CREATE INDEX IF NOT EXISTS idx_engrams_concept ON engrams(concept);
|
|
60
|
+
CREATE INDEX IF NOT EXISTS idx_engrams_retracted ON engrams(agent_id, retracted);
|
|
61
|
+
|
|
62
|
+
CREATE TABLE IF NOT EXISTS associations (
|
|
63
|
+
id TEXT PRIMARY KEY,
|
|
64
|
+
from_engram_id TEXT NOT NULL REFERENCES engrams(id) ON DELETE CASCADE,
|
|
65
|
+
to_engram_id TEXT NOT NULL REFERENCES engrams(id) ON DELETE CASCADE,
|
|
66
|
+
weight REAL NOT NULL DEFAULT 0.1,
|
|
67
|
+
confidence REAL NOT NULL DEFAULT 0.5,
|
|
68
|
+
type TEXT NOT NULL DEFAULT 'hebbian',
|
|
69
|
+
activation_count INTEGER NOT NULL DEFAULT 0,
|
|
70
|
+
created_at TEXT NOT NULL,
|
|
71
|
+
last_activated TEXT NOT NULL
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
CREATE INDEX IF NOT EXISTS idx_assoc_from ON associations(from_engram_id);
|
|
75
|
+
CREATE INDEX IF NOT EXISTS idx_assoc_to ON associations(to_engram_id);
|
|
76
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_assoc_pair ON associations(from_engram_id, to_engram_id);
|
|
77
|
+
|
|
78
|
+
CREATE TABLE IF NOT EXISTS agents (
|
|
79
|
+
id TEXT PRIMARY KEY,
|
|
80
|
+
name TEXT NOT NULL,
|
|
81
|
+
created_at TEXT NOT NULL,
|
|
82
|
+
config TEXT NOT NULL DEFAULT '{}'
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
-- FTS5 for full-text search (BM25 ranking built in)
|
|
86
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS engrams_fts USING fts5(
|
|
87
|
+
concept, content, tags,
|
|
88
|
+
content=engrams,
|
|
89
|
+
content_rowid=rowid
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
-- Triggers to keep FTS in sync
|
|
93
|
+
CREATE TRIGGER IF NOT EXISTS engrams_ai AFTER INSERT ON engrams BEGIN
|
|
94
|
+
INSERT INTO engrams_fts(rowid, concept, content, tags) VALUES (new.rowid, new.concept, new.content, new.tags);
|
|
95
|
+
END;
|
|
96
|
+
CREATE TRIGGER IF NOT EXISTS engrams_ad AFTER DELETE ON engrams BEGIN
|
|
97
|
+
INSERT INTO engrams_fts(engrams_fts, rowid, concept, content, tags) VALUES('delete', old.rowid, old.concept, old.content, old.tags);
|
|
98
|
+
END;
|
|
99
|
+
CREATE TRIGGER IF NOT EXISTS engrams_au AFTER UPDATE ON engrams BEGIN
|
|
100
|
+
INSERT INTO engrams_fts(engrams_fts, rowid, concept, content, tags) VALUES('delete', old.rowid, old.concept, old.content, old.tags);
|
|
101
|
+
INSERT INTO engrams_fts(rowid, concept, content, tags) VALUES (new.rowid, new.concept, new.content, new.tags);
|
|
102
|
+
END;
|
|
103
|
+
|
|
104
|
+
-- Eval event logs
|
|
105
|
+
CREATE TABLE IF NOT EXISTS activation_events (
|
|
106
|
+
id TEXT PRIMARY KEY,
|
|
107
|
+
agent_id TEXT NOT NULL,
|
|
108
|
+
timestamp TEXT NOT NULL,
|
|
109
|
+
context TEXT NOT NULL,
|
|
110
|
+
results_returned INTEGER NOT NULL,
|
|
111
|
+
top_score REAL,
|
|
112
|
+
latency_ms REAL NOT NULL,
|
|
113
|
+
engram_ids TEXT NOT NULL DEFAULT '[]'
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
CREATE TABLE IF NOT EXISTS staging_events (
|
|
117
|
+
engram_id TEXT NOT NULL,
|
|
118
|
+
agent_id TEXT NOT NULL,
|
|
119
|
+
action TEXT NOT NULL,
|
|
120
|
+
resonance_score REAL,
|
|
121
|
+
timestamp TEXT NOT NULL,
|
|
122
|
+
age_ms INTEGER NOT NULL
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
CREATE TABLE IF NOT EXISTS retrieval_feedback (
|
|
126
|
+
id TEXT PRIMARY KEY,
|
|
127
|
+
activation_event_id TEXT,
|
|
128
|
+
engram_id TEXT NOT NULL,
|
|
129
|
+
useful INTEGER NOT NULL,
|
|
130
|
+
context TEXT,
|
|
131
|
+
timestamp TEXT NOT NULL
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
CREATE TABLE IF NOT EXISTS episodes (
|
|
135
|
+
id TEXT PRIMARY KEY,
|
|
136
|
+
agent_id TEXT NOT NULL,
|
|
137
|
+
label TEXT NOT NULL,
|
|
138
|
+
embedding BLOB,
|
|
139
|
+
engram_count INTEGER NOT NULL DEFAULT 0,
|
|
140
|
+
start_time TEXT NOT NULL,
|
|
141
|
+
end_time TEXT NOT NULL,
|
|
142
|
+
created_at TEXT NOT NULL
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
CREATE INDEX IF NOT EXISTS idx_episodes_agent ON episodes(agent_id);
|
|
146
|
+
CREATE INDEX IF NOT EXISTS idx_episodes_time ON episodes(agent_id, end_time);
|
|
143
147
|
`);
|
|
144
148
|
// Migration: add episode_id column if missing
|
|
145
149
|
try {
|
|
@@ -153,10 +157,10 @@ export class EngramStore {
|
|
|
153
157
|
this.db.prepare('SELECT task_status FROM engrams LIMIT 0').get();
|
|
154
158
|
}
|
|
155
159
|
catch {
|
|
156
|
-
this.db.exec(`
|
|
157
|
-
ALTER TABLE engrams ADD COLUMN task_status TEXT;
|
|
158
|
-
ALTER TABLE engrams ADD COLUMN task_priority TEXT;
|
|
159
|
-
ALTER TABLE engrams ADD COLUMN blocked_by TEXT;
|
|
160
|
+
this.db.exec(`
|
|
161
|
+
ALTER TABLE engrams ADD COLUMN task_status TEXT;
|
|
162
|
+
ALTER TABLE engrams ADD COLUMN task_priority TEXT;
|
|
163
|
+
ALTER TABLE engrams ADD COLUMN blocked_by TEXT;
|
|
160
164
|
`);
|
|
161
165
|
this.db.exec('CREATE INDEX IF NOT EXISTS idx_engrams_task ON engrams(agent_id, task_status)');
|
|
162
166
|
}
|
|
@@ -165,29 +169,29 @@ export class EngramStore {
|
|
|
165
169
|
this.db.prepare('SELECT memory_class FROM engrams LIMIT 0').get();
|
|
166
170
|
}
|
|
167
171
|
catch {
|
|
168
|
-
this.db.exec(`
|
|
169
|
-
ALTER TABLE engrams ADD COLUMN memory_class TEXT NOT NULL DEFAULT 'working';
|
|
170
|
-
ALTER TABLE engrams ADD COLUMN superseded_by TEXT;
|
|
171
|
-
ALTER TABLE engrams ADD COLUMN supersedes TEXT;
|
|
172
|
+
this.db.exec(`
|
|
173
|
+
ALTER TABLE engrams ADD COLUMN memory_class TEXT NOT NULL DEFAULT 'working';
|
|
174
|
+
ALTER TABLE engrams ADD COLUMN superseded_by TEXT;
|
|
175
|
+
ALTER TABLE engrams ADD COLUMN supersedes TEXT;
|
|
172
176
|
`);
|
|
173
177
|
}
|
|
174
178
|
// Migration: add conscious_state table for checkpointing
|
|
175
|
-
this.db.exec(`
|
|
176
|
-
CREATE TABLE IF NOT EXISTS conscious_state (
|
|
177
|
-
agent_id TEXT PRIMARY KEY,
|
|
178
|
-
last_write_id TEXT,
|
|
179
|
-
last_recall_context TEXT,
|
|
180
|
-
last_recall_ids TEXT NOT NULL DEFAULT '[]',
|
|
181
|
-
last_activity_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
182
|
-
write_count_since_consolidation INTEGER NOT NULL DEFAULT 0,
|
|
183
|
-
recall_count_since_consolidation INTEGER NOT NULL DEFAULT 0,
|
|
184
|
-
execution_state TEXT,
|
|
185
|
-
checkpoint_at TEXT,
|
|
186
|
-
last_consolidation_at TEXT,
|
|
187
|
-
last_mini_consolidation_at TEXT,
|
|
188
|
-
consolidation_cycle_count INTEGER NOT NULL DEFAULT 0,
|
|
189
|
-
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
190
|
-
)
|
|
179
|
+
this.db.exec(`
|
|
180
|
+
CREATE TABLE IF NOT EXISTS conscious_state (
|
|
181
|
+
agent_id TEXT PRIMARY KEY,
|
|
182
|
+
last_write_id TEXT,
|
|
183
|
+
last_recall_context TEXT,
|
|
184
|
+
last_recall_ids TEXT NOT NULL DEFAULT '[]',
|
|
185
|
+
last_activity_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
186
|
+
write_count_since_consolidation INTEGER NOT NULL DEFAULT 0,
|
|
187
|
+
recall_count_since_consolidation INTEGER NOT NULL DEFAULT 0,
|
|
188
|
+
execution_state TEXT,
|
|
189
|
+
checkpoint_at TEXT,
|
|
190
|
+
last_consolidation_at TEXT,
|
|
191
|
+
last_mini_consolidation_at TEXT,
|
|
192
|
+
consolidation_cycle_count INTEGER NOT NULL DEFAULT 0,
|
|
193
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
194
|
+
)
|
|
191
195
|
`);
|
|
192
196
|
// Migration: add consolidation_cycle_count if missing (existing DBs)
|
|
193
197
|
try {
|
|
@@ -202,11 +206,11 @@ export class EngramStore {
|
|
|
202
206
|
const embeddingBlob = input.embedding
|
|
203
207
|
? Buffer.from(new Float32Array(input.embedding).buffer)
|
|
204
208
|
: null;
|
|
205
|
-
this.db.prepare(`
|
|
206
|
-
INSERT INTO engrams (id, agent_id, concept, content, embedding, confidence, salience,
|
|
207
|
-
access_count, last_accessed, created_at, salience_features, reason_codes, stage, tags, episode_id,
|
|
208
|
-
ttl, memory_class, supersedes, task_status, task_priority, blocked_by)
|
|
209
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?, ?, ?, ?, 'active', ?, ?, ?, ?, ?, ?, ?, ?)
|
|
209
|
+
this.db.prepare(`
|
|
210
|
+
INSERT INTO engrams (id, agent_id, concept, content, embedding, confidence, salience,
|
|
211
|
+
access_count, last_accessed, created_at, salience_features, reason_codes, stage, tags, episode_id,
|
|
212
|
+
ttl, memory_class, supersedes, task_status, task_priority, blocked_by)
|
|
213
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?, ?, ?, ?, 'active', ?, ?, ?, ?, ?, ?, ?, ?)
|
|
210
214
|
`).run(id, input.agentId, input.concept, input.content, embeddingBlob, input.confidence ?? 0.5, input.salience ?? 0.5, now, now, JSON.stringify(input.salienceFeatures ?? DEFAULT_SALIENCE_FEATURES), JSON.stringify(input.reasonCodes ?? []), JSON.stringify(input.tags ?? []), input.episodeId ?? null, input.ttl ?? null, input.memoryClass ?? 'working', input.supersedes ?? null, input.taskStatus ?? null, input.taskPriority ?? null, input.blockedBy ?? null);
|
|
211
215
|
return this.getEngram(id);
|
|
212
216
|
}
|
|
@@ -227,8 +231,8 @@ export class EngramStore {
|
|
|
227
231
|
return this.db.prepare(query).all(...params).map(r => this.rowToEngram(r));
|
|
228
232
|
}
|
|
229
233
|
touchEngram(id) {
|
|
230
|
-
this.db.prepare(`
|
|
231
|
-
UPDATE engrams SET access_count = access_count + 1, last_accessed = ? WHERE id = ?
|
|
234
|
+
this.db.prepare(`
|
|
235
|
+
UPDATE engrams SET access_count = access_count + 1, last_accessed = ? WHERE id = ?
|
|
232
236
|
`).run(new Date().toISOString(), id);
|
|
233
237
|
}
|
|
234
238
|
updateStage(id, stage) {
|
|
@@ -242,8 +246,8 @@ export class EngramStore {
|
|
|
242
246
|
this.db.prepare('UPDATE engrams SET embedding = ? WHERE id = ?').run(blob, id);
|
|
243
247
|
}
|
|
244
248
|
retractEngram(id, retractedBy) {
|
|
245
|
-
this.db.prepare(`
|
|
246
|
-
UPDATE engrams SET retracted = 1, retracted_by = ?, retracted_at = ? WHERE id = ?
|
|
249
|
+
this.db.prepare(`
|
|
250
|
+
UPDATE engrams SET retracted = 1, retracted_by = ?, retracted_at = ? WHERE id = ?
|
|
247
251
|
`).run(retractedBy, new Date().toISOString(), id);
|
|
248
252
|
}
|
|
249
253
|
deleteEngram(id) {
|
|
@@ -258,20 +262,20 @@ export class EngramStore {
|
|
|
258
262
|
let count = 0;
|
|
259
263
|
const shiftSec = Math.round(ms / 1000);
|
|
260
264
|
// Shift engram timestamps
|
|
261
|
-
const r1 = this.db.prepare(`
|
|
262
|
-
UPDATE engrams SET
|
|
263
|
-
created_at = datetime(created_at, '-${shiftSec} seconds'),
|
|
264
|
-
last_accessed = datetime(last_accessed, '-${shiftSec} seconds')
|
|
265
|
-
WHERE agent_id = ?
|
|
265
|
+
const r1 = this.db.prepare(`
|
|
266
|
+
UPDATE engrams SET
|
|
267
|
+
created_at = datetime(created_at, '-${shiftSec} seconds'),
|
|
268
|
+
last_accessed = datetime(last_accessed, '-${shiftSec} seconds')
|
|
269
|
+
WHERE agent_id = ?
|
|
266
270
|
`).run(agentId);
|
|
267
271
|
count += r1.changes;
|
|
268
272
|
// Shift association timestamps
|
|
269
|
-
const r2 = this.db.prepare(`
|
|
270
|
-
UPDATE associations SET
|
|
271
|
-
created_at = datetime(created_at, '-${shiftSec} seconds'),
|
|
272
|
-
last_activated = datetime(last_activated, '-${shiftSec} seconds')
|
|
273
|
-
WHERE from_engram_id IN (SELECT id FROM engrams WHERE agent_id = ?)
|
|
274
|
-
OR to_engram_id IN (SELECT id FROM engrams WHERE agent_id = ?)
|
|
273
|
+
const r2 = this.db.prepare(`
|
|
274
|
+
UPDATE associations SET
|
|
275
|
+
created_at = datetime(created_at, '-${shiftSec} seconds'),
|
|
276
|
+
last_activated = datetime(last_activated, '-${shiftSec} seconds')
|
|
277
|
+
WHERE from_engram_id IN (SELECT id FROM engrams WHERE agent_id = ?)
|
|
278
|
+
OR to_engram_id IN (SELECT id FROM engrams WHERE agent_id = ?)
|
|
275
279
|
`).run(agentId, agentId);
|
|
276
280
|
count += r2.changes;
|
|
277
281
|
return count;
|
|
@@ -296,12 +300,12 @@ export class EngramStore {
|
|
|
296
300
|
if (!sanitized)
|
|
297
301
|
return [];
|
|
298
302
|
try {
|
|
299
|
-
const rows = this.db.prepare(`
|
|
300
|
-
SELECT e.*, rank FROM engrams e
|
|
301
|
-
JOIN engrams_fts ON e.rowid = engrams_fts.rowid
|
|
302
|
-
WHERE engrams_fts MATCH ? AND e.agent_id = ? AND e.retracted = 0
|
|
303
|
-
ORDER BY rank
|
|
304
|
-
LIMIT ?
|
|
303
|
+
const rows = this.db.prepare(`
|
|
304
|
+
SELECT e.*, rank FROM engrams e
|
|
305
|
+
JOIN engrams_fts ON e.rowid = engrams_fts.rowid
|
|
306
|
+
WHERE engrams_fts MATCH ? AND e.agent_id = ? AND e.retracted = 0
|
|
307
|
+
ORDER BY rank
|
|
308
|
+
LIMIT ?
|
|
305
309
|
`).all(sanitized, agentId, limit);
|
|
306
310
|
return rows.map(r => ({
|
|
307
311
|
engram: this.rowToEngram(r),
|
|
@@ -381,14 +385,14 @@ export class EngramStore {
|
|
|
381
385
|
sql += ' AND task_status = ?';
|
|
382
386
|
params.push(status);
|
|
383
387
|
}
|
|
384
|
-
sql += ` ORDER BY
|
|
385
|
-
CASE task_priority
|
|
386
|
-
WHEN 'urgent' THEN 0
|
|
387
|
-
WHEN 'high' THEN 1
|
|
388
|
-
WHEN 'medium' THEN 2
|
|
389
|
-
WHEN 'low' THEN 3
|
|
390
|
-
ELSE 4
|
|
391
|
-
END,
|
|
388
|
+
sql += ` ORDER BY
|
|
389
|
+
CASE task_priority
|
|
390
|
+
WHEN 'urgent' THEN 0
|
|
391
|
+
WHEN 'high' THEN 1
|
|
392
|
+
WHEN 'medium' THEN 2
|
|
393
|
+
WHEN 'low' THEN 3
|
|
394
|
+
ELSE 4
|
|
395
|
+
END,
|
|
392
396
|
created_at DESC`;
|
|
393
397
|
return this.db.prepare(sql).all(...params).map(r => this.rowToEngram(r));
|
|
394
398
|
}
|
|
@@ -396,20 +400,20 @@ export class EngramStore {
|
|
|
396
400
|
* Get the next actionable task — highest priority that's not blocked or done.
|
|
397
401
|
*/
|
|
398
402
|
getNextTask(agentId) {
|
|
399
|
-
const row = this.db.prepare(`
|
|
400
|
-
SELECT * FROM engrams
|
|
401
|
-
WHERE agent_id = ? AND task_status IN ('open', 'in_progress') AND retracted = 0
|
|
402
|
-
ORDER BY
|
|
403
|
-
CASE task_status WHEN 'in_progress' THEN 0 ELSE 1 END,
|
|
404
|
-
CASE task_priority
|
|
405
|
-
WHEN 'urgent' THEN 0
|
|
406
|
-
WHEN 'high' THEN 1
|
|
407
|
-
WHEN 'medium' THEN 2
|
|
408
|
-
WHEN 'low' THEN 3
|
|
409
|
-
ELSE 4
|
|
410
|
-
END,
|
|
411
|
-
created_at ASC
|
|
412
|
-
LIMIT 1
|
|
403
|
+
const row = this.db.prepare(`
|
|
404
|
+
SELECT * FROM engrams
|
|
405
|
+
WHERE agent_id = ? AND task_status IN ('open', 'in_progress') AND retracted = 0
|
|
406
|
+
ORDER BY
|
|
407
|
+
CASE task_status WHEN 'in_progress' THEN 0 ELSE 1 END,
|
|
408
|
+
CASE task_priority
|
|
409
|
+
WHEN 'urgent' THEN 0
|
|
410
|
+
WHEN 'high' THEN 1
|
|
411
|
+
WHEN 'medium' THEN 2
|
|
412
|
+
WHEN 'low' THEN 3
|
|
413
|
+
ELSE 4
|
|
414
|
+
END,
|
|
415
|
+
created_at ASC
|
|
416
|
+
LIMIT 1
|
|
413
417
|
`).get(agentId);
|
|
414
418
|
return row ? this.rowToEngram(row) : null;
|
|
415
419
|
}
|
|
@@ -436,11 +440,11 @@ export class EngramStore {
|
|
|
436
440
|
upsertAssociation(fromId, toId, weight, type = 'hebbian', confidence = 0.5) {
|
|
437
441
|
const now = new Date().toISOString();
|
|
438
442
|
const id = randomUUID();
|
|
439
|
-
this.db.prepare(`
|
|
440
|
-
INSERT INTO associations (id, from_engram_id, to_engram_id, weight, confidence, type, activation_count, created_at, last_activated)
|
|
441
|
-
VALUES (?, ?, ?, ?, ?, ?, 0, ?, ?)
|
|
442
|
-
ON CONFLICT(from_engram_id, to_engram_id) DO UPDATE SET
|
|
443
|
-
weight = ?, confidence = ?, last_activated = ?, activation_count = activation_count + 1
|
|
443
|
+
this.db.prepare(`
|
|
444
|
+
INSERT INTO associations (id, from_engram_id, to_engram_id, weight, confidence, type, activation_count, created_at, last_activated)
|
|
445
|
+
VALUES (?, ?, ?, ?, ?, ?, 0, ?, ?)
|
|
446
|
+
ON CONFLICT(from_engram_id, to_engram_id) DO UPDATE SET
|
|
447
|
+
weight = ?, confidence = ?, last_activated = ?, activation_count = activation_count + 1
|
|
444
448
|
`).run(id, fromId, toId, weight, confidence, type, now, now, weight, confidence, now);
|
|
445
449
|
return this.getAssociation(fromId, toId);
|
|
446
450
|
}
|
|
@@ -468,22 +472,22 @@ export class EngramStore {
|
|
|
468
472
|
this.db.prepare('DELETE FROM associations WHERE id = ?').run(id);
|
|
469
473
|
}
|
|
470
474
|
getAllAssociations(agentId) {
|
|
471
|
-
const rows = this.db.prepare(`
|
|
472
|
-
SELECT a.* FROM associations a
|
|
473
|
-
JOIN engrams e ON a.from_engram_id = e.id
|
|
474
|
-
WHERE e.agent_id = ?
|
|
475
|
+
const rows = this.db.prepare(`
|
|
476
|
+
SELECT a.* FROM associations a
|
|
477
|
+
JOIN engrams e ON a.from_engram_id = e.id
|
|
478
|
+
WHERE e.agent_id = ?
|
|
475
479
|
`).all(agentId);
|
|
476
480
|
return rows.map(r => this.rowToAssociation(r));
|
|
477
481
|
}
|
|
478
482
|
// --- Eviction ---
|
|
479
483
|
getEvictionCandidates(agentId, limit) {
|
|
480
484
|
// Lowest combined score: low salience + low access + low confidence + oldest
|
|
481
|
-
const rows = this.db.prepare(`
|
|
482
|
-
SELECT * FROM engrams
|
|
483
|
-
WHERE agent_id = ? AND stage = 'active' AND retracted = 0
|
|
484
|
-
ORDER BY (salience * 0.3 + confidence * 0.3 + (CAST(access_count AS REAL) / (access_count + 5)) * 0.2 +
|
|
485
|
-
(1.0 / (1.0 + (julianday('now') - julianday(last_accessed)))) * 0.2) ASC
|
|
486
|
-
LIMIT ?
|
|
485
|
+
const rows = this.db.prepare(`
|
|
486
|
+
SELECT * FROM engrams
|
|
487
|
+
WHERE agent_id = ? AND stage = 'active' AND retracted = 0
|
|
488
|
+
ORDER BY (salience * 0.3 + confidence * 0.3 + (CAST(access_count AS REAL) / (access_count + 5)) * 0.2 +
|
|
489
|
+
(1.0 / (1.0 + (julianday('now') - julianday(last_accessed)))) * 0.2) ASC
|
|
490
|
+
LIMIT ?
|
|
487
491
|
`).all(agentId, limit);
|
|
488
492
|
return rows.map(r => this.rowToEngram(r));
|
|
489
493
|
}
|
|
@@ -498,8 +502,8 @@ export class EngramStore {
|
|
|
498
502
|
// --- Staging buffer ---
|
|
499
503
|
getExpiredStaging() {
|
|
500
504
|
const now = Date.now();
|
|
501
|
-
const rows = this.db.prepare(`
|
|
502
|
-
SELECT * FROM engrams WHERE stage = 'staging' AND ttl IS NOT NULL
|
|
505
|
+
const rows = this.db.prepare(`
|
|
506
|
+
SELECT * FROM engrams WHERE stage = 'staging' AND ttl IS NOT NULL
|
|
503
507
|
`).all();
|
|
504
508
|
return rows
|
|
505
509
|
.map(r => this.rowToEngram(r))
|
|
@@ -507,53 +511,53 @@ export class EngramStore {
|
|
|
507
511
|
}
|
|
508
512
|
// --- Eval event logging ---
|
|
509
513
|
logActivationEvent(event) {
|
|
510
|
-
this.db.prepare(`
|
|
511
|
-
INSERT INTO activation_events (id, agent_id, timestamp, context, results_returned, top_score, latency_ms, engram_ids)
|
|
512
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
514
|
+
this.db.prepare(`
|
|
515
|
+
INSERT INTO activation_events (id, agent_id, timestamp, context, results_returned, top_score, latency_ms, engram_ids)
|
|
516
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
513
517
|
`).run(event.id, event.agentId, event.timestamp.toISOString(), event.context, event.resultsReturned, event.topScore, event.latencyMs, JSON.stringify(event.engramIds));
|
|
514
518
|
}
|
|
515
519
|
logStagingEvent(event) {
|
|
516
|
-
this.db.prepare(`
|
|
517
|
-
INSERT INTO staging_events (engram_id, agent_id, action, resonance_score, timestamp, age_ms)
|
|
518
|
-
VALUES (?, ?, ?, ?, ?, ?)
|
|
520
|
+
this.db.prepare(`
|
|
521
|
+
INSERT INTO staging_events (engram_id, agent_id, action, resonance_score, timestamp, age_ms)
|
|
522
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
519
523
|
`).run(event.engramId, event.agentId, event.action, event.resonanceScore, event.timestamp.toISOString(), event.ageMs);
|
|
520
524
|
}
|
|
521
525
|
logRetrievalFeedback(activationEventId, engramId, useful, context) {
|
|
522
|
-
this.db.prepare(`
|
|
523
|
-
INSERT INTO retrieval_feedback (id, activation_event_id, engram_id, useful, context, timestamp)
|
|
524
|
-
VALUES (?, ?, ?, ?, ?, ?)
|
|
526
|
+
this.db.prepare(`
|
|
527
|
+
INSERT INTO retrieval_feedback (id, activation_event_id, engram_id, useful, context, timestamp)
|
|
528
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
525
529
|
`).run(randomUUID(), activationEventId, engramId, useful ? 1 : 0, context, new Date().toISOString());
|
|
526
530
|
}
|
|
527
531
|
// --- Eval metrics queries ---
|
|
528
532
|
getRetrievalPrecision(agentId, windowHours = 24) {
|
|
529
533
|
const since = new Date(Date.now() - windowHours * 3600_000).toISOString();
|
|
530
|
-
const row = this.db.prepare(`
|
|
531
|
-
SELECT
|
|
532
|
-
COUNT(CASE WHEN useful = 1 THEN 1 END) as useful_count,
|
|
533
|
-
COUNT(*) as total_count
|
|
534
|
-
FROM retrieval_feedback rf
|
|
535
|
-
LEFT JOIN activation_events ae ON rf.activation_event_id = ae.id
|
|
536
|
-
JOIN engrams e ON rf.engram_id = e.id
|
|
537
|
-
WHERE e.agent_id = ? AND rf.timestamp > ?
|
|
534
|
+
const row = this.db.prepare(`
|
|
535
|
+
SELECT
|
|
536
|
+
COUNT(CASE WHEN useful = 1 THEN 1 END) as useful_count,
|
|
537
|
+
COUNT(*) as total_count
|
|
538
|
+
FROM retrieval_feedback rf
|
|
539
|
+
LEFT JOIN activation_events ae ON rf.activation_event_id = ae.id
|
|
540
|
+
JOIN engrams e ON rf.engram_id = e.id
|
|
541
|
+
WHERE e.agent_id = ? AND rf.timestamp > ?
|
|
538
542
|
`).get(agentId, since);
|
|
539
543
|
return row.total_count > 0 ? row.useful_count / row.total_count : 0;
|
|
540
544
|
}
|
|
541
545
|
getStagingMetrics(agentId) {
|
|
542
|
-
const row = this.db.prepare(`
|
|
543
|
-
SELECT
|
|
544
|
-
COUNT(CASE WHEN action = 'promoted' THEN 1 END) as promoted,
|
|
545
|
-
COUNT(CASE WHEN action = 'discarded' THEN 1 END) as discarded,
|
|
546
|
-
COUNT(CASE WHEN action = 'expired' THEN 1 END) as expired
|
|
547
|
-
FROM staging_events WHERE agent_id = ?
|
|
546
|
+
const row = this.db.prepare(`
|
|
547
|
+
SELECT
|
|
548
|
+
COUNT(CASE WHEN action = 'promoted' THEN 1 END) as promoted,
|
|
549
|
+
COUNT(CASE WHEN action = 'discarded' THEN 1 END) as discarded,
|
|
550
|
+
COUNT(CASE WHEN action = 'expired' THEN 1 END) as expired
|
|
551
|
+
FROM staging_events WHERE agent_id = ?
|
|
548
552
|
`).get(agentId);
|
|
549
553
|
return { promoted: row.promoted, discarded: row.discarded, expired: row.expired };
|
|
550
554
|
}
|
|
551
555
|
getActivationStats(agentId, windowHours = 24) {
|
|
552
556
|
const since = new Date(Date.now() - windowHours * 3600_000).toISOString();
|
|
553
|
-
const rows = this.db.prepare(`
|
|
554
|
-
SELECT latency_ms FROM activation_events
|
|
555
|
-
WHERE agent_id = ? AND timestamp > ?
|
|
556
|
-
ORDER BY latency_ms ASC
|
|
557
|
+
const rows = this.db.prepare(`
|
|
558
|
+
SELECT latency_ms FROM activation_events
|
|
559
|
+
WHERE agent_id = ? AND timestamp > ?
|
|
560
|
+
ORDER BY latency_ms ASC
|
|
557
561
|
`).all(agentId, since);
|
|
558
562
|
if (rows.length === 0)
|
|
559
563
|
return { count: 0, avgLatencyMs: 0, p95LatencyMs: 0 };
|
|
@@ -621,9 +625,9 @@ export class EngramStore {
|
|
|
621
625
|
const embeddingBlob = input.embedding
|
|
622
626
|
? Buffer.from(new Float32Array(input.embedding).buffer)
|
|
623
627
|
: null;
|
|
624
|
-
this.db.prepare(`
|
|
625
|
-
INSERT INTO episodes (id, agent_id, label, embedding, engram_count, start_time, end_time, created_at)
|
|
626
|
-
VALUES (?, ?, ?, ?, 0, ?, ?, ?)
|
|
628
|
+
this.db.prepare(`
|
|
629
|
+
INSERT INTO episodes (id, agent_id, label, embedding, engram_count, start_time, end_time, created_at)
|
|
630
|
+
VALUES (?, ?, ?, ?, 0, ?, ?, ?)
|
|
627
631
|
`).run(id, input.agentId, input.label, embeddingBlob, now, now, now);
|
|
628
632
|
return this.getEpisode(id);
|
|
629
633
|
}
|
|
@@ -638,19 +642,19 @@ export class EngramStore {
|
|
|
638
642
|
getActiveEpisode(agentId, windowMs = 3600_000) {
|
|
639
643
|
// Find most recent episode that ended within the time window
|
|
640
644
|
const cutoff = new Date(Date.now() - windowMs).toISOString();
|
|
641
|
-
const row = this.db.prepare(`
|
|
642
|
-
SELECT * FROM episodes WHERE agent_id = ? AND end_time > ?
|
|
643
|
-
ORDER BY end_time DESC LIMIT 1
|
|
645
|
+
const row = this.db.prepare(`
|
|
646
|
+
SELECT * FROM episodes WHERE agent_id = ? AND end_time > ?
|
|
647
|
+
ORDER BY end_time DESC LIMIT 1
|
|
644
648
|
`).get(agentId, cutoff);
|
|
645
649
|
return row ? this.rowToEpisode(row) : null;
|
|
646
650
|
}
|
|
647
651
|
addEngramToEpisode(engramId, episodeId) {
|
|
648
652
|
this.db.prepare('UPDATE engrams SET episode_id = ? WHERE id = ?').run(episodeId, engramId);
|
|
649
|
-
this.db.prepare(`
|
|
650
|
-
UPDATE episodes SET
|
|
651
|
-
engram_count = engram_count + 1,
|
|
652
|
-
end_time = MAX(end_time, ?)
|
|
653
|
-
WHERE id = ?
|
|
653
|
+
this.db.prepare(`
|
|
654
|
+
UPDATE episodes SET
|
|
655
|
+
engram_count = engram_count + 1,
|
|
656
|
+
end_time = MAX(end_time, ?)
|
|
657
|
+
WHERE id = ?
|
|
654
658
|
`).run(new Date().toISOString(), episodeId);
|
|
655
659
|
}
|
|
656
660
|
getEngramsByEpisode(episodeId) {
|
|
@@ -701,49 +705,49 @@ export class EngramStore {
|
|
|
701
705
|
// --- Checkpointing ---
|
|
702
706
|
updateAutoCheckpointWrite(agentId, engramId) {
|
|
703
707
|
const now = new Date().toISOString();
|
|
704
|
-
this.db.prepare(`
|
|
705
|
-
INSERT INTO conscious_state (agent_id, last_write_id, last_activity_at, write_count_since_consolidation, updated_at)
|
|
706
|
-
VALUES (?, ?, ?, 1, ?)
|
|
707
|
-
ON CONFLICT(agent_id) DO UPDATE SET
|
|
708
|
-
last_write_id = excluded.last_write_id,
|
|
709
|
-
last_activity_at = excluded.last_activity_at,
|
|
710
|
-
write_count_since_consolidation = write_count_since_consolidation + 1,
|
|
711
|
-
updated_at = excluded.updated_at
|
|
708
|
+
this.db.prepare(`
|
|
709
|
+
INSERT INTO conscious_state (agent_id, last_write_id, last_activity_at, write_count_since_consolidation, updated_at)
|
|
710
|
+
VALUES (?, ?, ?, 1, ?)
|
|
711
|
+
ON CONFLICT(agent_id) DO UPDATE SET
|
|
712
|
+
last_write_id = excluded.last_write_id,
|
|
713
|
+
last_activity_at = excluded.last_activity_at,
|
|
714
|
+
write_count_since_consolidation = write_count_since_consolidation + 1,
|
|
715
|
+
updated_at = excluded.updated_at
|
|
712
716
|
`).run(agentId, engramId, now, now);
|
|
713
717
|
}
|
|
714
718
|
updateAutoCheckpointRecall(agentId, context, engramIds) {
|
|
715
719
|
const now = new Date().toISOString();
|
|
716
|
-
this.db.prepare(`
|
|
717
|
-
INSERT INTO conscious_state (agent_id, last_recall_context, last_recall_ids, last_activity_at, recall_count_since_consolidation, updated_at)
|
|
718
|
-
VALUES (?, ?, ?, ?, 1, ?)
|
|
719
|
-
ON CONFLICT(agent_id) DO UPDATE SET
|
|
720
|
-
last_recall_context = excluded.last_recall_context,
|
|
721
|
-
last_recall_ids = excluded.last_recall_ids,
|
|
722
|
-
last_activity_at = excluded.last_activity_at,
|
|
723
|
-
recall_count_since_consolidation = recall_count_since_consolidation + 1,
|
|
724
|
-
updated_at = excluded.updated_at
|
|
720
|
+
this.db.prepare(`
|
|
721
|
+
INSERT INTO conscious_state (agent_id, last_recall_context, last_recall_ids, last_activity_at, recall_count_since_consolidation, updated_at)
|
|
722
|
+
VALUES (?, ?, ?, ?, 1, ?)
|
|
723
|
+
ON CONFLICT(agent_id) DO UPDATE SET
|
|
724
|
+
last_recall_context = excluded.last_recall_context,
|
|
725
|
+
last_recall_ids = excluded.last_recall_ids,
|
|
726
|
+
last_activity_at = excluded.last_activity_at,
|
|
727
|
+
recall_count_since_consolidation = recall_count_since_consolidation + 1,
|
|
728
|
+
updated_at = excluded.updated_at
|
|
725
729
|
`).run(agentId, context, JSON.stringify(engramIds), now, now);
|
|
726
730
|
}
|
|
727
731
|
touchActivity(agentId) {
|
|
728
732
|
const now = new Date().toISOString();
|
|
729
|
-
this.db.prepare(`
|
|
730
|
-
INSERT INTO conscious_state (agent_id, last_activity_at, updated_at)
|
|
731
|
-
VALUES (?, ?, ?)
|
|
732
|
-
ON CONFLICT(agent_id) DO UPDATE SET
|
|
733
|
-
last_activity_at = excluded.last_activity_at,
|
|
734
|
-
updated_at = excluded.updated_at
|
|
733
|
+
this.db.prepare(`
|
|
734
|
+
INSERT INTO conscious_state (agent_id, last_activity_at, updated_at)
|
|
735
|
+
VALUES (?, ?, ?)
|
|
736
|
+
ON CONFLICT(agent_id) DO UPDATE SET
|
|
737
|
+
last_activity_at = excluded.last_activity_at,
|
|
738
|
+
updated_at = excluded.updated_at
|
|
735
739
|
`).run(agentId, now, now);
|
|
736
740
|
}
|
|
737
741
|
saveCheckpoint(agentId, state) {
|
|
738
742
|
const now = new Date().toISOString();
|
|
739
|
-
this.db.prepare(`
|
|
740
|
-
INSERT INTO conscious_state (agent_id, execution_state, checkpoint_at, last_activity_at, updated_at)
|
|
741
|
-
VALUES (?, ?, ?, ?, ?)
|
|
742
|
-
ON CONFLICT(agent_id) DO UPDATE SET
|
|
743
|
-
execution_state = excluded.execution_state,
|
|
744
|
-
checkpoint_at = excluded.checkpoint_at,
|
|
745
|
-
last_activity_at = excluded.last_activity_at,
|
|
746
|
-
updated_at = excluded.updated_at
|
|
743
|
+
this.db.prepare(`
|
|
744
|
+
INSERT INTO conscious_state (agent_id, execution_state, checkpoint_at, last_activity_at, updated_at)
|
|
745
|
+
VALUES (?, ?, ?, ?, ?)
|
|
746
|
+
ON CONFLICT(agent_id) DO UPDATE SET
|
|
747
|
+
execution_state = excluded.execution_state,
|
|
748
|
+
checkpoint_at = excluded.checkpoint_at,
|
|
749
|
+
last_activity_at = excluded.last_activity_at,
|
|
750
|
+
updated_at = excluded.updated_at
|
|
747
751
|
`).run(agentId, JSON.stringify(state), now, now, now);
|
|
748
752
|
}
|
|
749
753
|
getCheckpoint(agentId) {
|
|
@@ -770,20 +774,20 @@ export class EngramStore {
|
|
|
770
774
|
markConsolidation(agentId, mini) {
|
|
771
775
|
const now = new Date().toISOString();
|
|
772
776
|
if (mini) {
|
|
773
|
-
this.db.prepare(`
|
|
774
|
-
UPDATE conscious_state SET last_mini_consolidation_at = ?, updated_at = ? WHERE agent_id = ?
|
|
777
|
+
this.db.prepare(`
|
|
778
|
+
UPDATE conscious_state SET last_mini_consolidation_at = ?, updated_at = ? WHERE agent_id = ?
|
|
775
779
|
`).run(now, now, agentId);
|
|
776
780
|
}
|
|
777
781
|
else {
|
|
778
|
-
this.db.prepare(`
|
|
779
|
-
UPDATE conscious_state SET
|
|
780
|
-
last_consolidation_at = ?,
|
|
781
|
-
last_mini_consolidation_at = ?,
|
|
782
|
-
write_count_since_consolidation = 0,
|
|
783
|
-
recall_count_since_consolidation = 0,
|
|
784
|
-
consolidation_cycle_count = consolidation_cycle_count + 1,
|
|
785
|
-
updated_at = ?
|
|
786
|
-
WHERE agent_id = ?
|
|
782
|
+
this.db.prepare(`
|
|
783
|
+
UPDATE conscious_state SET
|
|
784
|
+
last_consolidation_at = ?,
|
|
785
|
+
last_mini_consolidation_at = ?,
|
|
786
|
+
write_count_since_consolidation = 0,
|
|
787
|
+
recall_count_since_consolidation = 0,
|
|
788
|
+
consolidation_cycle_count = consolidation_cycle_count + 1,
|
|
789
|
+
updated_at = ?
|
|
790
|
+
WHERE agent_id = ?
|
|
787
791
|
`).run(now, now, now, agentId);
|
|
788
792
|
}
|
|
789
793
|
}
|