@datafrog-io/n2n-memory 1.0.2 → 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/CHANGELOG.md +60 -0
- package/LICENSE +21 -21
- package/README.md +89 -125
- package/build/core/memory-manager.js +141 -0
- package/build/core/memory-manager.js.map +1 -0
- package/build/core/memory-service.js +340 -0
- package/build/core/memory-service.js.map +1 -0
- package/build/handlers/mcp-handlers.js +258 -0
- package/build/handlers/mcp-handlers.js.map +1 -0
- package/build/index.js +28 -236
- package/build/index.js.map +1 -1
- package/build/tools/definitions.js +67 -0
- package/build/tools/definitions.js.map +1 -0
- package/build/tools/schemas.js +79 -0
- package/build/tools/schemas.js.map +1 -0
- package/build/types.js +8 -0
- package/build/types.js.map +1 -1
- package/build/utils/env.js +27 -0
- package/build/utils/env.js.map +1 -0
- package/build/utils/path-utils.js +62 -0
- package/build/utils/path-utils.js.map +1 -0
- package/package.json +22 -8
- package/build/memory-manager.js +0 -102
- package/build/memory-manager.js.map +0 -1
- package/docs/API_REFERENCE.md +0 -70
- package/docs/DESIGN.md +0 -52
- package/docs/DEVELOPMENT.md +0 -54
package/build/memory-manager.js
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import fs from "fs-extra";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import { KnowledgeGraphSchema } from "./types.js";
|
|
4
|
-
export const MEMORY_FILE_PATH = ".mcp/memory.json";
|
|
5
|
-
export class MemoryManager {
|
|
6
|
-
static async readGraph(projectPath) {
|
|
7
|
-
const filePath = path.resolve(projectPath, MEMORY_FILE_PATH);
|
|
8
|
-
try {
|
|
9
|
-
if (await fs.pathExists(filePath)) {
|
|
10
|
-
const data = await fs.readJson(filePath);
|
|
11
|
-
return KnowledgeGraphSchema.parse(data);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
catch (error) {
|
|
15
|
-
throw new Error(`Failed to read memory file at ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
16
|
-
}
|
|
17
|
-
return { entities: [], relations: [] };
|
|
18
|
-
}
|
|
19
|
-
static async writeGraph(projectPath, graph) {
|
|
20
|
-
const filePath = path.resolve(projectPath, MEMORY_FILE_PATH);
|
|
21
|
-
const dirPath = path.dirname(filePath);
|
|
22
|
-
try {
|
|
23
|
-
// Git-friendly sorting
|
|
24
|
-
graph.entities.sort((a, b) => a.name.localeCompare(b.name));
|
|
25
|
-
graph.entities.forEach(entity => {
|
|
26
|
-
if (entity.observations) {
|
|
27
|
-
entity.observations.sort();
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
entity.observations = [];
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
graph.relations.sort((a, b) => {
|
|
34
|
-
const fromComp = a.from.localeCompare(b.from);
|
|
35
|
-
if (fromComp !== 0)
|
|
36
|
-
return fromComp;
|
|
37
|
-
const toComp = a.to.localeCompare(b.to);
|
|
38
|
-
if (toComp !== 0)
|
|
39
|
-
return toComp;
|
|
40
|
-
return a.relationType.localeCompare(b.relationType);
|
|
41
|
-
});
|
|
42
|
-
await fs.ensureDir(dirPath);
|
|
43
|
-
await fs.writeJson(filePath, graph, { spaces: 2 });
|
|
44
|
-
}
|
|
45
|
-
catch (error) {
|
|
46
|
-
throw new Error(`Failed to write memory file at ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
static async addEntities(projectPath, newEntities) {
|
|
50
|
-
const graph = await this.readGraph(projectPath);
|
|
51
|
-
newEntities.forEach(newEntity => {
|
|
52
|
-
const existing = graph.entities.find(e => e.name === newEntity.name);
|
|
53
|
-
if (existing) {
|
|
54
|
-
existing.observations = Array.from(new Set([...existing.observations, ...newEntity.observations]));
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
graph.entities.push(newEntity);
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
await this.writeGraph(projectPath, graph);
|
|
61
|
-
}
|
|
62
|
-
static async addObservations(projectPath, observations) {
|
|
63
|
-
const graph = await this.readGraph(projectPath);
|
|
64
|
-
let addedCount = 0;
|
|
65
|
-
observations.forEach(obs => {
|
|
66
|
-
const entity = graph.entities.find(e => e.name === obs.entityName);
|
|
67
|
-
if (entity) {
|
|
68
|
-
entity.observations = Array.from(new Set([...entity.observations, ...obs.contents]));
|
|
69
|
-
addedCount += obs.contents.length;
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
await this.writeGraph(projectPath, graph);
|
|
73
|
-
return addedCount;
|
|
74
|
-
}
|
|
75
|
-
static async createRelations(projectPath, newRelations) {
|
|
76
|
-
const graph = await this.readGraph(projectPath);
|
|
77
|
-
newRelations.forEach(newRel => {
|
|
78
|
-
const exists = graph.relations.some(r => r.from === newRel.from && r.to === newRel.to && r.relationType === newRel.relationType);
|
|
79
|
-
if (!exists) {
|
|
80
|
-
graph.relations.push(newRel);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
await this.writeGraph(projectPath, graph);
|
|
84
|
-
}
|
|
85
|
-
static async search(projectPath, query) {
|
|
86
|
-
const graph = await this.readGraph(projectPath);
|
|
87
|
-
const lowerQuery = query.toLowerCase();
|
|
88
|
-
const filteredEntities = graph.entities.filter(e => e.name.toLowerCase().includes(lowerQuery) ||
|
|
89
|
-
e.entityType.toLowerCase().includes(lowerQuery) ||
|
|
90
|
-
e.observations.some(o => o.toLowerCase().includes(lowerQuery)));
|
|
91
|
-
const entityNames = new Set(filteredEntities.map(e => e.name));
|
|
92
|
-
const filteredRelations = graph.relations.filter(r => r.from.toLowerCase().includes(lowerQuery) ||
|
|
93
|
-
r.to.toLowerCase().includes(lowerQuery) ||
|
|
94
|
-
r.relationType.toLowerCase().includes(lowerQuery) ||
|
|
95
|
-
(entityNames.has(r.from) || entityNames.has(r.to)));
|
|
96
|
-
return {
|
|
97
|
-
entities: filteredEntities,
|
|
98
|
-
relations: filteredRelations
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
//# sourceMappingURL=memory-manager.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"memory-manager.js","sourceRoot":"","sources":["../src/memory-manager.ts"],"names":[],"mappings":"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"}
|
package/docs/API_REFERENCE.md
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
# n2n-memory API 参考手册
|
|
2
|
-
|
|
3
|
-
本项目提供了一套基于项目本地路径的知识图谱管理工具。所有工具均要求传入 `projectPath` 以确保记忆的物理隔离。
|
|
4
|
-
|
|
5
|
-
## 核心工具集
|
|
6
|
-
|
|
7
|
-
### 1. `project_add_entities`
|
|
8
|
-
向项目的知识图谱中添加新的实体(名词/概念)。
|
|
9
|
-
|
|
10
|
-
**输入参数:**
|
|
11
|
-
- `projectPath` (string): 项目根目录的绝对路径。
|
|
12
|
-
- `entities` (Array): 实体对象列表。
|
|
13
|
-
- `name` (string): 实体名称(唯一标识)。
|
|
14
|
-
- `entityType` (string): 实体类型(如:CONCEPT, COMPONENT, BUG)。
|
|
15
|
-
- `observations` (string[]): 关于该实体的观测事实。
|
|
16
|
-
|
|
17
|
-
**逻辑描述:**
|
|
18
|
-
- 如果实体名称已存在,将合并 `observations` 并自动去重。
|
|
19
|
-
- 写入前会对实体名称进行字典序排序。
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
### 2. `project_add_observations`
|
|
24
|
-
为已存在的实体追加新的发现或事实。
|
|
25
|
-
|
|
26
|
-
**输入参数:**
|
|
27
|
-
- `projectPath` (string): 项目根目录的绝对路径。
|
|
28
|
-
- `observations` (Array):
|
|
29
|
-
- `entityName` (string): 目标实体名称。
|
|
30
|
-
- `contents` (string[]): 要追加的事实列表。
|
|
31
|
-
|
|
32
|
-
**逻辑描述:**
|
|
33
|
-
- 仅当实体存在时才会添加。
|
|
34
|
-
- 自动对 observation 内容执行字典序排序及去重。
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
### 3. `project_create_relations`
|
|
39
|
-
在实体之间建立逻辑关系(谓词)。
|
|
40
|
-
|
|
41
|
-
**输入参数:**
|
|
42
|
-
- `projectPath` (string): 项目根目录的绝对路径。
|
|
43
|
-
- `relations` (Array):
|
|
44
|
-
- `from` (string): 源实体名称。
|
|
45
|
-
- `to` (string): 目标实体名称。
|
|
46
|
-
- `relationType` (string): 关系类型(如:DEPENDS_ON, IMPLEMENTS)。
|
|
47
|
-
|
|
48
|
-
**逻辑描述:**
|
|
49
|
-
- 自动过滤完全重复的关系定义,防止数据冗余。
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
### 4. `project_read_graph`
|
|
54
|
-
读取指定项目的完整知识图谱。
|
|
55
|
-
|
|
56
|
-
**输入参数:**
|
|
57
|
-
- `projectPath` (string): 项目根目录的绝对路径。
|
|
58
|
-
|
|
59
|
-
**返回:**
|
|
60
|
-
- 包含 `entities` 和 `relations` 的标准 JSON 对象。
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
## 数据存储规范
|
|
65
|
-
- **路径**: `.mcp/memory.json`
|
|
66
|
-
- **格式**: 2 空格缩进的 JSON。
|
|
67
|
-
- **排序策略**:
|
|
68
|
-
- 实体:按 `name` 排序。
|
|
69
|
-
- 关系:按 `from` -> `to` -> `type` 排序。
|
|
70
|
-
- 观测:按字母序排序。
|
package/docs/DESIGN.md
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
# n2n-memory 开发方案
|
|
2
|
-
|
|
3
|
-
## 1. 背景与目标
|
|
4
|
-
解决全局 MCP Memory Server 导致的跨项目“记忆污染”与幻觉问题。通过将 AI 的认知碎片直接持久化在项目源码目录下,实现项目级的物理隔离与知识共享。
|
|
5
|
-
|
|
6
|
-
本项目旨在开发一个高度简约、工具中立、且对版本管理友好的 N2N 记忆服务。
|
|
7
|
-
|
|
8
|
-
## 2. 核心架构设计
|
|
9
|
-
|
|
10
|
-
### 2.1 存储逻辑
|
|
11
|
-
- **存储位置**: `[项目根目录]/.mcp/memory.json`
|
|
12
|
-
- **中立性**: 采用 `.mcp` 命名以脱离特定 AI 助手或 IDE 插件的品牌绑定。
|
|
13
|
-
- **物理隔离**: 一个项目一个文件,互不干扰,完全随项目代码同步。
|
|
14
|
-
|
|
15
|
-
### 2.2 交互规范
|
|
16
|
-
- **寻址方式**: AI 助理在调用工具时,必须传递当前工作区的**绝对路径 (Absolute Path)**。
|
|
17
|
-
- **无状态设计**: MCP Server 进程本身不维护任何路径状态,仅作为由路径驱动的存取器。
|
|
18
|
-
- **自动初始化**: 若目标路径下的 `.mcp/memory.json` 不存在,Server 应自动创建标准的空图谱结构。
|
|
19
|
-
|
|
20
|
-
## 3. 数据结构与检索
|
|
21
|
-
|
|
22
|
-
### 3.1 极简数据格式
|
|
23
|
-
JSON 内部**不包含**版本号、元数据、作者信息或时间戳。仅保留核心知识图谱数据(Entities & Relations),通过 Git 记录实现版本审计。
|
|
24
|
-
|
|
25
|
-
### 3.2 Git 友好型保存策略
|
|
26
|
-
为确保 `git diff` 可读:
|
|
27
|
-
1. **强制排序**: 对 `entities` 和 `relations` 执行字典序排序。
|
|
28
|
-
2. **规范缩进**: 统一使用 2 空格缩进。
|
|
29
|
-
|
|
30
|
-
### 3.3 分级检索机制 (Tiered Retrieval)
|
|
31
|
-
- **一级:精准检索**: 基于实体 ID 的 O(1) 匹配,保证逻辑严密性。
|
|
32
|
-
- **二级:语义理解**: AI 助手加载全量 JSON 后,利用模型自身的长上下文理解力处理模糊匹配,无需引入向量数据库。
|
|
33
|
-
|
|
34
|
-
## 4. 开发语言效率分析 (Go vs. Node.js vs. Python)
|
|
35
|
-
|
|
36
|
-
### 4.1 Node.js (TypeScript) - [默认推荐]
|
|
37
|
-
- **效率**: 开发效率极高,官方 SDK 最成熟。
|
|
38
|
-
- **性能**: 处理单个项目的 JSON(通常 < 10MB)绰绰有余。
|
|
39
|
-
- **分发**: 通过 `npx` 可实现免安装运行。
|
|
40
|
-
|
|
41
|
-
### 4.2 Go - [极致性能选型]
|
|
42
|
-
- **效率**: 运行效率最高,内存占用极低(仅需几 MB)。
|
|
43
|
-
- **分发**: 编译为单一二进制文件(Single Binary),部署最干净,适合对 IDE 性能有极致要求的用户。
|
|
44
|
-
- **场景**: 若未来需要处理拥有数万个节点的超大型知识图谱,Go 是唯一选择。
|
|
45
|
-
|
|
46
|
-
### 4.3 Python - [不推荐]
|
|
47
|
-
- **缺点**: 环境依赖重,分发困难,对于简单的、非 AI 计算密集的 I/O 任务显得过于沉重。
|
|
48
|
-
|
|
49
|
-
## 5. 优势总结
|
|
50
|
-
- **资产化**: 记忆即源码,可审计、可共享。
|
|
51
|
-
- **零漂移**: 物理隔离,杜绝跨项目污染。
|
|
52
|
-
- **确定性**: 结构化数据比高性能向量数据库更适合高精度的编码决策场景。
|
package/docs/DEVELOPMENT.md
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
# n2n-memory 开发指南
|
|
2
|
-
|
|
3
|
-
本手册记录了 N2N Memory MCP Server 的日常开发、测试及构建流程。
|
|
4
|
-
|
|
5
|
-
## 开发环境
|
|
6
|
-
- **Runtime**: Node.js v22.x+
|
|
7
|
-
- **Language**: TypeScript
|
|
8
|
-
- **Package Manager**: npm
|
|
9
|
-
|
|
10
|
-
## 常用指令
|
|
11
|
-
|
|
12
|
-
### 1. 安装依赖
|
|
13
|
-
```bash
|
|
14
|
-
npm install
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
### 2. 运行测试
|
|
18
|
-
本项目使用 `mocha` + `sinon` 执行单元测试。
|
|
19
|
-
```bash
|
|
20
|
-
npm test
|
|
21
|
-
```
|
|
22
|
-
> **注意**: 在 Windows 环境下,测试脚本已配置为使用 `tsx --import` 以正确处理 ESM 路径兼容性。
|
|
23
|
-
|
|
24
|
-
### 3. 开发模式 (热更新)
|
|
25
|
-
```bash
|
|
26
|
-
npm run dev
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
### 4. 生产构建
|
|
30
|
-
将 TypeScript 编译为原生 JavaScript(输出到 `build/` 目录)。
|
|
31
|
-
```bash
|
|
32
|
-
npm run build
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### 5. 启动服务
|
|
36
|
-
```bash
|
|
37
|
-
npm start
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## 核心架构说明
|
|
41
|
-
|
|
42
|
-
### 逻辑分层
|
|
43
|
-
1. **`index.ts`**: MCP 协议层。负责处理 JSON-RPC、Resources 接口,并使用 **Zod** 进行输入校验。
|
|
44
|
-
2. **`memory-manager.ts`**: 业务逻辑层。负责文件 I/O、数据排序、实体合并等核心算法。
|
|
45
|
-
3. **`types.ts`**: 类型与 Schema 定义。包含 Zod 校验规则,是整个项目的类型基准。
|
|
46
|
-
|
|
47
|
-
### 关键算法:Git 友好排序
|
|
48
|
-
每当执行写操作(Update/Create)时,`MemoryManager.writeGraph` 会被触发:
|
|
49
|
-
- 它会递归地对数组进行 `localeCompare` 排序。
|
|
50
|
-
- 这样做的目的是保证即使 AI 乱序生成了记忆片段,存入 Git 的文件 diff 依然是稳定且可读的。
|
|
51
|
-
|
|
52
|
-
## 贡献指南
|
|
53
|
-
- 所有的逻辑变更必须附带相应的单元测试。
|
|
54
|
-
- 修改存储结构前,请先更新 `docs/DESIGN.md`。
|