@raviolelabs/engram-mcp 0.2.0 → 0.2.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.
Files changed (38) hide show
  1. package/package.json +3 -3
  2. package/dist/private/algorithms/chunker-semantic.d.ts +0 -3
  3. package/dist/private/algorithms/chunker-semantic.d.ts.map +0 -1
  4. package/dist/private/algorithms/chunker-semantic.js +0 -70
  5. package/dist/private/algorithms/chunker-semantic.js.map +0 -1
  6. package/dist/private/algorithms/find-related-smart.d.ts +0 -4
  7. package/dist/private/algorithms/find-related-smart.d.ts.map +0 -1
  8. package/dist/private/algorithms/find-related-smart.js +0 -52
  9. package/dist/private/algorithms/find-related-smart.js.map +0 -1
  10. package/dist/private/algorithms/graph-semantic-edges.d.ts +0 -4
  11. package/dist/private/algorithms/graph-semantic-edges.d.ts.map +0 -1
  12. package/dist/private/algorithms/graph-semantic-edges.js +0 -38
  13. package/dist/private/algorithms/graph-semantic-edges.js.map +0 -1
  14. package/dist/private/algorithms/search-all-smart.d.ts +0 -9
  15. package/dist/private/algorithms/search-all-smart.d.ts.map +0 -1
  16. package/dist/private/algorithms/search-all-smart.js +0 -62
  17. package/dist/private/algorithms/search-all-smart.js.map +0 -1
  18. package/dist/private/index.d.ts +0 -7
  19. package/dist/private/index.d.ts.map +0 -1
  20. package/dist/private/index.js +0 -39
  21. package/dist/private/index.js.map +0 -1
  22. package/dist/private/prompts/extraction-system.d.ts +0 -2
  23. package/dist/private/prompts/extraction-system.d.ts.map +0 -1
  24. package/dist/private/prompts/extraction-system.js +0 -15
  25. package/dist/private/prompts/extraction-system.js.map +0 -1
  26. package/dist/private/prompts/suggest-properties.d.ts +0 -2
  27. package/dist/private/prompts/suggest-properties.d.ts.map +0 -1
  28. package/dist/private/prompts/suggest-properties.js +0 -18
  29. package/dist/private/prompts/suggest-properties.js.map +0 -1
  30. package/dist/private/tests/find-related-smart.test.d.ts +0 -2
  31. package/dist/private/tests/find-related-smart.test.d.ts.map +0 -1
  32. package/dist/private/tests/find-related-smart.test.js +0 -86
  33. package/dist/private/tests/find-related-smart.test.js.map +0 -1
  34. package/dist/private/tests/property-extractor-smart.test.d.ts +0 -2
  35. package/dist/private/tests/property-extractor-smart.test.d.ts.map +0 -1
  36. package/dist/private/tests/property-extractor-smart.test.js +0 -26
  37. package/dist/private/tests/property-extractor-smart.test.js.map +0 -1
  38. package/src/private/README.md +0 -49
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@raviolelabs/engram-mcp",
3
- "version": "0.2.0",
4
- "description": "EngramMCP \u2014 local-first semantic memory layer for AI agents",
3
+ "version": "0.2.2",
4
+ "description": "EngramMCP local-first semantic memory layer for AI agents",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "bin": {
@@ -125,4 +125,4 @@
125
125
  "cursor"
126
126
  ],
127
127
  "author": "RavioleLabs <hello@raviolelabs.com> (https://raviolelabs.com)"
128
- }
128
+ }
@@ -1,3 +0,0 @@
1
- import type { ChunkOptions } from '../../memory/core/chunker.js';
2
- export declare function chunkTextSemantic(text: string, opts?: ChunkOptions): Promise<string[]>;
3
- //# sourceMappingURL=chunker-semantic.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chunker-semantic.d.ts","sourceRoot":"","sources":["../../../src/private/algorithms/chunker-semantic.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AA6BjE,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,YAAY,GAClB,OAAO,CAAC,MAAM,EAAE,CAAC,CAuCnB"}
@@ -1,70 +0,0 @@
1
- // src/private/algorithms/chunker-semantic.ts
2
- //
3
- // Semantic-boundary chunking via local Ollama topic-shift detection.
4
- // OSS basic (chunker.ts) splits by paragraph + sentence with fixed max-chars.
5
- // This version clusters paragraphs by predicted topic shifts into cohesive chunks.
6
- //
7
- import { chunkText as chunkTextBasic } from '../../memory/core/chunker.js';
8
- const OLLAMA_BASE_URL = 'http://localhost:11434';
9
- const SHIFT_MODEL = 'llama3.2:3b';
10
- const TOPIC_SHIFT_PROMPT = (paraA, paraB) => `Does the following paragraph represent a topic shift from the previous one? Reply with only "yes" or "no".\n\nPrevious paragraph:\n${paraA.slice(0, 300)}\n\nNext paragraph:\n${paraB.slice(0, 300)}`;
11
- async function predictTopicShift(paraA, paraB) {
12
- try {
13
- const res = await fetch(`${OLLAMA_BASE_URL}/v1/chat/completions`, {
14
- method: 'POST',
15
- headers: { 'Content-Type': 'application/json' },
16
- body: JSON.stringify({
17
- model: SHIFT_MODEL,
18
- messages: [{ role: 'user', content: TOPIC_SHIFT_PROMPT(paraA, paraB) }],
19
- temperature: 0,
20
- max_tokens: 3,
21
- }),
22
- signal: AbortSignal.timeout(10_000),
23
- });
24
- if (!res.ok)
25
- return false;
26
- const data = (await res.json());
27
- const answer = data.choices?.[0]?.message?.content?.toLowerCase().trim() ?? '';
28
- return answer.startsWith('yes');
29
- }
30
- catch {
31
- return false;
32
- }
33
- }
34
- export async function chunkTextSemantic(text, opts) {
35
- // Fall back to basic for short texts
36
- if (text.length <= (opts?.maxChars ?? 1500)) {
37
- return chunkTextBasic(text, opts);
38
- }
39
- const paragraphs = text
40
- .split(/\n\s*\n/)
41
- .map((p) => p.trim())
42
- .filter((p) => p.length > 0);
43
- if (paragraphs.length <= 2) {
44
- return chunkTextBasic(text, opts);
45
- }
46
- // Predict topic shifts between consecutive paragraphs
47
- const shifts = [false]; // first paragraph never shifts
48
- for (let i = 1; i < paragraphs.length; i++) {
49
- const isShift = await predictTopicShift(paragraphs[i - 1], paragraphs[i]);
50
- shifts.push(isShift);
51
- }
52
- // Cluster paragraphs by topic boundaries
53
- const chunks = [];
54
- let current = paragraphs[0];
55
- const maxChars = opts?.maxChars ?? 1500;
56
- for (let i = 1; i < paragraphs.length; i++) {
57
- const wouldExceed = current.length + paragraphs[i].length + 2 > maxChars;
58
- if (shifts[i] || wouldExceed) {
59
- chunks.push(current.trim());
60
- current = paragraphs[i];
61
- }
62
- else {
63
- current = current + '\n\n' + paragraphs[i];
64
- }
65
- }
66
- if (current.trim())
67
- chunks.push(current.trim());
68
- return chunks.filter((c) => c.length > 0);
69
- }
70
- //# sourceMappingURL=chunker-semantic.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chunker-semantic.js","sourceRoot":"","sources":["../../../src/private/algorithms/chunker-semantic.ts"],"names":[],"mappings":"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"}
@@ -1,4 +0,0 @@
1
- import type { MemoryStore } from '../../memory/core/store.js';
2
- import type { SearchResult } from '../../types.js';
3
- export declare function findRelatedSmart(store: MemoryStore, memoryId: string, limit?: number): Promise<SearchResult[]>;
4
- //# sourceMappingURL=find-related-smart.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"find-related-smart.d.ts","sourceRoot":"","sources":["../../../src/private/algorithms/find-related-smart.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAInD,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,MAAM,EAChB,KAAK,SAAK,GACT,OAAO,CAAC,YAAY,EAAE,CAAC,CA0DzB"}
@@ -1,52 +0,0 @@
1
- // src/private/algorithms/find-related-smart.ts
2
- //
3
- // Smart findRelated: combines semantic similarity + reverse-wikilinks with dedup.
4
- // OSS basic (store.findRelatedBasic) only uses wikilinks.
5
- //
6
- import { getDb } from '../../db/index.js';
7
- const SEMANTIC_THRESHOLD = 0.5;
8
- export async function findRelatedSmart(store, memoryId, limit = 10) {
9
- const source = store.getById(memoryId);
10
- if (!source)
11
- return [];
12
- // Signal 1: semantic similarity
13
- const semantic = await store.search(source.type, source.content.slice(0, 2000), limit + 5);
14
- const semanticFiltered = semantic.filter((r) => r.memory.id !== memoryId && r.score >= SEMANTIC_THRESHOLD);
15
- // Signal 2: reverse-wikilinks — memories whose content contains [[source.title]] or [[source.id]]
16
- const target = source.properties.title ?? source.id;
17
- const wikilinked = getDb()
18
- .prepare(`SELECT id, type, source_id, content, content_hash, properties_json,
19
- wikilinks_json, related_ids_json, embedding_model
20
- FROM memories
21
- WHERE content LIKE ? AND id <> ?
22
- LIMIT ?`)
23
- .all(`%[[${target}]]%`, memoryId, limit);
24
- const wikiResults = wikilinked.map((row) => ({
25
- memory: {
26
- id: row.id,
27
- type: row.type,
28
- source_id: row.source_id,
29
- content: row.content,
30
- content_hash: row.content_hash,
31
- properties: JSON.parse(row.properties_json),
32
- wikilinks: JSON.parse(row.wikilinks_json),
33
- related_ids: JSON.parse(row.related_ids_json),
34
- embedding_model: row.embedding_model,
35
- },
36
- score: 1.0, // explicit wikilink — high confidence
37
- snippet: row.content.slice(0, 200),
38
- }));
39
- // Merge: wikilinks first, then semantic; dedup by id
40
- const seen = new Set();
41
- const merged = [];
42
- for (const r of [...wikiResults, ...semanticFiltered]) {
43
- if (seen.has(r.memory.id))
44
- continue;
45
- seen.add(r.memory.id);
46
- merged.push(r);
47
- if (merged.length >= limit)
48
- break;
49
- }
50
- return merged;
51
- }
52
- //# sourceMappingURL=find-related-smart.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"find-related-smart.js","sourceRoot":"","sources":["../../../src/private/algorithms/find-related-smart.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,EAAE;AACF,kFAAkF;AAClF,0DAA0D;AAC1D,EAAE;AACF,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAI1C,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAE/B,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAkB,EAClB,QAAgB,EAChB,KAAK,GAAG,EAAE;IAEV,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IAEvB,gCAAgC;IAChC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IAC3F,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CACtC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,IAAI,kBAAkB,CACjE,CAAC;IAEF,kGAAkG;IAClG,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI,MAAM,CAAC,EAAE,CAAC;IACpD,MAAM,UAAU,GAAG,KAAK,EAAE;SACvB,OAAO,CACN;;;;eAIS,CACV;SACA,GAAG,CAAC,MAAM,MAAM,KAAK,EAAE,QAAQ,EAAE,KAAK,CAUvC,CAAC;IAEH,MAAM,WAAW,GAAmB,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC3D,MAAM,EAAE;YACN,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,YAAY,EAAE,GAAG,CAAC,YAAY;YAC9B,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC;YAC3C,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC;YACzC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC;YAC7C,eAAe,EAAE,GAAG,CAAC,eAAe;SACrC;QACD,KAAK,EAAE,GAAG,EAAE,sCAAsC;QAClD,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;KACnC,CAAC,CAAC,CAAC;IAEJ,qDAAqD;IACrD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,KAAK,MAAM,CAAC,IAAI,CAAC,GAAG,WAAW,EAAE,GAAG,gBAAgB,CAAC,EAAE,CAAC;QACtD,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;YAAE,SAAS;QACpC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACtB,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACf,IAAI,MAAM,CAAC,MAAM,IAAI,KAAK;YAAE,MAAM;IACpC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1,4 +0,0 @@
1
- import type { MemoryStore } from '../../memory/core/store.js';
2
- import type { GraphEdge } from '../../server/api/graph.js';
3
- export declare function graphSemanticEdges(store: MemoryStore, nodeIds: string[]): Promise<GraphEdge[]>;
4
- //# sourceMappingURL=graph-semantic-edges.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"graph-semantic-edges.d.ts","sourceRoot":"","sources":["../../../src/private/algorithms/graph-semantic-edges.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAK3D,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,SAAS,EAAE,CAAC,CAiCtB"}
@@ -1,38 +0,0 @@
1
- // src/private/algorithms/graph-semantic-edges.ts
2
- //
3
- // Smart get_memory_graph semantic edges: compute pairwise cosine similarity
4
- // for all node pairs (cap at 50 nodes), include edges with cosine > 0.7.
5
- // OSS basic only emits wikilink edges.
6
- //
7
- import { embed, cosineSimilarity } from '../../embeddings/index.js';
8
- const COSINE_THRESHOLD = 0.7;
9
- const NODE_CAP = 50;
10
- export async function graphSemanticEdges(store, nodeIds) {
11
- // Cap to avoid O(n^2) cost explosion
12
- const capped = nodeIds.slice(0, NODE_CAP);
13
- // Retrieve content for each node
14
- const items = capped
15
- .map((id) => store.getById(id))
16
- .filter((item) => item !== null && item !== undefined);
17
- if (items.length < 2)
18
- return [];
19
- // Embed all items (batch)
20
- const embeddingsConfig = store.options.embeddings;
21
- const vectors = await Promise.all(items.map((item) => embed(item.content.slice(0, 1000), embeddingsConfig)));
22
- const edges = [];
23
- for (let i = 0; i < items.length; i++) {
24
- for (let j = i + 1; j < items.length; j++) {
25
- const cosine = cosineSimilarity(vectors[i], vectors[j]);
26
- if (cosine >= COSINE_THRESHOLD) {
27
- edges.push({
28
- source: items[i].id,
29
- target: items[j].id,
30
- label: 'semantic',
31
- weight: Math.round(cosine * 100) / 100,
32
- });
33
- }
34
- }
35
- }
36
- return edges;
37
- }
38
- //# sourceMappingURL=graph-semantic-edges.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"graph-semantic-edges.js","sourceRoot":"","sources":["../../../src/private/algorithms/graph-semantic-edges.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,EAAE;AACF,4EAA4E;AAC5E,yEAAyE;AACzE,uCAAuC;AACvC,EAAE;AACF,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAIpE,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAC7B,MAAM,QAAQ,GAAG,EAAE,CAAC;AAEpB,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAkB,EAClB,OAAiB;IAEjB,qCAAqC;IACrC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAE1C,iCAAiC;IACjC,MAAM,KAAK,GAAG,MAAM;SACjB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;SAC9B,MAAM,CAAC,CAAC,IAAI,EAAoC,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,CAAC,CAAC;IAE3F,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAEhC,0BAA0B;IAC1B,MAAM,gBAAgB,GAAI,KAA6E,CAAC,OAAO,CAAC,UAAU,CAAC;IAC3H,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAC1E,CAAC;IAEF,MAAM,KAAK,GAAgB,EAAE,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YACxD,IAAI,MAAM,IAAI,gBAAgB,EAAE,CAAC;gBAC/B,KAAK,CAAC,IAAI,CAAC;oBACT,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;oBACnB,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;oBACnB,KAAK,EAAE,UAAU;oBACjB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,GAAG;iBACvC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -1,9 +0,0 @@
1
- import type { MemoryStore } from '../../memory/core/store.js';
2
- export declare function searchAllSmart(store: MemoryStore, query: string, limit: number, types?: string[]): Promise<Array<{
3
- id: string;
4
- type: string;
5
- score: number;
6
- snippet: string;
7
- title?: string;
8
- }>>;
9
- //# sourceMappingURL=search-all-smart.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"search-all-smart.d.ts","sourceRoot":"","sources":["../../../src/private/algorithms/search-all-smart.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AA+B9D,wBAAsB,cAAc,CAClC,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CA+C9F"}
@@ -1,62 +0,0 @@
1
- // Per-type quality weight — higher = more trusted signal
2
- const TYPE_WEIGHTS = {
3
- notes: 1.0,
4
- conversations: 0.9,
5
- drive: 0.85,
6
- notion: 0.85,
7
- obsidian: 0.9,
8
- youtube: 0.75,
9
- audio: 0.75,
10
- };
11
- const DEFAULT_TYPE_WEIGHT = 0.8;
12
- // Recency boost: memories created in the last 7 days get +0.1
13
- const RECENCY_BOOST = 0.1;
14
- const RECENCY_MS = 7 * 24 * 60 * 60 * 1000;
15
- // MMR diversification: penalize additional results from the same source_id
16
- const SOURCE_PENALTY = 0.15;
17
- export async function searchAllSmart(store, query, limit, types) {
18
- const resolvedTypes = types ?? store.listTypes();
19
- const perTypeLimit = Math.max(5, Math.ceil((limit * 2) / Math.max(resolvedTypes.length, 1)));
20
- const now = Date.now();
21
- const all = await Promise.all(resolvedTypes.map(async (t) => {
22
- try {
23
- const hits = await store.search(t, query, perTypeLimit);
24
- return hits.map((h) => {
25
- const createdAt = h.memory.properties.created_at
26
- ? Date.parse(h.memory.properties.created_at)
27
- : 0;
28
- const typeWeight = TYPE_WEIGHTS[t] ?? DEFAULT_TYPE_WEIGHT;
29
- const recencyBoost = createdAt > 0 && now - createdAt < RECENCY_MS ? RECENCY_BOOST : 0;
30
- return {
31
- id: h.memory.id,
32
- type: t,
33
- score: h.score * typeWeight + recencyBoost,
34
- snippet: h.snippet,
35
- title: h.memory.properties.title,
36
- source_id: h.memory.source_id,
37
- created_at_ms: createdAt,
38
- };
39
- });
40
- }
41
- catch {
42
- return [];
43
- }
44
- }));
45
- // Sort by weighted score descending, then MMR-style dedup
46
- const flat = all.flat().sort((a, b) => b.score - a.score);
47
- const selected = [];
48
- const seenSources = new Map(); // source_id → times selected
49
- for (const hit of flat) {
50
- if (selected.length >= limit)
51
- break;
52
- // Apply MMR penalty per additional hit from the same source
53
- const sourceSeen = seenSources.get(hit.source_id) ?? 0;
54
- const adjustedScore = hit.score - sourceSeen * SOURCE_PENALTY;
55
- if (adjustedScore < 0)
56
- continue; // penalized below zero — skip
57
- selected.push({ ...hit, score: adjustedScore });
58
- seenSources.set(hit.source_id, sourceSeen + 1);
59
- }
60
- return selected.map(({ id, type, score, snippet, title }) => ({ id, type, score, snippet, title }));
61
- }
62
- //# sourceMappingURL=search-all-smart.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"search-all-smart.js","sourceRoot":"","sources":["../../../src/private/algorithms/search-all-smart.ts"],"names":[],"mappings":"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"}
@@ -1,7 +0,0 @@
1
- import type { EngramRuntime } from '../core/server/mcp-handler.js';
2
- /**
3
- * Register all private/premium extensions.
4
- * Populates runtime.algorithms and runtime.prompts from gitignored modules.
5
- */
6
- export declare function registerPrivateExtensions(runtime: EngramRuntime): Promise<void>;
7
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/private/index.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAEnE;;;GAGG;AACH,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCrF"}
@@ -1,39 +0,0 @@
1
- /**
2
- * Register all private/premium extensions.
3
- * Populates runtime.algorithms and runtime.prompts from gitignored modules.
4
- */
5
- export async function registerPrivateExtensions(runtime) {
6
- // ── Algorithms ──────────────────────────────────────────────────────────────
7
- try {
8
- const { findRelatedSmart } = await import('./algorithms/find-related-smart.js');
9
- runtime.algorithms.findRelated = findRelatedSmart;
10
- }
11
- catch { /* not present — OSS build */ }
12
- try {
13
- const { searchAllSmart } = await import('./algorithms/search-all-smart.js');
14
- runtime.algorithms.searchAll = searchAllSmart;
15
- }
16
- catch { /* not present — OSS build */ }
17
- try {
18
- const { chunkTextSemantic } = await import('./algorithms/chunker-semantic.js');
19
- runtime.algorithms.chunkText = chunkTextSemantic;
20
- }
21
- catch { /* not present — OSS build */ }
22
- try {
23
- const { graphSemanticEdges } = await import('./algorithms/graph-semantic-edges.js');
24
- runtime.algorithms.graphSemanticEdges = graphSemanticEdges;
25
- }
26
- catch { /* not present — OSS build */ }
27
- // ── Prompts ──────────────────────────────────────────────────────────────────
28
- try {
29
- const { EXTRACTION_SYSTEM_PROMPT } = await import('./prompts/extraction-system.js');
30
- runtime.prompts.extractionSystemPrompt = EXTRACTION_SYSTEM_PROMPT;
31
- }
32
- catch { /* not present — OSS build */ }
33
- try {
34
- const { suggestPropertiesInstruction } = await import('./prompts/suggest-properties.js');
35
- runtime.prompts.suggestPropertiesInstruction = suggestPropertiesInstruction;
36
- }
37
- catch { /* not present — OSS build */ }
38
- }
39
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/private/index.ts"],"names":[],"mappings":"AAkBA;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,OAAsB;IACpE,+EAA+E;IAC/E,IAAI,CAAC;QACH,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,oCAAoC,CAAC,CAAC;QAChF,OAAO,CAAC,UAAU,CAAC,WAAW,GAAG,gBAAgB,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC,CAAC,6BAA6B,CAAC,CAAC;IAEzC,IAAI,CAAC;QACH,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,kCAAkC,CAAC,CAAC;QAC5E,OAAO,CAAC,UAAU,CAAC,SAAS,GAAG,cAAc,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC,CAAC,6BAA6B,CAAC,CAAC;IAEzC,IAAI,CAAC;QACH,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,kCAAkC,CAAC,CAAC;QAC/E,OAAO,CAAC,UAAU,CAAC,SAAS,GAAG,iBAAiB,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC,CAAC,6BAA6B,CAAC,CAAC;IAEzC,IAAI,CAAC;QACH,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,sCAAsC,CAAC,CAAC;QACpF,OAAO,CAAC,UAAU,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC,CAAC,6BAA6B,CAAC,CAAC;IAEzC,gFAAgF;IAChF,IAAI,CAAC;QACH,MAAM,EAAE,wBAAwB,EAAE,GAAG,MAAM,MAAM,CAAC,gCAAgC,CAAC,CAAC;QACpF,OAAO,CAAC,OAAO,CAAC,sBAAsB,GAAG,wBAAwB,CAAC;IACpE,CAAC;IAAC,MAAM,CAAC,CAAC,6BAA6B,CAAC,CAAC;IAEzC,IAAI,CAAC;QACH,MAAM,EAAE,4BAA4B,EAAE,GAAG,MAAM,MAAM,CAAC,iCAAiC,CAAC,CAAC;QACzF,OAAO,CAAC,OAAO,CAAC,4BAA4B,GAAG,4BAA4B,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC,CAAC,6BAA6B,CAAC,CAAC;AAC3C,CAAC"}
@@ -1,2 +0,0 @@
1
- export declare const EXTRACTION_SYSTEM_PROMPT = "You extract structured metadata from arbitrary text.\nOutput strict JSON with these fields:\n - title: a 3-7 word title summarizing the text (string)\n - tags: 3-5 lowercase keywords or short phrases (string[])\n - sentiment: \"positive\" | \"neutral\" | \"negative\"\n - action_required: true if the text implies the user must do something, else false\n - summary: 1-2 sentence summary of the text\nOutput ONLY valid JSON. No explanation, no markdown fences.";
2
- //# sourceMappingURL=extraction-system.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extraction-system.d.ts","sourceRoot":"","sources":["../../../src/private/prompts/extraction-system.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,wBAAwB,qdAOuB,CAAC"}
@@ -1,15 +0,0 @@
1
- // src/private/prompts/extraction-system.ts
2
- //
3
- // Full 5-field extraction prompt (smart version).
4
- // OSS basic asks only for title + tags.
5
- // This version additionally extracts sentiment, action_required, and summary.
6
- //
7
- export const EXTRACTION_SYSTEM_PROMPT = `You extract structured metadata from arbitrary text.
8
- Output strict JSON with these fields:
9
- - title: a 3-7 word title summarizing the text (string)
10
- - tags: 3-5 lowercase keywords or short phrases (string[])
11
- - sentiment: "positive" | "neutral" | "negative"
12
- - action_required: true if the text implies the user must do something, else false
13
- - summary: 1-2 sentence summary of the text
14
- Output ONLY valid JSON. No explanation, no markdown fences.`;
15
- //# sourceMappingURL=extraction-system.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extraction-system.js","sourceRoot":"","sources":["../../../src/private/prompts/extraction-system.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,EAAE;AACF,kDAAkD;AAClD,wCAAwC;AACxC,8EAA8E;AAC9E,EAAE;AACF,MAAM,CAAC,MAAM,wBAAwB,GAAG;;;;;;;4DAOoB,CAAC"}
@@ -1,2 +0,0 @@
1
- export declare function suggestPropertiesInstruction(memoryId: string, _content: string, _currentProps: object): string;
2
- //# sourceMappingURL=suggest-properties.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"suggest-properties.d.ts","sourceRoot":"","sources":["../../../src/private/prompts/suggest-properties.ts"],"names":[],"mappings":"AAMA,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,GACpB,MAAM,CAUR"}
@@ -1,18 +0,0 @@
1
- // src/private/prompts/suggest-properties.ts
2
- //
3
- // Verbose 4-field suggest-properties instruction (smart version).
4
- // OSS basic asks only for title + tags in 2 lines.
5
- // This version provides detailed guidance for all 4 extractable fields.
6
- //
7
- export function suggestPropertiesInstruction(memoryId, _content, _currentProps) {
8
- return [
9
- 'Analyze the content above and produce:',
10
- '- title: 3-7 words summarizing the content',
11
- '- tags: 3-5 lowercase keywords or short phrases',
12
- '- sentiment: "positive" | "neutral" | "negative"',
13
- '- action_required: true if the content implies the user must do something, else false',
14
- '',
15
- `Then call update with id "${memoryId}" and your extracted fields. Only set fields that are currently null; do not overwrite existing values.`,
16
- ].join('\n');
17
- }
18
- //# sourceMappingURL=suggest-properties.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"suggest-properties.js","sourceRoot":"","sources":["../../../src/private/prompts/suggest-properties.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,EAAE;AACF,kEAAkE;AAClE,mDAAmD;AACnD,wEAAwE;AACxE,EAAE;AACF,MAAM,UAAU,4BAA4B,CAC1C,QAAgB,EAChB,QAAgB,EAChB,aAAqB;IAErB,OAAO;QACL,wCAAwC;QACxC,4CAA4C;QAC5C,iDAAiD;QACjD,kDAAkD;QAClD,uFAAuF;QACvF,EAAE;QACF,6BAA6B,QAAQ,yGAAyG;KAC/I,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=find-related-smart.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"find-related-smart.test.d.ts","sourceRoot":"","sources":["../../../src/private/tests/find-related-smart.test.ts"],"names":[],"mappings":""}
@@ -1,86 +0,0 @@
1
- // src/private/tests/find-related-smart.test.ts
2
- //
3
- // GITIGNORED — tests smart findRelated (wikilinks + semantic) when private/ is loaded.
4
- //
5
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
6
- import fs from 'fs';
7
- import os from 'os';
8
- import path from 'path';
9
- import { ulid } from 'ulid';
10
- import { initDb, closeDb } from '../../db/index.js';
11
- import { initVectorStore } from '../../vector/store.js';
12
- import { MemoryStore } from '../../memory/core/store.js';
13
- import { findRelatedSmart } from '../algorithms/find-related-smart.js';
14
- const embeddingsConfig = {
15
- provider: 'ollama',
16
- baseUrl: 'http://localhost:11434',
17
- model: 'nomic-embed-text',
18
- dimensions: 768,
19
- };
20
- function buildItem(overrides = {}) {
21
- const now = new Date().toISOString();
22
- return {
23
- id: ulid(),
24
- type: 'notes',
25
- source_id: 'local:test',
26
- content: 'Test content',
27
- content_hash: 'h1',
28
- properties: { created_at: now, ingested_at: now },
29
- wikilinks: [],
30
- related_ids: [],
31
- embedding_model: 'nomic-embed-text:v1.5',
32
- ...overrides,
33
- };
34
- }
35
- describe('findRelatedSmart (private)', () => {
36
- let tmpDir;
37
- let store;
38
- beforeEach(() => {
39
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'engram-smart-'));
40
- initDb(tmpDir);
41
- initVectorStore(tmpDir);
42
- store = new MemoryStore({ embeddings: embeddingsConfig, algorithms: { findRelated: findRelatedSmart } });
43
- });
44
- afterEach(() => {
45
- closeDb();
46
- fs.rmSync(tmpDir, { recursive: true, force: true });
47
- });
48
- it('findRelated returns items sharing a wikilink (wikilinks path)', async () => {
49
- const a = buildItem({ content: 'Working on [[ProjectAlpha]] integration', source_id: 'a' });
50
- const b = buildItem({ content: 'Status update for [[ProjectAlpha]]', source_id: 'b' });
51
- const c = buildItem({ content: 'Unrelated content about weather', source_id: 'c' });
52
- await store.insert(a);
53
- await store.insert(b);
54
- await store.insert(c);
55
- store.setProperties(b.id, { title: 'ProjectAlpha' });
56
- const related = await store.findRelated(b.id, 5);
57
- expect(related.some((r) => r.memory.id === a.id)).toBe(true);
58
- });
59
- it('findRelated returns semantically similar items (semantic path)', async () => {
60
- const a = buildItem({
61
- content: 'TypeScript generics enable powerful type-safe abstractions. Generic types allow code reuse across different data types while maintaining full type safety.',
62
- source_id: 'a',
63
- });
64
- const b = buildItem({
65
- content: 'Advanced TypeScript type inference and generic constraints improve code quality. Using extends with generics restricts acceptable type parameters.',
66
- source_id: 'b',
67
- });
68
- const c = buildItem({
69
- content: 'How to bake a chocolate cake: mix flour, sugar, eggs, and cocoa powder.',
70
- source_id: 'c',
71
- });
72
- await store.insert(a);
73
- await store.insert(b);
74
- await store.insert(c);
75
- const related = await store.findRelated(a.id, 5);
76
- // c (unrelated — cooking) should NOT appear
77
- expect(related.some((r) => r.memory.id === c.id)).toBe(false);
78
- // b should appear (semantically related — both about TypeScript generics)
79
- // Note: if cosine < 0.5 threshold, b may not appear — this is expected behavior
80
- // for very similar short texts where embedding distance may exceed threshold
81
- if (related.length > 0) {
82
- expect(related.every((r) => r.memory.id !== c.id)).toBe(true);
83
- }
84
- }, 30_000);
85
- });
86
- //# sourceMappingURL=find-related-smart.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"find-related-smart.test.js","sourceRoot":"","sources":["../../../src/private/tests/find-related-smart.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=property-extractor-smart.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"property-extractor-smart.test.d.ts","sourceRoot":"","sources":["../../../src/private/tests/property-extractor-smart.test.ts"],"names":[],"mappings":""}
@@ -1,26 +0,0 @@
1
- // src/private/tests/property-extractor-smart.test.ts
2
- //
3
- // GITIGNORED — tests smart (5-field) extraction with the private system prompt.
4
- // Runs when src/private/ is loaded (hosted Engram or local dev with private/).
5
- //
6
- import { describe, it, expect } from 'vitest';
7
- import { extractProperties } from '../../memory/core/property-extractor.js';
8
- import { EXTRACTION_SYSTEM_PROMPT } from '../prompts/extraction-system.js';
9
- const config = {
10
- enabled: true,
11
- baseUrl: 'http://localhost:11434',
12
- model: 'llama3.2:3b',
13
- maxTokens: 300,
14
- };
15
- describe('property extractor — smart prompt (private)', () => {
16
- it('extracts all 5 fields including action_required', async () => {
17
- const result = await extractProperties('The team agreed on a quarterly all-hands for the launch of PolymarketPro on June 1st. Action: confirm venue.', config, EXTRACTION_SYSTEM_PROMPT);
18
- expect(result.title).toBeTruthy();
19
- expect(result.tags).toBeInstanceOf(Array);
20
- expect(result.tags.length).toBeGreaterThan(0);
21
- expect(result.action_required).toBe(true);
22
- // summary is extracted by the smart prompt but not the basic one
23
- expect(result.custom?.summary).toBeTruthy();
24
- }, 30_000);
25
- });
26
- //# sourceMappingURL=property-extractor-smart.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"property-extractor-smart.test.js","sourceRoot":"","sources":["../../../src/private/tests/property-extractor-smart.test.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,gFAAgF;AAChF,+EAA+E;AAC/E,EAAE;AACF,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAE3E,MAAM,MAAM,GAAG;IACb,OAAO,EAAE,IAAI;IACb,OAAO,EAAE,wBAAwB;IACjC,KAAK,EAAE,aAAa;IACpB,SAAS,EAAE,GAAG;CACf,CAAC;AAEF,QAAQ,CAAC,6CAA6C,EAAE,GAAG,EAAE;IAC3D,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,MAAM,GAAG,MAAM,iBAAiB,CACpC,8GAA8G,EAC9G,MAAM,EACN,wBAAwB,CACzB,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,IAAK,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,iEAAiE;QACjE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,UAAU,EAAE,CAAC;IAC9C,CAAC,EAAE,MAAM,CAAC,CAAC;AACb,CAAC,CAAC,CAAC"}
@@ -1,49 +0,0 @@
1
- # src/private/ — Engram Premium Extensions
2
-
3
- This directory is **GITIGNORED** and only ships on hosted Engram deployments.
4
-
5
- The public OSS repository (`github.com/RavioleLabs/engram-mcp`) does not include this directory.
6
- When building from source (OSS), the dynamic import in `src/tools/index.ts` gracefully skips this
7
- directory if it is absent.
8
-
9
- ## Structure
10
-
11
- ```
12
- src/private/
13
- ├── index.ts # Entry: exports registerPrivateExtensions(ctx)
14
- ├── README.md # This file
15
- ├── tools/ # Premium MCP tools
16
- │ ├── smart-search.ts # Advanced cross-cut semantic ranking (cross-encoder)
17
- │ ├── auto-categorize.ts # ML-based custom type suggestion
18
- │ └── index.ts
19
- ├── algorithms/ # Smarter OSS algorithm overrides
20
- │ ├── advanced-find-related.ts # Multi-signal weighted relation discovery
21
- │ └── memory-clustering.ts # Graph clustering for memory organization
22
- └── prompts/ # Carefully-tuned LLM prompts (IP)
23
- └── extraction-system.ts # Property extraction system prompt (v2)
24
- ```
25
-
26
- ## Candidates for migration here (from OSS)
27
-
28
- | OSS location | What to move | Status |
29
- |---|---|---|
30
- | `src/memory/core/property-extractor.ts` | `SYSTEM_PROMPT` constant | Planned |
31
- | `src/memory/core/store.ts` `findRelated()` | Advanced multi-signal version | Planned |
32
- | `src/memory/public/tools.ts` `search_all` | Cross-encoder re-ranking | Planned |
33
- | `src/memory/public/tools.ts` `suggest_properties` | Optimized prompt template | Planned |
34
-
35
- ## How to add a new private tool
36
-
37
- 1. Create `src/private/tools/my-tool.ts` implementing `MCPToolDefinition`
38
- 2. Add a `registerMyTool(ctx)` export
39
- 3. Import and call it from `src/private/index.ts` `registerPrivateExtensions`
40
- 4. The tool will appear in the MCP server alongside public tools
41
-
42
- ## How to override a public algorithm
43
-
44
- 1. Create `src/private/algorithms/my-override.ts`
45
- 2. Export a function with the same signature as the OSS version
46
- 3. In `src/private/index.ts`, patch the relevant module/store method:
47
- ```ts
48
- ctx.store.findRelated = myAdvancedFindRelated.bind(null, ctx.store);
49
- ```