@199-bio/engram 0.6.1 → 0.7.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/dist/index.js CHANGED
@@ -59,7 +59,7 @@ const server = new Server({
59
59
  const TOOLS = [
60
60
  {
61
61
  name: "remember",
62
- description: "Store information with entities and relationships. Extract key people, organizations, and places from the content and pass them as entities. Include relationships between entities when mentioned (e.g., 'works_at', 'lives_in', 'knows').",
62
+ description: "Store NEW information the user shares. Extract entities (people, organizations, places) and relationships. Do NOT use for corrections - use edit_memory instead. Do NOT use before checking if info already exists - use recall first.",
63
63
  inputSchema: {
64
64
  type: "object",
65
65
  properties: {
@@ -69,14 +69,14 @@ const TOOLS = [
69
69
  },
70
70
  importance: {
71
71
  type: "number",
72
- description: "0-1 score. Use 0.8+ for key facts (names, preferences, important events), 0.5 for general info, 0.3- for trivial mentions",
72
+ description: "0-1 score with anchors: 0.9=core identity (name, birthday, family), 0.8=major preferences/life events, 0.6=notable facts, 0.5=general info (default), 0.3=casual mentions, 0.1=trivial/ephemeral",
73
73
  minimum: 0,
74
74
  maximum: 1,
75
75
  default: 0.5,
76
76
  },
77
77
  emotional_weight: {
78
78
  type: "number",
79
- description: "0-1 emotional significance. Use 0.8+ for emotionally charged content, celebrations, losses. Affects memory retention.",
79
+ description: "0-1 emotional significance with anchors: 0.9=major life events (births, deaths, achievements), 0.7=celebrations/disappointments, 0.5=neutral (default), 0.3=mild sentiment, 0.1=purely factual",
80
80
  minimum: 0,
81
81
  maximum: 1,
82
82
  default: 0.5,
@@ -91,7 +91,7 @@ const TOOLS = [
91
91
  items: {
92
92
  type: "object",
93
93
  properties: {
94
- name: { type: "string", description: "Entity name (e.g., 'Boris Djordjevic', 'Google', 'Paris')" },
94
+ name: { type: "string", description: "Entity name (e.g., 'John Smith', 'Google', 'Paris')" },
95
95
  type: { type: "string", enum: ["person", "organization", "place"], description: "Entity type" },
96
96
  },
97
97
  required: ["name", "type"],
@@ -123,7 +123,7 @@ const TOOLS = [
123
123
  },
124
124
  {
125
125
  name: "recall",
126
- description: "PRIMARY SEARCH TOOL. Use this FIRST when answering any question about stored information. Searches across all memories using semantic understanding, keywords, and knowledge graph connections. Returns relevant memories with context.",
126
+ description: "Search stored memories. Use FIRST before answering questions about the user, their preferences, history, or anything previously discussed. Also use before remember to check if information already exists.",
127
127
  inputSchema: {
128
128
  type: "object",
129
129
  properties: {
@@ -154,13 +154,13 @@ const TOOLS = [
154
154
  },
155
155
  {
156
156
  name: "forget",
157
- description: "Delete a specific memory by its ID. Use only when explicitly asked to remove information.",
157
+ description: "Delete a memory by its ID. Use when user explicitly asks to remove or forget specific stored information. Get the memory ID from recall results first.",
158
158
  inputSchema: {
159
159
  type: "object",
160
160
  properties: {
161
161
  id: {
162
162
  type: "string",
163
- description: "The memory ID to remove",
163
+ description: "The memory ID to delete (get this from recall results)",
164
164
  },
165
165
  },
166
166
  required: ["id"],
@@ -173,6 +173,37 @@ const TOOLS = [
173
173
  openWorldHint: false,
174
174
  },
175
175
  },
176
+ {
177
+ name: "edit_memory",
178
+ description: "Correct or update an existing memory. Use instead of forget+remember when fixing mistakes, updating outdated info, or adjusting importance. Preserves the memory's history and relationships.",
179
+ inputSchema: {
180
+ type: "object",
181
+ properties: {
182
+ id: {
183
+ type: "string",
184
+ description: "The memory ID to edit (get this from recall results)",
185
+ },
186
+ content: {
187
+ type: "string",
188
+ description: "New content for the memory (replaces existing). Omit to keep current content.",
189
+ },
190
+ importance: {
191
+ type: "number",
192
+ description: "New importance (0-1): 0.9=core identity, 0.8=major, 0.5=normal, 0.3=minor. Omit to keep current.",
193
+ minimum: 0,
194
+ maximum: 1,
195
+ },
196
+ },
197
+ required: ["id"],
198
+ },
199
+ annotations: {
200
+ title: "Edit Memory",
201
+ readOnlyHint: false,
202
+ destructiveHint: false,
203
+ idempotentHint: true,
204
+ openWorldHint: false,
205
+ },
206
+ },
176
207
  {
177
208
  name: "engram_web",
178
209
  description: "Launch the Engram web interface for browsing, searching, and editing memories visually. Returns a URL to open in your browser.",
@@ -196,7 +227,7 @@ const TOOLS = [
196
227
  },
197
228
  {
198
229
  name: "consolidate",
199
- description: "Run memory consolidation to compress episodes into memories and memories into digests. Like sleep for the memory system. Use periodically or when requested.",
230
+ description: "Run memory consolidation to compress episodes into memories and memories into digests. Like sleep for the memory system. Requires ANTHROPIC_API_KEY. Use periodically or when explicitly requested.",
200
231
  inputSchema: {
201
232
  type: "object",
202
233
  properties: {
@@ -213,7 +244,7 @@ const TOOLS = [
213
244
  readOnlyHint: false,
214
245
  destructiveHint: false,
215
246
  idempotentHint: false,
216
- openWorldHint: false,
247
+ openWorldHint: true, // Calls Anthropic API for consolidation
217
248
  },
218
249
  },
219
250
  ];
@@ -317,13 +348,62 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
317
348
  }
318
349
  // Remove from semantic index
319
350
  await search.removeFromIndex(id);
320
- // Delete from database
321
- db.deleteMemory(id);
351
+ // Soft-delete: mark as disabled instead of hard delete
352
+ db.updateMemory(id, { disabled: true });
353
+ return {
354
+ content: [
355
+ {
356
+ type: "text",
357
+ text: JSON.stringify({ success: true, disabled_id: id, message: "Memory disabled (soft-deleted)" }),
358
+ },
359
+ ],
360
+ };
361
+ }
362
+ case "edit_memory": {
363
+ const { id, content, importance } = args;
364
+ const memory = db.getMemory(id);
365
+ if (!memory) {
366
+ return {
367
+ content: [
368
+ {
369
+ type: "text",
370
+ text: JSON.stringify({ success: false, error: "Memory not found" }),
371
+ },
372
+ ],
373
+ };
374
+ }
375
+ // Build updates object
376
+ const updates = {};
377
+ if (content !== undefined)
378
+ updates.content = content;
379
+ if (importance !== undefined)
380
+ updates.importance = importance;
381
+ if (Object.keys(updates).length === 0) {
382
+ return {
383
+ content: [
384
+ {
385
+ type: "text",
386
+ text: JSON.stringify({ success: false, error: "No updates provided" }),
387
+ },
388
+ ],
389
+ };
390
+ }
391
+ // Update the memory
392
+ const updated = db.updateMemory(id, updates);
393
+ // Re-index if content changed
394
+ if (content !== undefined && updated) {
395
+ await search.removeFromIndex(id);
396
+ await search.indexMemory(updated);
397
+ }
322
398
  return {
323
399
  content: [
324
400
  {
325
401
  type: "text",
326
- text: JSON.stringify({ success: true, deleted_id: id }),
402
+ text: JSON.stringify({
403
+ success: true,
404
+ memory_id: id,
405
+ updated_fields: Object.keys(updates),
406
+ }),
327
407
  },
328
408
  ],
329
409
  };
@@ -1 +1 @@
1
- {"version":3,"file":"hybrid.d.ts","sourceRoot":"","sources":["../../src/retrieval/hybrid.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAA0B,MAAM,cAAc,CAAC;AAEzF,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAwDD,qBAAa,YAAY;IAErB,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,SAAS;gBAFT,EAAE,EAAE,cAAc,EAClB,KAAK,EAAE,cAAc,EACrB,SAAS,EAAE,gBAAgB,GAAG,eAAe;IAGvD;;;;;OAKG;IACG,MAAM,CACV,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,OAAO,CAAC;KACnB,GACL,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAyIhC;;OAEG;YACW,UAAU;IASxB;;OAEG;YACW,cAAc;IAS5B;;OAEG;YACW,WAAW;IAmBzB;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhD;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAYhD;;OAEG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGvD"}
1
+ {"version":3,"file":"hybrid.d.ts","sourceRoot":"","sources":["../../src/retrieval/hybrid.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAA0B,MAAM,cAAc,CAAC;AAEzF,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAwDD,qBAAa,YAAY;IAErB,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,SAAS;gBAFT,EAAE,EAAE,cAAc,EAClB,KAAK,EAAE,cAAc,EACrB,SAAS,EAAE,gBAAgB,GAAG,eAAe;IAGvD;;;;;OAKG;IACG,MAAM,CACV,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,OAAO,CAAC;KACnB,GACL,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAyIhC;;OAEG;YACW,UAAU;IASxB;;OAEG;YACW,cAAc;IAS5B;;;OAGG;IACH,OAAO,CAAC,aAAa;IAQrB;;;OAGG;YACW,WAAW;IA8BzB;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhD;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAYhD;;OAEG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGvD"}
@@ -1 +1 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/storage/database.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/storage/database.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,IAAI,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,cAAc,CAAC;IAChE,UAAU,EAAE,IAAI,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,IAAI,CAAC;IACjB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC3C,UAAU,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,IAAI,CAAC;IACjB,YAAY,EAAE,IAAI,CAAC;IACnB,UAAU,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,IAAI,CAAC;IACjB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;CAC1B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,SAAS,CAA8C;gBAEnD,MAAM,EAAE,MAAM;IAoB1B,OAAO,CAAC,UAAU;IAgKlB;;OAEG;IACH,OAAO,CAAC,aAAa;IAqBrB,YAAY,CACV,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAAuB,EAC/B,UAAU,GAAE,MAAY,EACxB,OAAO,GAAE;QACP,SAAS,CAAC,EAAE,IAAI,CAAC;QACjB,eAAe,CAAC,EAAE,MAAM,CAAC;KACrB,GACL,MAAM;IAkBT,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKpC,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,GAAG,YAAY,GAAG,UAAU,CAAC,CAAC,GAAG,MAAM,GAAG,IAAI;IAyB9G,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAMjC;;;OAGG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAW7B,cAAc,CAAC,KAAK,GAAE,MAAa,EAAE,eAAe,GAAE,OAAe,GAAG,MAAM,EAAE;IAUhF;;OAEG;IACH,aAAa,CACX,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GAAG,WAAW,EAC1B,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO;IAcV,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IAKtC,OAAO,CAAC,gBAAgB;IAOxB;;OAEG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,EAAE;IAOhD;;OAEG;IACH,yBAAyB,CAAC,KAAK,GAAE,MAAY,GAAG,OAAO,EAAE;IAOzD;;OAEG;IACH,wBAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI;IAOpD;;OAEG;IACH,iBAAiB,CAAC,KAAK,GAAE,MAAW,GAAG,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,IAAI,CAAA;KAAE,CAAC;IAgBhH,OAAO,CAAC,YAAY;IAcpB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,KAAK,CAAC,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAkBhF,OAAO,CAAC,eAAe;IAavB,YAAY,CACV,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EACpB,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAW,GAC9C,MAAM;IAUT,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKpC,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAU7C;;;OAGG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,MAAY,GAAG,MAAM,GAAG,IAAI;IA+BvE;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IA4C/B;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG;QAAE,iBAAiB,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE;IAgCxG;;OAEG;IACH,qBAAqB,IAAI,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,mBAAmB,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAoCjF,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE;IAgB9D,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,GAAE,MAAY,GAAG,MAAM,EAAE;IAiBlE,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAMjC,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;KAAE,GAAG,MAAM,GAAG,IAAI;IAc1F,cAAc,CACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,cAAc,GAAE,MAAM,GAAG,IAAW,EACpC,UAAU,GAAE,MAAY,GACvB,WAAW;IAUd,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAK9C,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,GAAE,OAAe,GAAG,WAAW,EAAE;IAYvF,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAOnC,cAAc,CACZ,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAW,GAChD,QAAQ;IAUX,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAKxC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,GAAG,IAAI,GAAG,MAAe,GAAG,QAAQ,EAAE;IAiB5F,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IActF,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAQnC,QAAQ,CACN,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAU,EACjB,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB;QAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,EAAE,QAAQ,EAAE,CAAC;QAAC,YAAY,EAAE,WAAW,EAAE,CAAA;KAAE;IA2C7E,YAAY,CACV,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,MAAM,EAAE,EACzB,OAAO,GAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,IAAI,CAAC;QACnB,SAAS,CAAC,EAAE,IAAI,CAAC;KACb,GACL,MAAM;IA4BT,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKpC,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,GAAE,MAAY,GAAG,MAAM,EAAE;IAgBzD,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAU5C,yBAAyB,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,GAAE,MAAY,GAAG,MAAM,EAAE;IAoBtE,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAQjC,mBAAmB,CACjB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,MAAM,GAChB,aAAa;IAUhB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAKlD,iBAAiB,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,KAAK,GAAE,MAAY,GAAG,aAAa,EAAE;IAgB3E,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO;IAU7D,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAQxC,QAAQ,IAAI;QACV,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;QAChB,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,uBAAuB,EAAE,MAAM,CAAC;KACjC;IA4BD,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,OAAO,CAAC,IAAI;IASZ,OAAO,CAAC,WAAW;IAgBnB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,kBAAkB;CAa3B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@199-bio/engram",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "description": "Give Claude a perfect memory. Local-first MCP server with hybrid search.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -74,8 +74,8 @@ const EPISODE_EXTRACTION_SYSTEM = `You are extracting structured memories from a
74
74
  "importance": 0.5,
75
75
  "emotional_weight": 0.5,
76
76
  "event_time": "2024-12-01 or null if not mentioned",
77
- "entities": [{"name": "Boris", "type": "person"}],
78
- "relationships": [{"from": "Boris", "to": "Google", "type": "works_at"}]
77
+ "entities": [{"name": "John", "type": "person"}],
78
+ "relationships": [{"from": "John", "to": "Acme Corp", "type": "works_at"}]
79
79
  }
80
80
  ]
81
81
  }
package/src/index.ts CHANGED
@@ -81,7 +81,7 @@ const TOOLS = [
81
81
  {
82
82
  name: "remember",
83
83
  description:
84
- "Store information with entities and relationships. Extract key people, organizations, and places from the content and pass them as entities. Include relationships between entities when mentioned (e.g., 'works_at', 'lives_in', 'knows').",
84
+ "Store NEW information the user shares. Extract entities (people, organizations, places) and relationships. Do NOT use for corrections - use edit_memory instead. Do NOT use before checking if info already exists - use recall first.",
85
85
  inputSchema: {
86
86
  type: "object" as const,
87
87
  properties: {
@@ -91,14 +91,14 @@ const TOOLS = [
91
91
  },
92
92
  importance: {
93
93
  type: "number",
94
- description: "0-1 score. Use 0.8+ for key facts (names, preferences, important events), 0.5 for general info, 0.3- for trivial mentions",
94
+ description: "0-1 score with anchors: 0.9=core identity (name, birthday, family), 0.8=major preferences/life events, 0.6=notable facts, 0.5=general info (default), 0.3=casual mentions, 0.1=trivial/ephemeral",
95
95
  minimum: 0,
96
96
  maximum: 1,
97
97
  default: 0.5,
98
98
  },
99
99
  emotional_weight: {
100
100
  type: "number",
101
- description: "0-1 emotional significance. Use 0.8+ for emotionally charged content, celebrations, losses. Affects memory retention.",
101
+ description: "0-1 emotional significance with anchors: 0.9=major life events (births, deaths, achievements), 0.7=celebrations/disappointments, 0.5=neutral (default), 0.3=mild sentiment, 0.1=purely factual",
102
102
  minimum: 0,
103
103
  maximum: 1,
104
104
  default: 0.5,
@@ -113,7 +113,7 @@ const TOOLS = [
113
113
  items: {
114
114
  type: "object",
115
115
  properties: {
116
- name: { type: "string", description: "Entity name (e.g., 'Boris Djordjevic', 'Google', 'Paris')" },
116
+ name: { type: "string", description: "Entity name (e.g., 'John Smith', 'Google', 'Paris')" },
117
117
  type: { type: "string", enum: ["person", "organization", "place"], description: "Entity type" },
118
118
  },
119
119
  required: ["name", "type"],
@@ -146,7 +146,7 @@ const TOOLS = [
146
146
  {
147
147
  name: "recall",
148
148
  description:
149
- "PRIMARY SEARCH TOOL. Use this FIRST when answering any question about stored information. Searches across all memories using semantic understanding, keywords, and knowledge graph connections. Returns relevant memories with context.",
149
+ "Search stored memories. Use FIRST before answering questions about the user, their preferences, history, or anything previously discussed. Also use before remember to check if information already exists.",
150
150
  inputSchema: {
151
151
  type: "object" as const,
152
152
  properties: {
@@ -177,13 +177,13 @@ const TOOLS = [
177
177
  },
178
178
  {
179
179
  name: "forget",
180
- description: "Delete a specific memory by its ID. Use only when explicitly asked to remove information.",
180
+ description: "Delete a memory by its ID. Use when user explicitly asks to remove or forget specific stored information. Get the memory ID from recall results first.",
181
181
  inputSchema: {
182
182
  type: "object" as const,
183
183
  properties: {
184
184
  id: {
185
185
  type: "string",
186
- description: "The memory ID to remove",
186
+ description: "The memory ID to delete (get this from recall results)",
187
187
  },
188
188
  },
189
189
  required: ["id"],
@@ -196,6 +196,37 @@ const TOOLS = [
196
196
  openWorldHint: false,
197
197
  },
198
198
  },
199
+ {
200
+ name: "edit_memory",
201
+ description: "Correct or update an existing memory. Use instead of forget+remember when fixing mistakes, updating outdated info, or adjusting importance. Preserves the memory's history and relationships.",
202
+ inputSchema: {
203
+ type: "object" as const,
204
+ properties: {
205
+ id: {
206
+ type: "string",
207
+ description: "The memory ID to edit (get this from recall results)",
208
+ },
209
+ content: {
210
+ type: "string",
211
+ description: "New content for the memory (replaces existing). Omit to keep current content.",
212
+ },
213
+ importance: {
214
+ type: "number",
215
+ description: "New importance (0-1): 0.9=core identity, 0.8=major, 0.5=normal, 0.3=minor. Omit to keep current.",
216
+ minimum: 0,
217
+ maximum: 1,
218
+ },
219
+ },
220
+ required: ["id"],
221
+ },
222
+ annotations: {
223
+ title: "Edit Memory",
224
+ readOnlyHint: false,
225
+ destructiveHint: false,
226
+ idempotentHint: true,
227
+ openWorldHint: false,
228
+ },
229
+ },
199
230
  {
200
231
  name: "engram_web",
201
232
  description: "Launch the Engram web interface for browsing, searching, and editing memories visually. Returns a URL to open in your browser.",
@@ -219,7 +250,7 @@ const TOOLS = [
219
250
  },
220
251
  {
221
252
  name: "consolidate",
222
- description: "Run memory consolidation to compress episodes into memories and memories into digests. Like sleep for the memory system. Use periodically or when requested.",
253
+ description: "Run memory consolidation to compress episodes into memories and memories into digests. Like sleep for the memory system. Requires ANTHROPIC_API_KEY. Use periodically or when explicitly requested.",
223
254
  inputSchema: {
224
255
  type: "object" as const,
225
256
  properties: {
@@ -236,7 +267,7 @@ const TOOLS = [
236
267
  readOnlyHint: false,
237
268
  destructiveHint: false,
238
269
  idempotentHint: false,
239
- openWorldHint: false,
270
+ openWorldHint: true, // Calls Anthropic API for consolidation
240
271
  },
241
272
  },
242
273
  ];
@@ -375,14 +406,72 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
375
406
  // Remove from semantic index
376
407
  await search.removeFromIndex(id);
377
408
 
378
- // Delete from database
379
- db.deleteMemory(id);
409
+ // Soft-delete: mark as disabled instead of hard delete
410
+ db.updateMemory(id, { disabled: true });
380
411
 
381
412
  return {
382
413
  content: [
383
414
  {
384
415
  type: "text" as const,
385
- text: JSON.stringify({ success: true, deleted_id: id }),
416
+ text: JSON.stringify({ success: true, disabled_id: id, message: "Memory disabled (soft-deleted)" }),
417
+ },
418
+ ],
419
+ };
420
+ }
421
+
422
+ case "edit_memory": {
423
+ const { id, content, importance } = args as {
424
+ id: string;
425
+ content?: string;
426
+ importance?: number;
427
+ };
428
+
429
+ const memory = db.getMemory(id);
430
+ if (!memory) {
431
+ return {
432
+ content: [
433
+ {
434
+ type: "text" as const,
435
+ text: JSON.stringify({ success: false, error: "Memory not found" }),
436
+ },
437
+ ],
438
+ };
439
+ }
440
+
441
+ // Build updates object
442
+ const updates: { content?: string; importance?: number } = {};
443
+ if (content !== undefined) updates.content = content;
444
+ if (importance !== undefined) updates.importance = importance;
445
+
446
+ if (Object.keys(updates).length === 0) {
447
+ return {
448
+ content: [
449
+ {
450
+ type: "text" as const,
451
+ text: JSON.stringify({ success: false, error: "No updates provided" }),
452
+ },
453
+ ],
454
+ };
455
+ }
456
+
457
+ // Update the memory
458
+ const updated = db.updateMemory(id, updates);
459
+
460
+ // Re-index if content changed
461
+ if (content !== undefined && updated) {
462
+ await search.removeFromIndex(id);
463
+ await search.indexMemory(updated);
464
+ }
465
+
466
+ return {
467
+ content: [
468
+ {
469
+ type: "text" as const,
470
+ text: JSON.stringify({
471
+ success: true,
472
+ memory_id: id,
473
+ updated_fields: Object.keys(updates),
474
+ }),
386
475
  },
387
476
  ],
388
477
  };
@@ -102,7 +102,7 @@ export class HybridSearch {
102
102
  includeGraph = true,
103
103
  bm25Weight = 1.0,
104
104
  semanticWeight = 1.0,
105
- graphWeight = 0.5,
105
+ graphWeight = 0.3,
106
106
  useReranking = true, // Default: reranking mode for better quality
107
107
  } = options;
108
108
 
@@ -257,22 +257,46 @@ export class HybridSearch {
257
257
  }
258
258
  }
259
259
 
260
+ /**
261
+ * Normalize a word for matching: lowercase, strip punctuation, handle possessives
262
+ * "John's" → "john", "Paris!" → "paris", "U.S.A." → "usa"
263
+ */
264
+ private normalizeWord(word: string): string {
265
+ return word
266
+ .toLowerCase()
267
+ .replace(/'s$/, '') // Remove possessives: john's → john
268
+ .replace(/[^\p{L}\p{N}]/gu, '') // Keep only letters/numbers (Unicode-safe)
269
+ .trim();
270
+ }
271
+
260
272
  /**
261
273
  * Graph-based search: find known entities in query, traverse graph
274
+ * Uses normalized word matching to handle punctuation and possessives
262
275
  */
263
276
  private async searchGraph(query: string): Promise<string[]> {
264
- // Find known entities whose names appear in the query
265
- const queryLower = query.toLowerCase();
277
+ // Tokenize and normalize query words
278
+ const queryWords = query.split(/\s+/)
279
+ .map(w => this.normalizeWord(w))
280
+ .filter(w => w.length > 0);
281
+ const queryWordSet = new Set(queryWords);
282
+
283
+ // Find entities whose normalized names match query words
266
284
  const allEntities = this.graph.listEntities(undefined, 500);
267
- const matchedEntities = allEntities.filter(e =>
268
- queryLower.includes(e.name.toLowerCase())
269
- );
285
+ const matchedEntities = allEntities.filter(e => {
286
+ const entityWords = e.name.split(/\s+/)
287
+ .map(w => this.normalizeWord(w))
288
+ .filter(w => w.length > 0);
289
+ // Entity matches if ALL its words appear in the query
290
+ // e.g., "john" matches entity "John" but not "John Smith"
291
+ // e.g., "john's friend" matches entity "John" (possessive handled)
292
+ return entityWords.every(w => queryWordSet.has(w));
293
+ });
270
294
 
271
295
  const memoryIds = new Set<string>();
272
296
 
273
297
  for (const entity of matchedEntities) {
274
- // Find related memory IDs through graph traversal
275
- const relatedIds = this.graph.findRelatedMemoryIds(entity.name, 2);
298
+ // Depth 1: only directly related memories, not transitive connections
299
+ const relatedIds = this.graph.findRelatedMemoryIds(entity.name, 1);
276
300
  relatedIds.forEach(id => memoryIds.add(id));
277
301
  }
278
302
 
@@ -19,6 +19,7 @@ export interface Memory {
19
19
  last_accessed: Date | null;
20
20
  stability: number; // Ebbinghaus stability score (increases with recalls)
21
21
  emotional_weight: number; // Salience: emotional significance 0-1
22
+ disabled: boolean; // Soft-deleted: excluded from search results
22
23
  }
23
24
 
24
25
  /**
@@ -287,6 +288,9 @@ export class EngramDatabase {
287
288
  if (!memoryColumns.has("emotional_weight")) {
288
289
  this.db.exec("ALTER TABLE memories ADD COLUMN emotional_weight REAL DEFAULT 0.5");
289
290
  }
291
+ if (!memoryColumns.has("disabled")) {
292
+ this.db.exec("ALTER TABLE memories ADD COLUMN disabled INTEGER DEFAULT 0");
293
+ }
290
294
  }
291
295
 
292
296
  // ============ Memory Operations ============
@@ -322,7 +326,7 @@ export class EngramDatabase {
322
326
  return row ? this.rowToMemory(row) : null;
323
327
  }
324
328
 
325
- updateMemory(id: string, updates: Partial<Pick<Memory, "content" | "importance">>): Memory | null {
329
+ updateMemory(id: string, updates: Partial<Pick<Memory, "content" | "importance" | "disabled">>): Memory | null {
326
330
  const sets: string[] = [];
327
331
  const values: unknown[] = [];
328
332
 
@@ -334,6 +338,10 @@ export class EngramDatabase {
334
338
  sets.push("importance = ?");
335
339
  values.push(updates.importance);
336
340
  }
341
+ if (updates.disabled !== undefined) {
342
+ sets.push("disabled = ?");
343
+ values.push(updates.disabled ? 1 : 0);
344
+ }
337
345
 
338
346
  if (sets.length === 0) return this.getMemory(id);
339
347
 
@@ -364,8 +372,11 @@ export class EngramDatabase {
364
372
  `).run(id);
365
373
  }
366
374
 
367
- getAllMemories(limit: number = 1000): Memory[] {
368
- const rows = this.stmt("SELECT * FROM memories ORDER BY timestamp DESC LIMIT ?").all(limit) as Record<string, unknown>[];
375
+ getAllMemories(limit: number = 1000, includeDisabled: boolean = false): Memory[] {
376
+ const sql = includeDisabled
377
+ ? "SELECT * FROM memories ORDER BY timestamp DESC LIMIT ?"
378
+ : "SELECT * FROM memories WHERE disabled = 0 ORDER BY timestamp DESC LIMIT ?";
379
+ const rows = this.stmt(sql).all(limit) as Record<string, unknown>[];
369
380
  return rows.map((row) => this.rowToMemory(row));
370
381
  }
371
382
 
@@ -475,7 +486,7 @@ export class EngramDatabase {
475
486
  SELECT m.*, bm25(memories_fts) as score
476
487
  FROM memories_fts fts
477
488
  JOIN memories m ON fts.rowid = m.rowid
478
- WHERE memories_fts MATCH ?
489
+ WHERE memories_fts MATCH ? AND m.disabled = 0
479
490
  ORDER BY score
480
491
  LIMIT ?
481
492
  `).all(escapedQuery, limit) as Array<Record<string, unknown>>;
@@ -530,7 +541,7 @@ export class EngramDatabase {
530
541
 
531
542
  /**
532
543
  * Find a similar entity using fuzzy matching
533
- * Catches "Boris D" matching "Boris Djordjevic", "John" matching "John Smith"
544
+ * Catches "John D" matching "John Doe", "Jane" matching "Jane Smith"
534
545
  */
535
546
  findSimilarEntity(name: string, threshold: number = 0.8): Entity | null {
536
547
  const normalizedName = name.toLowerCase().trim();
@@ -576,7 +587,7 @@ export class EngramDatabase {
576
587
  // Exact match
577
588
  if (full1 === full2) return 1.0;
578
589
 
579
- // One is prefix of the other (e.g., "Boris" vs "Boris Djordjevic")
590
+ // One is prefix of the other (e.g., "John" vs "John Doe")
580
591
  if (full1.startsWith(full2 + " ") || full2.startsWith(full1 + " ")) {
581
592
  return 0.9;
582
593
  }
@@ -589,7 +600,7 @@ export class EngramDatabase {
589
600
  return 0.7 + (0.2 * shorter / longer);
590
601
  }
591
602
 
592
- // Check for abbreviated names (e.g., "Boris D" vs "Boris Djordjevic")
603
+ // Check for abbreviated names (e.g., "John D" vs "John Doe")
593
604
  if (words1.length >= 2 && words2.length >= 2) {
594
605
  const last1 = words1[words1.length - 1];
595
606
  const last2 = words2[words2.length - 1];
@@ -1099,6 +1110,7 @@ export class EngramDatabase {
1099
1110
  last_accessed: row.last_accessed ? new Date(row.last_accessed as string) : null,
1100
1111
  stability: (row.stability as number) ?? 1.0,
1101
1112
  emotional_weight: (row.emotional_weight as number) ?? 0.5,
1113
+ disabled: Boolean(row.disabled),
1102
1114
  };
1103
1115
  }
1104
1116