@coreidentitylabs/open-graph-memory-mcp 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/mcp-builder/LICENSE.txt +202 -0
- package/.agents/skills/mcp-builder/SKILL.md +236 -0
- package/.agents/skills/mcp-builder/reference/evaluation.md +602 -0
- package/.agents/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
- package/.agents/skills/mcp-builder/reference/node_mcp_server.md +970 -0
- package/.agents/skills/mcp-builder/reference/python_mcp_server.md +719 -0
- package/.agents/skills/mcp-builder/scripts/connections.py +151 -0
- package/.agents/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/.agents/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/.agents/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/.env.example +26 -0
- package/Implementation Plan.md +358 -0
- package/README.md +187 -0
- package/dist/constants.d.ts +34 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +40 -0
- package/dist/constants.js.map +1 -0
- package/dist/encoding/embedder.d.ts +12 -0
- package/dist/encoding/embedder.d.ts.map +1 -0
- package/dist/encoding/embedder.js +85 -0
- package/dist/encoding/embedder.js.map +1 -0
- package/dist/encoding/pipeline.d.ts +28 -0
- package/dist/encoding/pipeline.d.ts.map +1 -0
- package/dist/encoding/pipeline.js +146 -0
- package/dist/encoding/pipeline.js.map +1 -0
- package/dist/evolution/consolidator.d.ts +12 -0
- package/dist/evolution/consolidator.d.ts.map +1 -0
- package/dist/evolution/consolidator.js +212 -0
- package/dist/evolution/consolidator.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/openai-provider.d.ts +23 -0
- package/dist/llm/openai-provider.d.ts.map +1 -0
- package/dist/llm/openai-provider.js +141 -0
- package/dist/llm/openai-provider.js.map +1 -0
- package/dist/llm/prompts.d.ts +10 -0
- package/dist/llm/prompts.d.ts.map +1 -0
- package/dist/llm/prompts.js +63 -0
- package/dist/llm/prompts.js.map +1 -0
- package/dist/llm/provider.d.ts +7 -0
- package/dist/llm/provider.d.ts.map +1 -0
- package/dist/llm/provider.js +25 -0
- package/dist/llm/provider.js.map +1 -0
- package/dist/resources/context-resource.d.ts +8 -0
- package/dist/resources/context-resource.d.ts.map +1 -0
- package/dist/resources/context-resource.js +51 -0
- package/dist/resources/context-resource.js.map +1 -0
- package/dist/retrieval/search.d.ts +24 -0
- package/dist/retrieval/search.d.ts.map +1 -0
- package/dist/retrieval/search.js +143 -0
- package/dist/retrieval/search.js.map +1 -0
- package/dist/storage/factory.d.ts +10 -0
- package/dist/storage/factory.d.ts.map +1 -0
- package/dist/storage/factory.js +35 -0
- package/dist/storage/factory.js.map +1 -0
- package/dist/storage/json-store.d.ts +34 -0
- package/dist/storage/json-store.d.ts.map +1 -0
- package/dist/storage/json-store.js +248 -0
- package/dist/storage/json-store.js.map +1 -0
- package/dist/storage/neo4j-store.d.ts +31 -0
- package/dist/storage/neo4j-store.d.ts.map +1 -0
- package/dist/storage/neo4j-store.js +440 -0
- package/dist/storage/neo4j-store.js.map +1 -0
- package/dist/tools/memory-tools.d.ts +4 -0
- package/dist/tools/memory-tools.d.ts.map +1 -0
- package/dist/tools/memory-tools.js +873 -0
- package/dist/tools/memory-tools.js.map +1 -0
- package/dist/types.d.ts +129 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/implementation_plan.md.resolved.md +322 -0
- package/package.json +43 -0
- package/src/constants.ts +52 -0
- package/src/encoding/embedder.ts +93 -0
- package/src/encoding/pipeline.ts +197 -0
- package/src/evolution/consolidator.ts +281 -0
- package/src/index.ts +67 -0
- package/src/llm/openai-provider.ts +208 -0
- package/src/llm/prompts.ts +66 -0
- package/src/llm/provider.ts +37 -0
- package/src/resources/context-resource.ts +74 -0
- package/src/retrieval/search.ts +203 -0
- package/src/storage/factory.ts +48 -0
- package/src/storage/json-store.ts +325 -0
- package/src/storage/neo4j-store.ts +564 -0
- package/src/tools/memory-tools.ts +1067 -0
- package/src/types.ts +207 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Embedding Service — Lightweight text-to-vector without external dependencies
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Uses character n-gram hashing for offline, zero-dependency embeddings.
|
|
5
|
+
// If an LLM provider is configured, it can be used for higher-quality embeddings.
|
|
6
|
+
// =============================================================================
|
|
7
|
+
const EMBEDDING_DIM = 256;
|
|
8
|
+
/**
|
|
9
|
+
* Generate a lightweight embedding from text using character n-gram hashing.
|
|
10
|
+
* This is a simple, deterministic approach that works offline without any API.
|
|
11
|
+
* Quality is lower than neural embeddings but sufficient for basic similarity.
|
|
12
|
+
*/
|
|
13
|
+
export function generateLocalEmbedding(text) {
|
|
14
|
+
const normalized = text.toLowerCase().trim();
|
|
15
|
+
const vector = new Float64Array(EMBEDDING_DIM).fill(0);
|
|
16
|
+
// Character trigram hashing
|
|
17
|
+
for (let i = 0; i < normalized.length - 2; i++) {
|
|
18
|
+
const trigram = normalized.substring(i, i + 3);
|
|
19
|
+
const hash = hashString(trigram);
|
|
20
|
+
const index = Math.abs(hash) % EMBEDDING_DIM;
|
|
21
|
+
// Random-ish sign based on hash
|
|
22
|
+
const sign = hash > 0 ? 1 : -1;
|
|
23
|
+
vector[index] += sign;
|
|
24
|
+
}
|
|
25
|
+
// Word-level hashing for broader semantic signals
|
|
26
|
+
const words = normalized.split(/\s+/).filter((w) => w.length > 0);
|
|
27
|
+
for (const word of words) {
|
|
28
|
+
const hash = hashString(word);
|
|
29
|
+
const index = Math.abs(hash) % EMBEDDING_DIM;
|
|
30
|
+
vector[index] += hash > 0 ? 0.5 : -0.5;
|
|
31
|
+
}
|
|
32
|
+
// Word bigram hashing for phrase-level patterns
|
|
33
|
+
for (let i = 0; i < words.length - 1; i++) {
|
|
34
|
+
const bigram = `${words[i]} ${words[i + 1]}`;
|
|
35
|
+
const hash = hashString(bigram);
|
|
36
|
+
const index = Math.abs(hash) % EMBEDDING_DIM;
|
|
37
|
+
vector[index] += hash > 0 ? 0.3 : -0.3;
|
|
38
|
+
}
|
|
39
|
+
// L2 normalize
|
|
40
|
+
return l2Normalize(Array.from(vector));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Compute cosine similarity between two vectors.
|
|
44
|
+
* Returns a value between -1 and 1 (1 = identical, 0 = orthogonal).
|
|
45
|
+
*/
|
|
46
|
+
export function cosineSimilarity(a, b) {
|
|
47
|
+
if (a.length !== b.length || a.length === 0)
|
|
48
|
+
return 0;
|
|
49
|
+
let dotProduct = 0;
|
|
50
|
+
let normA = 0;
|
|
51
|
+
let normB = 0;
|
|
52
|
+
for (let i = 0; i < a.length; i++) {
|
|
53
|
+
dotProduct += a[i] * b[i];
|
|
54
|
+
normA += a[i] * a[i];
|
|
55
|
+
normB += b[i] * b[i];
|
|
56
|
+
}
|
|
57
|
+
const denominator = Math.sqrt(normA) * Math.sqrt(normB);
|
|
58
|
+
if (denominator === 0)
|
|
59
|
+
return 0;
|
|
60
|
+
return dotProduct / denominator;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* L2 normalize a vector (unit length).
|
|
64
|
+
*/
|
|
65
|
+
function l2Normalize(vector) {
|
|
66
|
+
let norm = 0;
|
|
67
|
+
for (const v of vector)
|
|
68
|
+
norm += v * v;
|
|
69
|
+
norm = Math.sqrt(norm);
|
|
70
|
+
if (norm === 0)
|
|
71
|
+
return vector;
|
|
72
|
+
return vector.map((v) => v / norm);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Simple deterministic string hash (djb2 variant).
|
|
76
|
+
*/
|
|
77
|
+
function hashString(str) {
|
|
78
|
+
let hash = 5381;
|
|
79
|
+
for (let i = 0; i < str.length; i++) {
|
|
80
|
+
// hash * 33 + char
|
|
81
|
+
hash = ((hash << 5) + hash + str.charCodeAt(i)) | 0;
|
|
82
|
+
}
|
|
83
|
+
return hash;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=embedder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedder.js","sourceRoot":"","sources":["../../src/encoding/embedder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { StorageBackend, LLMProvider } from "../types.js";
|
|
2
|
+
export interface EncodingResult {
|
|
3
|
+
entitiesCreated: number;
|
|
4
|
+
entitiesUpdated: number;
|
|
5
|
+
relationsCreated: number;
|
|
6
|
+
details: {
|
|
7
|
+
entities: {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
status: string;
|
|
11
|
+
}[];
|
|
12
|
+
relations: {
|
|
13
|
+
source: string;
|
|
14
|
+
target: string;
|
|
15
|
+
relation: string;
|
|
16
|
+
status: string;
|
|
17
|
+
}[];
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Full server-side encoding pipeline:
|
|
22
|
+
* 1. Extract entities + relations from text using LLM
|
|
23
|
+
* 2. Resolve entities against existing graph (avoid duplicates)
|
|
24
|
+
* 3. Generate embeddings (LLM embeddings if available, local fallback)
|
|
25
|
+
* 4. Store nodes and edges
|
|
26
|
+
*/
|
|
27
|
+
export declare function encodeText(text: string, store: StorageBackend, llm: LLMProvider): Promise<EncodingResult>;
|
|
28
|
+
//# sourceMappingURL=pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/encoding/pipeline.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EAKZ,MAAM,aAAa,CAAC;AAGrB,MAAM,WAAW,cAAc;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE;QACP,QAAQ,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QACzD,SAAS,EAAE;YACT,MAAM,EAAE,MAAM,CAAC;YACf,MAAM,EAAE,MAAM,CAAC;YACf,QAAQ,EAAE,MAAM,CAAC;YACjB,MAAM,EAAE,MAAM,CAAC;SAChB,EAAE,CAAC;KACL,CAAC;CACH;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,cAAc,EACrB,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,cAAc,CAAC,CAwJzB"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Encoding Pipeline — Server-Side Entity Extraction + Storage
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Orchestrates: LLM extraction → entity resolution → embedding → storage
|
|
5
|
+
// Only available when LLM_API_KEY is configured.
|
|
6
|
+
// =============================================================================
|
|
7
|
+
import { v4 as uuidv4 } from "uuid";
|
|
8
|
+
import { generateLocalEmbedding } from "./embedder.js";
|
|
9
|
+
/**
|
|
10
|
+
* Full server-side encoding pipeline:
|
|
11
|
+
* 1. Extract entities + relations from text using LLM
|
|
12
|
+
* 2. Resolve entities against existing graph (avoid duplicates)
|
|
13
|
+
* 3. Generate embeddings (LLM embeddings if available, local fallback)
|
|
14
|
+
* 4. Store nodes and edges
|
|
15
|
+
*/
|
|
16
|
+
export async function encodeText(text, store, llm) {
|
|
17
|
+
const result = {
|
|
18
|
+
entitiesCreated: 0,
|
|
19
|
+
entitiesUpdated: 0,
|
|
20
|
+
relationsCreated: 0,
|
|
21
|
+
details: { entities: [], relations: [] },
|
|
22
|
+
};
|
|
23
|
+
// Step 1: Get existing entity names for resolution
|
|
24
|
+
const { nodes: existingNodes } = await store.getAllNodes(10000, 0);
|
|
25
|
+
const existingNames = existingNodes.map((n) => n.name);
|
|
26
|
+
// Step 2: Extract entities and relations via LLM
|
|
27
|
+
let extraction;
|
|
28
|
+
try {
|
|
29
|
+
extraction = await llm.extractEntitiesAndRelations(text, existingNames);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.error("[open-memory] LLM extraction failed:", error);
|
|
33
|
+
throw new Error(`LLM extraction failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
34
|
+
}
|
|
35
|
+
if (extraction.entities.length === 0 && extraction.relations.length === 0) {
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
// Step 3: Store entities (with resolution)
|
|
39
|
+
const entityNameToId = new Map();
|
|
40
|
+
// Pre-populate with existing entities
|
|
41
|
+
for (const node of existingNodes) {
|
|
42
|
+
entityNameToId.set(node.name.toLowerCase(), node.id);
|
|
43
|
+
}
|
|
44
|
+
for (const entity of extraction.entities) {
|
|
45
|
+
const nameLower = entity.name.toLowerCase();
|
|
46
|
+
const existingNode = await store.getNodeByName(entity.name);
|
|
47
|
+
// Generate embedding — try LLM first, fall back to local
|
|
48
|
+
let embedding;
|
|
49
|
+
try {
|
|
50
|
+
embedding = await llm.generateEmbedding(`${entity.name}: ${entity.description}`);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
embedding = generateLocalEmbedding(`${entity.name} ${entity.description}`);
|
|
54
|
+
}
|
|
55
|
+
if (existingNode) {
|
|
56
|
+
// Update existing entity with richer description
|
|
57
|
+
const mergedDescription = existingNode.description.length >= entity.description.length
|
|
58
|
+
? existingNode.description
|
|
59
|
+
: entity.description;
|
|
60
|
+
await store.updateNode(existingNode.id, {
|
|
61
|
+
description: mergedDescription,
|
|
62
|
+
embedding,
|
|
63
|
+
metadata: { ...existingNode.metadata, ...entity.metadata },
|
|
64
|
+
});
|
|
65
|
+
entityNameToId.set(nameLower, existingNode.id);
|
|
66
|
+
result.entitiesUpdated++;
|
|
67
|
+
result.details.entities.push({
|
|
68
|
+
id: existingNode.id,
|
|
69
|
+
name: entity.name,
|
|
70
|
+
status: "updated",
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// Create new entity
|
|
75
|
+
const now = new Date().toISOString();
|
|
76
|
+
const node = {
|
|
77
|
+
id: uuidv4(),
|
|
78
|
+
name: entity.name,
|
|
79
|
+
type: entity.type,
|
|
80
|
+
description: entity.description,
|
|
81
|
+
embedding,
|
|
82
|
+
metadata: entity.metadata ?? {},
|
|
83
|
+
createdAt: now,
|
|
84
|
+
updatedAt: now,
|
|
85
|
+
source: "llm_extraction",
|
|
86
|
+
accessCount: 0,
|
|
87
|
+
};
|
|
88
|
+
await store.addNode(node);
|
|
89
|
+
entityNameToId.set(nameLower, node.id);
|
|
90
|
+
result.entitiesCreated++;
|
|
91
|
+
result.details.entities.push({
|
|
92
|
+
id: node.id,
|
|
93
|
+
name: entity.name,
|
|
94
|
+
status: "created",
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Step 4: Store relations
|
|
99
|
+
for (const rel of extraction.relations) {
|
|
100
|
+
const sourceId = entityNameToId.get(rel.source.toLowerCase()) ?? null;
|
|
101
|
+
const targetId = entityNameToId.get(rel.target.toLowerCase()) ?? null;
|
|
102
|
+
if (!sourceId || !targetId) {
|
|
103
|
+
result.details.relations.push({
|
|
104
|
+
source: rel.source,
|
|
105
|
+
target: rel.target,
|
|
106
|
+
relation: rel.relation,
|
|
107
|
+
status: `skipped: ${!sourceId ? `source '${rel.source}' not found` : `target '${rel.target}' not found`}`,
|
|
108
|
+
});
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
// Avoid duplicate edges
|
|
112
|
+
const existingEdges = await store.getEdgesBetween(sourceId, targetId);
|
|
113
|
+
const duplicate = existingEdges.find((e) => e.relation === rel.relation);
|
|
114
|
+
if (duplicate) {
|
|
115
|
+
result.details.relations.push({
|
|
116
|
+
source: rel.source,
|
|
117
|
+
target: rel.target,
|
|
118
|
+
relation: rel.relation,
|
|
119
|
+
status: "skipped: duplicate",
|
|
120
|
+
});
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
const now = new Date().toISOString();
|
|
124
|
+
const edge = {
|
|
125
|
+
id: uuidv4(),
|
|
126
|
+
source: sourceId,
|
|
127
|
+
target: targetId,
|
|
128
|
+
relation: rel.relation,
|
|
129
|
+
description: rel.description ?? `${rel.source} ${rel.relation} ${rel.target}`,
|
|
130
|
+
weight: rel.weight ?? 0.8,
|
|
131
|
+
metadata: {},
|
|
132
|
+
createdAt: now,
|
|
133
|
+
updatedAt: now,
|
|
134
|
+
};
|
|
135
|
+
await store.addEdge(edge);
|
|
136
|
+
result.relationsCreated++;
|
|
137
|
+
result.details.relations.push({
|
|
138
|
+
source: rel.source,
|
|
139
|
+
target: rel.target,
|
|
140
|
+
relation: rel.relation,
|
|
141
|
+
status: "created",
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/encoding/pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { StorageBackend, ConsolidationResult, ConsolidationStrategy } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Run memory consolidation to keep the graph healthy.
|
|
4
|
+
*
|
|
5
|
+
* Strategies:
|
|
6
|
+
* - full: runs all operations
|
|
7
|
+
* - merge_only: only merge duplicates
|
|
8
|
+
* - prune_only: only prune stale nodes
|
|
9
|
+
* - infer_only: only infer transitive edges
|
|
10
|
+
*/
|
|
11
|
+
export declare function consolidateMemory(store: StorageBackend, strategy?: ConsolidationStrategy): Promise<ConsolidationResult>;
|
|
12
|
+
//# sourceMappingURL=consolidator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidator.d.ts","sourceRoot":"","sources":["../../src/evolution/consolidator.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,cAAc,EAGd,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,aAAa,CAAC;AAQrB;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,cAAc,EACrB,QAAQ,GAAE,qBAA8B,GACvC,OAAO,CAAC,mBAAmB,CAAC,CA0B9B"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Memory Evolution Engine — Consolidation, Dedup, Inference, Pruning
|
|
3
|
+
// =============================================================================
|
|
4
|
+
import { cosineSimilarity } from "../encoding/embedder.js";
|
|
5
|
+
import { DUPLICATE_SIMILARITY_THRESHOLD, STALE_NODE_AGE_DAYS, } from "../constants.js";
|
|
6
|
+
/**
|
|
7
|
+
* Run memory consolidation to keep the graph healthy.
|
|
8
|
+
*
|
|
9
|
+
* Strategies:
|
|
10
|
+
* - full: runs all operations
|
|
11
|
+
* - merge_only: only merge duplicates
|
|
12
|
+
* - prune_only: only prune stale nodes
|
|
13
|
+
* - infer_only: only infer transitive edges
|
|
14
|
+
*/
|
|
15
|
+
export async function consolidateMemory(store, strategy = "full") {
|
|
16
|
+
const startTime = Date.now();
|
|
17
|
+
const result = {
|
|
18
|
+
mergedNodes: 0,
|
|
19
|
+
resolvedConflicts: 0,
|
|
20
|
+
inferredEdges: 0,
|
|
21
|
+
prunedNodes: 0,
|
|
22
|
+
duration: 0,
|
|
23
|
+
};
|
|
24
|
+
if (strategy === "full" || strategy === "merge_only") {
|
|
25
|
+
const mergeResult = await mergeDuplicates(store);
|
|
26
|
+
result.mergedNodes = mergeResult.merged;
|
|
27
|
+
result.resolvedConflicts = mergeResult.conflicts;
|
|
28
|
+
}
|
|
29
|
+
if (strategy === "full" || strategy === "infer_only") {
|
|
30
|
+
result.inferredEdges = await inferTransitiveEdges(store);
|
|
31
|
+
}
|
|
32
|
+
if (strategy === "full" || strategy === "prune_only") {
|
|
33
|
+
result.prunedNodes = await pruneStaleNodes(store);
|
|
34
|
+
}
|
|
35
|
+
result.duration = Date.now() - startTime;
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
// -----------------------------------------------------------------------------
|
|
39
|
+
// Duplicate Merging
|
|
40
|
+
// -----------------------------------------------------------------------------
|
|
41
|
+
async function mergeDuplicates(store) {
|
|
42
|
+
const { nodes } = await store.getAllNodes(10000, 0);
|
|
43
|
+
let merged = 0;
|
|
44
|
+
let conflicts = 0;
|
|
45
|
+
const processedIds = new Set();
|
|
46
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
47
|
+
if (processedIds.has(nodes[i].id))
|
|
48
|
+
continue;
|
|
49
|
+
for (let j = i + 1; j < nodes.length; j++) {
|
|
50
|
+
if (processedIds.has(nodes[j].id))
|
|
51
|
+
continue;
|
|
52
|
+
const nodeA = nodes[i];
|
|
53
|
+
const nodeB = nodes[j];
|
|
54
|
+
// Check name similarity
|
|
55
|
+
const nameMatch = nodeA.name.toLowerCase() === nodeB.name.toLowerCase() ||
|
|
56
|
+
levenshteinSimilarity(nodeA.name.toLowerCase(), nodeB.name.toLowerCase()) > 0.85;
|
|
57
|
+
// Check embedding similarity if both have embeddings
|
|
58
|
+
let embeddingSimilar = false;
|
|
59
|
+
if (nodeA.embedding &&
|
|
60
|
+
nodeB.embedding &&
|
|
61
|
+
nodeA.embedding.length > 0 &&
|
|
62
|
+
nodeB.embedding.length > 0) {
|
|
63
|
+
const sim = cosineSimilarity(nodeA.embedding, nodeB.embedding);
|
|
64
|
+
embeddingSimilar = sim > DUPLICATE_SIMILARITY_THRESHOLD;
|
|
65
|
+
}
|
|
66
|
+
if (nameMatch || embeddingSimilar) {
|
|
67
|
+
// Merge B into A (keep the older/more accessed node)
|
|
68
|
+
const keepNode = nodeA.accessCount >= nodeB.accessCount ? nodeA : nodeB;
|
|
69
|
+
const removeNode = keepNode === nodeA ? nodeB : nodeA;
|
|
70
|
+
// Merge descriptions
|
|
71
|
+
const mergedDescription = keepNode.description.length >= removeNode.description.length
|
|
72
|
+
? keepNode.description
|
|
73
|
+
: `${keepNode.description} | ${removeNode.description}`;
|
|
74
|
+
// Re-point edges from removeNode to keepNode
|
|
75
|
+
const edges = await store.getEdgesForNode(removeNode.id);
|
|
76
|
+
for (const edge of edges) {
|
|
77
|
+
const newEdge = {
|
|
78
|
+
...edge,
|
|
79
|
+
source: edge.source === removeNode.id ? keepNode.id : edge.source,
|
|
80
|
+
target: edge.target === removeNode.id ? keepNode.id : edge.target,
|
|
81
|
+
updatedAt: new Date().toISOString(),
|
|
82
|
+
};
|
|
83
|
+
// Skip self-loops
|
|
84
|
+
if (newEdge.source === newEdge.target)
|
|
85
|
+
continue;
|
|
86
|
+
// Check if we already have this edge
|
|
87
|
+
const existing = await store.getEdgesBetween(newEdge.source, newEdge.target);
|
|
88
|
+
const duplicate = existing.find((e) => e.relation === newEdge.relation);
|
|
89
|
+
if (!duplicate) {
|
|
90
|
+
await store.addEdge(newEdge);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Update kept node and delete merged node
|
|
94
|
+
await store.updateNode(keepNode.id, {
|
|
95
|
+
description: mergedDescription,
|
|
96
|
+
accessCount: keepNode.accessCount + removeNode.accessCount,
|
|
97
|
+
});
|
|
98
|
+
await store.deleteNode(removeNode.id);
|
|
99
|
+
processedIds.add(removeNode.id);
|
|
100
|
+
merged++;
|
|
101
|
+
// Check for temporal conflicts
|
|
102
|
+
if (keepNode.validUntil &&
|
|
103
|
+
removeNode.validFrom &&
|
|
104
|
+
keepNode.validUntil < removeNode.validFrom) {
|
|
105
|
+
conflicts++;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return { merged, conflicts };
|
|
111
|
+
}
|
|
112
|
+
// -----------------------------------------------------------------------------
|
|
113
|
+
// Transitive Edge Inference
|
|
114
|
+
// -----------------------------------------------------------------------------
|
|
115
|
+
async function inferTransitiveEdges(store) {
|
|
116
|
+
const { nodes } = await store.getAllNodes(10000, 0);
|
|
117
|
+
let inferred = 0;
|
|
118
|
+
for (const node of nodes) {
|
|
119
|
+
const outEdges = await store.getEdgesForNode(node.id, "out");
|
|
120
|
+
for (const edgeAB of outEdges) {
|
|
121
|
+
// A -> B, now look for B -> C
|
|
122
|
+
const nextEdges = await store.getEdgesForNode(edgeAB.target, "out");
|
|
123
|
+
for (const edgeBC of nextEdges) {
|
|
124
|
+
// Skip if A == C (no self-loops)
|
|
125
|
+
if (edgeBC.target === node.id)
|
|
126
|
+
continue;
|
|
127
|
+
// Check if A -> C edge already exists
|
|
128
|
+
const existing = await store.getEdgesBetween(node.id, edgeBC.target);
|
|
129
|
+
if (existing.length > 0)
|
|
130
|
+
continue;
|
|
131
|
+
// Only infer for certain relationship types
|
|
132
|
+
if (edgeAB.relation === edgeBC.relation &&
|
|
133
|
+
isTransitiveRelation(edgeAB.relation)) {
|
|
134
|
+
const { v4: uuidv4 } = await import("uuid");
|
|
135
|
+
const now = new Date().toISOString();
|
|
136
|
+
await store.addEdge({
|
|
137
|
+
id: uuidv4(),
|
|
138
|
+
source: node.id,
|
|
139
|
+
target: edgeBC.target,
|
|
140
|
+
relation: edgeAB.relation,
|
|
141
|
+
description: `Inferred: transitive ${edgeAB.relation}`,
|
|
142
|
+
weight: Math.min(edgeAB.weight, edgeBC.weight) * 0.8,
|
|
143
|
+
metadata: { inferred: true },
|
|
144
|
+
createdAt: now,
|
|
145
|
+
updatedAt: now,
|
|
146
|
+
});
|
|
147
|
+
inferred++;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return inferred;
|
|
153
|
+
}
|
|
154
|
+
function isTransitiveRelation(relation) {
|
|
155
|
+
const transitiveRelations = [
|
|
156
|
+
"depends_on",
|
|
157
|
+
"part_of",
|
|
158
|
+
"belongs_to",
|
|
159
|
+
"contains",
|
|
160
|
+
"extends",
|
|
161
|
+
"imports",
|
|
162
|
+
];
|
|
163
|
+
return transitiveRelations.includes(relation);
|
|
164
|
+
}
|
|
165
|
+
// -----------------------------------------------------------------------------
|
|
166
|
+
// Stale Node Pruning
|
|
167
|
+
// -----------------------------------------------------------------------------
|
|
168
|
+
async function pruneStaleNodes(store) {
|
|
169
|
+
const { nodes } = await store.getAllNodes(10000, 0);
|
|
170
|
+
const cutoff = new Date();
|
|
171
|
+
cutoff.setDate(cutoff.getDate() - STALE_NODE_AGE_DAYS);
|
|
172
|
+
const cutoffStr = cutoff.toISOString();
|
|
173
|
+
let pruned = 0;
|
|
174
|
+
for (const node of nodes) {
|
|
175
|
+
// Don't prune conversations or decisions (high-value types)
|
|
176
|
+
if (node.type === "conversation" || node.type === "decision")
|
|
177
|
+
continue;
|
|
178
|
+
// Prune if never accessed and old
|
|
179
|
+
const lastActivity = node.lastAccessedAt ?? node.updatedAt;
|
|
180
|
+
if (lastActivity < cutoffStr && node.accessCount === 0) {
|
|
181
|
+
await store.deleteNode(node.id);
|
|
182
|
+
pruned++;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return pruned;
|
|
186
|
+
}
|
|
187
|
+
// -----------------------------------------------------------------------------
|
|
188
|
+
// Utilities
|
|
189
|
+
// -----------------------------------------------------------------------------
|
|
190
|
+
function levenshteinSimilarity(a, b) {
|
|
191
|
+
const maxLen = Math.max(a.length, b.length);
|
|
192
|
+
if (maxLen === 0)
|
|
193
|
+
return 1;
|
|
194
|
+
return 1 - levenshteinDistance(a, b) / maxLen;
|
|
195
|
+
}
|
|
196
|
+
function levenshteinDistance(a, b) {
|
|
197
|
+
const m = a.length;
|
|
198
|
+
const n = b.length;
|
|
199
|
+
const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
|
|
200
|
+
for (let i = 0; i <= m; i++)
|
|
201
|
+
dp[i][0] = i;
|
|
202
|
+
for (let j = 0; j <= n; j++)
|
|
203
|
+
dp[0][j] = j;
|
|
204
|
+
for (let i = 1; i <= m; i++) {
|
|
205
|
+
for (let j = 1; j <= n; j++) {
|
|
206
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
207
|
+
dp[i][j] = Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + cost);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return dp[m][n];
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=consolidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidator.js","sourceRoot":"","sources":["../../src/evolution/consolidator.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// Open-Memory MCP Server — Entry Point
|
|
4
|
+
// =============================================================================
|
|
5
|
+
// Graph-based agent memory for AI coding assistants.
|
|
6
|
+
// Extends context window by storing entities, relationships, and decisions
|
|
7
|
+
// in a persistent knowledge graph accessible via MCP tools.
|
|
8
|
+
// =============================================================================
|
|
9
|
+
import dotenv from "dotenv";
|
|
10
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
11
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
|
+
import { createStorageBackend } from "./storage/factory.js";
|
|
13
|
+
import { registerMemoryTools } from "./tools/memory-tools.js";
|
|
14
|
+
import { registerMemoryResources } from "./resources/context-resource.js";
|
|
15
|
+
import { createLLMProvider } from "./llm/provider.js";
|
|
16
|
+
import { SERVER_NAME, SERVER_VERSION } from "./constants.js";
|
|
17
|
+
// Load environment variables
|
|
18
|
+
dotenv.config();
|
|
19
|
+
async function main() {
|
|
20
|
+
console.error(`[open-memory] Starting ${SERVER_NAME} v${SERVER_VERSION}...`);
|
|
21
|
+
// 1. Initialize storage backend
|
|
22
|
+
const store = createStorageBackend();
|
|
23
|
+
await store.initialize();
|
|
24
|
+
// 2. Initialize optional LLM provider
|
|
25
|
+
const llm = createLLMProvider();
|
|
26
|
+
// 3. Create MCP server
|
|
27
|
+
const server = new McpServer({
|
|
28
|
+
name: SERVER_NAME,
|
|
29
|
+
version: SERVER_VERSION,
|
|
30
|
+
});
|
|
31
|
+
// 4. Register tools and resources
|
|
32
|
+
registerMemoryTools(server, store, llm);
|
|
33
|
+
registerMemoryResources(server, store);
|
|
34
|
+
const toolCount = llm ? 12 : 11;
|
|
35
|
+
console.error(`[open-memory] Registered ${toolCount} tools and 2 resources`);
|
|
36
|
+
// 5. Connect via stdio transport
|
|
37
|
+
const transport = new StdioServerTransport();
|
|
38
|
+
await server.connect(transport);
|
|
39
|
+
console.error(`[open-memory] Server running via stdio. Ready for connections.`);
|
|
40
|
+
// Graceful shutdown
|
|
41
|
+
const shutdown = async () => {
|
|
42
|
+
console.error(`[open-memory] Shutting down...`);
|
|
43
|
+
await store.close();
|
|
44
|
+
process.exit(0);
|
|
45
|
+
};
|
|
46
|
+
process.on("SIGINT", shutdown);
|
|
47
|
+
process.on("SIGTERM", shutdown);
|
|
48
|
+
}
|
|
49
|
+
main().catch((error) => {
|
|
50
|
+
console.error(`[open-memory] Fatal error:`, error);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,gFAAgF;AAChF,uCAAuC;AACvC,gFAAgF;AAChF,qDAAqD;AACrD,2EAA2E;AAC3E,4DAA4D;AAC5D,gFAAgF;AAEhF,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAE7D,6BAA6B;AAC7B,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,KAAK,UAAU,IAAI;IACjB,OAAO,CAAC,KAAK,CAAC,0BAA0B,WAAW,KAAK,cAAc,KAAK,CAAC,CAAC;IAE7E,gCAAgC;IAChC,MAAM,KAAK,GAAG,oBAAoB,EAAE,CAAC;IACrC,MAAM,KAAK,CAAC,UAAU,EAAE,CAAC;IAEzB,sCAAsC;IACtC,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;IAEhC,uBAAuB;IACvB,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,cAAc;KACxB,CAAC,CAAC;IAEH,kCAAkC;IAClC,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;IACxC,uBAAuB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAEvC,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,4BAA4B,SAAS,wBAAwB,CAAC,CAAC;IAE7E,iCAAiC;IACjC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,OAAO,CAAC,KAAK,CACX,gEAAgE,CACjE,CAAC;IAEF,oBAAoB;IACpB,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAChD,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { LLMProvider, ExtractionResult } from "../types.js";
|
|
2
|
+
export declare class OpenAIProvider implements LLMProvider {
|
|
3
|
+
private apiKey;
|
|
4
|
+
private baseUrl;
|
|
5
|
+
private chatModel;
|
|
6
|
+
private embeddingModel;
|
|
7
|
+
constructor(apiKey: string, baseUrl: string, chatModel: string, embeddingModel: string);
|
|
8
|
+
/**
|
|
9
|
+
* Extract entities and relationships from text using the chat model.
|
|
10
|
+
*/
|
|
11
|
+
extractEntitiesAndRelations(text: string, existingEntities: string[]): Promise<ExtractionResult>;
|
|
12
|
+
/**
|
|
13
|
+
* Generate a single embedding vector.
|
|
14
|
+
*/
|
|
15
|
+
generateEmbedding(text: string): Promise<number[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Generate embeddings for multiple texts in a single batch.
|
|
18
|
+
*/
|
|
19
|
+
generateEmbeddingBatch(texts: string[]): Promise<number[][]>;
|
|
20
|
+
private chatCompletion;
|
|
21
|
+
private embeddingRequest;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=openai-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-provider.d.ts","sourceRoot":"","sources":["../../src/llm/openai-provider.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAGjB,MAAM,aAAa,CAAC;AAyBrB,qBAAa,cAAe,YAAW,WAAW;IAChD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAS;gBAG7B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM;IAQxB;;OAEG;IACG,2BAA2B,CAC/B,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,MAAM,EAAE,GACzB,OAAO,CAAC,gBAAgB,CAAC;IA0D5B;;OAEG;IACG,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKxD;;OAEG;IACG,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAQpD,cAAc;YA4Bd,gBAAgB;CAyB/B"}
|