@cogmem/engram 0.0.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.
@@ -0,0 +1,417 @@
1
+ {
2
+ "version": "6",
3
+ "dialect": "sqlite",
4
+ "id": "99e5e201-971a-435f-b2d5-74854a400ee4",
5
+ "prevId": "00000000-0000-0000-0000-000000000000",
6
+ "tables": {
7
+ "access_log": {
8
+ "name": "access_log",
9
+ "columns": {
10
+ "id": {
11
+ "name": "id",
12
+ "type": "text",
13
+ "primaryKey": true,
14
+ "notNull": true,
15
+ "autoincrement": false
16
+ },
17
+ "memory_id": {
18
+ "name": "memory_id",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": true,
22
+ "autoincrement": false
23
+ },
24
+ "accessed_at": {
25
+ "name": "accessed_at",
26
+ "type": "integer",
27
+ "primaryKey": false,
28
+ "notNull": true,
29
+ "autoincrement": false
30
+ },
31
+ "access_type": {
32
+ "name": "access_type",
33
+ "type": "text",
34
+ "primaryKey": false,
35
+ "notNull": true,
36
+ "autoincrement": false
37
+ }
38
+ },
39
+ "indexes": {
40
+ "idx_access_log_memory_id": {
41
+ "name": "idx_access_log_memory_id",
42
+ "columns": [
43
+ "memory_id"
44
+ ],
45
+ "isUnique": false
46
+ },
47
+ "idx_access_log_accessed_at": {
48
+ "name": "idx_access_log_accessed_at",
49
+ "columns": [
50
+ "accessed_at"
51
+ ],
52
+ "isUnique": false
53
+ }
54
+ },
55
+ "foreignKeys": {
56
+ "access_log_memory_id_memories_id_fk": {
57
+ "name": "access_log_memory_id_memories_id_fk",
58
+ "tableFrom": "access_log",
59
+ "tableTo": "memories",
60
+ "columnsFrom": [
61
+ "memory_id"
62
+ ],
63
+ "columnsTo": [
64
+ "id"
65
+ ],
66
+ "onDelete": "cascade",
67
+ "onUpdate": "no action"
68
+ }
69
+ },
70
+ "compositePrimaryKeys": {},
71
+ "uniqueConstraints": {},
72
+ "checkConstraints": {}
73
+ },
74
+ "associations": {
75
+ "name": "associations",
76
+ "columns": {
77
+ "id": {
78
+ "name": "id",
79
+ "type": "text",
80
+ "primaryKey": true,
81
+ "notNull": true,
82
+ "autoincrement": false
83
+ },
84
+ "source_id": {
85
+ "name": "source_id",
86
+ "type": "text",
87
+ "primaryKey": false,
88
+ "notNull": true,
89
+ "autoincrement": false
90
+ },
91
+ "target_id": {
92
+ "name": "target_id",
93
+ "type": "text",
94
+ "primaryKey": false,
95
+ "notNull": true,
96
+ "autoincrement": false
97
+ },
98
+ "strength": {
99
+ "name": "strength",
100
+ "type": "real",
101
+ "primaryKey": false,
102
+ "notNull": true,
103
+ "autoincrement": false,
104
+ "default": 0.5
105
+ },
106
+ "formed_at": {
107
+ "name": "formed_at",
108
+ "type": "integer",
109
+ "primaryKey": false,
110
+ "notNull": true,
111
+ "autoincrement": false
112
+ },
113
+ "type": {
114
+ "name": "type",
115
+ "type": "text",
116
+ "primaryKey": false,
117
+ "notNull": true,
118
+ "autoincrement": false
119
+ }
120
+ },
121
+ "indexes": {
122
+ "idx_associations_source": {
123
+ "name": "idx_associations_source",
124
+ "columns": [
125
+ "source_id"
126
+ ],
127
+ "isUnique": false
128
+ },
129
+ "idx_associations_target": {
130
+ "name": "idx_associations_target",
131
+ "columns": [
132
+ "target_id"
133
+ ],
134
+ "isUnique": false
135
+ },
136
+ "unique_source_target": {
137
+ "name": "unique_source_target",
138
+ "columns": [
139
+ "source_id",
140
+ "target_id"
141
+ ],
142
+ "isUnique": true
143
+ }
144
+ },
145
+ "foreignKeys": {
146
+ "associations_source_id_memories_id_fk": {
147
+ "name": "associations_source_id_memories_id_fk",
148
+ "tableFrom": "associations",
149
+ "tableTo": "memories",
150
+ "columnsFrom": [
151
+ "source_id"
152
+ ],
153
+ "columnsTo": [
154
+ "id"
155
+ ],
156
+ "onDelete": "cascade",
157
+ "onUpdate": "no action"
158
+ },
159
+ "associations_target_id_memories_id_fk": {
160
+ "name": "associations_target_id_memories_id_fk",
161
+ "tableFrom": "associations",
162
+ "tableTo": "memories",
163
+ "columnsFrom": [
164
+ "target_id"
165
+ ],
166
+ "columnsTo": [
167
+ "id"
168
+ ],
169
+ "onDelete": "cascade",
170
+ "onUpdate": "no action"
171
+ }
172
+ },
173
+ "compositePrimaryKeys": {},
174
+ "uniqueConstraints": {},
175
+ "checkConstraints": {}
176
+ },
177
+ "consolidation_log": {
178
+ "name": "consolidation_log",
179
+ "columns": {
180
+ "id": {
181
+ "name": "id",
182
+ "type": "text",
183
+ "primaryKey": true,
184
+ "notNull": true,
185
+ "autoincrement": false
186
+ },
187
+ "ran_at": {
188
+ "name": "ran_at",
189
+ "type": "integer",
190
+ "primaryKey": false,
191
+ "notNull": true,
192
+ "autoincrement": false
193
+ },
194
+ "memories_strengthened": {
195
+ "name": "memories_strengthened",
196
+ "type": "integer",
197
+ "primaryKey": false,
198
+ "notNull": true,
199
+ "autoincrement": false,
200
+ "default": 0
201
+ },
202
+ "memories_pruned": {
203
+ "name": "memories_pruned",
204
+ "type": "integer",
205
+ "primaryKey": false,
206
+ "notNull": true,
207
+ "autoincrement": false,
208
+ "default": 0
209
+ },
210
+ "facts_extracted": {
211
+ "name": "facts_extracted",
212
+ "type": "integer",
213
+ "primaryKey": false,
214
+ "notNull": true,
215
+ "autoincrement": false,
216
+ "default": 0
217
+ },
218
+ "associations_discovered": {
219
+ "name": "associations_discovered",
220
+ "type": "integer",
221
+ "primaryKey": false,
222
+ "notNull": true,
223
+ "autoincrement": false,
224
+ "default": 0
225
+ }
226
+ },
227
+ "indexes": {},
228
+ "foreignKeys": {},
229
+ "compositePrimaryKeys": {},
230
+ "uniqueConstraints": {},
231
+ "checkConstraints": {}
232
+ },
233
+ "memories": {
234
+ "name": "memories",
235
+ "columns": {
236
+ "id": {
237
+ "name": "id",
238
+ "type": "text",
239
+ "primaryKey": true,
240
+ "notNull": true,
241
+ "autoincrement": false
242
+ },
243
+ "type": {
244
+ "name": "type",
245
+ "type": "text",
246
+ "primaryKey": false,
247
+ "notNull": true,
248
+ "autoincrement": false
249
+ },
250
+ "content": {
251
+ "name": "content",
252
+ "type": "text",
253
+ "primaryKey": false,
254
+ "notNull": true,
255
+ "autoincrement": false
256
+ },
257
+ "encoded_at": {
258
+ "name": "encoded_at",
259
+ "type": "integer",
260
+ "primaryKey": false,
261
+ "notNull": true,
262
+ "autoincrement": false
263
+ },
264
+ "last_recalled_at": {
265
+ "name": "last_recalled_at",
266
+ "type": "integer",
267
+ "primaryKey": false,
268
+ "notNull": false,
269
+ "autoincrement": false
270
+ },
271
+ "recall_count": {
272
+ "name": "recall_count",
273
+ "type": "integer",
274
+ "primaryKey": false,
275
+ "notNull": true,
276
+ "autoincrement": false,
277
+ "default": 0
278
+ },
279
+ "activation": {
280
+ "name": "activation",
281
+ "type": "real",
282
+ "primaryKey": false,
283
+ "notNull": true,
284
+ "autoincrement": false,
285
+ "default": 0
286
+ },
287
+ "emotion": {
288
+ "name": "emotion",
289
+ "type": "text",
290
+ "primaryKey": false,
291
+ "notNull": true,
292
+ "autoincrement": false,
293
+ "default": "'neutral'"
294
+ },
295
+ "emotion_weight": {
296
+ "name": "emotion_weight",
297
+ "type": "real",
298
+ "primaryKey": false,
299
+ "notNull": true,
300
+ "autoincrement": false,
301
+ "default": 0
302
+ },
303
+ "context": {
304
+ "name": "context",
305
+ "type": "text",
306
+ "primaryKey": false,
307
+ "notNull": false,
308
+ "autoincrement": false
309
+ },
310
+ "chunk_id": {
311
+ "name": "chunk_id",
312
+ "type": "text",
313
+ "primaryKey": false,
314
+ "notNull": false,
315
+ "autoincrement": false
316
+ },
317
+ "reconsolidation_count": {
318
+ "name": "reconsolidation_count",
319
+ "type": "integer",
320
+ "primaryKey": false,
321
+ "notNull": true,
322
+ "autoincrement": false,
323
+ "default": 0
324
+ }
325
+ },
326
+ "indexes": {
327
+ "idx_memories_type": {
328
+ "name": "idx_memories_type",
329
+ "columns": [
330
+ "type"
331
+ ],
332
+ "isUnique": false
333
+ },
334
+ "idx_memories_activation": {
335
+ "name": "idx_memories_activation",
336
+ "columns": [
337
+ "activation"
338
+ ],
339
+ "isUnique": false
340
+ },
341
+ "idx_memories_encoded_at": {
342
+ "name": "idx_memories_encoded_at",
343
+ "columns": [
344
+ "encoded_at"
345
+ ],
346
+ "isUnique": false
347
+ },
348
+ "idx_memories_context": {
349
+ "name": "idx_memories_context",
350
+ "columns": [
351
+ "context"
352
+ ],
353
+ "isUnique": false
354
+ },
355
+ "idx_memories_chunk_id": {
356
+ "name": "idx_memories_chunk_id",
357
+ "columns": [
358
+ "chunk_id"
359
+ ],
360
+ "isUnique": false
361
+ }
362
+ },
363
+ "foreignKeys": {},
364
+ "compositePrimaryKeys": {},
365
+ "uniqueConstraints": {},
366
+ "checkConstraints": {}
367
+ },
368
+ "working_memory": {
369
+ "name": "working_memory",
370
+ "columns": {
371
+ "slot": {
372
+ "name": "slot",
373
+ "type": "integer",
374
+ "primaryKey": true,
375
+ "notNull": true,
376
+ "autoincrement": false
377
+ },
378
+ "memory_ref": {
379
+ "name": "memory_ref",
380
+ "type": "text",
381
+ "primaryKey": false,
382
+ "notNull": false,
383
+ "autoincrement": false
384
+ },
385
+ "content": {
386
+ "name": "content",
387
+ "type": "text",
388
+ "primaryKey": false,
389
+ "notNull": true,
390
+ "autoincrement": false
391
+ },
392
+ "pushed_at": {
393
+ "name": "pushed_at",
394
+ "type": "integer",
395
+ "primaryKey": false,
396
+ "notNull": true,
397
+ "autoincrement": false
398
+ }
399
+ },
400
+ "indexes": {},
401
+ "foreignKeys": {},
402
+ "compositePrimaryKeys": {},
403
+ "uniqueConstraints": {},
404
+ "checkConstraints": {}
405
+ }
406
+ },
407
+ "views": {},
408
+ "enums": {},
409
+ "_meta": {
410
+ "schemas": {},
411
+ "tables": {},
412
+ "columns": {}
413
+ },
414
+ "internal": {
415
+ "indexes": {}
416
+ }
417
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "version": "7",
3
+ "dialect": "sqlite",
4
+ "entries": [
5
+ {
6
+ "idx": 0,
7
+ "version": "6",
8
+ "when": 1772220277792,
9
+ "tag": "0000_jittery_ender_wiggin",
10
+ "breakpoints": true
11
+ }
12
+ ]
13
+ }
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@cogmem/engram",
3
+ "version": "0.0.0",
4
+ "description": "Human memory for artificial minds — a cognitive memory system modeled on neuroscience",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "bun": "./src/index.ts",
9
+ "types": "./src/index.ts",
10
+ "default": "./src/index.ts"
11
+ }
12
+ },
13
+ "main": "./src/index.ts",
14
+ "types": "./src/index.ts",
15
+ "bin": {
16
+ "engram": "src/cli/index.ts",
17
+ "engram-mcp": "src/mcp/server.ts"
18
+ },
19
+ "files": [
20
+ "src/",
21
+ "drizzle/"
22
+ ],
23
+ "scripts": {
24
+ "start": "bun run src/cli/index.ts",
25
+ "test": "bun test",
26
+ "mcp": "bun run src/mcp/server.ts",
27
+ "lint": "oxlint src/",
28
+ "fmt": "oxfmt --write src/",
29
+ "typecheck": "bunx tsc --noEmit",
30
+ "db:generate": "bunx drizzle-kit generate",
31
+ "db:push": "bunx drizzle-kit push"
32
+ },
33
+ "dependencies": {
34
+ "@modelcontextprotocol/sdk": "^1.27.1",
35
+ "citty": "^0.2.1",
36
+ "cli-table3": "^0.6.5",
37
+ "dayjs": "^1.11.19",
38
+ "drizzle-orm": "^0.45.1",
39
+ "kleur": "^4.1.5",
40
+ "zod": "^4.3.6"
41
+ },
42
+ "devDependencies": {
43
+ "@changesets/cli": "^2.29.4",
44
+ "@types/bun": "latest",
45
+ "drizzle-kit": "^0.31.9",
46
+ "oxfmt": "^0.35.0",
47
+ "oxlint": "^1.50.0"
48
+ },
49
+ "peerDependencies": {
50
+ "typescript": "^5"
51
+ },
52
+ "repository": {
53
+ "type": "git",
54
+ "url": "git+https://github.com/faltawy/engram.git"
55
+ },
56
+ "keywords": [
57
+ "memory",
58
+ "ai",
59
+ "agents",
60
+ "cognitive",
61
+ "mcp",
62
+ "bun",
63
+ "neuroscience"
64
+ ],
65
+ "publishConfig": {
66
+ "access": "public"
67
+ },
68
+ "license": "MIT",
69
+ "engines": {
70
+ "bun": ">=1.0.0"
71
+ }
72
+ }
@@ -0,0 +1,71 @@
1
+ import { defineCommand } from "citty";
2
+ import { EngramEngine } from "../../core/engine.ts";
3
+ import { encode } from "../../core/encoder.ts";
4
+ import { isValidEmotion } from "../../core/emotional-tag.ts";
5
+ import { isValidMemoryType, Emotion } from "../../core/memory.ts";
6
+ import { formatMemoryEncoded } from "../format.ts";
7
+
8
+ export const encodeCommand = defineCommand({
9
+ meta: {
10
+ name: "encode",
11
+ description: "Form a new memory",
12
+ },
13
+ args: {
14
+ content: {
15
+ type: "positional",
16
+ description: "The memory content to encode",
17
+ required: true,
18
+ },
19
+ type: {
20
+ type: "string",
21
+ description: "Memory type (episodic, semantic, procedural)",
22
+ default: "semantic",
23
+ },
24
+ emotion: {
25
+ type: "string",
26
+ description: `Emotional tag (${Object.values(Emotion).join(", ")})`,
27
+ default: "neutral",
28
+ },
29
+ context: {
30
+ type: "string",
31
+ description: "Context tag (e.g. project:acme)",
32
+ },
33
+ emotionWeight: {
34
+ type: "string",
35
+ description: "Emotion intensity 0-1 (overrides default)",
36
+ alias: "w",
37
+ },
38
+ },
39
+ run({ args }) {
40
+ const typeStr = args.type ?? "semantic";
41
+ if (!isValidMemoryType(typeStr)) {
42
+ console.error(`Invalid type: ${typeStr}. Valid: episodic, semantic, procedural`);
43
+ process.exit(1);
44
+ }
45
+
46
+ const emotionStr = args.emotion ?? "neutral";
47
+ if (!isValidEmotion(emotionStr)) {
48
+ console.error(`Invalid emotion: ${emotionStr}. Valid: ${Object.values(Emotion).join(", ")}`);
49
+ process.exit(1);
50
+ }
51
+
52
+ const engine = EngramEngine.create();
53
+ try {
54
+ const memory = encode(
55
+ engine.storage,
56
+ {
57
+ content: args.content,
58
+ type: typeStr,
59
+ emotion: emotionStr,
60
+ emotionWeight: args.emotionWeight ? Number(args.emotionWeight) : undefined,
61
+ context: args.context ?? engine.projectContext ?? undefined,
62
+ },
63
+ engine.config,
64
+ );
65
+
66
+ console.log(formatMemoryEncoded(memory));
67
+ } finally {
68
+ engine.close();
69
+ }
70
+ },
71
+ });
@@ -0,0 +1,106 @@
1
+ import { defineCommand } from "citty";
2
+ import { EngramEngine } from "../../core/engine.ts";
3
+ import {
4
+ pushFocus,
5
+ popFocus,
6
+ getFocus,
7
+ clearFocus,
8
+ focusUtilization,
9
+ } from "../../core/working-memory.ts";
10
+ import { bold, dim, cyan, isInteractive } from "../format.ts";
11
+
12
+ export const focusCommand = defineCommand({
13
+ meta: {
14
+ name: "focus",
15
+ description: "Manage working memory (what you're actively thinking about)",
16
+ },
17
+ args: {
18
+ content: {
19
+ type: "positional",
20
+ description: "Content to push into working memory (omit to view current focus)",
21
+ },
22
+ clear: {
23
+ type: "boolean",
24
+ description: "Clear all working memory",
25
+ default: false,
26
+ },
27
+ pop: {
28
+ type: "boolean",
29
+ description: "Remove the most recent item from working memory",
30
+ default: false,
31
+ },
32
+ },
33
+ run({ args }) {
34
+ const engine = EngramEngine.create();
35
+ try {
36
+ if (args.clear) {
37
+ const count = clearFocus(engine.storage);
38
+ if (!isInteractive()) {
39
+ console.log(JSON.stringify({ cleared: count }));
40
+ } else {
41
+ console.log(dim(` Cleared ${count} items from working memory.`));
42
+ }
43
+ return;
44
+ }
45
+
46
+ if (args.pop) {
47
+ const popped = popFocus(engine.storage);
48
+ if (!isInteractive()) {
49
+ console.log(
50
+ JSON.stringify(popped ? { slot: popped.slot, content: popped.content } : null),
51
+ );
52
+ } else if (popped) {
53
+ console.log(dim(" Removed: ") + bold(popped.content));
54
+ } else {
55
+ console.log(dim(" Working memory is empty."));
56
+ }
57
+ return;
58
+ }
59
+
60
+ if (args.content) {
61
+ const { slot, evicted } = pushFocus(engine.storage, args.content, engine.config);
62
+ if (!isInteractive()) {
63
+ console.log(
64
+ JSON.stringify({
65
+ slot: slot.slot,
66
+ content: slot.content,
67
+ evicted: evicted ? { slot: evicted.slot, content: evicted.content } : null,
68
+ }),
69
+ );
70
+ } else {
71
+ console.log(cyan(" Focused on: ") + bold(slot.content) + dim(` [slot ${slot.slot}]`));
72
+ if (evicted) {
73
+ console.log(dim(` Evicted: "${evicted.content}" (oldest item, capacity reached)`));
74
+ }
75
+ }
76
+ return;
77
+ }
78
+
79
+ const slots = getFocus(engine.storage);
80
+ const { used, capacity } = focusUtilization(engine.storage, engine.config);
81
+
82
+ if (!isInteractive()) {
83
+ console.log(
84
+ JSON.stringify({
85
+ used,
86
+ capacity,
87
+ slots: slots.map((s) => ({ slot: s.slot, content: s.content, memoryRef: s.memoryRef })),
88
+ }),
89
+ );
90
+ return;
91
+ }
92
+
93
+ if (slots.length === 0) {
94
+ console.log(dim(" Working memory is empty."));
95
+ return;
96
+ }
97
+
98
+ console.log(bold(` Working Memory`) + dim(` [${used}/${capacity}]`));
99
+ for (const slot of slots) {
100
+ console.log(` ${cyan(">")} ${slot.content}` + dim(` [slot ${slot.slot}]`));
101
+ }
102
+ } finally {
103
+ engine.close();
104
+ }
105
+ },
106
+ });