@199-bio/engram 0.4.0 → 0.4.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"knowledge-graph.d.ts","sourceRoot":"","sources":["../../src/graph/knowledge-graph.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,cAAc,EACd,MAAM,EACN,WAAW,EACX,QAAQ,EACT,MAAM,wBAAwB,CAAC;AAGhC,MAAM,WAAW,iBAAkB,SAAQ,MAAM;IAC/C,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,aAAa,EAAE,KAAK,CAAC,QAAQ,GAAG;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1D,WAAW,EAAE,KAAK,CAAC,QAAQ,GAAG;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE,WAAW,EAAE,CAAC;CAC7B;AAED,qBAAa,cAAc;IACb,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,cAAc;IAItC;;OAEG;IACH,iBAAiB,CACf,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,MAAM,CAAC,MAAM,CAAY,GAC9B,MAAM;IAMT;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI;IAoC5D;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE;IAI5D;;OAEG;IACH,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,GAAE,MAAY,GAAG,MAAM,EAAE;IAMlE;;OAEG;IACH,cAAc,CACZ,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,EACf,cAAc,CAAC,EAAE,MAAM,EACvB,UAAU,GAAE,MAAY,GACvB,WAAW;IAWd;;OAEG;IACH,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,WAAW,EAAE;IAWtD;;OAEG;IACH,MAAM,CACJ,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,QAAQ;IAgBX;;OAEG;IACH,YAAY,CACV,cAAc,EAAE,MAAM,EACtB,SAAS,GAAE,MAAM,GAAG,IAAI,GAAG,MAAe,GACzC,QAAQ,EAAE;IAWb;;OAEG;IACH,QAAQ,CACN,cAAc,EAAE,MAAM,EACtB,KAAK,GAAE,MAAU,EACjB,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,cAAc,GAAG,IAAI;IAgBxB;;OAEG;IACH,eAAe,CACb,IAAI,EAAE,MAAM,EACZ,cAAc,CAAC,EAAE,MAAM,GACtB;QAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,YAAY,EAAE,WAAW,EAAE,CAAA;KAAE;IAyCtD;;OAEG;IACH,oBAAoB,CAClB,cAAc,EAAE,MAAM,EACtB,KAAK,GAAE,MAAU,GAChB,MAAM,EAAE;CAcZ"}
1
+ {"version":3,"file":"knowledge-graph.d.ts","sourceRoot":"","sources":["../../src/graph/knowledge-graph.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,cAAc,EACd,MAAM,EACN,WAAW,EACX,QAAQ,EACT,MAAM,wBAAwB,CAAC;AAEhC,MAAM,WAAW,iBAAkB,SAAQ,MAAM;IAC/C,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,aAAa,EAAE,KAAK,CAAC,QAAQ,GAAG;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1D,WAAW,EAAE,KAAK,CAAC,QAAQ,GAAG;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE,WAAW,EAAE,CAAC;CAC7B;AAED,qBAAa,cAAc;IACb,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,cAAc;IAItC;;OAEG;IACH,iBAAiB,CACf,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,MAAM,CAAC,MAAM,CAAY,GAC9B,MAAM;IAMT;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI;IAoC5D;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE;IAI5D;;OAEG;IACH,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,GAAE,MAAY,GAAG,MAAM,EAAE;IAMlE;;OAEG;IACH,cAAc,CACZ,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,EACf,cAAc,CAAC,EAAE,MAAM,EACvB,UAAU,GAAE,MAAY,GACvB,WAAW;IAWd;;OAEG;IACH,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,WAAW,EAAE;IAWtD;;OAEG;IACH,MAAM,CACJ,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,QAAQ;IAgBX;;OAEG;IACH,YAAY,CACV,cAAc,EAAE,MAAM,EACtB,SAAS,GAAE,MAAM,GAAG,IAAI,GAAG,MAAe,GACzC,QAAQ,EAAE;IAWb;;OAEG;IACH,QAAQ,CACN,cAAc,EAAE,MAAM,EACtB,KAAK,GAAE,MAAU,EACjB,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,cAAc,GAAG,IAAI;IAcxB;;OAEG;IACH,oBAAoB,CAClB,cAAc,EAAE,MAAM,EACtB,KAAK,GAAE,MAAU,GAChB,MAAM,EAAE;CAcZ"}
package/dist/index.js CHANGED
@@ -42,7 +42,7 @@ async function initialize() {
42
42
  // ============ MCP Server ============
43
43
  const server = new Server({
44
44
  name: "engram",
45
- version: "0.4.0",
45
+ version: "0.4.2",
46
46
  }, {
47
47
  capabilities: {
48
48
  tools: {},
@@ -53,26 +53,46 @@ const server = new Server({
53
53
  const TOOLS = [
54
54
  {
55
55
  name: "remember",
56
- description: "PRIMARY STORAGE TOOL. Use this for ALL new information - conversations, facts, observations, notes. Automatically extracts people, organizations, and places as entities and creates relationships. Do NOT also call create_entity/observe/relate - remember handles entity extraction automatically. Only use remember once per piece of information.",
56
+ 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').",
57
57
  inputSchema: {
58
58
  type: "object",
59
59
  properties: {
60
60
  content: {
61
61
  type: "string",
62
- description: "The information to store - can be a conversation snippet, fact, observation, or note",
63
- },
64
- source: {
65
- type: "string",
66
- description: "Source of the memory (e.g., 'conversation', 'note', 'import')",
67
- default: "conversation",
62
+ description: "The information to store",
68
63
  },
69
64
  importance: {
70
65
  type: "number",
71
- description: "Importance score from 0 to 1 (higher = more important). Use 0.7+ for key facts, 0.3- for casual mentions",
66
+ 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
67
  minimum: 0,
73
68
  maximum: 1,
74
69
  default: 0.5,
75
70
  },
71
+ entities: {
72
+ type: "array",
73
+ description: "Key entities mentioned (people, organizations, places). Only include clear, specific named entities.",
74
+ items: {
75
+ type: "object",
76
+ properties: {
77
+ name: { type: "string", description: "Entity name (e.g., 'Boris Djordjevic', 'Google', 'Paris')" },
78
+ type: { type: "string", enum: ["person", "organization", "place"], description: "Entity type" },
79
+ },
80
+ required: ["name", "type"],
81
+ },
82
+ },
83
+ relationships: {
84
+ type: "array",
85
+ description: "Relationships between entities mentioned in the content",
86
+ items: {
87
+ type: "object",
88
+ properties: {
89
+ from: { type: "string", description: "Source entity name" },
90
+ to: { type: "string", description: "Target entity name" },
91
+ type: { type: "string", description: "Relationship type (e.g., 'works_at', 'lives_in', 'sibling_of', 'knows')" },
92
+ },
93
+ required: ["from", "to", "type"],
94
+ },
95
+ },
76
96
  },
77
97
  required: ["content"],
78
98
  },
@@ -168,13 +188,33 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
168
188
  try {
169
189
  switch (name) {
170
190
  case "remember": {
171
- const { content, source = "conversation", importance = 0.5 } = args;
191
+ const { content, source = "conversation", importance = 0.5, entities: providedEntities = [], relationships: providedRelationships = [], } = args;
172
192
  // Create memory
173
193
  const memory = db.createMemory(content, source, importance);
174
194
  // Index for semantic search
175
195
  await search.indexMemory(memory);
176
- // Extract and store entities/relationships
177
- const { entities, observations } = graph.extractAndStore(content, memory.id);
196
+ // Store Claude-provided entities and link to memory
197
+ const storedEntities = [];
198
+ for (const ent of providedEntities) {
199
+ const entity = graph.getOrCreateEntity(ent.name, ent.type);
200
+ storedEntities.push(entity.name);
201
+ // Create observation linking entity to this memory
202
+ db.addObservation(entity.id, content, memory.id, 1.0);
203
+ }
204
+ // Store Claude-provided relationships
205
+ const storedRelations = [];
206
+ for (const rel of providedRelationships) {
207
+ try {
208
+ // Ensure both entities exist (create if not provided explicitly)
209
+ const fromEntity = graph.getOrCreateEntity(rel.from, "person");
210
+ const toEntity = graph.getOrCreateEntity(rel.to, "person");
211
+ graph.relate(fromEntity.name, toEntity.name, rel.type);
212
+ storedRelations.push(`${rel.from} -[${rel.type}]-> ${rel.to}`);
213
+ }
214
+ catch {
215
+ // Skip invalid relationships
216
+ }
217
+ }
178
218
  return {
179
219
  content: [
180
220
  {
@@ -182,8 +222,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
182
222
  text: JSON.stringify({
183
223
  success: true,
184
224
  memory_id: memory.id,
185
- entities_extracted: entities.map((e) => e.name),
186
- observations_created: observations.length,
225
+ entities_stored: storedEntities,
226
+ relationships_stored: storedRelations,
187
227
  }, null, 2),
188
228
  },
189
229
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"hybrid.d.ts","sourceRoot":"","sources":["../../src/retrieval/hybrid.ts"],"names":[],"mappings":"AAAA;;;GAGG;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;AAGzF,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,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;IAqHhC;;OAEG;YACW,UAAU;IASxB;;OAEG;YACW,cAAc;IAS5B;;OAEG;YACW,WAAW;IAezB;;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;;;GAGG;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,OAAO,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,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;IAqHhC;;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 +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":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-handler.d.ts","sourceRoot":"","sources":["../../src/web/chat-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,cAAc,EAAkB,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAiLtD,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,mBAAmB,CAAgC;gBAE/C,OAAO,EAAE;QACnB,EAAE,EAAE,cAAc,CAAC;QACnB,KAAK,EAAE,cAAc,CAAC;QACtB,MAAM,EAAE,YAAY,CAAC;KACtB;IAWD,YAAY,IAAI,OAAO;IAIvB,YAAY,IAAI,IAAI;IAId,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAgFlC,WAAW;CAgL1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAiBtD,UAAU,gBAAgB;IACxB,EAAE,EAAE,cAAc,CAAC;IACnB,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,IAAI,CAAS;gBAET,OAAO,EAAE,gBAAgB;IAO/B,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAkB9B,IAAI,IAAI,IAAI;YAOE,aAAa;YA+Bb,SAAS;YAyKT,WAAW;IAgCzB,OAAO,CAAC,SAAS;CAclB"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAiBtD,UAAU,gBAAgB;IACxB,EAAE,EAAE,cAAc,CAAC;IACnB,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,IAAI,CAAc;IAC1B,OAAO,CAAC,IAAI,CAAS;gBAET,OAAO,EAAE,gBAAgB;IAY/B,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAkB9B,IAAI,IAAI,IAAI;YAOE,aAAa;YA+Bb,SAAS;YAwMT,WAAW;IAgCzB,OAAO,CAAC,SAAS;CAclB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@199-bio/engram",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
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",
@@ -46,6 +46,7 @@
46
46
  "node": ">=18.0.0"
47
47
  },
48
48
  "dependencies": {
49
+ "@anthropic-ai/sdk": "^0.71.2",
49
50
  "@modelcontextprotocol/sdk": "^1.25.0",
50
51
  "better-sqlite3": "^11.10.0",
51
52
  "chrono-node": "^2.7.0",
@@ -1,2 +1 @@
1
- export * from "./extractor.js";
2
1
  export * from "./knowledge-graph.js";
@@ -9,7 +9,6 @@ import {
9
9
  Observation,
10
10
  Relation,
11
11
  } from "../storage/database.js";
12
- import { entityExtractor, ExtractedEntity } from "./extractor.js";
13
12
 
14
13
  export interface EntityWithDetails extends Entity {
15
14
  observations: Observation[];
@@ -191,55 +190,6 @@ export class KnowledgeGraph {
191
190
  };
192
191
  }
193
192
 
194
- // ============ Auto-extraction ============
195
-
196
- /**
197
- * Extract entities from text and add them to the graph
198
- */
199
- extractAndStore(
200
- text: string,
201
- sourceMemoryId?: string
202
- ): { entities: Entity[]; observations: Observation[] } {
203
- const extracted = entityExtractor.extractAll(text);
204
- const entities: Entity[] = [];
205
- const observations: Observation[] = [];
206
-
207
- for (const ext of extracted) {
208
- // Only store high-confidence extractions
209
- if (ext.confidence < 0.5) continue;
210
-
211
- // Get or create entity
212
- const entity = this.getOrCreateEntity(ext.name, ext.type);
213
- entities.push(entity);
214
-
215
- // Create observation linking this entity to the memory content
216
- const obs = this.db.addObservation(
217
- entity.id,
218
- text,
219
- sourceMemoryId || null,
220
- ext.confidence
221
- );
222
- observations.push(obs);
223
- }
224
-
225
- // Extract and create relationships
226
- const relationships = entityExtractor.extractRelationships(text);
227
- for (const rel of relationships) {
228
- try {
229
- // Ensure both entities exist
230
- const fromEntity = this.getOrCreateEntity(rel.subject, "person");
231
- const toEntity = this.getOrCreateEntity(rel.object, "person");
232
-
233
- // Create the relation
234
- this.db.createRelation(fromEntity.id, toEntity.id, rel.relation);
235
- } catch {
236
- // Silently ignore relation creation failures
237
- }
238
- }
239
-
240
- return { entities, observations };
241
- }
242
-
243
193
  /**
244
194
  * Find memories related to an entity by traversing the graph
245
195
  */
package/src/index.ts CHANGED
@@ -60,7 +60,7 @@ async function initialize(): Promise<void> {
60
60
  const server = new Server(
61
61
  {
62
62
  name: "engram",
63
- version: "0.4.0",
63
+ version: "0.4.2",
64
64
  },
65
65
  {
66
66
  capabilities: {
@@ -75,26 +75,46 @@ const TOOLS = [
75
75
  {
76
76
  name: "remember",
77
77
  description:
78
- "PRIMARY STORAGE TOOL. Use this for ALL new information - conversations, facts, observations, notes. Automatically extracts people, organizations, and places as entities and creates relationships. Do NOT also call create_entity/observe/relate - remember handles entity extraction automatically. Only use remember once per piece of information.",
78
+ "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').",
79
79
  inputSchema: {
80
80
  type: "object" as const,
81
81
  properties: {
82
82
  content: {
83
83
  type: "string",
84
- description: "The information to store - can be a conversation snippet, fact, observation, or note",
85
- },
86
- source: {
87
- type: "string",
88
- description: "Source of the memory (e.g., 'conversation', 'note', 'import')",
89
- default: "conversation",
84
+ description: "The information to store",
90
85
  },
91
86
  importance: {
92
87
  type: "number",
93
- description: "Importance score from 0 to 1 (higher = more important). Use 0.7+ for key facts, 0.3- for casual mentions",
88
+ 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
89
  minimum: 0,
95
90
  maximum: 1,
96
91
  default: 0.5,
97
92
  },
93
+ entities: {
94
+ type: "array",
95
+ description: "Key entities mentioned (people, organizations, places). Only include clear, specific named entities.",
96
+ items: {
97
+ type: "object",
98
+ properties: {
99
+ name: { type: "string", description: "Entity name (e.g., 'Boris Djordjevic', 'Google', 'Paris')" },
100
+ type: { type: "string", enum: ["person", "organization", "place"], description: "Entity type" },
101
+ },
102
+ required: ["name", "type"],
103
+ },
104
+ },
105
+ relationships: {
106
+ type: "array",
107
+ description: "Relationships between entities mentioned in the content",
108
+ items: {
109
+ type: "object",
110
+ properties: {
111
+ from: { type: "string", description: "Source entity name" },
112
+ to: { type: "string", description: "Target entity name" },
113
+ type: { type: "string", description: "Relationship type (e.g., 'works_at', 'lives_in', 'sibling_of', 'knows')" },
114
+ },
115
+ required: ["from", "to", "type"],
116
+ },
117
+ },
98
118
  },
99
119
  required: ["content"],
100
120
  },
@@ -194,10 +214,18 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
194
214
  try {
195
215
  switch (name) {
196
216
  case "remember": {
197
- const { content, source = "conversation", importance = 0.5 } = args as {
217
+ const {
218
+ content,
219
+ source = "conversation",
220
+ importance = 0.5,
221
+ entities: providedEntities = [],
222
+ relationships: providedRelationships = [],
223
+ } = args as {
198
224
  content: string;
199
225
  source?: string;
200
226
  importance?: number;
227
+ entities?: Array<{ name: string; type: "person" | "organization" | "place" }>;
228
+ relationships?: Array<{ from: string; to: string; type: string }>;
201
229
  };
202
230
 
203
231
  // Create memory
@@ -206,8 +234,28 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
206
234
  // Index for semantic search
207
235
  await search.indexMemory(memory);
208
236
 
209
- // Extract and store entities/relationships
210
- const { entities, observations } = graph.extractAndStore(content, memory.id);
237
+ // Store Claude-provided entities and link to memory
238
+ const storedEntities: string[] = [];
239
+ for (const ent of providedEntities) {
240
+ const entity = graph.getOrCreateEntity(ent.name, ent.type);
241
+ storedEntities.push(entity.name);
242
+ // Create observation linking entity to this memory
243
+ db.addObservation(entity.id, content, memory.id, 1.0);
244
+ }
245
+
246
+ // Store Claude-provided relationships
247
+ const storedRelations: string[] = [];
248
+ for (const rel of providedRelationships) {
249
+ try {
250
+ // Ensure both entities exist (create if not provided explicitly)
251
+ const fromEntity = graph.getOrCreateEntity(rel.from, "person");
252
+ const toEntity = graph.getOrCreateEntity(rel.to, "person");
253
+ graph.relate(fromEntity.name, toEntity.name, rel.type);
254
+ storedRelations.push(`${rel.from} -[${rel.type}]-> ${rel.to}`);
255
+ } catch {
256
+ // Skip invalid relationships
257
+ }
258
+ }
211
259
 
212
260
  return {
213
261
  content: [
@@ -216,8 +264,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
216
264
  text: JSON.stringify({
217
265
  success: true,
218
266
  memory_id: memory.id,
219
- entities_extracted: entities.map((e) => e.name),
220
- observations_created: observations.length,
267
+ entities_stored: storedEntities,
268
+ relationships_stored: storedRelations,
221
269
  }, null, 2),
222
270
  },
223
271
  ],
@@ -6,7 +6,6 @@
6
6
  import { EngramDatabase, Memory } from "../storage/database.js";
7
7
  import { KnowledgeGraph } from "../graph/knowledge-graph.js";
8
8
  import { ColBERTRetriever, SimpleRetriever, SearchResult, Document } from "./colbert.js";
9
- import { entityExtractor } from "../graph/extractor.js";
10
9
 
11
10
  export interface HybridSearchResult {
12
11
  memory: Memory;
@@ -183,15 +182,19 @@ export class HybridSearch {
183
182
  }
184
183
 
185
184
  /**
186
- * Graph-based search: find entities in query, traverse graph
185
+ * Graph-based search: find known entities in query, traverse graph
187
186
  */
188
187
  private async searchGraph(query: string): Promise<string[]> {
189
- // Extract entities from query
190
- const entities = entityExtractor.extractAll(query);
188
+ // Find known entities whose names appear in the query
189
+ const queryLower = query.toLowerCase();
190
+ const allEntities = this.graph.listEntities(undefined, 500);
191
+ const matchedEntities = allEntities.filter(e =>
192
+ queryLower.includes(e.name.toLowerCase())
193
+ );
191
194
 
192
195
  const memoryIds = new Set<string>();
193
196
 
194
- for (const entity of entities) {
197
+ for (const entity of matchedEntities) {
195
198
  // Find related memory IDs through graph traversal
196
199
  const relatedIds = this.graph.findRelatedMemoryIds(entity.name, 2);
197
200
  relatedIds.forEach(id => memoryIds.add(id));
@@ -471,6 +471,18 @@ export class EngramDatabase {
471
471
  return result.changes > 0;
472
472
  }
473
473
 
474
+ updateEntity(id: string, updates: { name?: string; type?: Entity["type"] }): Entity | null {
475
+ const entity = this.getEntity(id);
476
+ if (!entity) return null;
477
+
478
+ const newName = updates.name ?? entity.name;
479
+ const newType = updates.type ?? entity.type;
480
+
481
+ const stmt = this.db.prepare("UPDATE entities SET name = ?, type = ? WHERE id = ?");
482
+ stmt.run(newName, newType, id);
483
+ return this.getEntity(id);
484
+ }
485
+
474
486
  // ============ Observation Operations ============
475
487
 
476
488
  addObservation(