@coreidentitylabs/open-graph-memory-mcp 1.0.1 → 1.0.3
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/README.md +74 -0
- package/dist/analysis/deep-analyzer.d.ts +66 -0
- package/dist/analysis/deep-analyzer.d.ts.map +1 -0
- package/dist/analysis/deep-analyzer.js +247 -0
- package/dist/analysis/deep-analyzer.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/tools/memory-tools.d.ts.map +1 -1
- package/dist/tools/memory-tools.js +102 -1
- package/dist/tools/memory-tools.js.map +1 -1
- package/package.json +11 -2
- package/.agents/skills/mcp-builder/LICENSE.txt +0 -202
- package/.agents/skills/mcp-builder/SKILL.md +0 -236
- package/.agents/skills/mcp-builder/reference/evaluation.md +0 -602
- package/.agents/skills/mcp-builder/reference/mcp_best_practices.md +0 -249
- package/.agents/skills/mcp-builder/reference/node_mcp_server.md +0 -970
- package/.agents/skills/mcp-builder/reference/python_mcp_server.md +0 -719
- package/.agents/skills/mcp-builder/scripts/connections.py +0 -151
- package/.agents/skills/mcp-builder/scripts/evaluation.py +0 -373
- package/.agents/skills/mcp-builder/scripts/example_evaluation.xml +0 -22
- package/.agents/skills/mcp-builder/scripts/requirements.txt +0 -2
- package/Implementation Plan.md +0 -358
- package/implementation_plan.md.resolved.md +0 -322
- package/src/constants.ts +0 -52
- package/src/encoding/embedder.ts +0 -93
- package/src/encoding/pipeline.ts +0 -197
- package/src/evolution/consolidator.ts +0 -281
- package/src/index.ts +0 -67
- package/src/llm/openai-provider.ts +0 -208
- package/src/llm/prompts.ts +0 -66
- package/src/llm/provider.ts +0 -37
- package/src/resources/context-resource.ts +0 -74
- package/src/retrieval/search.ts +0 -203
- package/src/storage/factory.ts +0 -48
- package/src/storage/json-store.ts +0 -325
- package/src/storage/neo4j-store.ts +0 -564
- package/src/tools/memory-tools.ts +0 -1067
- package/src/types.ts +0 -207
package/README.md
CHANGED
|
@@ -16,6 +16,7 @@ You chat with your AI assistant
|
|
|
16
16
|
↓ Calls memory_add_entities / memory_add_relations
|
|
17
17
|
↓ Entities stored in knowledge graph (JSON or Neo4j)
|
|
18
18
|
↓ Before next task, agent calls memory_search or memory_get_context
|
|
19
|
+
↓ Before complex tasks, agent calls memory_deep_analyze for rich multi-pass context
|
|
19
20
|
↓ Relevant historical context injected into prompt
|
|
20
21
|
= AI remembers your project across sessions
|
|
21
22
|
```
|
|
@@ -118,6 +119,44 @@ Add to your MCP config (e.g. `mcp_config.json`):
|
|
|
118
119
|
}
|
|
119
120
|
```
|
|
120
121
|
|
|
122
|
+
## Real-World Applications & Use Cases
|
|
123
|
+
|
|
124
|
+
Open-Memory is designed to solve specific challenges in complex, distributed, and fast-moving development environments:
|
|
125
|
+
|
|
126
|
+
### 1. Cross-Repository Microservices
|
|
127
|
+
|
|
128
|
+
In microservice architectures, knowledge is often fragmented across multiple repositories. Open-Memory acts as a decentralized knowledge bridge, allowing AI agents to:
|
|
129
|
+
|
|
130
|
+
- **Track Cross-Service Dependencies**: Remember how service A interacts with service B via specific API contracts or message schemas.
|
|
131
|
+
- **Maintain Architectural Consistency**: Store system-wide design patterns and security standards that apply to all repositories.
|
|
132
|
+
- **Unified Onboarding**: Help new developers (and AI agents) understand the "big picture" by querying a persistent graph of how various services fit together.
|
|
133
|
+
|
|
134
|
+
### 2. Guiding AI Agents with Full Context
|
|
135
|
+
|
|
136
|
+
Traditional context windows are transient. By using a persistent memory, you can "train" your AI agents over time:
|
|
137
|
+
|
|
138
|
+
- **Persistent Logic & Decisions**: Store the "why" behind past architectural choices so the AI doesn't suggest reverting them in future sessions.
|
|
139
|
+
- **Project-Specific Knowledge**: Maintain a record of non-obvious business logic, domain-specific terminology, and custom internal tools.
|
|
140
|
+
- **Contextual Recall**: When switching between tasks, the agent can call `memory_get_context` to instantly remember the relevant parts of the system it worked on last.
|
|
141
|
+
|
|
142
|
+
### 3. Rapidly Changing Codebases
|
|
143
|
+
|
|
144
|
+
When code is evolving fast, documentation often lags behind. Open-Memory helps keep pace by:
|
|
145
|
+
|
|
146
|
+
- **Tracking In-Flight Changes**: Store ongoing refactorings and temporary architectural shifts that haven't been finalized yet.
|
|
147
|
+
- **Delta Memory**: Use `memory_encode_text` to capture technical debt, "TODOs" discussed in chat, and emerging patterns before they are formally documented.
|
|
148
|
+
- **Change History**: Query how a specific module's purpose or implementation has evolved over several iterations based on previous developer-AI interactions.
|
|
149
|
+
|
|
150
|
+
### 4. Deep Analysis Before High-Stakes Decisions
|
|
151
|
+
|
|
152
|
+
Before architectural changes, major refactors, or complex feature work, agents can call `memory_deep_analyze` to get a rich structured report on any topic:
|
|
153
|
+
|
|
154
|
+
- **Key Entities by Centrality**: Surfaces the most connected concepts in the graph relevant to your topic
|
|
155
|
+
- **Cluster Detection**: Reveals hidden communities of related decisions, patterns, and code structures
|
|
156
|
+
- **Temporal Reasoning**: Shows how a technology, decision, or pattern evolved over calendar quarters
|
|
157
|
+
- **Contradiction Detection**: Automatically flags conflicting facts stored across different sessions
|
|
158
|
+
- **Suggested Next Steps**: Actionable pointers for deeper investigation before you commit to a direction
|
|
159
|
+
|
|
121
160
|
## Tools
|
|
122
161
|
|
|
123
162
|
### Write
|
|
@@ -139,6 +178,12 @@ Add to your MCP config (e.g. `mcp_config.json`):
|
|
|
139
178
|
| `memory_get_relations` | Get relationships for an entity |
|
|
140
179
|
| `memory_get_context` | Get formatted context for prompt injection |
|
|
141
180
|
|
|
181
|
+
### Analysis
|
|
182
|
+
|
|
183
|
+
| Tool | Description | LLM Required |
|
|
184
|
+
| --------------------- | ------------------------------------------------------------------------------- | :----------: |
|
|
185
|
+
| `memory_deep_analyze` | Multi-pass deep analysis: centrality, clusters, temporal trends, contradictions | ❌ |
|
|
186
|
+
|
|
142
187
|
### Management
|
|
143
188
|
|
|
144
189
|
| Tool | Description |
|
|
@@ -167,6 +212,8 @@ src/
|
|
|
167
212
|
│ └── prompts.ts # Extraction prompts
|
|
168
213
|
├── retrieval/
|
|
169
214
|
│ └── search.ts # Hybrid search engine
|
|
215
|
+
├── analysis/
|
|
216
|
+
│ └── deep-analyzer.ts # Multi-pass deep analysis engine
|
|
170
217
|
├── evolution/
|
|
171
218
|
│ └── consolidator.ts # Memory consolidation
|
|
172
219
|
├── tools/
|
|
@@ -182,6 +229,33 @@ src/
|
|
|
182
229
|
- **Encoding**: Optional server-side LLM pipeline (OpenAI, Ollama, Azure, etc.)
|
|
183
230
|
- **Transport**: stdio (standard for IDE integrations)
|
|
184
231
|
|
|
232
|
+
## References & Inspiration
|
|
233
|
+
|
|
234
|
+
### Core Research and Surveys
|
|
235
|
+
|
|
236
|
+
- **Yang, C., et al. (2026).** _Graph-based Agent Memory: Taxonomy, Techniques, and Applications._ This comprehensive survey provides the foundational taxonomy for structured topological models of experience, covering the memory lifecycle of extraction, storage, retrieval, and evolution.
|
|
237
|
+
- [Link: arXiv:2602.05665](https://arxiv.org/abs/2602.05665)
|
|
238
|
+
- [Repository: Awesome-GraphMemory](https://github.com/Graph-based-Agent-Memory)
|
|
239
|
+
- **Yusuke, S. (2026).** _Graph-Based Agent Memory: A Complete Guide to Structure, Retrieval, and Evolution._ A detailed synthesis of design patterns for AI agents to solve context window limitations using graph structures.
|
|
240
|
+
- [Link: Medium Article](https://medium.com/@yusuke_s/graph-based-agent-memory-a-complete-guide-to-structure-retrieval-and-evolution-6824b22fb75e)
|
|
241
|
+
|
|
242
|
+
### Architecture and Implementation Guides
|
|
243
|
+
|
|
244
|
+
- **Lyon, W. (GraphGeeks).** _Building Intelligent Memory: Graph Databases for AI Agent Context and Retrieval._ A practical implementation guide focusing on Neo4j, Dgraph, and the Model Context Protocol (MCP) to perform context engineering and solve "AI amnesia".
|
|
245
|
+
- [Link: YouTube Video](https://www.youtube.com/watch?v=lyon_w_graphgeeks)
|
|
246
|
+
- [Project Demo: Go Fetch (Graph Oriented Fast Edge Traversal)](https://github.com/graph-geeks/go-fetch)
|
|
247
|
+
- **MAGMA Architecture.** _Memory-Augmented Graph-based Multi-Agent Architecture._ This source details the four-layer graph model (Semantic, Temporal, Causal, and Entity) used for long-horizon task reasoning and dual-stream memory evolution.
|
|
248
|
+
- [Link: arXiv:2601.03236](https://arxiv.org/abs/2601.03236)
|
|
249
|
+
|
|
250
|
+
### Key Protocols
|
|
251
|
+
|
|
252
|
+
- **Model Context Protocol (MCP):** The standardized protocol used in this repository to expose graph memory search and storage tools to agents in VS Code and Google Antigravity.
|
|
253
|
+
- [Link: Model Context Protocol Official Site](https://modelcontextprotocol.io)
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
**Implementation Note:** This project, `open-graph-memory-mcp`, is an implementation of the Model Context Protocol (MCP) specifically designed to realize the Temporal and Knowledge Memory structures proposed in the research cited above.
|
|
258
|
+
|
|
185
259
|
## License
|
|
186
260
|
|
|
187
261
|
MIT
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { StorageBackend } from "../types.js";
|
|
2
|
+
export interface DeepAnalysisOptions {
|
|
3
|
+
topic: string;
|
|
4
|
+
/** Graph traversal depth from each seed node (default: 3) */
|
|
5
|
+
maxDepth?: number;
|
|
6
|
+
/** Number of seed nodes from initial hybrid search (default: 15) */
|
|
7
|
+
topK?: number;
|
|
8
|
+
/** Whether to include temporal trend analysis (default: true) */
|
|
9
|
+
includeTemporalAnalysis?: boolean;
|
|
10
|
+
/** Whether to detect topic clusters (default: true) */
|
|
11
|
+
includeClusters?: boolean;
|
|
12
|
+
/** Hard cap on nodes explored to bound performance (default: 100) */
|
|
13
|
+
maxNodes?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface ClusterSummary {
|
|
16
|
+
/** Most connected node in this cluster */
|
|
17
|
+
centroid: string;
|
|
18
|
+
members: string[];
|
|
19
|
+
sharedRelations: string[];
|
|
20
|
+
}
|
|
21
|
+
export interface TemporalInsight {
|
|
22
|
+
/** Calendar quarter, e.g. "2025-Q1" */
|
|
23
|
+
period: string;
|
|
24
|
+
activeEntities: string[];
|
|
25
|
+
decisions: string[];
|
|
26
|
+
trend: "growing" | "stable" | "declining";
|
|
27
|
+
}
|
|
28
|
+
export interface DeepAnalysisReport {
|
|
29
|
+
topic: string;
|
|
30
|
+
analyzedAt: string;
|
|
31
|
+
seedNodes: {
|
|
32
|
+
name: string;
|
|
33
|
+
type: string;
|
|
34
|
+
score: number;
|
|
35
|
+
}[];
|
|
36
|
+
totalNodesExplored: number;
|
|
37
|
+
totalEdgesTraversed: number;
|
|
38
|
+
keyEntities: {
|
|
39
|
+
name: string;
|
|
40
|
+
type: string;
|
|
41
|
+
centrality: number;
|
|
42
|
+
description: string;
|
|
43
|
+
}[];
|
|
44
|
+
criticalPaths: {
|
|
45
|
+
path: string[];
|
|
46
|
+
relations: string[];
|
|
47
|
+
significance: string;
|
|
48
|
+
}[];
|
|
49
|
+
clusters: ClusterSummary[];
|
|
50
|
+
temporalInsights: TemporalInsight[];
|
|
51
|
+
contradictions: {
|
|
52
|
+
entity: string;
|
|
53
|
+
conflictDescription: string;
|
|
54
|
+
}[];
|
|
55
|
+
synthesizedSummary: string;
|
|
56
|
+
suggestedNextSteps: string[];
|
|
57
|
+
/** 0–1: based on seed coverage and graph density around the topic */
|
|
58
|
+
confidence: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Multi-pass deep analysis of a topic across the memory graph.
|
|
62
|
+
* Returns a structured DeepAnalysisReport with key entities, clusters,
|
|
63
|
+
* temporal trends, contradictions, and actionable next steps.
|
|
64
|
+
*/
|
|
65
|
+
export declare function deepAnalyze(store: StorageBackend, options: DeepAnalysisOptions): Promise<DeepAnalysisReport>;
|
|
66
|
+
//# sourceMappingURL=deep-analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deep-analyzer.d.ts","sourceRoot":"","sources":["../../src/analysis/deep-analyzer.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAA0B,MAAM,aAAa,CAAC;AAW1E,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,uDAAuD;IACvD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;CAC3C;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3D,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACrB,EAAE,CAAC;IACJ,aAAa,EAAE;QACb,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;KACtB,EAAE,CAAC;IACJ,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,cAAc,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,mBAAmB,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAClE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CA8O7B"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Deep Analysis Engine — Multi-Pass Graph Analysis for Topic Context
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Performs 5 analysis passes to produce a structured DeepAnalysisReport:
|
|
5
|
+
// Pass 1: Seed Search — hybrid search to find top-K anchor nodes
|
|
6
|
+
// Pass 2: BFS Expansion — full subgraph traversal to configurable depth
|
|
7
|
+
// Pass 3: Centrality — degree centrality + cluster detection
|
|
8
|
+
// Pass 4: Temporal — timeline of decisions/events by quarter
|
|
9
|
+
// Pass 5: Contradictions — conflicting facts via cosine similarity
|
|
10
|
+
// Synthesis — key entities, critical paths, summary, next steps
|
|
11
|
+
// =============================================================================
|
|
12
|
+
import { hybridSearch } from "../retrieval/search.js";
|
|
13
|
+
import { generateLocalEmbedding, cosineSimilarity, } from "../encoding/embedder.js";
|
|
14
|
+
// =============================================================================
|
|
15
|
+
// Main Entry Point
|
|
16
|
+
// =============================================================================
|
|
17
|
+
/**
|
|
18
|
+
* Multi-pass deep analysis of a topic across the memory graph.
|
|
19
|
+
* Returns a structured DeepAnalysisReport with key entities, clusters,
|
|
20
|
+
* temporal trends, contradictions, and actionable next steps.
|
|
21
|
+
*/
|
|
22
|
+
export async function deepAnalyze(store, options) {
|
|
23
|
+
const { topic, maxDepth = 3, topK = 15, includeTemporalAnalysis = true, includeClusters = true, maxNodes = 100, } = options;
|
|
24
|
+
const analyzedAt = new Date().toISOString();
|
|
25
|
+
// ── Pass 1: Seed Search ───────────────────────────────────────────────────
|
|
26
|
+
const seedResults = await hybridSearch(store, { query: topic, topK });
|
|
27
|
+
const seedNodes = seedResults.nodes;
|
|
28
|
+
const visitedIds = new Set(seedNodes.map((n) => n.node.id));
|
|
29
|
+
const allNodes = new Map(seedNodes.map((n) => [n.node.id, n.node]));
|
|
30
|
+
const allEdges = new Map();
|
|
31
|
+
// ── Pass 2: BFS Subgraph Expansion ───────────────────────────────────────
|
|
32
|
+
let frontier = seedNodes.map((n) => n.node.id);
|
|
33
|
+
for (let depth = 0; depth < maxDepth && allNodes.size < maxNodes; depth++) {
|
|
34
|
+
const nextFrontier = [];
|
|
35
|
+
for (const nodeId of frontier) {
|
|
36
|
+
const subgraph = await store.getNeighborhood(nodeId, 1);
|
|
37
|
+
for (const edge of subgraph.edges) {
|
|
38
|
+
allEdges.set(edge.id, edge);
|
|
39
|
+
}
|
|
40
|
+
for (const neighbor of subgraph.nodes) {
|
|
41
|
+
if (!visitedIds.has(neighbor.id) && allNodes.size < maxNodes) {
|
|
42
|
+
visitedIds.add(neighbor.id);
|
|
43
|
+
allNodes.set(neighbor.id, neighbor);
|
|
44
|
+
nextFrontier.push(neighbor.id);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
frontier = nextFrontier;
|
|
49
|
+
if (frontier.length === 0)
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
// ── Pass 3: Centrality & Cluster Analysis ─────────────────────────────────
|
|
53
|
+
// Degree centrality: count edge connections per node
|
|
54
|
+
const degreeCentrality = new Map();
|
|
55
|
+
for (const edge of allEdges.values()) {
|
|
56
|
+
degreeCentrality.set(edge.source, (degreeCentrality.get(edge.source) ?? 0) + 1);
|
|
57
|
+
degreeCentrality.set(edge.target, (degreeCentrality.get(edge.target) ?? 0) + 1);
|
|
58
|
+
}
|
|
59
|
+
const edgeCount = Math.max(allEdges.size, 1);
|
|
60
|
+
const keyEntities = [...allNodes.values()]
|
|
61
|
+
.map((n) => ({
|
|
62
|
+
name: n.name,
|
|
63
|
+
type: n.type,
|
|
64
|
+
centrality: (degreeCentrality.get(n.id) ?? 0) / edgeCount,
|
|
65
|
+
description: n.description.substring(0, 300),
|
|
66
|
+
}))
|
|
67
|
+
.sort((a, b) => b.centrality - a.centrality)
|
|
68
|
+
.slice(0, 10);
|
|
69
|
+
// Cluster detection: community members around hub nodes
|
|
70
|
+
const clusters = [];
|
|
71
|
+
if (includeClusters) {
|
|
72
|
+
for (const hub of keyEntities.slice(0, 3)) {
|
|
73
|
+
const hubNode = [...allNodes.values()].find((n) => n.name === hub.name);
|
|
74
|
+
if (!hubNode)
|
|
75
|
+
continue;
|
|
76
|
+
const hubEdges = [...allEdges.values()].filter((e) => e.source === hubNode.id || e.target === hubNode.id);
|
|
77
|
+
const memberIds = new Set(hubEdges.flatMap((e) => [e.source, e.target]));
|
|
78
|
+
memberIds.delete(hubNode.id);
|
|
79
|
+
const members = [...memberIds]
|
|
80
|
+
.map((id) => allNodes.get(id)?.name)
|
|
81
|
+
.filter(Boolean);
|
|
82
|
+
const sharedRelations = [...new Set(hubEdges.map((e) => e.relation))];
|
|
83
|
+
if (members.length > 0) {
|
|
84
|
+
clusters.push({
|
|
85
|
+
centroid: hub.name,
|
|
86
|
+
members: members.slice(0, 8),
|
|
87
|
+
sharedRelations,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// ── Pass 4: Temporal Analysis ────────────────────────────────────────────
|
|
93
|
+
const temporalInsights = [];
|
|
94
|
+
if (includeTemporalAnalysis) {
|
|
95
|
+
const byQuarter = new Map();
|
|
96
|
+
for (const node of allNodes.values()) {
|
|
97
|
+
const d = new Date(node.createdAt);
|
|
98
|
+
const key = `${d.getFullYear()}-Q${Math.ceil((d.getMonth() + 1) / 3)}`;
|
|
99
|
+
if (!byQuarter.has(key))
|
|
100
|
+
byQuarter.set(key, []);
|
|
101
|
+
byQuarter.get(key).push(node);
|
|
102
|
+
}
|
|
103
|
+
const sortedPeriods = [...byQuarter.keys()].sort();
|
|
104
|
+
for (const period of sortedPeriods) {
|
|
105
|
+
const nodes = byQuarter.get(period);
|
|
106
|
+
const decisions = nodes
|
|
107
|
+
.filter((n) => n.type === "decision")
|
|
108
|
+
.map((n) => n.name);
|
|
109
|
+
const activeEntities = nodes
|
|
110
|
+
.filter((n) => n.type !== "conversation")
|
|
111
|
+
.map((n) => n.name)
|
|
112
|
+
.slice(0, 6);
|
|
113
|
+
const prevIdx = sortedPeriods.indexOf(period) - 1;
|
|
114
|
+
const prevCount = prevIdx >= 0 ? (byQuarter.get(sortedPeriods[prevIdx])?.length ?? 0) : 0;
|
|
115
|
+
const trend = nodes.length > prevCount
|
|
116
|
+
? "growing"
|
|
117
|
+
: nodes.length < prevCount
|
|
118
|
+
? "declining"
|
|
119
|
+
: "stable";
|
|
120
|
+
temporalInsights.push({ period, activeEntities, decisions, trend });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// ── Pass 5: Contradiction Detection ──────────────────────────────────────
|
|
124
|
+
// Heuristic: same-name nodes with semantically divergent descriptions
|
|
125
|
+
const contradictions = [];
|
|
126
|
+
const nameGroups = new Map();
|
|
127
|
+
for (const node of allNodes.values()) {
|
|
128
|
+
const key = node.name.toLowerCase();
|
|
129
|
+
if (!nameGroups.has(key))
|
|
130
|
+
nameGroups.set(key, []);
|
|
131
|
+
nameGroups.get(key).push(node);
|
|
132
|
+
}
|
|
133
|
+
for (const nodes of nameGroups.values()) {
|
|
134
|
+
if (nodes.length < 2)
|
|
135
|
+
continue;
|
|
136
|
+
const embedding0 = generateLocalEmbedding(nodes[0].description);
|
|
137
|
+
for (let i = 1; i < nodes.length; i++) {
|
|
138
|
+
const embeddingI = generateLocalEmbedding(nodes[i].description);
|
|
139
|
+
const sim = cosineSimilarity(embedding0, embeddingI);
|
|
140
|
+
if (sim < 0.5) {
|
|
141
|
+
contradictions.push({
|
|
142
|
+
entity: nodes[0].name,
|
|
143
|
+
conflictDescription: `Multiple descriptions with low similarity (${sim.toFixed(2)}): ` +
|
|
144
|
+
`"${nodes[0].description.substring(0, 100)}" vs ` +
|
|
145
|
+
`"${nodes[i].description.substring(0, 100)}"`,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// ── Critical Path Discovery ──────────────────────────────────────────────
|
|
151
|
+
const criticalPaths = discoverCriticalPaths(allEdges, allNodes, keyEntities.slice(0, 5));
|
|
152
|
+
// ── Synthesis ────────────────────────────────────────────────────────────
|
|
153
|
+
const topEntityNames = keyEntities
|
|
154
|
+
.slice(0, 5)
|
|
155
|
+
.map((e) => e.name)
|
|
156
|
+
.join(", ");
|
|
157
|
+
const synthesizedSummary = [
|
|
158
|
+
`Deep analysis of "${topic}" explored ${allNodes.size} nodes and ${allEdges.size} relationships.`,
|
|
159
|
+
keyEntities.length > 0
|
|
160
|
+
? `Key entities by centrality: ${topEntityNames}.`
|
|
161
|
+
: "",
|
|
162
|
+
clusters.length > 0
|
|
163
|
+
? `Identified ${clusters.length} cluster(s) around: ${clusters.map((c) => c.centroid).join(", ")}.`
|
|
164
|
+
: "",
|
|
165
|
+
contradictions.length > 0
|
|
166
|
+
? `⚠️ ${contradictions.length} potential contradiction(s) detected.`
|
|
167
|
+
: "",
|
|
168
|
+
temporalInsights.length > 0
|
|
169
|
+
? `Temporal span: ${temporalInsights[0].period} → ${temporalInsights.at(-1).period}.`
|
|
170
|
+
: "",
|
|
171
|
+
]
|
|
172
|
+
.filter(Boolean)
|
|
173
|
+
.join(" ");
|
|
174
|
+
const suggestedNextSteps = buildSuggestedNextSteps(keyEntities, contradictions, clusters);
|
|
175
|
+
// Confidence = seed coverage ratio + edge density factor (0–1)
|
|
176
|
+
const edgeDensity = allEdges.size / Math.max(allNodes.size, 1);
|
|
177
|
+
const confidence = Math.min(1, (seedNodes.length / topK) * 0.5 + Math.min(edgeDensity / 5, 0.5));
|
|
178
|
+
// Update access counts for all explored nodes
|
|
179
|
+
for (const [id, node] of allNodes.entries()) {
|
|
180
|
+
await store.updateNode(id, {
|
|
181
|
+
accessCount: node.accessCount + 1,
|
|
182
|
+
lastAccessedAt: analyzedAt,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
topic,
|
|
187
|
+
analyzedAt,
|
|
188
|
+
seedNodes: seedNodes.map((n) => ({
|
|
189
|
+
name: n.node.name,
|
|
190
|
+
type: n.node.type,
|
|
191
|
+
score: n.score,
|
|
192
|
+
})),
|
|
193
|
+
totalNodesExplored: allNodes.size,
|
|
194
|
+
totalEdgesTraversed: allEdges.size,
|
|
195
|
+
keyEntities,
|
|
196
|
+
criticalPaths,
|
|
197
|
+
clusters,
|
|
198
|
+
temporalInsights,
|
|
199
|
+
contradictions,
|
|
200
|
+
synthesizedSummary,
|
|
201
|
+
suggestedNextSteps,
|
|
202
|
+
confidence,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
// =============================================================================
|
|
206
|
+
// Private Helpers
|
|
207
|
+
// =============================================================================
|
|
208
|
+
function discoverCriticalPaths(allEdges, allNodes, topEntities) {
|
|
209
|
+
const paths = [];
|
|
210
|
+
for (let i = 0; i < topEntities.length - 1; i++) {
|
|
211
|
+
const fromName = topEntities[i].name;
|
|
212
|
+
const toName = topEntities[i + 1].name;
|
|
213
|
+
const fromNode = [...allNodes.values()].find((n) => n.name === fromName);
|
|
214
|
+
const toNode = [...allNodes.values()].find((n) => n.name === toName);
|
|
215
|
+
if (!fromNode || !toNode)
|
|
216
|
+
continue;
|
|
217
|
+
const directEdge = [...allEdges.values()].find((e) => (e.source === fromNode.id && e.target === toNode.id) ||
|
|
218
|
+
(e.source === toNode.id && e.target === fromNode.id));
|
|
219
|
+
if (directEdge) {
|
|
220
|
+
paths.push({
|
|
221
|
+
path: [fromName, toName],
|
|
222
|
+
relations: [directEdge.relation],
|
|
223
|
+
significance: "Direct link between two high-centrality entities",
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return paths.slice(0, 5);
|
|
228
|
+
}
|
|
229
|
+
function buildSuggestedNextSteps(keyEntities, contradictions, clusters) {
|
|
230
|
+
const steps = [];
|
|
231
|
+
if (contradictions.length > 0) {
|
|
232
|
+
steps.push(`Resolve contradictions for: ${contradictions.map((c) => c.entity).join(", ")}`);
|
|
233
|
+
}
|
|
234
|
+
const decisions = keyEntities.filter((e) => e.type === "decision");
|
|
235
|
+
if (decisions.length > 0) {
|
|
236
|
+
steps.push(`Review key decisions: ${decisions.map((e) => e.name).join(", ")}`);
|
|
237
|
+
}
|
|
238
|
+
if (clusters.length > 1) {
|
|
239
|
+
steps.push(`Investigate cluster relationships between "${clusters[0].centroid}" and "${clusters[1].centroid}"`);
|
|
240
|
+
}
|
|
241
|
+
steps.push(`Run memory_search with refined queries based on: ${keyEntities
|
|
242
|
+
.slice(0, 3)
|
|
243
|
+
.map((e) => e.name)
|
|
244
|
+
.join(", ")}`);
|
|
245
|
+
return steps.slice(0, 5);
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=deep-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deep-analyzer.js","sourceRoot":"","sources":["../../src/analysis/deep-analyzer.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ async function main() {
|
|
|
31
31
|
// 4. Register tools and resources
|
|
32
32
|
registerMemoryTools(server, store, llm);
|
|
33
33
|
registerMemoryResources(server, store);
|
|
34
|
-
const toolCount = llm ?
|
|
34
|
+
const toolCount = llm ? 13 : 12;
|
|
35
35
|
console.error(`[open-memory] Registered ${toolCount} tools and 2 resources`);
|
|
36
36
|
// 5. Connect via stdio transport
|
|
37
37
|
const transport = new StdioServerTransport();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-tools.d.ts","sourceRoot":"","sources":["../../src/tools/memory-tools.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,KAAK,EACV,cAAc,EAKd,WAAW,EACZ,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"memory-tools.d.ts","sourceRoot":"","sources":["../../src/tools/memory-tools.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,KAAK,EACV,cAAc,EAKd,WAAW,EACZ,MAAM,aAAa,CAAC;AAgBrB,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,cAAc,EACrB,GAAG,CAAC,EAAE,WAAW,GAAG,IAAI,GACvB,IAAI,CAiCN"}
|
|
@@ -7,6 +7,7 @@ import { generateLocalEmbedding } from "../encoding/embedder.js";
|
|
|
7
7
|
import { hybridSearch, getContextForTopic } from "../retrieval/search.js";
|
|
8
8
|
import { consolidateMemory } from "../evolution/consolidator.js";
|
|
9
9
|
import { encodeText } from "../encoding/pipeline.js";
|
|
10
|
+
import { deepAnalyze } from "../analysis/deep-analyzer.js";
|
|
10
11
|
import { DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE, CHARACTER_LIMIT, } from "../constants.js";
|
|
11
12
|
// =============================================================================
|
|
12
13
|
// Tool Registration
|
|
@@ -26,6 +27,8 @@ export function registerMemoryTools(server, store, llm) {
|
|
|
26
27
|
registerDeleteEntity(server, store);
|
|
27
28
|
registerConsolidate(server, store);
|
|
28
29
|
registerStatus(server, store);
|
|
30
|
+
// ---- ANALYSIS TOOLS ----
|
|
31
|
+
registerDeepAnalyze(server, store);
|
|
29
32
|
// ---- OPTIONAL SERVER-SIDE ENCODING ----
|
|
30
33
|
if (llm) {
|
|
31
34
|
registerEncodeText(server, store, llm);
|
|
@@ -433,10 +436,12 @@ Provide either entity name or ID.`,
|
|
|
433
436
|
};
|
|
434
437
|
}
|
|
435
438
|
// Update access count
|
|
436
|
-
await store.updateNode(node.id, {
|
|
439
|
+
const updatedNode = await store.updateNode(node.id, {
|
|
437
440
|
accessCount: node.accessCount + 1,
|
|
438
441
|
lastAccessedAt: new Date().toISOString(),
|
|
439
442
|
});
|
|
443
|
+
if (updatedNode)
|
|
444
|
+
node = updatedNode;
|
|
440
445
|
// Get relationships
|
|
441
446
|
const edges = await store.getEdgesForNode(node.id);
|
|
442
447
|
// Resolve edge node names
|
|
@@ -856,6 +861,102 @@ Set autoStore=false to preview extraction results without saving.`,
|
|
|
856
861
|
});
|
|
857
862
|
}
|
|
858
863
|
// =============================================================================
|
|
864
|
+
// Analysis Tools
|
|
865
|
+
// =============================================================================
|
|
866
|
+
function registerDeepAnalyze(server, store) {
|
|
867
|
+
const InputSchema = z.object({
|
|
868
|
+
topic: z
|
|
869
|
+
.string()
|
|
870
|
+
.min(1)
|
|
871
|
+
.describe("The topic or question to perform deep analysis on"),
|
|
872
|
+
maxDepth: z
|
|
873
|
+
.number()
|
|
874
|
+
.int()
|
|
875
|
+
.min(1)
|
|
876
|
+
.max(5)
|
|
877
|
+
.default(3)
|
|
878
|
+
.describe("Graph traversal depth from each seed node (1=shallow, 5=deep)"),
|
|
879
|
+
topK: z
|
|
880
|
+
.number()
|
|
881
|
+
.int()
|
|
882
|
+
.min(5)
|
|
883
|
+
.max(30)
|
|
884
|
+
.default(15)
|
|
885
|
+
.describe("Number of seed nodes from initial hybrid search"),
|
|
886
|
+
includeTemporalAnalysis: z
|
|
887
|
+
.boolean()
|
|
888
|
+
.default(true)
|
|
889
|
+
.describe("Include temporal trend analysis grouped by calendar quarter"),
|
|
890
|
+
includeClusters: z
|
|
891
|
+
.boolean()
|
|
892
|
+
.default(true)
|
|
893
|
+
.describe("Detect topic clusters around hub entities"),
|
|
894
|
+
maxNodes: z
|
|
895
|
+
.number()
|
|
896
|
+
.int()
|
|
897
|
+
.min(20)
|
|
898
|
+
.max(200)
|
|
899
|
+
.default(100)
|
|
900
|
+
.describe("Hard cap on nodes explored — keeps performance bounded"),
|
|
901
|
+
});
|
|
902
|
+
server.registerTool("memory_deep_analyze", {
|
|
903
|
+
title: "Deep Analysis of a Topic",
|
|
904
|
+
description: `Perform multi-pass, graph-aware deep analysis of a topic across the entire memory graph.
|
|
905
|
+
|
|
906
|
+
Goes far beyond memory_search by running 5 structured passes:
|
|
907
|
+
1. Seed Search — hybrid search to find top-K anchor nodes
|
|
908
|
+
2. BFS Expansion — full subgraph traversal to configurable depth
|
|
909
|
+
3. Centrality/Cluster — surface hub entities and topic communities
|
|
910
|
+
4. Temporal Analysis — trend timeline grouped by quarter
|
|
911
|
+
5. Contradiction Check — flags conflicting facts via semantic similarity
|
|
912
|
+
|
|
913
|
+
Use before major decisions, refactors, or complex implementations.
|
|
914
|
+
Returns: DeepAnalysisReport with keyEntities, clusters, temporalInsights, contradictions, synthesizedSummary, and suggestedNextSteps.`,
|
|
915
|
+
inputSchema: InputSchema,
|
|
916
|
+
annotations: {
|
|
917
|
+
readOnlyHint: true,
|
|
918
|
+
destructiveHint: false,
|
|
919
|
+
idempotentHint: false, // updates access counts
|
|
920
|
+
openWorldHint: false,
|
|
921
|
+
},
|
|
922
|
+
}, async (params) => {
|
|
923
|
+
try {
|
|
924
|
+
const report = await deepAnalyze(store, {
|
|
925
|
+
topic: params.topic,
|
|
926
|
+
maxDepth: params.maxDepth,
|
|
927
|
+
topK: params.topK,
|
|
928
|
+
includeTemporalAnalysis: params.includeTemporalAnalysis,
|
|
929
|
+
includeClusters: params.includeClusters,
|
|
930
|
+
maxNodes: params.maxNodes,
|
|
931
|
+
});
|
|
932
|
+
let text = JSON.stringify(report, null, 2);
|
|
933
|
+
if (text.length > CHARACTER_LIMIT) {
|
|
934
|
+
// Slim down to essentials when exceeding the token budget
|
|
935
|
+
const slim = {
|
|
936
|
+
topic: report.topic,
|
|
937
|
+
analyzedAt: report.analyzedAt,
|
|
938
|
+
totalNodesExplored: report.totalNodesExplored,
|
|
939
|
+
totalEdgesTraversed: report.totalEdgesTraversed,
|
|
940
|
+
confidence: report.confidence,
|
|
941
|
+
keyEntities: report.keyEntities.slice(0, 5),
|
|
942
|
+
clusters: report.clusters.slice(0, 2),
|
|
943
|
+
contradictions: report.contradictions.slice(0, 3),
|
|
944
|
+
synthesizedSummary: report.synthesizedSummary,
|
|
945
|
+
suggestedNextSteps: report.suggestedNextSteps,
|
|
946
|
+
truncated: true,
|
|
947
|
+
};
|
|
948
|
+
text = JSON.stringify(slim, null, 2);
|
|
949
|
+
}
|
|
950
|
+
return {
|
|
951
|
+
content: [{ type: "text", text }],
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
catch (error) {
|
|
955
|
+
return errorResponse(error);
|
|
956
|
+
}
|
|
957
|
+
});
|
|
958
|
+
}
|
|
959
|
+
// =============================================================================
|
|
859
960
|
// Helpers
|
|
860
961
|
// =============================================================================
|
|
861
962
|
function errorResponse(error) {
|