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.
- package/LICENSE +21 -0
- package/README.md +311 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +2 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/routes.d.ts +53 -0
- package/dist/api/routes.d.ts.map +1 -0
- package/dist/api/routes.js +388 -0
- package/dist/api/routes.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +245 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/decay.d.ts +36 -0
- package/dist/core/decay.d.ts.map +1 -0
- package/dist/core/decay.js +38 -0
- package/dist/core/decay.js.map +1 -0
- package/dist/core/embeddings.d.ts +33 -0
- package/dist/core/embeddings.d.ts.map +1 -0
- package/dist/core/embeddings.js +76 -0
- package/dist/core/embeddings.js.map +1 -0
- package/dist/core/hebbian.d.ts +38 -0
- package/dist/core/hebbian.d.ts.map +1 -0
- package/dist/core/hebbian.js +74 -0
- package/dist/core/hebbian.js.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/query-expander.d.ts +24 -0
- package/dist/core/query-expander.d.ts.map +1 -0
- package/dist/core/query-expander.js +58 -0
- package/dist/core/query-expander.js.map +1 -0
- package/dist/core/reranker.d.ts +25 -0
- package/dist/core/reranker.d.ts.map +1 -0
- package/dist/core/reranker.js +75 -0
- package/dist/core/reranker.js.map +1 -0
- package/dist/core/salience.d.ts +30 -0
- package/dist/core/salience.d.ts.map +1 -0
- package/dist/core/salience.js +81 -0
- package/dist/core/salience.js.map +1 -0
- package/dist/engine/activation.d.ts +38 -0
- package/dist/engine/activation.d.ts.map +1 -0
- package/dist/engine/activation.js +516 -0
- package/dist/engine/activation.js.map +1 -0
- package/dist/engine/connections.d.ts +31 -0
- package/dist/engine/connections.d.ts.map +1 -0
- package/dist/engine/connections.js +74 -0
- package/dist/engine/connections.js.map +1 -0
- package/dist/engine/consolidation-scheduler.d.ts +31 -0
- package/dist/engine/consolidation-scheduler.d.ts.map +1 -0
- package/dist/engine/consolidation-scheduler.js +115 -0
- package/dist/engine/consolidation-scheduler.js.map +1 -0
- package/dist/engine/consolidation.d.ts +62 -0
- package/dist/engine/consolidation.d.ts.map +1 -0
- package/dist/engine/consolidation.js +368 -0
- package/dist/engine/consolidation.js.map +1 -0
- package/dist/engine/eval.d.ts +22 -0
- package/dist/engine/eval.d.ts.map +1 -0
- package/dist/engine/eval.js +79 -0
- package/dist/engine/eval.js.map +1 -0
- package/dist/engine/eviction.d.ts +29 -0
- package/dist/engine/eviction.d.ts.map +1 -0
- package/dist/engine/eviction.js +86 -0
- package/dist/engine/eviction.js.map +1 -0
- package/dist/engine/index.d.ts +7 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +7 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/retraction.d.ts +32 -0
- package/dist/engine/retraction.d.ts.map +1 -0
- package/dist/engine/retraction.js +77 -0
- package/dist/engine/retraction.js.map +1 -0
- package/dist/engine/staging.d.ts +33 -0
- package/dist/engine/staging.d.ts.map +1 -0
- package/dist/engine/staging.js +63 -0
- package/dist/engine/staging.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +95 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp.d.ts +24 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +532 -0
- package/dist/mcp.js.map +1 -0
- package/dist/storage/index.d.ts +2 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +2 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/sqlite.d.ts +116 -0
- package/dist/storage/sqlite.d.ts.map +1 -0
- package/dist/storage/sqlite.js +750 -0
- package/dist/storage/sqlite.js.map +1 -0
- package/dist/types/agent.d.ts +30 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +23 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/checkpoint.d.ts +50 -0
- package/dist/types/checkpoint.d.ts.map +1 -0
- package/dist/types/checkpoint.js +8 -0
- package/dist/types/checkpoint.js.map +1 -0
- package/dist/types/engram.d.ts +165 -0
- package/dist/types/engram.d.ts.map +1 -0
- package/dist/types/engram.js +8 -0
- package/dist/types/engram.js.map +1 -0
- package/dist/types/eval.d.ts +84 -0
- package/dist/types/eval.d.ts.map +1 -0
- package/dist/types/eval.js +11 -0
- package/dist/types/eval.js.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +55 -0
- package/src/api/index.ts +1 -0
- package/src/api/routes.ts +528 -0
- package/src/cli.ts +260 -0
- package/src/core/decay.ts +61 -0
- package/src/core/embeddings.ts +82 -0
- package/src/core/hebbian.ts +91 -0
- package/src/core/index.ts +3 -0
- package/src/core/query-expander.ts +64 -0
- package/src/core/reranker.ts +99 -0
- package/src/core/salience.ts +95 -0
- package/src/engine/activation.ts +577 -0
- package/src/engine/connections.ts +101 -0
- package/src/engine/consolidation-scheduler.ts +123 -0
- package/src/engine/consolidation.ts +443 -0
- package/src/engine/eval.ts +100 -0
- package/src/engine/eviction.ts +99 -0
- package/src/engine/index.ts +6 -0
- package/src/engine/retraction.ts +98 -0
- package/src/engine/staging.ts +72 -0
- package/src/index.ts +100 -0
- package/src/mcp.ts +635 -0
- package/src/storage/index.ts +1 -0
- package/src/storage/sqlite.ts +893 -0
- package/src/types/agent.ts +65 -0
- package/src/types/checkpoint.ts +44 -0
- package/src/types/engram.ts +194 -0
- package/src/types/eval.ts +98 -0
- 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 @@
|
|
|
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"}
|