@cogmem/engram 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -26
- package/SKILL.md +40 -33
- package/drizzle/meta/0000_snapshot.json +17 -50
- package/drizzle/meta/_journal.json +1 -1
- package/package.json +27 -27
- package/src/cli/commands/encode.ts +15 -6
- package/src/cli/commands/focus.ts +38 -11
- package/src/cli/commands/health.ts +47 -13
- package/src/cli/commands/inspect.ts +7 -2
- package/src/cli/commands/install.ts +14 -5
- package/src/cli/commands/list.ts +3 -1
- package/src/cli/commands/recall.ts +4 -2
- package/src/cli/commands/sleep.ts +31 -11
- package/src/cli/commands/stats.ts +38 -15
- package/src/cli/format.ts +3 -2
- package/src/cli/index.ts +5 -4
- package/src/cli/providers/claude.ts +16 -5
- package/src/cli/providers/types.ts +5 -1
- package/src/config/defaults.ts +5 -2
- package/src/core/activation.ts +43 -11
- package/src/core/associations.ts +1 -4
- package/src/core/chunking.ts +14 -4
- package/src/core/consolidation.ts +21 -6
- package/src/core/encoder.ts +3 -3
- package/src/core/engine.ts +3 -2
- package/src/core/forgetting.ts +11 -4
- package/src/core/memory.ts +2 -1
- package/src/core/procedural-store.ts +1 -1
- package/src/core/recall.ts +27 -9
- package/src/core/reconsolidation.ts +5 -2
- package/src/core/working-memory.ts +8 -4
- package/src/mcp/server.ts +53 -15
- package/src/mcp/tools.ts +108 -45
- package/src/storage/schema.ts +1 -0
- package/src/storage/sqlite.ts +8 -7
package/README.md
CHANGED
|
@@ -25,12 +25,13 @@ The `install` command sets up the skill file and MCP server config for your edit
|
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
27
|
engram install # interactive — prompts for provider + scope
|
|
28
|
-
engram install --provider claude --global #
|
|
29
|
-
engram install --provider claude --project #
|
|
28
|
+
engram install --provider claude --global # skill → ~/.claude/skills/, MCP → ~/.claude.json
|
|
29
|
+
engram install --provider claude --project # skill → .claude/skills/, MCP → .mcp.json
|
|
30
30
|
engram install --provider claude --global --dry-run # preview without writing files
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
This installs two things:
|
|
34
|
+
|
|
34
35
|
1. **SKILL.md** — a cognitive protocol that teaches agents how to use engram effectively
|
|
35
36
|
2. **MCP config** — adds the engram server to your editor's MCP settings
|
|
36
37
|
|
|
@@ -42,12 +43,12 @@ engram is built on memory research. Every design decision traces back to how the
|
|
|
42
43
|
|
|
43
44
|
The brain has distinct memory systems with different properties:
|
|
44
45
|
|
|
45
|
-
| System
|
|
46
|
-
|
|
47
|
-
| **Working Memory**
|
|
48
|
-
| **Episodic Memory**
|
|
49
|
-
| **Semantic Memory**
|
|
50
|
-
| **Procedural Memory** | Basal Ganglia
|
|
46
|
+
| System | Brain Region | Duration | engram Mapping |
|
|
47
|
+
| --------------------- | ----------------------- | ------------------- | -------------------------------------------------------------------- |
|
|
48
|
+
| **Working Memory** | Prefrontal Cortex | Seconds | `engram focus` — capacity-limited buffer (Miller's Law: 7 ± 2 items) |
|
|
49
|
+
| **Episodic Memory** | Hippocampus → Neocortex | Minutes to lifetime | Contextual experiences — the _what, when, where, how it felt_ |
|
|
50
|
+
| **Semantic Memory** | Neocortex | Very long-term | Facts and concepts, detached from when you learned them |
|
|
51
|
+
| **Procedural Memory** | Basal Ganglia | Lifetime | Skills and habits — immune to decay, expressed through action |
|
|
51
52
|
|
|
52
53
|
### ACT-R Activation Model
|
|
53
54
|
|
|
@@ -93,7 +94,7 @@ When one memory is activated, activation spreads along associative links to rela
|
|
|
93
94
|
S_ji = S - ln(fan_j)
|
|
94
95
|
```
|
|
95
96
|
|
|
96
|
-
Memories with many connections receive
|
|
97
|
+
Memories with many connections receive _less_ boost from each (diffusion). Specific cues work better than generic ones.
|
|
97
98
|
|
|
98
99
|
### Consolidation (Sleep)
|
|
99
100
|
|
|
@@ -188,11 +189,11 @@ The easiest way is `engram install` (see above). To configure manually, add to y
|
|
|
188
189
|
|
|
189
190
|
### Available Tools
|
|
190
191
|
|
|
191
|
-
| Tool
|
|
192
|
-
|
|
193
|
-
| `memory_store`
|
|
192
|
+
| Tool | Description |
|
|
193
|
+
| --------------- | ------------------------------------------------------- |
|
|
194
|
+
| `memory_store` | Encode new memories or reconsolidate existing ones |
|
|
194
195
|
| `memory_recall` | Cue-based retrieval, memory inspection, or system stats |
|
|
195
|
-
| `memory_manage` | Run consolidation or manage working memory
|
|
196
|
+
| `memory_manage` | Run consolidation or manage working memory |
|
|
196
197
|
|
|
197
198
|
## Programmatic API
|
|
198
199
|
|
|
@@ -202,11 +203,15 @@ import { EngramEngine, encode, recall, consolidate } from "engram";
|
|
|
202
203
|
const engine = EngramEngine.inMemory();
|
|
203
204
|
|
|
204
205
|
// Encode
|
|
205
|
-
const memory = encode(
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
206
|
+
const memory = encode(
|
|
207
|
+
engine.storage,
|
|
208
|
+
{
|
|
209
|
+
content: "important fact",
|
|
210
|
+
type: "semantic",
|
|
211
|
+
emotion: "curiosity",
|
|
212
|
+
},
|
|
213
|
+
engine.config,
|
|
214
|
+
);
|
|
210
215
|
|
|
211
216
|
// Recall
|
|
212
217
|
const results = recall(engine.storage, "important", engine.config);
|
|
@@ -221,12 +226,12 @@ engine.close();
|
|
|
221
226
|
|
|
222
227
|
Cognitive parameters can be tuned via environment variables or the `loadConfig()` function:
|
|
223
228
|
|
|
224
|
-
| Parameter
|
|
225
|
-
|
|
226
|
-
| `decayRate`
|
|
227
|
-
| `retrievalThreshold`
|
|
228
|
-
| `workingMemoryCapacity` | 7
|
|
229
|
-
| `dbPath`
|
|
229
|
+
| Parameter | Default | Env Variable | Description |
|
|
230
|
+
| ----------------------- | --------------------- | ---------------------------- | ------------------------------- |
|
|
231
|
+
| `decayRate` | 0.5 | `ENGRAM_DECAY_RATE` | ACT-R power law decay parameter |
|
|
232
|
+
| `retrievalThreshold` | -1.0 | `ENGRAM_RETRIEVAL_THRESHOLD` | Minimum activation for recall |
|
|
233
|
+
| `workingMemoryCapacity` | 7 | `ENGRAM_WM_CAPACITY` | Miller's Law capacity limit |
|
|
234
|
+
| `dbPath` | `~/.engram/memory.db` | `ENGRAM_DB_PATH` | SQLite database location |
|
|
230
235
|
|
|
231
236
|
All parameters are also configurable programmatically:
|
|
232
237
|
|
|
@@ -242,8 +247,8 @@ const engine = new EngramEngine({
|
|
|
242
247
|
|
|
243
248
|
## References
|
|
244
249
|
|
|
245
|
-
- Anderson, J.R. (1993).
|
|
246
|
-
- Ebbinghaus, H. (1885).
|
|
250
|
+
- Anderson, J.R. (1993). _Rules of the Mind_. ACT-R Cognitive Architecture.
|
|
251
|
+
- Ebbinghaus, H. (1885). _Uber das Gedachtnis_. Memory and forgetting curves.
|
|
247
252
|
- Collins, A.M. & Loftus, E.F. (1975). A spreading-activation theory of semantic processing.
|
|
248
253
|
- Nader, K., Schafe, G.E. & Le Doux, J.E. (2000). Fear memories require protein synthesis in the amygdala for reconsolidation after retrieval.
|
|
249
254
|
- Miller, G.A. (1956). The magical number seven, plus or minus two.
|
package/SKILL.md
CHANGED
|
@@ -10,28 +10,31 @@ You have a biologically-inspired memory system. Use it like a brain, not a datab
|
|
|
10
10
|
## Session Lifecycle
|
|
11
11
|
|
|
12
12
|
**Start:** Recall what you know about the current context.
|
|
13
|
+
|
|
13
14
|
```
|
|
14
15
|
memory_recall → { action: "recall", cue: "<project or topic>" }
|
|
15
16
|
memory_manage → { action: "focus_get" }
|
|
16
17
|
```
|
|
17
18
|
|
|
18
19
|
**During:** Encode insights as they emerge. Don't batch everything at the end.
|
|
20
|
+
|
|
19
21
|
```
|
|
20
22
|
memory_store → { action: "encode", content: "...", type: "...", emotion: "..." }
|
|
21
23
|
```
|
|
22
24
|
|
|
23
25
|
**End:** Consolidate to strengthen and link memories.
|
|
26
|
+
|
|
24
27
|
```
|
|
25
28
|
memory_manage → { action: "consolidate" }
|
|
26
29
|
```
|
|
27
30
|
|
|
28
31
|
## Memory Types
|
|
29
32
|
|
|
30
|
-
| Type
|
|
31
|
-
|
|
32
|
-
| `episodic`
|
|
33
|
-
| `semantic`
|
|
34
|
-
| `procedural` | A
|
|
33
|
+
| Type | Use when | Examples |
|
|
34
|
+
| ------------ | --------------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
|
35
|
+
| `episodic` | Something _happened_ — events, interactions, debugging sessions | "User reported login failing on Safari", "Deployed v2.3 with new caching" |
|
|
36
|
+
| `semantic` | A _fact_ or _concept_ — knowledge, definitions, relationships | "Auth uses JWT with 24h expiry", "The payments module depends on Stripe SDK" |
|
|
37
|
+
| `procedural` | A _skill_ or _process_ — how to do things, patterns, workflows | "To deploy: run tests → build → push to staging → verify → promote" |
|
|
35
38
|
|
|
36
39
|
**Default to `semantic`** when unsure. Procedural memories never decay — use them for durable skills.
|
|
37
40
|
|
|
@@ -39,44 +42,47 @@ memory_manage → { action: "consolidate" }
|
|
|
39
42
|
|
|
40
43
|
Tag memories with emotional context. This affects recall priority — emotional memories surface faster.
|
|
41
44
|
|
|
42
|
-
| Emotion
|
|
43
|
-
|
|
44
|
-
| `joy`
|
|
45
|
-
| `satisfaction` | Task completed successfully, clean solution
|
|
46
|
-
| `curiosity`
|
|
47
|
-
| `surprise`
|
|
48
|
-
| `anxiety`
|
|
49
|
-
| `frustration`
|
|
50
|
-
| `neutral`
|
|
45
|
+
| Emotion | When to use |
|
|
46
|
+
| -------------- | ----------------------------------------------------- |
|
|
47
|
+
| `joy` | Something worked well, positive outcome, breakthrough |
|
|
48
|
+
| `satisfaction` | Task completed successfully, clean solution |
|
|
49
|
+
| `curiosity` | Interesting finding, worth exploring further |
|
|
50
|
+
| `surprise` | Unexpected behavior, counter-intuitive result |
|
|
51
|
+
| `anxiety` | Risk identified, potential failure, fragile code |
|
|
52
|
+
| `frustration` | Recurring problem, friction, workaround needed |
|
|
53
|
+
| `neutral` | Routine fact, no emotional significance |
|
|
51
54
|
|
|
52
55
|
Omit emotion for routine facts. Tag frustration on pain points — it helps surface them when they recur.
|
|
53
56
|
|
|
54
57
|
## MCP Tools Reference
|
|
55
58
|
|
|
56
59
|
### memory_store
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
60
|
+
|
|
61
|
+
| Action | Required | Optional |
|
|
62
|
+
| --------------- | ------------------- | ------------------------------------------------------ |
|
|
63
|
+
| `encode` | `content` | `type`, `emotion`, `emotionWeight` (0-1), `context` |
|
|
64
|
+
| `encode_batch` | `memories[]` (1-50) | each: `type`, `emotion`, `emotionWeight`, `context` |
|
|
65
|
+
| `reconsolidate` | `id` | `newContext`, `currentEmotion`, `currentEmotionWeight` |
|
|
62
66
|
|
|
63
67
|
### memory_recall
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
|
67
|
-
| `
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
68
|
+
|
|
69
|
+
| Action | Required | Optional |
|
|
70
|
+
| --------- | -------- | ---------------------------------------------------------- |
|
|
71
|
+
| `recall` | `cue` | `limit`, `type`, `context`, `associative` (bool), `format` |
|
|
72
|
+
| `list` | — | `type`, `context`, `limit`, `offset`, `format` |
|
|
73
|
+
| `inspect` | `id` | — |
|
|
74
|
+
| `stats` | — | — |
|
|
70
75
|
|
|
71
76
|
### memory_manage
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
|
75
|
-
| `
|
|
76
|
-
| `
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
79
|
-
| `
|
|
77
|
+
|
|
78
|
+
| Action | Required | Optional |
|
|
79
|
+
| ----------------- | --------- | -------------------------- |
|
|
80
|
+
| `consolidate` | — | — |
|
|
81
|
+
| `focus_push` | `content` | `memoryRef` |
|
|
82
|
+
| `focus_pop` | — | — |
|
|
83
|
+
| `focus_get` | — | — |
|
|
84
|
+
| `focus_clear` | — | — |
|
|
85
|
+
| `recall_to_focus` | `cue` | `limit`, `type`, `context` |
|
|
80
86
|
|
|
81
87
|
## Working Memory (Focus Buffer)
|
|
82
88
|
|
|
@@ -88,6 +94,7 @@ Omit emotion for routine facts. Tag frustration on pain points — it helps surf
|
|
|
88
94
|
- The buffer is LIFO — newest items pop first
|
|
89
95
|
|
|
90
96
|
**Priming pattern:** At session start, recall + focus to seed your working context:
|
|
97
|
+
|
|
91
98
|
```
|
|
92
99
|
memory_manage → { action: "recall_to_focus", cue: "<current task>" }
|
|
93
100
|
```
|
|
@@ -39,16 +39,12 @@
|
|
|
39
39
|
"indexes": {
|
|
40
40
|
"idx_access_log_memory_id": {
|
|
41
41
|
"name": "idx_access_log_memory_id",
|
|
42
|
-
"columns": [
|
|
43
|
-
"memory_id"
|
|
44
|
-
],
|
|
42
|
+
"columns": ["memory_id"],
|
|
45
43
|
"isUnique": false
|
|
46
44
|
},
|
|
47
45
|
"idx_access_log_accessed_at": {
|
|
48
46
|
"name": "idx_access_log_accessed_at",
|
|
49
|
-
"columns": [
|
|
50
|
-
"accessed_at"
|
|
51
|
-
],
|
|
47
|
+
"columns": ["accessed_at"],
|
|
52
48
|
"isUnique": false
|
|
53
49
|
}
|
|
54
50
|
},
|
|
@@ -57,12 +53,8 @@
|
|
|
57
53
|
"name": "access_log_memory_id_memories_id_fk",
|
|
58
54
|
"tableFrom": "access_log",
|
|
59
55
|
"tableTo": "memories",
|
|
60
|
-
"columnsFrom": [
|
|
61
|
-
|
|
62
|
-
],
|
|
63
|
-
"columnsTo": [
|
|
64
|
-
"id"
|
|
65
|
-
],
|
|
56
|
+
"columnsFrom": ["memory_id"],
|
|
57
|
+
"columnsTo": ["id"],
|
|
66
58
|
"onDelete": "cascade",
|
|
67
59
|
"onUpdate": "no action"
|
|
68
60
|
}
|
|
@@ -121,24 +113,17 @@
|
|
|
121
113
|
"indexes": {
|
|
122
114
|
"idx_associations_source": {
|
|
123
115
|
"name": "idx_associations_source",
|
|
124
|
-
"columns": [
|
|
125
|
-
"source_id"
|
|
126
|
-
],
|
|
116
|
+
"columns": ["source_id"],
|
|
127
117
|
"isUnique": false
|
|
128
118
|
},
|
|
129
119
|
"idx_associations_target": {
|
|
130
120
|
"name": "idx_associations_target",
|
|
131
|
-
"columns": [
|
|
132
|
-
"target_id"
|
|
133
|
-
],
|
|
121
|
+
"columns": ["target_id"],
|
|
134
122
|
"isUnique": false
|
|
135
123
|
},
|
|
136
124
|
"unique_source_target": {
|
|
137
125
|
"name": "unique_source_target",
|
|
138
|
-
"columns": [
|
|
139
|
-
"source_id",
|
|
140
|
-
"target_id"
|
|
141
|
-
],
|
|
126
|
+
"columns": ["source_id", "target_id"],
|
|
142
127
|
"isUnique": true
|
|
143
128
|
}
|
|
144
129
|
},
|
|
@@ -147,12 +132,8 @@
|
|
|
147
132
|
"name": "associations_source_id_memories_id_fk",
|
|
148
133
|
"tableFrom": "associations",
|
|
149
134
|
"tableTo": "memories",
|
|
150
|
-
"columnsFrom": [
|
|
151
|
-
|
|
152
|
-
],
|
|
153
|
-
"columnsTo": [
|
|
154
|
-
"id"
|
|
155
|
-
],
|
|
135
|
+
"columnsFrom": ["source_id"],
|
|
136
|
+
"columnsTo": ["id"],
|
|
156
137
|
"onDelete": "cascade",
|
|
157
138
|
"onUpdate": "no action"
|
|
158
139
|
},
|
|
@@ -160,12 +141,8 @@
|
|
|
160
141
|
"name": "associations_target_id_memories_id_fk",
|
|
161
142
|
"tableFrom": "associations",
|
|
162
143
|
"tableTo": "memories",
|
|
163
|
-
"columnsFrom": [
|
|
164
|
-
|
|
165
|
-
],
|
|
166
|
-
"columnsTo": [
|
|
167
|
-
"id"
|
|
168
|
-
],
|
|
144
|
+
"columnsFrom": ["target_id"],
|
|
145
|
+
"columnsTo": ["id"],
|
|
169
146
|
"onDelete": "cascade",
|
|
170
147
|
"onUpdate": "no action"
|
|
171
148
|
}
|
|
@@ -326,37 +303,27 @@
|
|
|
326
303
|
"indexes": {
|
|
327
304
|
"idx_memories_type": {
|
|
328
305
|
"name": "idx_memories_type",
|
|
329
|
-
"columns": [
|
|
330
|
-
"type"
|
|
331
|
-
],
|
|
306
|
+
"columns": ["type"],
|
|
332
307
|
"isUnique": false
|
|
333
308
|
},
|
|
334
309
|
"idx_memories_activation": {
|
|
335
310
|
"name": "idx_memories_activation",
|
|
336
|
-
"columns": [
|
|
337
|
-
"activation"
|
|
338
|
-
],
|
|
311
|
+
"columns": ["activation"],
|
|
339
312
|
"isUnique": false
|
|
340
313
|
},
|
|
341
314
|
"idx_memories_encoded_at": {
|
|
342
315
|
"name": "idx_memories_encoded_at",
|
|
343
|
-
"columns": [
|
|
344
|
-
"encoded_at"
|
|
345
|
-
],
|
|
316
|
+
"columns": ["encoded_at"],
|
|
346
317
|
"isUnique": false
|
|
347
318
|
},
|
|
348
319
|
"idx_memories_context": {
|
|
349
320
|
"name": "idx_memories_context",
|
|
350
|
-
"columns": [
|
|
351
|
-
"context"
|
|
352
|
-
],
|
|
321
|
+
"columns": ["context"],
|
|
353
322
|
"isUnique": false
|
|
354
323
|
},
|
|
355
324
|
"idx_memories_chunk_id": {
|
|
356
325
|
"name": "idx_memories_chunk_id",
|
|
357
|
-
"columns": [
|
|
358
|
-
"chunk_id"
|
|
359
|
-
],
|
|
326
|
+
"columns": ["chunk_id"],
|
|
360
327
|
"isUnique": false
|
|
361
328
|
}
|
|
362
329
|
},
|
|
@@ -414,4 +381,4 @@
|
|
|
414
381
|
"internal": {
|
|
415
382
|
"indexes": {}
|
|
416
383
|
}
|
|
417
|
-
}
|
|
384
|
+
}
|
package/package.json
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cogmem/engram",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Human memory for artificial minds — a cognitive memory system modeled on neuroscience",
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
"keywords": [
|
|
6
|
+
"agents",
|
|
7
|
+
"ai",
|
|
8
|
+
"bun",
|
|
9
|
+
"cognitive",
|
|
10
|
+
"mcp",
|
|
11
|
+
"memory",
|
|
12
|
+
"neuroscience"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/faltawy/engram.git"
|
|
12
18
|
},
|
|
13
|
-
"main": "./src/index.ts",
|
|
14
|
-
"types": "./src/index.ts",
|
|
15
19
|
"bin": {
|
|
16
20
|
"engram": "src/cli/index.ts",
|
|
17
21
|
"engram-mcp": "src/mcp/server.ts"
|
|
@@ -21,6 +25,19 @@
|
|
|
21
25
|
"drizzle/",
|
|
22
26
|
"SKILL.md"
|
|
23
27
|
],
|
|
28
|
+
"type": "module",
|
|
29
|
+
"main": "./src/index.ts",
|
|
30
|
+
"types": "./src/index.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./src/index.ts",
|
|
34
|
+
"bun": "./src/index.ts",
|
|
35
|
+
"default": "./src/index.ts"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
24
41
|
"scripts": {
|
|
25
42
|
"start": "bun run src/cli/index.ts",
|
|
26
43
|
"test": "bun test",
|
|
@@ -51,23 +68,6 @@
|
|
|
51
68
|
"peerDependencies": {
|
|
52
69
|
"typescript": "^5"
|
|
53
70
|
},
|
|
54
|
-
"repository": {
|
|
55
|
-
"type": "git",
|
|
56
|
-
"url": "git+https://github.com/faltawy/engram.git"
|
|
57
|
-
},
|
|
58
|
-
"keywords": [
|
|
59
|
-
"memory",
|
|
60
|
-
"ai",
|
|
61
|
-
"agents",
|
|
62
|
-
"cognitive",
|
|
63
|
-
"mcp",
|
|
64
|
-
"bun",
|
|
65
|
-
"neuroscience"
|
|
66
|
-
],
|
|
67
|
-
"publishConfig": {
|
|
68
|
-
"access": "public"
|
|
69
|
-
},
|
|
70
|
-
"license": "MIT",
|
|
71
71
|
"engines": {
|
|
72
72
|
"bun": ">=1.0.0"
|
|
73
73
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { defineCommand } from "citty";
|
|
2
|
-
|
|
3
|
-
import { encode } from "../../core/encoder.ts";
|
|
2
|
+
|
|
4
3
|
import { isValidEmotion } from "../../core/emotional-tag.ts";
|
|
4
|
+
import { encode } from "../../core/encoder.ts";
|
|
5
|
+
import { EngramEngine } from "../../core/engine.ts";
|
|
5
6
|
import { isValidMemoryType, Emotion } from "../../core/memory.ts";
|
|
6
7
|
import { formatMemoryEncoded } from "../format.ts";
|
|
7
8
|
|
|
@@ -39,13 +40,19 @@ export const encodeCommand = defineCommand({
|
|
|
39
40
|
run({ args }) {
|
|
40
41
|
const typeStr = args.type ?? "semantic";
|
|
41
42
|
if (!isValidMemoryType(typeStr)) {
|
|
42
|
-
console.error(
|
|
43
|
+
console.error(
|
|
44
|
+
`Invalid type: ${typeStr}. Valid: episodic, semantic, procedural`
|
|
45
|
+
);
|
|
43
46
|
process.exit(1);
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
const emotionStr = args.emotion ?? "neutral";
|
|
47
50
|
if (!isValidEmotion(emotionStr)) {
|
|
48
|
-
console.error(
|
|
51
|
+
console.error(
|
|
52
|
+
`Invalid emotion: ${emotionStr}. Valid: ${Object.values(Emotion).join(
|
|
53
|
+
", "
|
|
54
|
+
)}`
|
|
55
|
+
);
|
|
49
56
|
process.exit(1);
|
|
50
57
|
}
|
|
51
58
|
|
|
@@ -57,10 +64,12 @@ export const encodeCommand = defineCommand({
|
|
|
57
64
|
content: args.content,
|
|
58
65
|
type: typeStr,
|
|
59
66
|
emotion: emotionStr,
|
|
60
|
-
emotionWeight: args.emotionWeight
|
|
67
|
+
emotionWeight: args.emotionWeight
|
|
68
|
+
? Number(args.emotionWeight)
|
|
69
|
+
: undefined,
|
|
61
70
|
context: args.context ?? engine.projectContext ?? undefined,
|
|
62
71
|
},
|
|
63
|
-
engine.config
|
|
72
|
+
engine.config
|
|
64
73
|
);
|
|
65
74
|
|
|
66
75
|
console.log(formatMemoryEncoded(memory));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { defineCommand } from "citty";
|
|
2
|
+
|
|
2
3
|
import { EngramEngine } from "../../core/engine.ts";
|
|
3
4
|
import {
|
|
4
5
|
pushFocus,
|
|
@@ -17,7 +18,8 @@ export const focusCommand = defineCommand({
|
|
|
17
18
|
args: {
|
|
18
19
|
content: {
|
|
19
20
|
type: "positional",
|
|
20
|
-
description:
|
|
21
|
+
description:
|
|
22
|
+
"Content to push into working memory (omit to view current focus)",
|
|
21
23
|
},
|
|
22
24
|
clear: {
|
|
23
25
|
type: "boolean",
|
|
@@ -47,7 +49,9 @@ export const focusCommand = defineCommand({
|
|
|
47
49
|
const popped = popFocus(engine.storage);
|
|
48
50
|
if (!isInteractive()) {
|
|
49
51
|
console.log(
|
|
50
|
-
JSON.stringify(
|
|
52
|
+
JSON.stringify(
|
|
53
|
+
popped ? { slot: popped.slot, content: popped.content } : null
|
|
54
|
+
)
|
|
51
55
|
);
|
|
52
56
|
} else if (popped) {
|
|
53
57
|
console.log(dim(" Removed: ") + bold(popped.content));
|
|
@@ -58,34 +62,55 @@ export const focusCommand = defineCommand({
|
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
if (args.content) {
|
|
61
|
-
const { slot, evicted } = pushFocus(
|
|
65
|
+
const { slot, evicted } = pushFocus(
|
|
66
|
+
engine.storage,
|
|
67
|
+
args.content,
|
|
68
|
+
engine.config
|
|
69
|
+
);
|
|
62
70
|
if (!isInteractive()) {
|
|
63
71
|
console.log(
|
|
64
72
|
JSON.stringify({
|
|
65
73
|
slot: slot.slot,
|
|
66
74
|
content: slot.content,
|
|
67
|
-
evicted: evicted
|
|
68
|
-
|
|
75
|
+
evicted: evicted
|
|
76
|
+
? { slot: evicted.slot, content: evicted.content }
|
|
77
|
+
: null,
|
|
78
|
+
})
|
|
69
79
|
);
|
|
70
80
|
} else {
|
|
71
|
-
console.log(
|
|
81
|
+
console.log(
|
|
82
|
+
cyan(" Focused on: ") +
|
|
83
|
+
bold(slot.content) +
|
|
84
|
+
dim(` [slot ${slot.slot}]`)
|
|
85
|
+
);
|
|
72
86
|
if (evicted) {
|
|
73
|
-
console.log(
|
|
87
|
+
console.log(
|
|
88
|
+
dim(
|
|
89
|
+
` Evicted: "${evicted.content}" (oldest item, capacity reached)`
|
|
90
|
+
)
|
|
91
|
+
);
|
|
74
92
|
}
|
|
75
93
|
}
|
|
76
94
|
return;
|
|
77
95
|
}
|
|
78
96
|
|
|
79
97
|
const slots = getFocus(engine.storage);
|
|
80
|
-
const { used, capacity } = focusUtilization(
|
|
98
|
+
const { used, capacity } = focusUtilization(
|
|
99
|
+
engine.storage,
|
|
100
|
+
engine.config
|
|
101
|
+
);
|
|
81
102
|
|
|
82
103
|
if (!isInteractive()) {
|
|
83
104
|
console.log(
|
|
84
105
|
JSON.stringify({
|
|
85
106
|
used,
|
|
86
107
|
capacity,
|
|
87
|
-
slots: slots.map((s) => ({
|
|
88
|
-
|
|
108
|
+
slots: slots.map((s) => ({
|
|
109
|
+
slot: s.slot,
|
|
110
|
+
content: s.content,
|
|
111
|
+
memoryRef: s.memoryRef,
|
|
112
|
+
})),
|
|
113
|
+
})
|
|
89
114
|
);
|
|
90
115
|
return;
|
|
91
116
|
}
|
|
@@ -97,7 +122,9 @@ export const focusCommand = defineCommand({
|
|
|
97
122
|
|
|
98
123
|
console.log(bold(` Working Memory`) + dim(` [${used}/${capacity}]`));
|
|
99
124
|
for (const slot of slots) {
|
|
100
|
-
console.log(
|
|
125
|
+
console.log(
|
|
126
|
+
` ${cyan(">")} ${slot.content}` + dim(` [slot ${slot.slot}]`)
|
|
127
|
+
);
|
|
101
128
|
}
|
|
102
129
|
} finally {
|
|
103
130
|
engine.close();
|