agent-working-memory 0.4.2 → 0.4.3
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/LICENSE +190 -21
- package/README.md +19 -3
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +2 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/routes.d.ts.map +1 -1
- package/dist/api/routes.js +7 -0
- package/dist/api/routes.js.map +1 -1
- package/dist/cli.d.ts +0 -9
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +69 -67
- package/dist/cli.js.map +1 -1
- package/dist/core/decay.d.ts.map +1 -1
- package/dist/core/decay.js +2 -0
- package/dist/core/decay.js.map +1 -1
- package/dist/core/embeddings.d.ts.map +1 -1
- package/dist/core/embeddings.js +2 -0
- package/dist/core/embeddings.js.map +1 -1
- package/dist/core/hebbian.d.ts.map +1 -1
- package/dist/core/hebbian.js +2 -0
- package/dist/core/hebbian.js.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +2 -0
- package/dist/core/logger.js.map +1 -1
- package/dist/core/query-expander.d.ts.map +1 -1
- package/dist/core/query-expander.js +2 -0
- package/dist/core/query-expander.js.map +1 -1
- package/dist/core/reranker.d.ts.map +1 -1
- package/dist/core/reranker.js +2 -0
- package/dist/core/reranker.js.map +1 -1
- package/dist/core/salience.d.ts.map +1 -1
- package/dist/core/salience.js +12 -8
- package/dist/core/salience.js.map +1 -1
- package/dist/engine/activation.d.ts.map +1 -1
- package/dist/engine/activation.js +2 -0
- package/dist/engine/activation.js.map +1 -1
- package/dist/engine/connections.d.ts.map +1 -1
- package/dist/engine/connections.js +2 -0
- package/dist/engine/connections.js.map +1 -1
- package/dist/engine/consolidation-scheduler.d.ts.map +1 -1
- package/dist/engine/consolidation-scheduler.js +2 -0
- package/dist/engine/consolidation-scheduler.js.map +1 -1
- package/dist/engine/consolidation.d.ts.map +1 -1
- package/dist/engine/consolidation.js +12 -3
- package/dist/engine/consolidation.js.map +1 -1
- package/dist/engine/eval.d.ts.map +1 -1
- package/dist/engine/eval.js +2 -0
- package/dist/engine/eval.js.map +1 -1
- package/dist/engine/eviction.d.ts.map +1 -1
- package/dist/engine/eviction.js +2 -0
- package/dist/engine/eviction.js.map +1 -1
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +2 -0
- package/dist/engine/index.js.map +1 -1
- package/dist/engine/retraction.d.ts.map +1 -1
- package/dist/engine/retraction.js +2 -0
- package/dist/engine/retraction.js.map +1 -1
- package/dist/engine/staging.d.ts.map +1 -1
- package/dist/engine/staging.js +2 -0
- package/dist/engine/staging.js.map +1 -1
- package/dist/hooks/sidecar.d.ts.map +1 -1
- package/dist/hooks/sidecar.js +2 -0
- package/dist/hooks/sidecar.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +2 -0
- package/dist/mcp.js.map +1 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +2 -0
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +12 -2
- package/dist/storage/sqlite.js.map +1 -1
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/agent.js +2 -0
- package/dist/types/agent.js.map +1 -1
- package/dist/types/checkpoint.d.ts.map +1 -1
- package/dist/types/checkpoint.js +2 -0
- package/dist/types/checkpoint.js.map +1 -1
- package/dist/types/engram.d.ts.map +1 -1
- package/dist/types/engram.js +2 -0
- package/dist/types/engram.js.map +1 -1
- package/dist/types/eval.d.ts.map +1 -1
- package/dist/types/eval.js +2 -0
- package/dist/types/eval.js.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/package.json +2 -2
- package/src/api/index.ts +2 -0
- package/src/api/routes.ts +8 -0
- package/src/cli.ts +385 -383
- package/src/core/decay.ts +2 -0
- package/src/core/embeddings.ts +2 -0
- package/src/core/hebbian.ts +2 -0
- package/src/core/index.ts +2 -0
- package/src/core/logger.ts +2 -0
- package/src/core/query-expander.ts +2 -0
- package/src/core/reranker.ts +2 -0
- package/src/core/salience.ts +14 -10
- package/src/engine/activation.ts +2 -0
- package/src/engine/connections.ts +2 -0
- package/src/engine/consolidation-scheduler.ts +125 -123
- package/src/engine/consolidation.ts +11 -3
- package/src/engine/eval.ts +2 -0
- package/src/engine/eviction.ts +2 -0
- package/src/engine/index.ts +2 -0
- package/src/engine/retraction.ts +2 -0
- package/src/engine/staging.ts +2 -0
- package/src/hooks/sidecar.ts +2 -0
- package/src/index.ts +2 -0
- package/src/mcp.ts +2 -0
- package/src/storage/index.ts +2 -0
- package/src/storage/sqlite.ts +12 -2
- package/src/types/agent.ts +2 -0
- package/src/types/checkpoint.ts +46 -44
- package/src/types/engram.ts +2 -0
- package/src/types/eval.ts +2 -0
- package/src/types/index.ts +2 -0
package/src/core/decay.ts
CHANGED
package/src/core/embeddings.ts
CHANGED
package/src/core/hebbian.ts
CHANGED
package/src/core/index.ts
CHANGED
package/src/core/logger.ts
CHANGED
package/src/core/reranker.ts
CHANGED
package/src/core/salience.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// Copyright 2026 Robert Winter / Complete Ideas
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
1
3
|
/**
|
|
2
4
|
* Salience Filter — decides what's worth remembering.
|
|
3
5
|
*
|
|
@@ -118,22 +120,24 @@ export function evaluateSalience(
|
|
|
118
120
|
* The check is cheap (~1ms) because BM25 is synchronous SQLite FTS5.
|
|
119
121
|
*/
|
|
120
122
|
export function computeNovelty(store: EngramStore, agentId: string, concept: string, content: string): number {
|
|
121
|
-
// Search using concept + first 100 chars of content (enough to detect duplicates, fast)
|
|
122
|
-
const searchText = `${concept} ${content.slice(0, 100)}`;
|
|
123
|
-
|
|
124
123
|
try {
|
|
124
|
+
// Search using concept + first 100 chars of content (enough to detect duplicates, fast)
|
|
125
|
+
const contentStr = typeof content === 'string' ? content : '';
|
|
126
|
+
const conceptStr = typeof concept === 'string' ? concept : '';
|
|
127
|
+
const searchText = `${conceptStr} ${contentStr.slice(0, 100)}`;
|
|
128
|
+
|
|
125
129
|
const results = store.searchBM25WithRank(agentId, searchText, 3);
|
|
126
130
|
if (results.length === 0) return 1.0; // Nothing similar — fully novel
|
|
127
131
|
|
|
128
|
-
//
|
|
129
|
-
//
|
|
132
|
+
// searchBM25WithRank normalizes scores to 0..1 via |rank|/(1+|rank|).
|
|
133
|
+
// Higher score = stronger match = less novel.
|
|
130
134
|
const topScore = results[0].bm25Score;
|
|
131
135
|
|
|
132
|
-
if (topScore >
|
|
133
|
-
if (topScore >
|
|
134
|
-
if (topScore >
|
|
135
|
-
if (topScore >
|
|
136
|
-
return 0.9;
|
|
136
|
+
if (topScore > 0.95) return 0.1; // Near-duplicate
|
|
137
|
+
if (topScore > 0.85) return 0.3; // High overlap
|
|
138
|
+
if (topScore > 0.70) return 0.5; // Moderate overlap
|
|
139
|
+
if (topScore > 0.50) return 0.7; // Some overlap
|
|
140
|
+
return 0.9; // Minimal overlap — mostly novel
|
|
137
141
|
} catch {
|
|
138
142
|
// If BM25 search fails (e.g., FTS not ready), assume novel
|
|
139
143
|
return 0.8;
|
package/src/engine/activation.ts
CHANGED
|
@@ -1,123 +1,125 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
console.
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
}
|
|
1
|
+
// Copyright 2026 Robert Winter / Complete Ideas
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* Consolidation Scheduler — automatically triggers sleep cycles.
|
|
5
|
+
*
|
|
6
|
+
* Four triggers:
|
|
7
|
+
* 1. Idle — agent inactive >10min → full consolidation
|
|
8
|
+
* 2. Volume — 50+ writes since last consolidation → full consolidation
|
|
9
|
+
* 3. Time — 30min since last consolidation → full consolidation
|
|
10
|
+
* 4. Adaptive — retrieval precision <0.4 → full consolidation
|
|
11
|
+
*
|
|
12
|
+
* Also provides mini-consolidation for restore (fire-and-forget, lightweight).
|
|
13
|
+
* Checks every 30 seconds across all active agents.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type { EngramStore } from '../storage/sqlite.js';
|
|
17
|
+
import type { ConsolidationEngine } from './consolidation.js';
|
|
18
|
+
|
|
19
|
+
const TICK_INTERVAL_MS = 30_000; // Check every 30s
|
|
20
|
+
const IDLE_THRESHOLD_MS = 10 * 60_000; // 10 minutes
|
|
21
|
+
const VOLUME_THRESHOLD = 50; // 50 writes
|
|
22
|
+
const TIME_THRESHOLD_MS = 30 * 60_000; // 30 minutes
|
|
23
|
+
const PRECISION_THRESHOLD = 0.4; // Below this triggers consolidation
|
|
24
|
+
|
|
25
|
+
export class ConsolidationScheduler {
|
|
26
|
+
private timer: ReturnType<typeof setInterval> | null = null;
|
|
27
|
+
private running = false;
|
|
28
|
+
|
|
29
|
+
constructor(
|
|
30
|
+
private store: EngramStore,
|
|
31
|
+
private consolidationEngine: ConsolidationEngine,
|
|
32
|
+
) {}
|
|
33
|
+
|
|
34
|
+
start(): void {
|
|
35
|
+
if (this.timer) return;
|
|
36
|
+
this.timer = setInterval(() => this.tick(), TICK_INTERVAL_MS);
|
|
37
|
+
console.log('ConsolidationScheduler started (30s tick)');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
stop(): void {
|
|
41
|
+
if (this.timer) {
|
|
42
|
+
clearInterval(this.timer);
|
|
43
|
+
this.timer = null;
|
|
44
|
+
}
|
|
45
|
+
console.log('ConsolidationScheduler stopped');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Mini-consolidation — lightweight, called from restore path.
|
|
50
|
+
* Only runs replay + strengthen (phases 1-2), skips heavy phases.
|
|
51
|
+
*/
|
|
52
|
+
async runMiniConsolidation(agentId: string): Promise<void> {
|
|
53
|
+
if (this.running) return;
|
|
54
|
+
this.running = true;
|
|
55
|
+
try {
|
|
56
|
+
console.log(`[scheduler] mini-consolidation for ${agentId}`);
|
|
57
|
+
this.consolidationEngine.consolidate(agentId);
|
|
58
|
+
this.store.markConsolidation(agentId, true);
|
|
59
|
+
} catch (err) {
|
|
60
|
+
console.error(`[scheduler] mini-consolidation failed for ${agentId}:`, err);
|
|
61
|
+
} finally {
|
|
62
|
+
this.running = false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private tick(): void {
|
|
67
|
+
if (this.running) return;
|
|
68
|
+
|
|
69
|
+
const agents = this.store.getActiveAgents();
|
|
70
|
+
const now = Date.now();
|
|
71
|
+
|
|
72
|
+
for (const agent of agents) {
|
|
73
|
+
const idleMs = now - agent.lastActivityAt.getTime();
|
|
74
|
+
const sinceConsolidation = agent.lastConsolidationAt
|
|
75
|
+
? now - agent.lastConsolidationAt.getTime()
|
|
76
|
+
: Infinity;
|
|
77
|
+
|
|
78
|
+
let trigger: string | null = null;
|
|
79
|
+
|
|
80
|
+
// 1. Idle trigger — agent stopped writing/recalling >10min ago
|
|
81
|
+
if (idleMs > IDLE_THRESHOLD_MS && sinceConsolidation > IDLE_THRESHOLD_MS) {
|
|
82
|
+
trigger = `idle (${Math.round(idleMs / 60_000)}min)`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 2. Volume trigger — many writes accumulated
|
|
86
|
+
if (!trigger && agent.writeCount >= VOLUME_THRESHOLD) {
|
|
87
|
+
trigger = `volume (${agent.writeCount} writes)`;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 3. Time trigger — been too long since last consolidation
|
|
91
|
+
if (!trigger && sinceConsolidation > TIME_THRESHOLD_MS) {
|
|
92
|
+
trigger = `time (${Math.round(sinceConsolidation / 60_000)}min)`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 4. Adaptive trigger — precision is low
|
|
96
|
+
if (!trigger) {
|
|
97
|
+
try {
|
|
98
|
+
const precision = this.store.getRetrievalPrecision(agent.agentId, 1);
|
|
99
|
+
if (precision > 0 && precision < PRECISION_THRESHOLD) {
|
|
100
|
+
trigger = `adaptive (precision ${(precision * 100).toFixed(0)}%)`;
|
|
101
|
+
}
|
|
102
|
+
} catch { /* precision check is non-fatal */ }
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (trigger) {
|
|
106
|
+
this.runFullConsolidation(agent.agentId, trigger);
|
|
107
|
+
return; // One consolidation per tick to avoid overload
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private runFullConsolidation(agentId: string, reason: string): void {
|
|
113
|
+
this.running = true;
|
|
114
|
+
try {
|
|
115
|
+
console.log(`[scheduler] full consolidation for ${agentId} — trigger: ${reason}`);
|
|
116
|
+
const result = this.consolidationEngine.consolidate(agentId);
|
|
117
|
+
this.store.markConsolidation(agentId, false);
|
|
118
|
+
console.log(`[scheduler] consolidation done: ${result.edgesStrengthened} strengthened, ${result.memoriesForgotten} forgotten`);
|
|
119
|
+
} catch (err) {
|
|
120
|
+
console.error(`[scheduler] consolidation failed for ${agentId}:`, err);
|
|
121
|
+
} finally {
|
|
122
|
+
this.running = false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// Copyright 2026 Robert Winter / Complete Ideas
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
1
3
|
/**
|
|
2
4
|
* Sleep Cycle — offline memory consolidation.
|
|
3
5
|
*
|
|
@@ -226,13 +228,19 @@ export class ConsolidationEngine {
|
|
|
226
228
|
// --- Phase 5: Synaptic homeostasis ---
|
|
227
229
|
// Normalize total outgoing edge weight per node to prevent hub explosion.
|
|
228
230
|
// Nodes with many strong edges get scaled down so relative weights stay meaningful.
|
|
231
|
+
// Track processed edge IDs to avoid rescaling the same edge from both endpoints.
|
|
229
232
|
const engramIds = new Set(engrams.map(e => e.id));
|
|
233
|
+
const processedEdgeIds = new Set<string>();
|
|
230
234
|
for (const id of engramIds) {
|
|
231
|
-
|
|
232
|
-
const
|
|
235
|
+
// Only outgoing edges — filter to edges originating from this node
|
|
236
|
+
const allEdges = this.store.getAssociationsFor(id);
|
|
237
|
+
const outgoing = allEdges.filter(e => e.fromEngramId === id);
|
|
238
|
+
const totalWeight = outgoing.reduce((sum, a) => sum + a.weight, 0);
|
|
233
239
|
if (totalWeight > HOMEOSTASIS_TARGET) {
|
|
234
240
|
const scale = HOMEOSTASIS_TARGET / totalWeight;
|
|
235
|
-
for (const edge of
|
|
241
|
+
for (const edge of outgoing) {
|
|
242
|
+
if (processedEdgeIds.has(edge.id)) continue;
|
|
243
|
+
processedEdgeIds.add(edge.id);
|
|
236
244
|
const newWeight = edge.weight * scale;
|
|
237
245
|
if (newWeight < PRUNE_THRESHOLD) {
|
|
238
246
|
this.store.deleteAssociation(edge.id);
|
package/src/engine/eval.ts
CHANGED
package/src/engine/eviction.ts
CHANGED
package/src/engine/index.ts
CHANGED
package/src/engine/retraction.ts
CHANGED
package/src/engine/staging.ts
CHANGED
package/src/hooks/sidecar.ts
CHANGED
package/src/index.ts
CHANGED
package/src/mcp.ts
CHANGED
package/src/storage/index.ts
CHANGED
package/src/storage/sqlite.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// Copyright 2026 Robert Winter / Complete Ideas
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
1
3
|
/**
|
|
2
4
|
* SQLite storage layer — persistence for engrams, associations, and eval events.
|
|
3
5
|
*
|
|
@@ -14,6 +16,14 @@ import type {
|
|
|
14
16
|
ConsciousState, AutoCheckpoint, CheckpointRow,
|
|
15
17
|
} from '../types/index.js';
|
|
16
18
|
|
|
19
|
+
/** Safely convert a Node Buffer to Float32Array, respecting byteOffset/byteLength. */
|
|
20
|
+
function bufferToFloat32Array(buf: Buffer | ArrayBuffer): Float32Array {
|
|
21
|
+
if (buf instanceof ArrayBuffer) return new Float32Array(buf);
|
|
22
|
+
// Node Buffer may share an underlying ArrayBuffer — slice to the exact region
|
|
23
|
+
const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
|
24
|
+
return new Float32Array(ab);
|
|
25
|
+
}
|
|
26
|
+
|
|
17
27
|
const DEFAULT_SALIENCE_FEATURES: SalienceFeatures = {
|
|
18
28
|
surprise: 0, decisionMade: false, causalDepth: 0, resolutionEffort: 0, eventType: 'observation',
|
|
19
29
|
};
|
|
@@ -641,7 +651,7 @@ export class EngramStore {
|
|
|
641
651
|
concept: row.concept,
|
|
642
652
|
content: row.content,
|
|
643
653
|
embedding: row.embedding
|
|
644
|
-
? Array.from(
|
|
654
|
+
? Array.from(bufferToFloat32Array(row.embedding))
|
|
645
655
|
: null,
|
|
646
656
|
confidence: row.confidence,
|
|
647
657
|
salience: row.salience,
|
|
@@ -751,7 +761,7 @@ export class EngramStore {
|
|
|
751
761
|
agentId: row.agent_id,
|
|
752
762
|
label: row.label,
|
|
753
763
|
embedding: row.embedding
|
|
754
|
-
? Array.from(
|
|
764
|
+
? Array.from(bufferToFloat32Array(row.embedding))
|
|
755
765
|
: null,
|
|
756
766
|
engramCount: row.engram_count,
|
|
757
767
|
startTime: new Date(row.start_time),
|
package/src/types/agent.ts
CHANGED
package/src/types/checkpoint.ts
CHANGED
|
@@ -1,44 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
1
|
+
// Copyright 2026 Robert Winter / Complete Ideas
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* Checkpoint types — conscious state preservation across compaction.
|
|
5
|
+
*
|
|
6
|
+
* ConsciousState: explicit structured snapshot (saved by agent)
|
|
7
|
+
* AutoCheckpoint: implicit lightweight tracking (updated on every write/recall)
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export interface ConsciousState {
|
|
11
|
+
currentTask: string;
|
|
12
|
+
decisions: string[];
|
|
13
|
+
activeFiles: string[];
|
|
14
|
+
nextSteps: string[];
|
|
15
|
+
relatedMemoryIds: string[];
|
|
16
|
+
notes: string;
|
|
17
|
+
episodeId: string | null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface AutoCheckpoint {
|
|
21
|
+
lastWriteId: string | null;
|
|
22
|
+
lastRecallContext: string | null;
|
|
23
|
+
lastRecallIds: string[];
|
|
24
|
+
lastActivityAt: Date;
|
|
25
|
+
writeCountSinceConsolidation: number;
|
|
26
|
+
recallCountSinceConsolidation: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface CheckpointRow {
|
|
30
|
+
agentId: string;
|
|
31
|
+
auto: AutoCheckpoint;
|
|
32
|
+
executionState: ConsciousState | null;
|
|
33
|
+
checkpointAt: Date | null;
|
|
34
|
+
lastConsolidationAt: Date | null;
|
|
35
|
+
lastMiniConsolidationAt: Date | null;
|
|
36
|
+
updatedAt: Date;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface RestoreResult {
|
|
40
|
+
executionState: ConsciousState | null;
|
|
41
|
+
checkpointAt: Date | null;
|
|
42
|
+
recalledMemories: Array<{ id: string; concept: string; content: string; score: number }>;
|
|
43
|
+
lastWrite: { id: string; concept: string; content: string } | null;
|
|
44
|
+
idleMs: number;
|
|
45
|
+
miniConsolidationTriggered: boolean;
|
|
46
|
+
}
|
package/src/types/engram.ts
CHANGED
package/src/types/eval.ts
CHANGED