@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,141 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// OpenAI-Compatible LLM Provider
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Works with: OpenAI, Azure OpenAI, Ollama (OpenAI-compat mode), and any
|
|
5
|
+
// provider exposing the OpenAI chat completions & embeddings API.
|
|
6
|
+
// =============================================================================
|
|
7
|
+
import { getExtractionSystemPrompt, getExtractionUserPrompt, } from "./prompts.js";
|
|
8
|
+
export class OpenAIProvider {
|
|
9
|
+
apiKey;
|
|
10
|
+
baseUrl;
|
|
11
|
+
chatModel;
|
|
12
|
+
embeddingModel;
|
|
13
|
+
constructor(apiKey, baseUrl, chatModel, embeddingModel) {
|
|
14
|
+
this.apiKey = apiKey;
|
|
15
|
+
this.baseUrl = baseUrl.replace(/\/$/, ""); // strip trailing slash
|
|
16
|
+
this.chatModel = chatModel;
|
|
17
|
+
this.embeddingModel = embeddingModel;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Extract entities and relationships from text using the chat model.
|
|
21
|
+
*/
|
|
22
|
+
async extractEntitiesAndRelations(text, existingEntities) {
|
|
23
|
+
const messages = [
|
|
24
|
+
{ role: "system", content: getExtractionSystemPrompt(existingEntities) },
|
|
25
|
+
{ role: "user", content: getExtractionUserPrompt(text) },
|
|
26
|
+
];
|
|
27
|
+
const responseText = await this.chatCompletion(messages);
|
|
28
|
+
try {
|
|
29
|
+
// Clean response — strip markdown code fences if present
|
|
30
|
+
let cleaned = responseText.trim();
|
|
31
|
+
if (cleaned.startsWith("```")) {
|
|
32
|
+
cleaned = cleaned
|
|
33
|
+
.replace(/^```(?:json)?\s*\n?/, "")
|
|
34
|
+
.replace(/\n?```\s*$/, "");
|
|
35
|
+
}
|
|
36
|
+
const parsed = JSON.parse(cleaned);
|
|
37
|
+
const entities = (parsed.entities ?? [])
|
|
38
|
+
.map((e) => {
|
|
39
|
+
const entity = e;
|
|
40
|
+
return {
|
|
41
|
+
name: String(entity.name ?? ""),
|
|
42
|
+
type: validateNodeType(String(entity.type ?? "entity")),
|
|
43
|
+
description: String(entity.description ?? ""),
|
|
44
|
+
metadata: entity.metadata ?? {},
|
|
45
|
+
};
|
|
46
|
+
})
|
|
47
|
+
.filter((e) => e.name.length > 0);
|
|
48
|
+
const relations = (parsed.relations ?? [])
|
|
49
|
+
.map((r) => {
|
|
50
|
+
const rel = r;
|
|
51
|
+
return {
|
|
52
|
+
source: String(rel.source ?? ""),
|
|
53
|
+
target: String(rel.target ?? ""),
|
|
54
|
+
relation: String(rel.relation ?? "related_to"),
|
|
55
|
+
description: rel.description ? String(rel.description) : undefined,
|
|
56
|
+
weight: typeof rel.weight === "number" ? rel.weight : 0.8,
|
|
57
|
+
};
|
|
58
|
+
})
|
|
59
|
+
.filter((r) => r.source.length > 0 && r.target.length > 0);
|
|
60
|
+
return { entities, relations };
|
|
61
|
+
}
|
|
62
|
+
catch (parseError) {
|
|
63
|
+
console.error(`[open-memory] Failed to parse LLM extraction response:`, parseError);
|
|
64
|
+
console.error(`[open-memory] Raw response:`, responseText);
|
|
65
|
+
return { entities: [], relations: [] };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Generate a single embedding vector.
|
|
70
|
+
*/
|
|
71
|
+
async generateEmbedding(text) {
|
|
72
|
+
const result = await this.embeddingRequest([text]);
|
|
73
|
+
return result[0] ?? [];
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Generate embeddings for multiple texts in a single batch.
|
|
77
|
+
*/
|
|
78
|
+
async generateEmbeddingBatch(texts) {
|
|
79
|
+
return this.embeddingRequest(texts);
|
|
80
|
+
}
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
// HTTP Helpers
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
async chatCompletion(messages) {
|
|
85
|
+
const url = `${this.baseUrl}/chat/completions`;
|
|
86
|
+
const response = await fetch(url, {
|
|
87
|
+
method: "POST",
|
|
88
|
+
headers: {
|
|
89
|
+
"Content-Type": "application/json",
|
|
90
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
91
|
+
},
|
|
92
|
+
body: JSON.stringify({
|
|
93
|
+
model: this.chatModel,
|
|
94
|
+
messages,
|
|
95
|
+
temperature: 0.1,
|
|
96
|
+
max_tokens: 4096,
|
|
97
|
+
}),
|
|
98
|
+
});
|
|
99
|
+
if (!response.ok) {
|
|
100
|
+
const errorBody = await response.text();
|
|
101
|
+
throw new Error(`LLM chat completion failed (${response.status}): ${errorBody}`);
|
|
102
|
+
}
|
|
103
|
+
const data = (await response.json());
|
|
104
|
+
return data.choices[0]?.message?.content ?? "";
|
|
105
|
+
}
|
|
106
|
+
async embeddingRequest(inputs) {
|
|
107
|
+
const url = `${this.baseUrl}/embeddings`;
|
|
108
|
+
const response = await fetch(url, {
|
|
109
|
+
method: "POST",
|
|
110
|
+
headers: {
|
|
111
|
+
"Content-Type": "application/json",
|
|
112
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
113
|
+
},
|
|
114
|
+
body: JSON.stringify({
|
|
115
|
+
model: this.embeddingModel,
|
|
116
|
+
input: inputs,
|
|
117
|
+
}),
|
|
118
|
+
});
|
|
119
|
+
if (!response.ok) {
|
|
120
|
+
const errorBody = await response.text();
|
|
121
|
+
throw new Error(`LLM embedding request failed (${response.status}): ${errorBody}`);
|
|
122
|
+
}
|
|
123
|
+
const data = (await response.json());
|
|
124
|
+
return data.data.map((d) => d.embedding);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
// Helpers
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
function validateNodeType(type) {
|
|
131
|
+
const valid = [
|
|
132
|
+
"entity",
|
|
133
|
+
"concept",
|
|
134
|
+
"event",
|
|
135
|
+
"code_pattern",
|
|
136
|
+
"decision",
|
|
137
|
+
"conversation",
|
|
138
|
+
];
|
|
139
|
+
return valid.includes(type) ? type : "entity";
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=openai-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-provider.js","sourceRoot":"","sources":["../../src/llm/openai-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System prompt for entity and relationship extraction from developer conversations.
|
|
3
|
+
* Instructs the LLM to return structured JSON with entities and relations.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getExtractionSystemPrompt(existingEntities: string[]): string;
|
|
6
|
+
/**
|
|
7
|
+
* Build the user message for extraction.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getExtractionUserPrompt(text: string): string;
|
|
10
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/llm/prompts.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,gBAAgB,EAAE,MAAM,EAAE,GAAG,MAAM,CAkD5E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5D"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Extraction Prompts — Optimized for developer conversations
|
|
3
|
+
// =============================================================================
|
|
4
|
+
/**
|
|
5
|
+
* System prompt for entity and relationship extraction from developer conversations.
|
|
6
|
+
* Instructs the LLM to return structured JSON with entities and relations.
|
|
7
|
+
*/
|
|
8
|
+
export function getExtractionSystemPrompt(existingEntities) {
|
|
9
|
+
const existingList = existingEntities.length > 0
|
|
10
|
+
? `\n\nKnown entities already in memory (use these exact names for entity resolution):\n${existingEntities.map((e) => `- ${e}`).join("\n")}`
|
|
11
|
+
: "";
|
|
12
|
+
return `You are a specialized entity and relationship extraction system for developer conversations.
|
|
13
|
+
|
|
14
|
+
Your task is to extract structured entities and relationships from the given text.
|
|
15
|
+
|
|
16
|
+
## Entity Types
|
|
17
|
+
- **entity**: People, teams, organizations, tools, libraries, frameworks, services, APIs, databases
|
|
18
|
+
- **concept**: Abstract ideas, design patterns, paradigms, methodologies
|
|
19
|
+
- **event**: Meetings, deployments, incidents, releases, decisions made at a point in time
|
|
20
|
+
- **code_pattern**: Recurring code structures, architectural patterns, implementation approaches
|
|
21
|
+
- **decision**: Technical decisions with rationale (e.g., "chose React Query over SWR because...")
|
|
22
|
+
- **conversation**: Conversation summaries or session references
|
|
23
|
+
|
|
24
|
+
## Extraction Rules
|
|
25
|
+
1. Extract SPECIFIC entities, not generic terms (e.g., "React Query" not "library")
|
|
26
|
+
2. For each entity, provide a concise but informative description
|
|
27
|
+
3. For relationships, use clear verb-based relation types (uses, depends_on, replaced_by, decided_to, part_of, implements, configures, deployed_to, etc.)
|
|
28
|
+
4. If an entity matches one of the known entities below, use the EXACT same name
|
|
29
|
+
5. Capture temporal information when present (e.g., "decided last week" → include in metadata)
|
|
30
|
+
6. Focus on information a developer would want to recall later
|
|
31
|
+
${existingList}
|
|
32
|
+
|
|
33
|
+
## Output Format
|
|
34
|
+
Return ONLY valid JSON in this exact format:
|
|
35
|
+
{
|
|
36
|
+
"entities": [
|
|
37
|
+
{
|
|
38
|
+
"name": "EntityName",
|
|
39
|
+
"type": "entity|concept|event|code_pattern|decision",
|
|
40
|
+
"description": "Concise description of what this entity is and its relevance",
|
|
41
|
+
"metadata": { "optional": "key-value pairs for extra context" }
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"relations": [
|
|
45
|
+
{
|
|
46
|
+
"source": "SourceEntityName",
|
|
47
|
+
"target": "TargetEntityName",
|
|
48
|
+
"relation": "verb_based_relation",
|
|
49
|
+
"description": "Brief description of this relationship"
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
Return an empty arrays if no meaningful entities or relationships can be extracted.
|
|
55
|
+
Do NOT include markdown code fences or any text outside the JSON.`;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build the user message for extraction.
|
|
59
|
+
*/
|
|
60
|
+
export function getExtractionUserPrompt(text) {
|
|
61
|
+
return `Extract entities and relationships from the following text:\n\n${text}`;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/llm/prompts.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,6DAA6D;AAC7D,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,gBAA0B;IAClE,MAAM,YAAY,GAChB,gBAAgB,CAAC,MAAM,GAAG,CAAC;QACzB,CAAC,CAAC,wFAAwF,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QAC5I,CAAC,CAAC,EAAE,CAAC;IAET,OAAO;;;;;;;;;;;;;;;;;;;EAmBP,YAAY;;;;;;;;;;;;;;;;;;;;;;;;kEAwBoD,CAAC;AACnE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,OAAO,kEAAkE,IAAI,EAAE,CAAC;AAClF,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { LLMProvider } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Create an LLM provider if configured, or return null.
|
|
4
|
+
* The LLM provider is OPTIONAL — the agent-driven flow works without it.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createLLMProvider(): LLMProvider | null;
|
|
7
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/llm/provider.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,WAAW,GAAG,IAAI,CAqBtD"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// LLM Provider — Interface & Factory
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Optional: only loaded if LLM_API_KEY is configured.
|
|
5
|
+
// Powers the memory_encode_text tool for server-side entity extraction.
|
|
6
|
+
// =============================================================================
|
|
7
|
+
import { ENV_KEYS } from "../constants.js";
|
|
8
|
+
import { OpenAIProvider } from "./openai-provider.js";
|
|
9
|
+
/**
|
|
10
|
+
* Create an LLM provider if configured, or return null.
|
|
11
|
+
* The LLM provider is OPTIONAL — the agent-driven flow works without it.
|
|
12
|
+
*/
|
|
13
|
+
export function createLLMProvider() {
|
|
14
|
+
const apiKey = process.env[ENV_KEYS.LLM_API_KEY];
|
|
15
|
+
if (!apiKey) {
|
|
16
|
+
console.error("[open-memory] No LLM_API_KEY configured. Server-side encoding (memory_encode_text) disabled.");
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const baseUrl = process.env[ENV_KEYS.LLM_BASE_URL] ?? "https://api.openai.com/v1";
|
|
20
|
+
const chatModel = process.env[ENV_KEYS.LLM_CHAT_MODEL] ?? "gpt-4o-mini";
|
|
21
|
+
const embeddingModel = process.env[ENV_KEYS.LLM_EMBEDDING_MODEL] ?? "text-embedding-3-small";
|
|
22
|
+
console.error(`[open-memory] LLM provider enabled: ${baseUrl} (chat: ${chatModel}, embed: ${embeddingModel})`);
|
|
23
|
+
return new OpenAIProvider(apiKey, baseUrl, chatModel, embeddingModel);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/llm/provider.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,qCAAqC;AACrC,gFAAgF;AAChF,sDAAsD;AACtD,wEAAwE;AACxE,gFAAgF;AAGhF,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAEjD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CACX,8FAA8F,CAC/F,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GACX,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,2BAA2B,CAAC;IACpE,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,aAAa,CAAC;IACxE,MAAM,cAAc,GAClB,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,wBAAwB,CAAC;IAExE,OAAO,CAAC,KAAK,CACX,uCAAuC,OAAO,WAAW,SAAS,YAAY,cAAc,GAAG,CAChG,CAAC;IAEF,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { StorageBackend } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Register MCP resources for automatic context injection.
|
|
5
|
+
* Agents can read these resources to get relevant context without explicit tool calls.
|
|
6
|
+
*/
|
|
7
|
+
export declare function registerMemoryResources(server: McpServer, store: StorageBackend): void;
|
|
8
|
+
//# sourceMappingURL=context-resource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-resource.d.ts","sourceRoot":"","sources":["../../src/resources/context-resource.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,cAAc,GACpB,IAAI,CA2DN"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// MCP Resource — Auto-injectable recent memory context
|
|
3
|
+
// =============================================================================
|
|
4
|
+
/**
|
|
5
|
+
* Register MCP resources for automatic context injection.
|
|
6
|
+
* Agents can read these resources to get relevant context without explicit tool calls.
|
|
7
|
+
*/
|
|
8
|
+
export function registerMemoryResources(server, store) {
|
|
9
|
+
// Recent entities resource
|
|
10
|
+
server.registerResource("recent_entities", "memory://entities/recent", {
|
|
11
|
+
description: "Most recently updated entities in the memory graph",
|
|
12
|
+
mimeType: "application/json",
|
|
13
|
+
}, async () => {
|
|
14
|
+
const { nodes } = await store.getAllNodes(20, 0);
|
|
15
|
+
const sorted = nodes
|
|
16
|
+
.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime())
|
|
17
|
+
.slice(0, 20);
|
|
18
|
+
const content = sorted.map((n) => ({
|
|
19
|
+
name: n.name,
|
|
20
|
+
type: n.type,
|
|
21
|
+
description: n.description.substring(0, 200),
|
|
22
|
+
updatedAt: n.updatedAt,
|
|
23
|
+
}));
|
|
24
|
+
return {
|
|
25
|
+
contents: [
|
|
26
|
+
{
|
|
27
|
+
uri: "memory://entities/recent",
|
|
28
|
+
mimeType: "application/json",
|
|
29
|
+
text: JSON.stringify(content, null, 2),
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
// Graph stats resource
|
|
35
|
+
server.registerResource("graph_stats", "memory://stats", {
|
|
36
|
+
description: "Current memory graph statistics (node counts, edge counts, backend type)",
|
|
37
|
+
mimeType: "application/json",
|
|
38
|
+
}, async () => {
|
|
39
|
+
const stats = await store.getStats();
|
|
40
|
+
return {
|
|
41
|
+
contents: [
|
|
42
|
+
{
|
|
43
|
+
uri: "memory://stats",
|
|
44
|
+
mimeType: "application/json",
|
|
45
|
+
text: JSON.stringify(stats, null, 2),
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=context-resource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-resource.js","sourceRoot":"","sources":["../../src/resources/context-resource.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,uDAAuD;AACvD,gFAAgF;AAKhF;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,MAAiB,EACjB,KAAqB;IAErB,2BAA2B;IAC3B,MAAM,CAAC,gBAAgB,CACrB,iBAAiB,EACjB,0BAA0B,EAC1B;QACE,WAAW,EAAE,oDAAoD;QACjE,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,IAAI,EAAE;QACT,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,KAAK,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,KAAK;aACjB,IAAI,CACH,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CACpE;aACA,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAEhB,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjC,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC;YAC5C,SAAS,EAAE,CAAC,CAAC,SAAS;SACvB,CAAC,CAAC,CAAC;QAEJ,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,0BAA0B;oBAC/B,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;iBACvC;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,uBAAuB;IACvB,MAAM,CAAC,gBAAgB,CACrB,aAAa,EACb,gBAAgB,EAChB;QACE,WAAW,EACT,0EAA0E;QAC5E,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,IAAI,EAAE;QACT,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrC,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,gBAAgB;oBACrB,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;iBACrC;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { StorageBackend, SearchResult, NodeType } from "../types.js";
|
|
2
|
+
export interface SearchOptions {
|
|
3
|
+
query: string;
|
|
4
|
+
topK?: number;
|
|
5
|
+
type?: NodeType;
|
|
6
|
+
timeRange?: {
|
|
7
|
+
after?: string;
|
|
8
|
+
before?: string;
|
|
9
|
+
};
|
|
10
|
+
traversalDepth?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Hybrid retrieval combining:
|
|
14
|
+
* 1. Text match on node names and descriptions
|
|
15
|
+
* 2. Cosine similarity on embeddings (semantic anchors)
|
|
16
|
+
* 3. Graph traversal from top anchors (2-hop neighborhood)
|
|
17
|
+
* 4. Ranking by: score = α·semantic + β·textMatch + γ·recency + δ·accessFreq
|
|
18
|
+
*/
|
|
19
|
+
export declare function hybridSearch(store: StorageBackend, options: SearchOptions): Promise<SearchResult>;
|
|
20
|
+
/**
|
|
21
|
+
* Get context for a specific topic, formatted for prompt injection.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getContextForTopic(store: StorageBackend, topic: string, maxTokens?: number): Promise<string>;
|
|
24
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/retrieval/search.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,cAAc,EAId,YAAY,EACZ,QAAQ,EACT,MAAM,aAAa,CAAC;AAOrB,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,SAAS,CAAC,EAAE;QACV,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,YAAY,CAAC,CAyHvB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,cAAc,EACrB,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAa,GACvB,OAAO,CAAC,MAAM,CAAC,CAiCjB"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Hybrid Retrieval Engine — Semantic + Graph + Text Search
|
|
3
|
+
// =============================================================================
|
|
4
|
+
import { generateLocalEmbedding, cosineSimilarity, } from "../encoding/embedder.js";
|
|
5
|
+
import { DEFAULT_TOP_K, DEFAULT_TRAVERSAL_DEPTH } from "../constants.js";
|
|
6
|
+
/**
|
|
7
|
+
* Hybrid retrieval combining:
|
|
8
|
+
* 1. Text match on node names and descriptions
|
|
9
|
+
* 2. Cosine similarity on embeddings (semantic anchors)
|
|
10
|
+
* 3. Graph traversal from top anchors (2-hop neighborhood)
|
|
11
|
+
* 4. Ranking by: score = α·semantic + β·textMatch + γ·recency + δ·accessFreq
|
|
12
|
+
*/
|
|
13
|
+
export async function hybridSearch(store, options) {
|
|
14
|
+
const { query, topK = DEFAULT_TOP_K, type, timeRange, traversalDepth = DEFAULT_TRAVERSAL_DEPTH, } = options;
|
|
15
|
+
const queryLower = query.toLowerCase();
|
|
16
|
+
const queryEmbedding = generateLocalEmbedding(query);
|
|
17
|
+
// Step 1: Get all candidate nodes
|
|
18
|
+
const { nodes: allNodes } = await store.getAllNodes(10000, 0);
|
|
19
|
+
// Step 2: Score each node
|
|
20
|
+
const scored = [];
|
|
21
|
+
for (const node of allNodes) {
|
|
22
|
+
// Apply type filter
|
|
23
|
+
if (type && node.type !== type)
|
|
24
|
+
continue;
|
|
25
|
+
// Apply time range filter
|
|
26
|
+
if (timeRange?.after && node.createdAt < timeRange.after)
|
|
27
|
+
continue;
|
|
28
|
+
if (timeRange?.before && node.createdAt > timeRange.before)
|
|
29
|
+
continue;
|
|
30
|
+
let totalScore = 0;
|
|
31
|
+
let matchType = "text";
|
|
32
|
+
// Text match scoring
|
|
33
|
+
const nameMatch = node.name.toLowerCase().includes(queryLower) ? 0.6 : 0;
|
|
34
|
+
const descMatch = node.description.toLowerCase().includes(queryLower)
|
|
35
|
+
? 0.4
|
|
36
|
+
: 0;
|
|
37
|
+
// Partial word matching
|
|
38
|
+
const queryWords = queryLower.split(/\s+/).filter((w) => w.length > 2);
|
|
39
|
+
let wordMatchScore = 0;
|
|
40
|
+
for (const word of queryWords) {
|
|
41
|
+
if (node.name.toLowerCase().includes(word))
|
|
42
|
+
wordMatchScore += 0.15;
|
|
43
|
+
if (node.description.toLowerCase().includes(word))
|
|
44
|
+
wordMatchScore += 0.1;
|
|
45
|
+
}
|
|
46
|
+
const textScore = Math.min(1, nameMatch + descMatch + wordMatchScore);
|
|
47
|
+
// Semantic similarity scoring
|
|
48
|
+
let semanticScore = 0;
|
|
49
|
+
if (node.embedding && node.embedding.length > 0) {
|
|
50
|
+
semanticScore = cosineSimilarity(queryEmbedding, node.embedding);
|
|
51
|
+
if (semanticScore > textScore)
|
|
52
|
+
matchType = "semantic";
|
|
53
|
+
}
|
|
54
|
+
// Recency boost (decays over 30 days)
|
|
55
|
+
const ageMs = Date.now() - new Date(node.updatedAt).getTime();
|
|
56
|
+
const ageDays = ageMs / (1000 * 60 * 60 * 24);
|
|
57
|
+
const recencyBoost = Math.max(0, 1 - ageDays / 30) * 0.1;
|
|
58
|
+
// Access frequency boost (capped)
|
|
59
|
+
const accessBoost = Math.min(node.accessCount / 100, 0.1);
|
|
60
|
+
// Weighted combination
|
|
61
|
+
totalScore =
|
|
62
|
+
0.4 * semanticScore +
|
|
63
|
+
0.4 * textScore +
|
|
64
|
+
0.1 * recencyBoost +
|
|
65
|
+
0.1 * accessBoost;
|
|
66
|
+
if (totalScore > 0.05) {
|
|
67
|
+
scored.push({ node, score: totalScore, matchType });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Step 3: Sort by score, take top K
|
|
71
|
+
scored.sort((a, b) => b.score - a.score);
|
|
72
|
+
const topResults = scored.slice(0, topK);
|
|
73
|
+
// Step 4: Graph traversal from top anchors to find related context
|
|
74
|
+
const relatedEdgesMap = new Map();
|
|
75
|
+
const graphNodeIds = new Set(topResults.map((r) => r.node.id));
|
|
76
|
+
// Traverse from top 3 anchors
|
|
77
|
+
const anchors = topResults.slice(0, 3);
|
|
78
|
+
for (const anchor of anchors) {
|
|
79
|
+
const neighborhood = await store.getNeighborhood(anchor.node.id, traversalDepth);
|
|
80
|
+
for (const edge of neighborhood.edges) {
|
|
81
|
+
relatedEdgesMap.set(edge.id, edge);
|
|
82
|
+
}
|
|
83
|
+
// Add graph-discovered nodes that aren't already in results
|
|
84
|
+
for (const neighbor of neighborhood.nodes) {
|
|
85
|
+
if (!graphNodeIds.has(neighbor.id)) {
|
|
86
|
+
graphNodeIds.add(neighbor.id);
|
|
87
|
+
topResults.push({
|
|
88
|
+
node: neighbor,
|
|
89
|
+
score: anchor.score * 0.5, // Discounted score for graph neighbors
|
|
90
|
+
matchType: "graph",
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Step 5: Update access counts for returned nodes
|
|
96
|
+
for (const result of topResults) {
|
|
97
|
+
await store.updateNode(result.node.id, {
|
|
98
|
+
accessCount: result.node.accessCount + 1,
|
|
99
|
+
lastAccessedAt: new Date().toISOString(),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
// Re-sort after adding graph neighbors
|
|
103
|
+
topResults.sort((a, b) => b.score - a.score);
|
|
104
|
+
return {
|
|
105
|
+
nodes: topResults.slice(0, topK),
|
|
106
|
+
relatedEdges: Array.from(relatedEdgesMap.values()),
|
|
107
|
+
totalNodes: scored.length,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get context for a specific topic, formatted for prompt injection.
|
|
112
|
+
*/
|
|
113
|
+
export async function getContextForTopic(store, topic, maxTokens = 2000) {
|
|
114
|
+
const results = await hybridSearch(store, {
|
|
115
|
+
query: topic,
|
|
116
|
+
topK: 10,
|
|
117
|
+
traversalDepth: 1,
|
|
118
|
+
});
|
|
119
|
+
const lines = [];
|
|
120
|
+
let estimatedTokens = 0;
|
|
121
|
+
lines.push(`## Relevant Memory Context: "${topic}"\n`);
|
|
122
|
+
for (const { node, score } of results.nodes) {
|
|
123
|
+
if (estimatedTokens > maxTokens)
|
|
124
|
+
break;
|
|
125
|
+
const entry = `### ${node.name} (${node.type})\n${node.description}\n`;
|
|
126
|
+
estimatedTokens += entry.length / 4; // rough token estimate
|
|
127
|
+
lines.push(entry);
|
|
128
|
+
}
|
|
129
|
+
if (results.relatedEdges.length > 0) {
|
|
130
|
+
lines.push(`### Relationships\n`);
|
|
131
|
+
for (const edge of results.relatedEdges.slice(0, 10)) {
|
|
132
|
+
const fromNode = results.nodes.find((n) => n.node.id === edge.source);
|
|
133
|
+
const toNode = results.nodes.find((n) => n.node.id === edge.target);
|
|
134
|
+
const fromName = fromNode?.node.name ?? edge.source;
|
|
135
|
+
const toName = toNode?.node.name ?? edge.target;
|
|
136
|
+
lines.push(`- ${fromName} **${edge.relation}** ${toName}`);
|
|
137
|
+
if (edge.description)
|
|
138
|
+
lines.push(` _${edge.description}_`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return lines.join("\n");
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/retrieval/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { StorageBackend } from "../types.js";
|
|
2
|
+
export type StorageType = "json" | "neo4j";
|
|
3
|
+
/**
|
|
4
|
+
* Create a storage backend based on environment configuration.
|
|
5
|
+
*
|
|
6
|
+
* STORAGE_BACKEND=json → Local JSON file (default, zero-config)
|
|
7
|
+
* STORAGE_BACKEND=neo4j → Neo4j graph database
|
|
8
|
+
*/
|
|
9
|
+
export declare function createStorageBackend(): StorageBackend;
|
|
10
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/storage/factory.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKlD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3C;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,CA8BrD"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Storage Backend Factory
|
|
3
|
+
// =============================================================================
|
|
4
|
+
import { JsonStore } from "./json-store.js";
|
|
5
|
+
import { Neo4jStore } from "./neo4j-store.js";
|
|
6
|
+
import { ENV_KEYS, DEFAULT_MEMORY_STORE_PATH } from "../constants.js";
|
|
7
|
+
/**
|
|
8
|
+
* Create a storage backend based on environment configuration.
|
|
9
|
+
*
|
|
10
|
+
* STORAGE_BACKEND=json → Local JSON file (default, zero-config)
|
|
11
|
+
* STORAGE_BACKEND=neo4j → Neo4j graph database
|
|
12
|
+
*/
|
|
13
|
+
export function createStorageBackend() {
|
|
14
|
+
const backendType = (process.env[ENV_KEYS.STORAGE_BACKEND] ?? "json").toLowerCase();
|
|
15
|
+
switch (backendType) {
|
|
16
|
+
case "neo4j": {
|
|
17
|
+
const uri = process.env[ENV_KEYS.NEO4J_URI];
|
|
18
|
+
const user = process.env[ENV_KEYS.NEO4J_USER];
|
|
19
|
+
const password = process.env[ENV_KEYS.NEO4J_PASSWORD];
|
|
20
|
+
if (!uri || !user || !password) {
|
|
21
|
+
console.error(`[open-memory] ERROR: Neo4j requires NEO4J_URI, NEO4J_USER, and NEO4J_PASSWORD environment variables.`);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
console.error(`[open-memory] Using Neo4j storage backend at ${uri}`);
|
|
25
|
+
return new Neo4jStore(uri, user, password);
|
|
26
|
+
}
|
|
27
|
+
case "json":
|
|
28
|
+
default: {
|
|
29
|
+
const filePath = process.env[ENV_KEYS.MEMORY_STORE_PATH] ?? DEFAULT_MEMORY_STORE_PATH;
|
|
30
|
+
console.error(`[open-memory] Using JSON storage backend at ${filePath}`);
|
|
31
|
+
return new JsonStore(filePath);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/storage/factory.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,0BAA0B;AAC1B,gFAAgF;AAGhF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAItE;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,WAAW,GAAG,CAClB,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,MAAM,CAChD,CAAC,WAAW,EAAiB,CAAC;IAE/B,QAAQ,WAAW,EAAE,CAAC;QACpB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YAC9C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;YAEtD,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC/B,OAAO,CAAC,KAAK,CACX,sGAAsG,CACvG,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,OAAO,CAAC,KAAK,CAAC,gDAAgD,GAAG,EAAE,CAAC,CAAC;YACrE,OAAO,IAAI,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC7C,CAAC;QAED,KAAK,MAAM,CAAC;QACZ,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,QAAQ,GACZ,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,yBAAyB,CAAC;YACvE,OAAO,CAAC,KAAK,CAAC,+CAA+C,QAAQ,EAAE,CAAC,CAAC;YACzE,OAAO,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { StorageBackend, MemoryNode, MemoryEdge, ScoredNode, Subgraph, NodeFilter, GraphStats } from "../types.js";
|
|
2
|
+
export declare class JsonStore implements StorageBackend {
|
|
3
|
+
private nodes;
|
|
4
|
+
private edges;
|
|
5
|
+
private lastConsolidated?;
|
|
6
|
+
private filePath;
|
|
7
|
+
constructor(filePath: string);
|
|
8
|
+
initialize(): Promise<void>;
|
|
9
|
+
private persist;
|
|
10
|
+
addNode(node: MemoryNode): Promise<void>;
|
|
11
|
+
updateNode(id: string, updates: Partial<MemoryNode>): Promise<MemoryNode | null>;
|
|
12
|
+
deleteNode(id: string): Promise<boolean>;
|
|
13
|
+
getNode(id: string): Promise<MemoryNode | null>;
|
|
14
|
+
getNodeByName(name: string): Promise<MemoryNode | null>;
|
|
15
|
+
findNodes(filter: NodeFilter): Promise<MemoryNode[]>;
|
|
16
|
+
getAllNodes(limit: number, offset: number): Promise<{
|
|
17
|
+
nodes: MemoryNode[];
|
|
18
|
+
total: number;
|
|
19
|
+
}>;
|
|
20
|
+
findNodesByEmbedding(embedding: number[], topK: number): Promise<ScoredNode[]>;
|
|
21
|
+
addEdge(edge: MemoryEdge): Promise<void>;
|
|
22
|
+
updateEdge(id: string, updates: Partial<MemoryEdge>): Promise<MemoryEdge | null>;
|
|
23
|
+
deleteEdge(id: string): Promise<boolean>;
|
|
24
|
+
getEdge(id: string): Promise<MemoryEdge | null>;
|
|
25
|
+
getEdgesForNode(nodeId: string, direction?: "in" | "out" | "both"): Promise<MemoryEdge[]>;
|
|
26
|
+
getEdgesBetween(sourceId: string, targetId: string): Promise<MemoryEdge[]>;
|
|
27
|
+
getNeighborhood(nodeId: string, depth: number): Promise<Subgraph>;
|
|
28
|
+
getStats(): Promise<GraphStats>;
|
|
29
|
+
close(): Promise<void>;
|
|
30
|
+
getNodesMap(): Map<string, MemoryNode>;
|
|
31
|
+
getEdgesMap(): Map<string, MemoryEdge>;
|
|
32
|
+
setLastConsolidated(timestamp: string): void;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=json-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-store.d.ts","sourceRoot":"","sources":["../../src/storage/json-store.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,cAAc,EACd,UAAU,EACV,UAAU,EACV,UAAU,EACV,QAAQ,EACR,UAAU,EACV,UAAU,EACX,MAAM,aAAa,CAAC;AAUrB,qBAAa,SAAU,YAAW,cAAc;IAC9C,OAAO,CAAC,KAAK,CAAsC;IACnD,OAAO,CAAC,KAAK,CAAsC;IACnD,OAAO,CAAC,gBAAgB,CAAC,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,EAAE,MAAM;IAItB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBjC,OAAO,CAAC,OAAO;IAmBT,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxC,UAAU,CACd,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,GAC3B,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAcvB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAcxC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAI/C,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAUvD,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAuBpD,WAAW,CACf,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,KAAK,EAAE,UAAU,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAQ5C,oBAAoB,CACxB,SAAS,EAAE,MAAM,EAAE,EACnB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,EAAE,CAAC;IAclB,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxC,UAAU,CACd,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,GAC3B,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAcvB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMxC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAI/C,eAAe,CACnB,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,IAAI,GAAG,KAAK,GAAG,MAAe,GACxC,OAAO,CAAC,UAAU,EAAE,CAAC;IAclB,eAAe,CACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,EAAE,CAAC;IAelB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IA2CjE,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC;IAe/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC;IAItC,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC;IAItC,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAI7C"}
|