agent-working-memory 0.3.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.
Files changed (143) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +311 -0
  3. package/dist/api/index.d.ts +2 -0
  4. package/dist/api/index.d.ts.map +1 -0
  5. package/dist/api/index.js +2 -0
  6. package/dist/api/index.js.map +1 -0
  7. package/dist/api/routes.d.ts +53 -0
  8. package/dist/api/routes.d.ts.map +1 -0
  9. package/dist/api/routes.js +388 -0
  10. package/dist/api/routes.js.map +1 -0
  11. package/dist/cli.d.ts +12 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +245 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/core/decay.d.ts +36 -0
  16. package/dist/core/decay.d.ts.map +1 -0
  17. package/dist/core/decay.js +38 -0
  18. package/dist/core/decay.js.map +1 -0
  19. package/dist/core/embeddings.d.ts +33 -0
  20. package/dist/core/embeddings.d.ts.map +1 -0
  21. package/dist/core/embeddings.js +76 -0
  22. package/dist/core/embeddings.js.map +1 -0
  23. package/dist/core/hebbian.d.ts +38 -0
  24. package/dist/core/hebbian.d.ts.map +1 -0
  25. package/dist/core/hebbian.js +74 -0
  26. package/dist/core/hebbian.js.map +1 -0
  27. package/dist/core/index.d.ts +4 -0
  28. package/dist/core/index.d.ts.map +1 -0
  29. package/dist/core/index.js +4 -0
  30. package/dist/core/index.js.map +1 -0
  31. package/dist/core/query-expander.d.ts +24 -0
  32. package/dist/core/query-expander.d.ts.map +1 -0
  33. package/dist/core/query-expander.js +58 -0
  34. package/dist/core/query-expander.js.map +1 -0
  35. package/dist/core/reranker.d.ts +25 -0
  36. package/dist/core/reranker.d.ts.map +1 -0
  37. package/dist/core/reranker.js +75 -0
  38. package/dist/core/reranker.js.map +1 -0
  39. package/dist/core/salience.d.ts +30 -0
  40. package/dist/core/salience.d.ts.map +1 -0
  41. package/dist/core/salience.js +81 -0
  42. package/dist/core/salience.js.map +1 -0
  43. package/dist/engine/activation.d.ts +38 -0
  44. package/dist/engine/activation.d.ts.map +1 -0
  45. package/dist/engine/activation.js +516 -0
  46. package/dist/engine/activation.js.map +1 -0
  47. package/dist/engine/connections.d.ts +31 -0
  48. package/dist/engine/connections.d.ts.map +1 -0
  49. package/dist/engine/connections.js +74 -0
  50. package/dist/engine/connections.js.map +1 -0
  51. package/dist/engine/consolidation-scheduler.d.ts +31 -0
  52. package/dist/engine/consolidation-scheduler.d.ts.map +1 -0
  53. package/dist/engine/consolidation-scheduler.js +115 -0
  54. package/dist/engine/consolidation-scheduler.js.map +1 -0
  55. package/dist/engine/consolidation.d.ts +62 -0
  56. package/dist/engine/consolidation.d.ts.map +1 -0
  57. package/dist/engine/consolidation.js +368 -0
  58. package/dist/engine/consolidation.js.map +1 -0
  59. package/dist/engine/eval.d.ts +22 -0
  60. package/dist/engine/eval.d.ts.map +1 -0
  61. package/dist/engine/eval.js +79 -0
  62. package/dist/engine/eval.js.map +1 -0
  63. package/dist/engine/eviction.d.ts +29 -0
  64. package/dist/engine/eviction.d.ts.map +1 -0
  65. package/dist/engine/eviction.js +86 -0
  66. package/dist/engine/eviction.js.map +1 -0
  67. package/dist/engine/index.d.ts +7 -0
  68. package/dist/engine/index.d.ts.map +1 -0
  69. package/dist/engine/index.js +7 -0
  70. package/dist/engine/index.js.map +1 -0
  71. package/dist/engine/retraction.d.ts +32 -0
  72. package/dist/engine/retraction.d.ts.map +1 -0
  73. package/dist/engine/retraction.js +77 -0
  74. package/dist/engine/retraction.js.map +1 -0
  75. package/dist/engine/staging.d.ts +33 -0
  76. package/dist/engine/staging.d.ts.map +1 -0
  77. package/dist/engine/staging.js +63 -0
  78. package/dist/engine/staging.js.map +1 -0
  79. package/dist/index.d.ts +2 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +95 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/mcp.d.ts +24 -0
  84. package/dist/mcp.d.ts.map +1 -0
  85. package/dist/mcp.js +532 -0
  86. package/dist/mcp.js.map +1 -0
  87. package/dist/storage/index.d.ts +2 -0
  88. package/dist/storage/index.d.ts.map +1 -0
  89. package/dist/storage/index.js +2 -0
  90. package/dist/storage/index.js.map +1 -0
  91. package/dist/storage/sqlite.d.ts +116 -0
  92. package/dist/storage/sqlite.d.ts.map +1 -0
  93. package/dist/storage/sqlite.js +750 -0
  94. package/dist/storage/sqlite.js.map +1 -0
  95. package/dist/types/agent.d.ts +30 -0
  96. package/dist/types/agent.d.ts.map +1 -0
  97. package/dist/types/agent.js +23 -0
  98. package/dist/types/agent.js.map +1 -0
  99. package/dist/types/checkpoint.d.ts +50 -0
  100. package/dist/types/checkpoint.d.ts.map +1 -0
  101. package/dist/types/checkpoint.js +8 -0
  102. package/dist/types/checkpoint.js.map +1 -0
  103. package/dist/types/engram.d.ts +165 -0
  104. package/dist/types/engram.d.ts.map +1 -0
  105. package/dist/types/engram.js +8 -0
  106. package/dist/types/engram.js.map +1 -0
  107. package/dist/types/eval.d.ts +84 -0
  108. package/dist/types/eval.d.ts.map +1 -0
  109. package/dist/types/eval.js +11 -0
  110. package/dist/types/eval.js.map +1 -0
  111. package/dist/types/index.d.ts +5 -0
  112. package/dist/types/index.d.ts.map +1 -0
  113. package/dist/types/index.js +5 -0
  114. package/dist/types/index.js.map +1 -0
  115. package/package.json +55 -0
  116. package/src/api/index.ts +1 -0
  117. package/src/api/routes.ts +528 -0
  118. package/src/cli.ts +260 -0
  119. package/src/core/decay.ts +61 -0
  120. package/src/core/embeddings.ts +82 -0
  121. package/src/core/hebbian.ts +91 -0
  122. package/src/core/index.ts +3 -0
  123. package/src/core/query-expander.ts +64 -0
  124. package/src/core/reranker.ts +99 -0
  125. package/src/core/salience.ts +95 -0
  126. package/src/engine/activation.ts +577 -0
  127. package/src/engine/connections.ts +101 -0
  128. package/src/engine/consolidation-scheduler.ts +123 -0
  129. package/src/engine/consolidation.ts +443 -0
  130. package/src/engine/eval.ts +100 -0
  131. package/src/engine/eviction.ts +99 -0
  132. package/src/engine/index.ts +6 -0
  133. package/src/engine/retraction.ts +98 -0
  134. package/src/engine/staging.ts +72 -0
  135. package/src/index.ts +100 -0
  136. package/src/mcp.ts +635 -0
  137. package/src/storage/index.ts +1 -0
  138. package/src/storage/sqlite.ts +893 -0
  139. package/src/types/agent.ts +65 -0
  140. package/src/types/checkpoint.ts +44 -0
  141. package/src/types/engram.ts +194 -0
  142. package/src/types/eval.ts +98 -0
  143. package/src/types/index.ts +4 -0
@@ -0,0 +1,368 @@
1
+ /**
2
+ * Sleep Cycle — offline memory consolidation.
3
+ *
4
+ * Models the brain's consolidation during sleep:
5
+ * 1. Replay — find clusters of semantically similar memories
6
+ * 2. Strengthen — reinforce edges within clusters + access-weighted boost
7
+ * 3. Bridge — create cross-cluster shortcuts between related topic areas
8
+ * 4. Decay — weaken unused edges, prune dead ones
9
+ * 5. Homeostasis — normalize outgoing edge weights to prevent hub explosion
10
+ * 6. Forget — archive/delete memories that were never retrieved (age-gated)
11
+ * 7. Sweep — promote or discard uncertain (staging) memories
12
+ *
13
+ * No artificial "summary nodes" are created. Instead, the associative
14
+ * graph gets denser where knowledge overlaps and sparser where it doesn't.
15
+ * The beam search graph walk in activation.ts naturally propagates through
16
+ * these strengthened pathways.
17
+ *
18
+ * Run between sessions or on a timer (e.g., every few hours).
19
+ */
20
+ import { cosineSimilarity } from '../core/embeddings.js';
21
+ import { strengthenAssociation, decayAssociation } from '../core/hebbian.js';
22
+ /** Cosine similarity threshold for considering two memories related */
23
+ const SIMILARITY_THRESHOLD = 0.65;
24
+ /** Lower threshold for cross-cluster bridge edges */
25
+ const BRIDGE_THRESHOLD = 0.25;
26
+ /** Minimum edge weight to form a new connection during replay */
27
+ const INITIAL_EDGE_WEIGHT = 0.3;
28
+ /** Boost factor for strengthening existing edges between cluster members */
29
+ const CONSOLIDATION_SIGNAL = 0.5;
30
+ /** Max new edges to create per sleep cycle (prevent graph explosion) */
31
+ const MAX_NEW_EDGES_PER_CYCLE = 50;
32
+ /** Max bridge edges per cycle (cross-cluster shortcuts) */
33
+ const MAX_BRIDGE_EDGES_PER_CYCLE = 20;
34
+ /** Edge weight below which we prune during decay */
35
+ const PRUNE_THRESHOLD = 0.01;
36
+ /** Target total outgoing edge weight per node (homeostasis) */
37
+ const HOMEOSTASIS_TARGET = 10.0;
38
+ /** Grace period before forgetting curve starts (days) */
39
+ const FORGET_GRACE_DAYS = 7;
40
+ /** Age at which never-retrieved memories get archived (days) */
41
+ const FORGET_ARCHIVE_DAYS = 30;
42
+ /** Age at which archived, never-retrieved, unconnected memories get deleted (days) */
43
+ const FORGET_DELETE_DAYS = 90;
44
+ /** Cosine similarity above which two low-confidence memories are considered redundant */
45
+ const REDUNDANCY_THRESHOLD = 0.85;
46
+ /** Max redundant memories to prune per cycle (gradual, not sudden) */
47
+ const MAX_REDUNDANCY_PRUNE_PER_CYCLE = 10;
48
+ export class ConsolidationEngine {
49
+ store;
50
+ constructor(store) {
51
+ this.store = store;
52
+ }
53
+ /**
54
+ * Run a full sleep cycle for an agent.
55
+ *
56
+ * Phase 1: Replay — find clusters of semantically similar memories
57
+ * Phase 2: Strengthen — reinforce edges within clusters (access-weighted)
58
+ * Phase 3: Bridge — create cross-cluster shortcuts
59
+ * Phase 4: Decay — weaken unused edges, prune dead ones
60
+ * Phase 5: Homeostasis — normalize outgoing edge weights per node
61
+ * Phase 6: Forget — archive/delete memories never retrieved (age-gated)
62
+ * Phase 7: Sweep — check staging buffer for resonance
63
+ */
64
+ consolidate(agentId) {
65
+ const result = {
66
+ clustersFound: 0,
67
+ edgesStrengthened: 0,
68
+ edgesCreated: 0,
69
+ bridgesCreated: 0,
70
+ edgesDecayed: 0,
71
+ edgesPruned: 0,
72
+ edgesNormalized: 0,
73
+ memoriesForgotten: 0,
74
+ memoriesArchived: 0,
75
+ redundancyPruned: 0,
76
+ stagingPromoted: 0,
77
+ stagingDiscarded: 0,
78
+ engramsProcessed: 0,
79
+ };
80
+ // --- Phase 1: Replay ---
81
+ // Get all active engrams with embeddings
82
+ const engrams = this.store.getEngramsByAgent(agentId, 'active')
83
+ .filter(e => e.embedding && e.embedding.length > 0);
84
+ result.engramsProcessed = engrams.length;
85
+ if (engrams.length < 2)
86
+ return result;
87
+ // Find clusters of related memories
88
+ const clusters = this.findClusters(engrams);
89
+ result.clustersFound = clusters.length;
90
+ // --- Phase 2: Strengthen (access-weighted) ---
91
+ // Memories that are retrieved more often get stronger consolidation.
92
+ // This mirrors how the brain preferentially consolidates practiced memories.
93
+ let newEdges = 0;
94
+ for (const cluster of clusters) {
95
+ for (let i = 0; i < cluster.length; i++) {
96
+ for (let j = i + 1; j < cluster.length; j++) {
97
+ const a = cluster[i];
98
+ const b = cluster[j];
99
+ // Access-weighted signal: more retrieved = stronger consolidation
100
+ const accessFactor = Math.min(1.0, 0.3 + 0.7 * Math.log1p(a.accessCount + b.accessCount) / Math.log1p(20));
101
+ const existing = this.store.getAssociation(a.id, b.id);
102
+ if (existing) {
103
+ const newWeight = strengthenAssociation(existing.weight, CONSOLIDATION_SIGNAL * accessFactor, 0.25);
104
+ this.store.upsertAssociation(a.id, b.id, newWeight, existing.type, existing.confidence);
105
+ result.edgesStrengthened++;
106
+ }
107
+ else if (newEdges < MAX_NEW_EDGES_PER_CYCLE) {
108
+ this.store.upsertAssociation(a.id, b.id, INITIAL_EDGE_WEIGHT * accessFactor, 'connection');
109
+ newEdges++;
110
+ result.edgesCreated++;
111
+ }
112
+ }
113
+ }
114
+ }
115
+ // --- Phase 3: Cross-cluster bridge edges ---
116
+ // For each pair of clusters, compute centroid similarity. If moderate
117
+ // similarity exists but no direct edge, create a low-weight bridge.
118
+ // This is what enables cross-topic retrieval to improve over time.
119
+ if (clusters.length >= 2) {
120
+ let bridges = 0;
121
+ const centroids = clusters.map(cluster => this.computeCentroid(cluster));
122
+ for (let i = 0; i < clusters.length && bridges < MAX_BRIDGE_EDGES_PER_CYCLE; i++) {
123
+ for (let j = i + 1; j < clusters.length && bridges < MAX_BRIDGE_EDGES_PER_CYCLE; j++) {
124
+ const sim = cosineSimilarity(centroids[i], centroids[j]);
125
+ if (sim < BRIDGE_THRESHOLD || sim >= SIMILARITY_THRESHOLD)
126
+ continue;
127
+ // Find the best representative from each cluster (highest accessCount)
128
+ const repA = clusters[i].reduce((best, e) => e.accessCount > best.accessCount ? e : best);
129
+ const repB = clusters[j].reduce((best, e) => e.accessCount > best.accessCount ? e : best);
130
+ const existing = this.store.getAssociation(repA.id, repB.id);
131
+ if (!existing) {
132
+ // Bridge weight proportional to inter-cluster similarity
133
+ const bridgeWeight = 0.15 + 0.15 * ((sim - BRIDGE_THRESHOLD) / (SIMILARITY_THRESHOLD - BRIDGE_THRESHOLD));
134
+ this.store.upsertAssociation(repA.id, repB.id, bridgeWeight, 'bridge');
135
+ bridges++;
136
+ result.bridgesCreated++;
137
+ }
138
+ }
139
+ }
140
+ }
141
+ // --- Phase 4: Decay (confidence-modulated) ---
142
+ // High-confidence edges decay slower. This means edges between memories
143
+ // that received positive feedback are more durable — just like how
144
+ // practiced memories are more resistant to forgetting in the brain.
145
+ // Base half-life: 7 days. High-confidence (0.8+) gets up to 30 days.
146
+ const engramConfMap = new Map(engrams.map(e => [e.id, e.confidence]));
147
+ const associations = this.store.getAllAssociations(agentId);
148
+ for (const assoc of associations) {
149
+ const daysSince = (Date.now() - assoc.lastActivated.getTime()) / (1000 * 60 * 60 * 24);
150
+ if (daysSince < 0.5)
151
+ continue; // Skip recently activated
152
+ // Confidence-modulated half-life: higher confidence = slower decay (capped at 3x)
153
+ // Base: 7 days. Conf 0.5 → 7 days. Conf 0.8 → ~15 days. Conf 1.0 → 21 days (3x).
154
+ // Cap prevents any edge from becoming immortal.
155
+ const fromConf = engramConfMap.get(assoc.fromEngramId) ?? 0.5;
156
+ const toConf = engramConfMap.get(assoc.toEngramId) ?? 0.5;
157
+ const maxConf = Math.max(fromConf, toConf);
158
+ const halfLifeDays = Math.min(7 * (1 + 2 * Math.max(0, (maxConf - 0.5) / 0.5)), 21);
159
+ const newWeight = decayAssociation(assoc.weight, daysSince, halfLifeDays);
160
+ if (newWeight < PRUNE_THRESHOLD) {
161
+ this.store.deleteAssociation(assoc.id);
162
+ result.edgesPruned++;
163
+ }
164
+ else if (Math.abs(newWeight - assoc.weight) > 0.001) {
165
+ this.store.upsertAssociation(assoc.fromEngramId, assoc.toEngramId, newWeight, assoc.type, assoc.confidence);
166
+ result.edgesDecayed++;
167
+ }
168
+ }
169
+ // --- Phase 5: Synaptic homeostasis ---
170
+ // Normalize total outgoing edge weight per node to prevent hub explosion.
171
+ // Nodes with many strong edges get scaled down so relative weights stay meaningful.
172
+ const engramIds = new Set(engrams.map(e => e.id));
173
+ for (const id of engramIds) {
174
+ const edges = this.store.getAssociationsFor(id);
175
+ const totalWeight = edges.reduce((sum, a) => sum + a.weight, 0);
176
+ if (totalWeight > HOMEOSTASIS_TARGET) {
177
+ const scale = HOMEOSTASIS_TARGET / totalWeight;
178
+ for (const edge of edges) {
179
+ const newWeight = edge.weight * scale;
180
+ if (newWeight < PRUNE_THRESHOLD) {
181
+ this.store.deleteAssociation(edge.id);
182
+ result.edgesPruned++;
183
+ }
184
+ else {
185
+ this.store.upsertAssociation(edge.fromEngramId, edge.toEngramId, newWeight, edge.type, edge.confidence);
186
+ }
187
+ }
188
+ result.edgesNormalized++;
189
+ }
190
+ }
191
+ // --- Phase 6: Forgetting (age-gated) ---
192
+ // Models how human memory actually works:
193
+ // - New memories get a grace period (too new to judge)
194
+ // - Retrieval acts as rehearsal — resets the forgetting clock
195
+ // - Well-connected memories persist (edges = integration into knowledge)
196
+ // - Old, isolated, unretrieved memories fade to archive (not deleted)
197
+ // - Archived memories can still be recovered via deep search
198
+ // - Only truly orphaned, ancient memories get deleted
199
+ //
200
+ // Key insight: outdated memories still have value as historical context.
201
+ // "We used to use X" helps explain why we now use Y.
202
+ for (const engram of engrams) {
203
+ const ageDays = (Date.now() - engram.createdAt.getTime()) / (1000 * 60 * 60 * 24);
204
+ if (ageDays < FORGET_GRACE_DAYS)
205
+ continue; // Grace period — too new to judge
206
+ const edgeCount = this.store.countAssociationsFor(engram.id);
207
+ // Connections keep memories alive — well-integrated knowledge persists.
208
+ // High-confidence memories (feedback-confirmed) need fewer edges to survive.
209
+ // Models a senior dev who remembers standalone important facts.
210
+ // Default: 3 edges. At conf 0.7: 2 edges. At conf 0.8+: 1 edge.
211
+ const edgeProtectionThreshold = engram.confidence > 0.7
212
+ ? Math.max(1, Math.round(3 - 4 * (engram.confidence - 0.5)))
213
+ : 3;
214
+ if (edgeCount > edgeProtectionThreshold)
215
+ continue;
216
+ // Compute effective forgetting threshold based on memory strength signals.
217
+ // Rehearsal (access + feedback) extends protection but NEVER makes immortal.
218
+ // Models a sharp 20-year senior dev: confirmed knowledge persists for months/years.
219
+ // - Base: FORGET_ARCHIVE_DAYS (30 days)
220
+ // - Access extends by log-scaled factor: 5 accesses ≈ 2x, 10 ≈ 2.5x
221
+ // - Confidence modulates up to 4x (0.5→1x, 0.7→2.6x, 0.8→3.4x, 1.0→4x)
222
+ // - Hard cap: 12x base (360 days) — even the sharpest memory fades after a year
223
+ const accessFactor = 1 + Math.log1p(engram.accessCount) * 0.6;
224
+ const confFactor = 1 + 3 * Math.max(0, (engram.confidence - 0.5) / 0.5);
225
+ const effectiveArchiveDays = Math.min(FORGET_ARCHIVE_DAYS * accessFactor * confFactor, FORGET_ARCHIVE_DAYS * 12);
226
+ const daysSinceAccess = (Date.now() - engram.lastAccessed.getTime()) / (1000 * 60 * 60 * 24);
227
+ if (engram.accessCount === 0 && ageDays > FORGET_ARCHIVE_DAYS) {
228
+ // Never retrieved, old, weakly connected → archive
229
+ this.store.updateStage(engram.id, 'archived');
230
+ result.memoriesArchived++;
231
+ }
232
+ else if (engram.accessCount > 0 && daysSinceAccess > effectiveArchiveDays) {
233
+ // Accessed before but not recently enough given its strength — archive
234
+ this.store.updateStage(engram.id, 'archived');
235
+ result.memoriesArchived++;
236
+ }
237
+ }
238
+ // Check archived memories for deletion — only truly orphaned ancient ones
239
+ const archived = this.store.getEngramsByAgent(agentId, 'archived');
240
+ for (const engram of archived) {
241
+ const ageDays = (Date.now() - engram.createdAt.getTime()) / (1000 * 60 * 60 * 24);
242
+ const edgeCount = this.store.countAssociationsFor(engram.id);
243
+ if (engram.accessCount === 0 && ageDays > FORGET_DELETE_DAYS && edgeCount === 0) {
244
+ // Very old, never accessed, completely isolated → truly forgotten
245
+ this.store.deleteEngram(engram.id);
246
+ result.memoriesForgotten++;
247
+ }
248
+ // Otherwise: stay archived — still searchable, just not in active recall
249
+ }
250
+ // --- Phase 6.5: Redundancy pruning ---
251
+ // A senior dev doesn't store 30 nearly-identical memories. When multiple
252
+ // low-confidence memories are semantically redundant (cosine > 0.85), keep
253
+ // only the one with highest accessCount + confidence and archive the rest.
254
+ // This naturally defeats volume-based attacks (narcissistic interference,
255
+ // spam) while improving signal-to-noise ratio for linked memories.
256
+ // High-confidence memories (feedback-confirmed) are never pruned — they
257
+ // represent verified knowledge worth keeping even if similar.
258
+ // Only consider memories that are both low-confidence AND rarely accessed.
259
+ // Memories retrieved 3+ times have proven useful — they stay even if similar
260
+ // to others. This prevents pruning seed memories that match bulk templates.
261
+ const lowConfEngrams = engrams.filter(e => e.confidence < 0.6 && e.accessCount < 3 && e.embedding && e.embedding.length > 0);
262
+ const pruned = new Set();
263
+ let redundancyCount = 0;
264
+ // Sort by quality: highest accessCount + confidence first (survivors)
265
+ const sortedLow = [...lowConfEngrams].sort((a, b) => (b.accessCount + b.confidence * 10) - (a.accessCount + a.confidence * 10));
266
+ for (let i = 0; i < sortedLow.length && redundancyCount < MAX_REDUNDANCY_PRUNE_PER_CYCLE; i++) {
267
+ if (pruned.has(sortedLow[i].id))
268
+ continue;
269
+ for (let j = i + 1; j < sortedLow.length && redundancyCount < MAX_REDUNDANCY_PRUNE_PER_CYCLE; j++) {
270
+ if (pruned.has(sortedLow[j].id))
271
+ continue;
272
+ if (!sortedLow[i].embedding || !sortedLow[j].embedding)
273
+ continue;
274
+ const sim = cosineSimilarity(sortedLow[i].embedding, sortedLow[j].embedding);
275
+ if (sim >= REDUNDANCY_THRESHOLD) {
276
+ // Archive the lower-quality duplicate
277
+ this.store.updateStage(sortedLow[j].id, 'archived');
278
+ pruned.add(sortedLow[j].id);
279
+ redundancyCount++;
280
+ }
281
+ }
282
+ }
283
+ result.redundancyPruned = redundancyCount;
284
+ // --- Phase 7: Sweep staging ---
285
+ const staging = this.store.getEngramsByAgent(agentId, 'staging')
286
+ .filter(e => e.embedding && e.embedding.length > 0);
287
+ for (const staged of staging) {
288
+ const ageMs = Date.now() - staged.createdAt.getTime();
289
+ // Check if this staging memory resonates with any active memory
290
+ let maxSim = 0;
291
+ for (const active of engrams) {
292
+ if (!active.embedding || !staged.embedding)
293
+ continue;
294
+ const sim = cosineSimilarity(staged.embedding, active.embedding);
295
+ if (sim > maxSim)
296
+ maxSim = sim;
297
+ }
298
+ if (maxSim >= 0.6) {
299
+ // Resonates — promote to active
300
+ this.store.updateStage(staged.id, 'active');
301
+ result.stagingPromoted++;
302
+ }
303
+ else if (ageMs > 24 * 60 * 60 * 1000) {
304
+ // Over 24h and no resonance — discard
305
+ this.store.deleteEngram(staged.id);
306
+ result.stagingDiscarded++;
307
+ }
308
+ // Otherwise: leave in staging, maybe next cycle
309
+ }
310
+ return result;
311
+ }
312
+ /**
313
+ * Find clusters of semantically similar memories.
314
+ * Greedy agglomerative — each memory belongs to at most one cluster.
315
+ * Clusters of size 2+ are returned (pairs count — they link).
316
+ */
317
+ findClusters(engrams) {
318
+ const assigned = new Set();
319
+ const clusters = [];
320
+ // Seed clusters from most-accessed memories (strongest traces)
321
+ const sorted = [...engrams].sort((a, b) => b.accessCount - a.accessCount);
322
+ for (const seed of sorted) {
323
+ if (assigned.has(seed.id))
324
+ continue;
325
+ const cluster = [seed];
326
+ assigned.add(seed.id);
327
+ for (const candidate of sorted) {
328
+ if (assigned.has(candidate.id))
329
+ continue;
330
+ if (!seed.embedding || !candidate.embedding)
331
+ continue;
332
+ const sim = cosineSimilarity(seed.embedding, candidate.embedding);
333
+ if (sim >= SIMILARITY_THRESHOLD) {
334
+ cluster.push(candidate);
335
+ assigned.add(candidate.id);
336
+ }
337
+ }
338
+ if (cluster.length >= 2) {
339
+ clusters.push(cluster);
340
+ }
341
+ else {
342
+ for (const e of cluster)
343
+ assigned.delete(e.id);
344
+ }
345
+ }
346
+ return clusters;
347
+ }
348
+ /**
349
+ * Compute the centroid (average embedding) of a cluster.
350
+ */
351
+ computeCentroid(cluster) {
352
+ const withEmbed = cluster.filter(e => e.embedding && e.embedding.length > 0);
353
+ if (withEmbed.length === 0)
354
+ return [];
355
+ const dim = withEmbed[0].embedding.length;
356
+ const centroid = new Array(dim).fill(0);
357
+ for (const e of withEmbed) {
358
+ for (let i = 0; i < dim; i++) {
359
+ centroid[i] += e.embedding[i];
360
+ }
361
+ }
362
+ for (let i = 0; i < dim; i++) {
363
+ centroid[i] /= withEmbed.length;
364
+ }
365
+ return centroid;
366
+ }
367
+ }
368
+ //# sourceMappingURL=consolidation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consolidation.js","sourceRoot":"","sources":["../../src/engine/consolidation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Evaluation Engine — measures whether memory actually helps.
3
+ *
4
+ * Four dimensions (from Codex):
5
+ * 1. Retrieval quality — precision@k, latency
6
+ * 2. Connection quality — edge utility, stability
7
+ * 3. Staging accuracy — promotion precision, discard regret
8
+ * 4. Memory health — contamination tracking, confidence distribution
9
+ *
10
+ * Task impact (with/without memory) is measured externally via TaskTrial records.
11
+ */
12
+ import type { EngramStore } from '../storage/sqlite.js';
13
+ import type { EvalMetrics } from '../types/index.js';
14
+ export declare class EvalEngine {
15
+ private store;
16
+ constructor(store: EngramStore);
17
+ /**
18
+ * Compute aggregate metrics for an agent over a time window.
19
+ */
20
+ computeMetrics(agentId: string, windowHours?: number): EvalMetrics;
21
+ }
22
+ //# sourceMappingURL=eval.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval.d.ts","sourceRoot":"","sources":["../../src/engine/eval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAAc;gBAEf,KAAK,EAAE,WAAW;IAI9B;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,GAAE,MAAW,GAAG,WAAW;CA0EvE"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Evaluation Engine — measures whether memory actually helps.
3
+ *
4
+ * Four dimensions (from Codex):
5
+ * 1. Retrieval quality — precision@k, latency
6
+ * 2. Connection quality — edge utility, stability
7
+ * 3. Staging accuracy — promotion precision, discard regret
8
+ * 4. Memory health — contamination tracking, confidence distribution
9
+ *
10
+ * Task impact (with/without memory) is measured externally via TaskTrial records.
11
+ */
12
+ export class EvalEngine {
13
+ store;
14
+ constructor(store) {
15
+ this.store = store;
16
+ }
17
+ /**
18
+ * Compute aggregate metrics for an agent over a time window.
19
+ */
20
+ computeMetrics(agentId, windowHours = 24) {
21
+ const window = windowHours <= 24 ? '24h' : `${Math.round(windowHours / 24)}d`;
22
+ // Retrieval quality
23
+ const precision = this.store.getRetrievalPrecision(agentId, windowHours);
24
+ // Staging accuracy
25
+ const stagingMetrics = this.store.getStagingMetrics(agentId);
26
+ const totalStaged = stagingMetrics.promoted + stagingMetrics.discarded + stagingMetrics.expired;
27
+ const promotionPrecision = totalStaged > 0 ? stagingMetrics.promoted / totalStaged : 0;
28
+ // Memory health
29
+ const activeEngrams = this.store.getEngramsByAgent(agentId, 'active');
30
+ const stagingEngrams = this.store.getEngramsByAgent(agentId, 'staging');
31
+ const retractedEngrams = this.store.getEngramsByAgent(agentId, undefined, true)
32
+ .filter(e => e.retracted);
33
+ const allAssociations = this.store.getAllAssociations(agentId);
34
+ const avgConfidence = activeEngrams.length > 0
35
+ ? activeEngrams.reduce((sum, e) => sum + e.confidence, 0) / activeEngrams.length
36
+ : 0;
37
+ // Edge utility — % of edges that have been used in activation
38
+ const usedEdges = allAssociations.filter(a => a.activationCount > 0);
39
+ const edgeUtility = allAssociations.length > 0
40
+ ? usedEdges.length / allAssociations.length
41
+ : 0;
42
+ // Edge survival — average age of edges that are still above minimum weight
43
+ const livingEdges = allAssociations.filter(a => a.weight > 0.01);
44
+ const avgSurvival = livingEdges.length > 0
45
+ ? livingEdges.reduce((sum, a) => sum + (Date.now() - a.createdAt.getTime()) / (1000 * 60 * 60 * 24), 0) / livingEdges.length
46
+ : 0;
47
+ // Activation performance stats
48
+ const activationStats = this.store.getActivationStats(agentId, windowHours);
49
+ // Consolidated count
50
+ const consolidatedCount = this.store.getConsolidatedCount(agentId);
51
+ return {
52
+ agentId,
53
+ timestamp: new Date(),
54
+ window,
55
+ activationCount: activationStats.count,
56
+ avgPrecisionAtK: precision,
57
+ avgLatencyMs: activationStats.avgLatencyMs,
58
+ p95LatencyMs: activationStats.p95LatencyMs,
59
+ totalEdges: allAssociations.length,
60
+ edgesUsedInActivation: usedEdges.length,
61
+ edgeUtilityRate: edgeUtility,
62
+ avgEdgeSurvivalDays: avgSurvival,
63
+ totalStaged: totalStaged,
64
+ promotedCount: stagingMetrics.promoted,
65
+ discardedCount: stagingMetrics.discarded,
66
+ promotionPrecision,
67
+ discardRegret: 0, // Requires tracking discarded-then-rediscovered items
68
+ activeEngramCount: activeEngrams.length,
69
+ stagingEngramCount: stagingEngrams.length,
70
+ retractedCount: retractedEngrams.length,
71
+ consolidatedCount,
72
+ avgConfidence,
73
+ staleUsageCount: 0, // Requires per-activation age/confidence tracking
74
+ retractionRate: retractedEngrams.length /
75
+ Math.max(activeEngrams.length + retractedEngrams.length, 1),
76
+ };
77
+ }
78
+ }
79
+ //# sourceMappingURL=eval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval.js","sourceRoot":"","sources":["../../src/engine/eval.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Eviction Engine — capacity enforcement and edge pruning.
3
+ *
4
+ * When memory budgets are exceeded:
5
+ * 1. Archive lowest-value active engrams
6
+ * 2. Delete expired staging engrams
7
+ * 3. Prune weakest edges when per-engram cap exceeded
8
+ * 4. Decay unused association weights over time
9
+ */
10
+ import type { EngramStore } from '../storage/sqlite.js';
11
+ import type { AgentConfig } from '../types/agent.js';
12
+ export declare class EvictionEngine {
13
+ private store;
14
+ constructor(store: EngramStore);
15
+ /**
16
+ * Check capacity budgets and evict if needed.
17
+ * Returns count of evicted engrams.
18
+ */
19
+ enforceCapacity(agentId: string, config: AgentConfig): {
20
+ evicted: number;
21
+ edgesPruned: number;
22
+ };
23
+ /**
24
+ * Decay all association weights based on time since last activation.
25
+ * Run periodically (e.g., daily).
26
+ */
27
+ decayEdges(agentId: string, halfLifeDays?: number): number;
28
+ }
29
+ //# sourceMappingURL=eviction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eviction.d.ts","sourceRoot":"","sources":["../../src/engine/eviction.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAc;gBAEf,KAAK,EAAE,WAAW;IAI9B;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE;IA8C/F;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,GAAE,MAAU,GAAG,MAAM;CAuB9D"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Eviction Engine — capacity enforcement and edge pruning.
3
+ *
4
+ * When memory budgets are exceeded:
5
+ * 1. Archive lowest-value active engrams
6
+ * 2. Delete expired staging engrams
7
+ * 3. Prune weakest edges when per-engram cap exceeded
8
+ * 4. Decay unused association weights over time
9
+ */
10
+ import { decayAssociation } from '../core/hebbian.js';
11
+ export class EvictionEngine {
12
+ store;
13
+ constructor(store) {
14
+ this.store = store;
15
+ }
16
+ /**
17
+ * Check capacity budgets and evict if needed.
18
+ * Returns count of evicted engrams.
19
+ */
20
+ enforceCapacity(agentId, config) {
21
+ let evicted = 0;
22
+ let edgesPruned = 0;
23
+ // Active engram budget
24
+ const activeCount = this.store.getActiveCount(agentId);
25
+ if (activeCount > config.maxActiveEngrams) {
26
+ const excess = activeCount - config.maxActiveEngrams;
27
+ const candidates = this.store.getEvictionCandidates(agentId, excess);
28
+ for (const engram of candidates) {
29
+ this.store.updateStage(engram.id, 'archived');
30
+ evicted++;
31
+ }
32
+ }
33
+ // Staging budget
34
+ const stagingCount = this.store.getStagingCount(agentId);
35
+ if (stagingCount > config.maxStagingEngrams) {
36
+ const expired = this.store.getExpiredStaging();
37
+ for (const engram of expired) {
38
+ this.store.deleteEngram(engram.id);
39
+ evicted++;
40
+ }
41
+ }
42
+ // Edge pruning — cap per engram
43
+ const engrams = this.store.getEngramsByAgent(agentId, 'active');
44
+ for (const engram of engrams) {
45
+ const edgeCount = this.store.countAssociationsFor(engram.id);
46
+ if (edgeCount > config.maxEdgesPerEngram) {
47
+ // Remove weakest edges until under cap
48
+ let toRemove = edgeCount - config.maxEdgesPerEngram;
49
+ while (toRemove > 0) {
50
+ const weakest = this.store.getWeakestAssociation(engram.id);
51
+ if (weakest) {
52
+ this.store.deleteAssociation(weakest.id);
53
+ edgesPruned++;
54
+ }
55
+ toRemove--;
56
+ }
57
+ }
58
+ }
59
+ return { evicted, edgesPruned };
60
+ }
61
+ /**
62
+ * Decay all association weights based on time since last activation.
63
+ * Run periodically (e.g., daily).
64
+ */
65
+ decayEdges(agentId, halfLifeDays = 7) {
66
+ const associations = this.store.getAllAssociations(agentId);
67
+ let decayed = 0;
68
+ for (const assoc of associations) {
69
+ const daysSince = (Date.now() - assoc.lastActivated.getTime()) / (1000 * 60 * 60 * 24);
70
+ if (daysSince < 0.5)
71
+ continue; // Skip recently activated
72
+ const newWeight = decayAssociation(assoc.weight, daysSince, halfLifeDays);
73
+ if (newWeight < 0.01) {
74
+ // Below minimum useful weight — prune
75
+ this.store.deleteAssociation(assoc.id);
76
+ decayed++;
77
+ }
78
+ else if (Math.abs(newWeight - assoc.weight) > 0.001) {
79
+ this.store.upsertAssociation(assoc.fromEngramId, assoc.toEngramId, newWeight, assoc.type, assoc.confidence);
80
+ decayed++;
81
+ }
82
+ }
83
+ return decayed;
84
+ }
85
+ }
86
+ //# sourceMappingURL=eviction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eviction.js","sourceRoot":"","sources":["../../src/engine/eviction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export * from './activation.js';
2
+ export * from './staging.js';
3
+ export * from './connections.js';
4
+ export * from './eviction.js';
5
+ export * from './retraction.js';
6
+ export * from './eval.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC"}