@yun-zero/claw-memory 0.1.0
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/.claude/settings.local.json +68 -0
- package/README.md +323 -0
- package/dist/config/llm.d.ts +13 -0
- package/dist/config/llm.d.ts.map +1 -0
- package/dist/config/llm.js +96 -0
- package/dist/config/llm.js.map +1 -0
- package/dist/config/plugin.d.ts +15 -0
- package/dist/config/plugin.d.ts.map +1 -0
- package/dist/config/plugin.js +32 -0
- package/dist/config/plugin.js.map +1 -0
- package/dist/db/entityRepository.d.ts +21 -0
- package/dist/db/entityRepository.d.ts.map +1 -0
- package/dist/db/entityRepository.js +55 -0
- package/dist/db/entityRepository.js.map +1 -0
- package/dist/db/repository.d.ts +22 -0
- package/dist/db/repository.d.ts.map +1 -0
- package/dist/db/repository.js +77 -0
- package/dist/db/repository.js.map +1 -0
- package/dist/db/schema.d.ts +5 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +112 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/db/todoRepository.d.ts +26 -0
- package/dist/db/todoRepository.d.ts.map +1 -0
- package/dist/db/todoRepository.js +54 -0
- package/dist/db/todoRepository.js.map +1 -0
- package/dist/hooks/bootstrap.d.ts +3 -0
- package/dist/hooks/bootstrap.d.ts.map +1 -0
- package/dist/hooks/bootstrap.js +28 -0
- package/dist/hooks/bootstrap.js.map +1 -0
- package/dist/hooks/message.d.ts +18 -0
- package/dist/hooks/message.d.ts.map +1 -0
- package/dist/hooks/message.js +52 -0
- package/dist/hooks/message.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/tools.d.ts +26 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +360 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/plugin.d.ts +18 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +62 -0
- package/dist/plugin.js.map +1 -0
- package/dist/services/entityGraphService.d.ts +87 -0
- package/dist/services/entityGraphService.d.ts.map +1 -0
- package/dist/services/entityGraphService.js +271 -0
- package/dist/services/entityGraphService.js.map +1 -0
- package/dist/services/memory.d.ts +26 -0
- package/dist/services/memory.d.ts.map +1 -0
- package/dist/services/memory.js +281 -0
- package/dist/services/memory.js.map +1 -0
- package/dist/services/memoryIndex.d.ts +34 -0
- package/dist/services/memoryIndex.d.ts.map +1 -0
- package/dist/services/memoryIndex.js +100 -0
- package/dist/services/memoryIndex.js.map +1 -0
- package/dist/services/metadataExtractor.d.ts +16 -0
- package/dist/services/metadataExtractor.d.ts.map +1 -0
- package/dist/services/metadataExtractor.js +75 -0
- package/dist/services/metadataExtractor.js.map +1 -0
- package/dist/services/retrieval.d.ts +24 -0
- package/dist/services/retrieval.d.ts.map +1 -0
- package/dist/services/retrieval.js +40 -0
- package/dist/services/retrieval.js.map +1 -0
- package/dist/services/scheduler.d.ts +122 -0
- package/dist/services/scheduler.d.ts.map +1 -0
- package/dist/services/scheduler.js +434 -0
- package/dist/services/scheduler.js.map +1 -0
- package/dist/services/summarizer.d.ts +43 -0
- package/dist/services/summarizer.d.ts.map +1 -0
- package/dist/services/summarizer.js +252 -0
- package/dist/services/summarizer.js.map +1 -0
- package/dist/services/tagService.d.ts +64 -0
- package/dist/services/tagService.d.ts.map +1 -0
- package/dist/services/tagService.js +281 -0
- package/dist/services/tagService.js.map +1 -0
- package/dist/tools/memory.d.ts +3 -0
- package/dist/tools/memory.d.ts.map +1 -0
- package/dist/tools/memory.js +114 -0
- package/dist/tools/memory.js.map +1 -0
- package/dist/types.d.ts +128 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/docs/plans/2026-03-02-claw-memory-design.md +445 -0
- package/docs/plans/2026-03-02-incremental-summary-design.md +157 -0
- package/docs/plans/2026-03-02-incremental-summary-implementation.md +468 -0
- package/docs/plans/2026-03-02-memory-index-design.md +163 -0
- package/docs/plans/2026-03-02-memory-index-implementation.md +836 -0
- package/docs/plans/2026-03-02-mvp-implementation.md +1703 -0
- package/docs/plans/2026-03-02-testing-implementation.md +395 -0
- package/docs/plans/2026-03-02-testing-plan.md +93 -0
- package/docs/plans/2026-03-03-claw-memory-openclaw-plugin-design.md +285 -0
- package/docs/plans/2026-03-03-claw-memory-plugin-implementation.md +642 -0
- package/docs/plans/2026-03-03-entity-graph-design.md +121 -0
- package/docs/plans/2026-03-03-entity-graph-implementation.md +687 -0
- package/docs/plans/2026-03-03-llm-generic-config-design.md +43 -0
- package/docs/plans/2026-03-03-llm-generic-config-implementation.md +186 -0
- package/docs/plans/2026-03-03-memory-e2e-stress-test-design.md +110 -0
- package/docs/plans/2026-03-03-memory-e2e-stress-test-implementation.md +464 -0
- package/docs/plans/2026-03-03-minimax-llm-fix.md +156 -0
- package/docs/plans/2026-03-03-scheduler-design.md +165 -0
- package/docs/plans/2026-03-03-scheduler-implementation.md +777 -0
- package/docs/plans/2026-03-03-tags-visualization-design.md +73 -0
- package/docs/plans/2026-03-03-tags-visualization-implementation.md +539 -0
- package/openclaw.plugin.json +11 -0
- package/package.json +41 -0
- package/src/config/llm.ts +129 -0
- package/src/config/plugin.ts +47 -0
- package/src/db/entityRepository.ts +80 -0
- package/src/db/repository.ts +106 -0
- package/src/db/schema.ts +121 -0
- package/src/db/todoRepository.ts +76 -0
- package/src/hooks/bootstrap.ts +36 -0
- package/src/hooks/message.ts +84 -0
- package/src/index.ts +50 -0
- package/src/plugin.ts +85 -0
- package/src/services/entityGraphService.ts +367 -0
- package/src/services/memory.ts +338 -0
- package/src/services/memoryIndex.ts +140 -0
- package/src/services/metadataExtractor.ts +89 -0
- package/src/services/retrieval.ts +71 -0
- package/src/services/scheduler.ts +529 -0
- package/src/services/summarizer.ts +318 -0
- package/src/services/tagService.ts +335 -0
- package/src/tools/memory.ts +137 -0
- package/src/types.ts +139 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +16 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(npm install)",
|
|
5
|
+
"Bash(git -C /home/ubuntu/openclaw/claw-memory status)",
|
|
6
|
+
"Bash(npm run build)",
|
|
7
|
+
"Bash(git -C /home/ubuntu/openclaw/claw-memory log --oneline -5)",
|
|
8
|
+
"Bash(git -C /home/ubuntu/openclaw/claw-memory add package.json tsconfig.json .gitignore src/index.ts)",
|
|
9
|
+
"Bash(git -C /home/ubuntu/openclaw/claw-memory commit -m \"$\\(cat <<'EOF'\nchore: initialize project with TypeScript configuration\n\n- Add package.json with dependencies \\(MCP SDK, better-sqlite3, commander, uuid\\)\n- Add tsconfig.json for ES2022/ESNext compilation\n- Add .gitignore for node_modules, dist, and database files\n- Create basic src/index.ts entry point\n- Install all dependencies\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
10
|
+
"Bash(git config user.email \"287614652@qq.com\" && git config user.name \"yun-zero\")",
|
|
11
|
+
"Bash(git commit -m \"$\\(cat <<'EOF'\nchore: initialize project with TypeScript configuration\n\n- Add package.json with dependencies \\(MCP SDK, better-sqlite3, commander\\)\n- Add tsconfig.json with strict TypeScript config\n- Add .gitignore for node_modules, dist, etc.\n- Add basic CLI entry point\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
12
|
+
"Bash(npx tsc --noEmit)",
|
|
13
|
+
"Bash(git -C /home/ubuntu/openclaw/claw-memory log --oneline -3)",
|
|
14
|
+
"Bash(npm test tests/db/schema.test.ts)",
|
|
15
|
+
"Bash(npx tsx test-mcp.ts 2>&1)",
|
|
16
|
+
"Bash(npx tsx test-mcp-simple.ts 2>&1)",
|
|
17
|
+
"Bash(npx tsx import-claude.ts)",
|
|
18
|
+
"Bash(npx tsx test-claude-memories.ts)",
|
|
19
|
+
"Bash(npx tsx test-list.ts)",
|
|
20
|
+
"Bash(npx tsx test-commands.ts)",
|
|
21
|
+
"Bash(npx tsx test-search-dev.ts)",
|
|
22
|
+
"Bash(npx tsx import-claude-v2.ts)",
|
|
23
|
+
"Bash(npx tsx test-verify.ts)",
|
|
24
|
+
"Bash(npm test tests/services/memory.test.ts)",
|
|
25
|
+
"Bash(git add tests/services/memory.test.ts src/services/memory.ts)",
|
|
26
|
+
"Bash(git commit -m \"$\\(cat <<'EOF'\ntest: add searchMemory boundary test cases\n\nAdd boundary tests for searchMemory including:\n- Empty query returns all memories\n- Non-existent query returns empty array\n- limit=0 returns empty array\n- limit parameter is respected\n- Large limit is handled properly\n\nAlso fix searchMemory implementation to actually filter by query string\nby checking both summary and content fields.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
27
|
+
"Bash(npm test tests/services/retrieval.test.ts)",
|
|
28
|
+
"Bash(npm test tests/services/error-handling.test.ts 2>&1)",
|
|
29
|
+
"Bash(git -C /home/ubuntu/openclaw/claw-memory diff HEAD~1 src/services/memory.ts | head -100)",
|
|
30
|
+
"Bash(git -C /home/ubuntu/openclaw/claw-memory show HEAD~1:src/services/memory.ts | grep -A10 \"private async readContentFromFile\")",
|
|
31
|
+
"Bash(npm test 2>&1)",
|
|
32
|
+
"Bash(git -C /home/ubuntu/openclaw/claw-memory diff src/mcp/tools.ts | head -50)",
|
|
33
|
+
"Bash(git -C /home/ubuntu/openclaw/claw-memory log --oneline -10)",
|
|
34
|
+
"Bash(git -C /home/ubuntu/openclaw/claw-memory diff)",
|
|
35
|
+
"Bash(git -C /home/ubuntu/openclaw/claw-memory add tests/services/error-handling.test.ts src/services/memory.ts)",
|
|
36
|
+
"Bash(git -C /home/ubuntu/openclaw/claw-memory commit -m \"$\\(cat <<'EOF'\ntest: add error handling test cases\n\nAdd test cases for:\n- Invalid importance value \\(>1 should be capped at 1\\)\n- Negative importance \\(<0 should be clamped to 0\\)\n- Missing query in searchMemory\n- Missing content field handling\n\nAlso fix MemoryService to clamp importance values to valid range [0, 1]\nand make readContentFromFile synchronous to fix TypeScript strict mode errors.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
37
|
+
"Bash(npm test)",
|
|
38
|
+
"Bash(git push)",
|
|
39
|
+
"Bash(npm test -- --run tests/mcp/tools.test.ts)",
|
|
40
|
+
"Bash(git add src/types.ts src/services/memory.ts src/config/ src/services/summarizer.ts tests/services/memory.test.ts tests/services/summarizer.test.ts)",
|
|
41
|
+
"Bash(git commit -m \"$\\(cat <<'EOF'\nfeat: implement weekly summary with LLM integration\n\n- Add WeeklyReport type with multi-dimensional analysis\n- Create SummarizerService for data aggregation \\(tags, keywords, importance, access patterns, entities\\)\n- Add LLM config module supporting OpenAI and Anthropic API keys\n- Implement getSummary with date range calculation and time bucket storage\n- Add tests for summarizer and getSummary functionality\n\nAll 58 tests passing.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
42
|
+
"mcp__web-search-prime__webSearchPrime",
|
|
43
|
+
"Bash(git -C /home/ubuntu/openclaw/claw-memory log --oneline -15)",
|
|
44
|
+
"Bash(LLM_FORMAT=openai-compatible \\\\\nLLM_BASE_URL=https://api.minimax.chat/v1 \\\\\nLLM_API_KEY=test-key \\\\\nLLM_MODEL=abab6.5s-chat \\\\\nnode -e \"import\\('./dist/config/llm.js'\\).then\\(m => console.log\\(JSON.stringify\\(m.getLLMConfig\\(\\), null, 2\\)\\)\\)\")",
|
|
45
|
+
"Bash(env | grep -i llm)",
|
|
46
|
+
"Bash(source ~/.bashrc && env | grep -i \"llm\\\\|mini\\\\|zhipu\")",
|
|
47
|
+
"Bash(source ~/.bashrc && env | grep -E \"^LLM_|^MINIMAX|^ZHIPU|^OPENAI\")",
|
|
48
|
+
"Bash(source ~/.bashrc && npm test 2>&1)",
|
|
49
|
+
"Bash(export LLM_FORMAT=anthropic LLM_BASE_URL=https://api.minimaxi.com/anthropic LLM_API_KEY=\"sk-cp-44gTAYHU1drLe7TFzJagmg6E_FaliukdnORiRuo0MkqsZitz5kv81UkaQ8XVkLH0bCsWgfixWgcTo-VBDmL8FmgD7qJ2aiVSCRBC9k8m8UM2bI9gyHNo8Pw\" LLM_MODEL=\"MiniMax-M2.5-highspeed\" && npm test 2>&1)",
|
|
50
|
+
"Bash(curl -s -o /dev/null -w \"%{http_code}\" -X POST \"https://api.minimaxi.com/anthropic/v1/messages\" \\\\\n -H \"Content-Type: application/json\" \\\\\n -H \"x-api-key: sk-cp-44gTAYHU1drLe7TFzJagmg6E_FaliukdnORiRuo0MkqsZitz5kv81UkaQ8XVkLH0bCsWgfixWgcTo-VBDmL8FmgD7qJ2aiVSCRBC9k8m8UM2bI9gyHNo8Pw\" \\\\\n -H \"anthropic-version: 2023-06-01\" \\\\\n -d '{\"model\":\"MiniMax-M2.5-highspeed\",\"max_tokens\":1024,\"messages\":[{\"role\":\"user\",\"content\":\"hi\"}]}')",
|
|
51
|
+
"Bash(git add -A && git commit -m \"fix: use config.baseUrl and add v1 path for MiniMax Anthropic API\n\n- Fix hardcoded Anthropic API URL in generateWithAnthropic\n- Auto-add /v1 path for MiniMax compatibility\n- Increase vitest timeout to 60s\"\n\ngit status)",
|
|
52
|
+
"Bash(git rm -r --cached \"test/data/2026/\" 2>/dev/null; git status --short | head -20)",
|
|
53
|
+
"Bash(git add .gitignore && git commit --amend --no-edit)",
|
|
54
|
+
"Bash(ls -la /home/ubuntu/openclaw/claw-memory/*.md 2>/dev/null || echo \"No md files in root\")",
|
|
55
|
+
"Bash(git check-ignore -q .worktrees 2>/dev/null && echo \"IGNORED\" || echo \"NOT_IGNORED\")",
|
|
56
|
+
"Bash(git add .gitignore && git commit -m \"chore: add .worktrees to gitignore\")",
|
|
57
|
+
"Bash(git worktree add .worktrees/feature-implementations -b feature-implementations)",
|
|
58
|
+
"Bash(npm install node-cron && npm install -D @types/node-cron)",
|
|
59
|
+
"Bash(git add /home/ubuntu/openclaw/claw-memory/.worktrees/feature-implementations/src/services/scheduler.ts)",
|
|
60
|
+
"Bash(git commit -m \"$\\(cat <<'EOF'\nfeat: implement daily summary task in Scheduler\n\n- Add import for generateSummaryWithLLM from config/llm\n- Implement dailySummary\\(\\) method that:\n - Gets yesterday's date\n - Checks if summary already exists in time_buckets\n - Retrieves memories created on that date\n - Reads memory content \\(limited to 1000 chars\\)\n - Calls LLM to generate summary\n - Saves summary to time_buckets table\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
61
|
+
"Bash(node /home/ubuntu/openclaw/claw-memory/.worktrees/feature-implementations/dist/index.js serve --help)",
|
|
62
|
+
"Bash(git -C /home/ubuntu/openclaw/claw-memory/.worktrees/feature-implementations add src/index.ts)",
|
|
63
|
+
"Bash(git -C /home/ubuntu/openclaw/claw-memory/.worktrees/feature-implementations commit -m \"$\\(cat <<'EOF'\nfeat: add CLI option to disable scheduler\n\nAdd --scheduler-disabled \\(-s\\) option to serve command to allow\ndisabling the scheduler when starting the MCP server.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
64
|
+
"Bash(git -C /home/ubuntu/openclaw/claw-memory/.worktrees/feature-implementations status)",
|
|
65
|
+
"Bash(git add /home/ubuntu/openclaw/claw-memory/.worktrees/feature-implementations/src/services/tagService.ts)"
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
}
|
package/README.md
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
# Claw-Memory
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>OpenClaw 记忆插件 - 自动保存对话,智能注入上下文</strong>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="#特性">特性</a> •
|
|
9
|
+
<a href="#架构">架构</a> •
|
|
10
|
+
<a href="#快速开始">快速开始</a> •
|
|
11
|
+
<a href="#使用方法">使用方法</a> •
|
|
12
|
+
<a href="#配置">配置</a>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<img src="https://img.shields.io/badge/typescript-5.0+-blue.svg" alt="TypeScript">
|
|
17
|
+
<img src="https://img.shields.io/badge/node-18+-green.svg" alt="Node.js">
|
|
18
|
+
<img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License">
|
|
19
|
+
<img src="https://img.shields.io/badge/status-alpha-orange.svg" alt="Status">
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 特性
|
|
25
|
+
|
|
26
|
+
- 🧠 **自动保存对话** - 每条消息自动保存 Q&A 到记忆
|
|
27
|
+
- 🔗 **图结构关联** - 关键词、标签、主体以图的形式组织,支持多跳检索
|
|
28
|
+
- ⏰ **时间维度组织** - 按天/周/月/年组织记忆,智能时间衰减权重
|
|
29
|
+
- 🏷️ **层级标签系统** - 支持多级标签分类,如 `技术/前端/React`
|
|
30
|
+
- 🔌 **OpenClaw 插件** - 原生集成,自动跟随 OpenClaw 启动
|
|
31
|
+
- 💾 **轻量级部署** - SQLite + 本地文件,无需额外数据库服务
|
|
32
|
+
- 🤖 **自动元数据提取** - 使用 OpenClaw 内置 LLM 提取标签、关键词
|
|
33
|
+
- ✅ **待办事项管理** - 支持 day/week/month 周期的待办管理
|
|
34
|
+
- ⏱️ **定时任务系统** - 自动每日/每周/每月总结,自动去重
|
|
35
|
+
- 📊 **标签可视化** - CLI 生成静态 HTML 报告,展示标签树和统计
|
|
36
|
+
- 🔍 **实体关系图查询** - 查询实体关联,D3.js 可视化
|
|
37
|
+
|
|
38
|
+
## 架构
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
42
|
+
│ OpenClaw Gateway │
|
|
43
|
+
│ │
|
|
44
|
+
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
45
|
+
│ │ @openclaw/claw-memory-plugin │ │
|
|
46
|
+
│ │ │ │
|
|
47
|
+
│ │ Hooks: │ │
|
|
48
|
+
│ │ ├── message:sent ──▶ 提取 Q&A,保存记忆 │ │
|
|
49
|
+
│ │ └── agent:bootstrap ──▶ 注入记忆摘要到上下文 │ │
|
|
50
|
+
│ │ │ │
|
|
51
|
+
│ │ Tools: │ │
|
|
52
|
+
│ │ ├── memory_save 保存记忆(带 LLM 元数据提取) │ │
|
|
53
|
+
│ │ ├── memory_search 搜索记忆 │ │
|
|
54
|
+
│ │ └── memory_summary 获取记忆摘要 │ │
|
|
55
|
+
│ │ │ │
|
|
56
|
+
│ │ Scheduler: │ │
|
|
57
|
+
│ │ ├── 01:00 去重任务 │ │
|
|
58
|
+
│ │ ├── 02:00 每日总结 │ │
|
|
59
|
+
│ │ ├── 03:00 每周总结 │ │
|
|
60
|
+
│ │ └── 04:00 每月总结 │ │
|
|
61
|
+
│ │ │ │
|
|
62
|
+
│ │ 内置 LLM 调用(复用 OpenClaw 配置) │ │
|
|
63
|
+
│ └─────────────────────────────────────────────────────────┘ │
|
|
64
|
+
│ │ │
|
|
65
|
+
│ ▼ │
|
|
66
|
+
│ ┌───────────────────────────────────┐ │
|
|
67
|
+
│ │ ~/.openclaw/claw-memory/ │ │
|
|
68
|
+
│ │ ├── memory.db (SQLite) │ │
|
|
69
|
+
│ │ └── memories/ (对话文件) │ │
|
|
70
|
+
│ └───────────────────────────────────┘ │
|
|
71
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 数据模型
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
memories (记忆表)
|
|
78
|
+
├── id, content_path, created_at
|
|
79
|
+
├── importance, access_count
|
|
80
|
+
├── token_count
|
|
81
|
+
└── summary, integrated_summary (JSON)
|
|
82
|
+
|
|
83
|
+
entities (实体表 - 含层级)
|
|
84
|
+
├── id, name, type, parent_id
|
|
85
|
+
├── level, embedding
|
|
86
|
+
└── type: keyword | tag | subject | person | project
|
|
87
|
+
|
|
88
|
+
memory_entities (关联表)
|
|
89
|
+
├── memory_id, entity_id
|
|
90
|
+
└── relevance
|
|
91
|
+
|
|
92
|
+
entity_relations (实体关系图)
|
|
93
|
+
├── source_id, target_id
|
|
94
|
+
├── relation_type, weight
|
|
95
|
+
└── 支持: related | parent | similar
|
|
96
|
+
|
|
97
|
+
time_buckets (时间桶)
|
|
98
|
+
├── date, memory_count
|
|
99
|
+
└── summary, summary_generated_at
|
|
100
|
+
|
|
101
|
+
todos (待办事项)
|
|
102
|
+
├── id, content, period
|
|
103
|
+
├── completed_at, created_at
|
|
104
|
+
└── type: day | week | month
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## 快速开始
|
|
108
|
+
|
|
109
|
+
### 安装插件
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# 安装插件
|
|
113
|
+
openclaw plugins install @openclaw/claw-memory
|
|
114
|
+
|
|
115
|
+
# 配置
|
|
116
|
+
openclaw config set plugins.claw-memory.enabled true
|
|
117
|
+
|
|
118
|
+
# 重启
|
|
119
|
+
openclaw gateway restart
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 配置
|
|
123
|
+
|
|
124
|
+
插件配置文件位于 `~/.openclaw/openclaw.json`:
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"plugins": {
|
|
129
|
+
"claw-memory": {
|
|
130
|
+
"enabled": true,
|
|
131
|
+
"autoSave": true,
|
|
132
|
+
"saveMode": "qa",
|
|
133
|
+
"dataDir": "~/.openclaw/claw-memory",
|
|
134
|
+
"scheduler": {
|
|
135
|
+
"enabled": true,
|
|
136
|
+
"deduplicateTime": "01:00",
|
|
137
|
+
"dailyTime": "02:00",
|
|
138
|
+
"weeklyTime": "03:00",
|
|
139
|
+
"monthlyTime": "04:00"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### 配置选项说明
|
|
147
|
+
|
|
148
|
+
| 选项 | 默认值 | 说明 |
|
|
149
|
+
|------|--------|------|
|
|
150
|
+
| `enabled` | `true` | 是否启用插件 |
|
|
151
|
+
| `autoSave` | `true` | 是否自动保存对话 |
|
|
152
|
+
| `saveMode` | `"qa"` | 保存模式:`qa` 仅 Q&A,`full` 完整对话 |
|
|
153
|
+
| `dataDir` | `~/.openclaw/claw-memory` | 数据存储目录 |
|
|
154
|
+
| `scheduler.enabled` | `true` | 是否启用定时任务 |
|
|
155
|
+
|
|
156
|
+
## 使用方法
|
|
157
|
+
|
|
158
|
+
### 自动保存
|
|
159
|
+
|
|
160
|
+
插件会在每次消息发送后自动保存对话:
|
|
161
|
+
- 提取 Q&A 对
|
|
162
|
+
- 调用 LLM 提取元数据(标签、关键词、重要性)
|
|
163
|
+
- 保存到 SQLite 数据库
|
|
164
|
+
|
|
165
|
+
### 主动调用工具
|
|
166
|
+
|
|
167
|
+
Agent 可以主动调用以下工具:
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
// 保存记忆
|
|
171
|
+
await tool("memory_save", {
|
|
172
|
+
content: "用户讨论了 React Hooks 的使用...",
|
|
173
|
+
metadata: {
|
|
174
|
+
tags: ["技术/前端/React"],
|
|
175
|
+
keywords: ["useState", "useEffect"],
|
|
176
|
+
importance: 0.8
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// 搜索记忆
|
|
181
|
+
await tool("memory_search", {
|
|
182
|
+
query: "React Hooks 怎么用",
|
|
183
|
+
limit: 10
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// 获取摘要
|
|
187
|
+
await tool("memory_summary", {
|
|
188
|
+
period: "week"
|
|
189
|
+
});
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 检索权重计算
|
|
193
|
+
|
|
194
|
+
记忆按以下维度计算综合权重:
|
|
195
|
+
|
|
196
|
+
| 维度 | 权重范围 | 说明 |
|
|
197
|
+
|-----|---------|------|
|
|
198
|
+
| 实体匹配 | 0-40 | 匹配的关键词/主体数量 |
|
|
199
|
+
| 时间衰减 | 0-30 | 今天(30) > 本周(20) > 本月(10) > 本年(5) |
|
|
200
|
+
| 标签层级 | 0-20 | 层级越接近权重越高 |
|
|
201
|
+
| 重要性 | 0-10 | 访问频率 + 标记重要性 |
|
|
202
|
+
|
|
203
|
+
### CLI 命令
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
# 标签可视化
|
|
207
|
+
claw-memory tags tree [--output <file>] # 生成标签树 HTML
|
|
208
|
+
claw-memory tags stats [--output <file>] # 生成标签统计 HTML
|
|
209
|
+
|
|
210
|
+
# 实体关系图
|
|
211
|
+
claw-memory relations graph [--entity <name>] [--hops <n>] [--output <file>]
|
|
212
|
+
claw-memory relations stats [--output <file>]
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### NPM Scripts
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
npm run build # 编译 TypeScript
|
|
219
|
+
npm run test # 运行测试
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## 配置
|
|
223
|
+
|
|
224
|
+
### LLM 配置
|
|
225
|
+
|
|
226
|
+
插件使用 OpenClaw 已配置的 LLM,无需额外配置。
|
|
227
|
+
|
|
228
|
+
### 数据目录
|
|
229
|
+
|
|
230
|
+
数据存储在 `~/.openclaw/claw-memory/` 目录下:
|
|
231
|
+
```
|
|
232
|
+
~/.openclaw/claw-memory/
|
|
233
|
+
├── memories/
|
|
234
|
+
│ └── {uuid}.md # 记忆内容文件
|
|
235
|
+
└── memory.db # SQLite 数据库
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## 项目结构
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
claw-memory/
|
|
242
|
+
├── src/
|
|
243
|
+
│ ├── index.ts # CLI 入口
|
|
244
|
+
│ ├── plugin.ts # OpenClaw 插件入口
|
|
245
|
+
│ ├── config/
|
|
246
|
+
│ │ ├── llm.ts # LLM 配置
|
|
247
|
+
│ │ └── plugin.ts # 插件配置管理
|
|
248
|
+
│ ├── db/
|
|
249
|
+
│ │ ├── schema.ts # 数据库 Schema
|
|
250
|
+
│ │ ├── repository.ts # 记忆仓库
|
|
251
|
+
│ │ ├── entityRepository.ts # 实体仓库
|
|
252
|
+
│ │ └── todoRepository.ts # 待办仓库
|
|
253
|
+
│ ├── services/
|
|
254
|
+
│ │ ├── memory.ts # 记忆服务
|
|
255
|
+
│ │ ├── memoryIndex.ts # 记忆索引服务
|
|
256
|
+
│ │ ├── retrieval.ts # 检索逻辑
|
|
257
|
+
│ │ ├── summarizer.ts # 总结服务
|
|
258
|
+
│ │ ├── scheduler.ts # 定时任务服务
|
|
259
|
+
│ │ ├── tagService.ts # 标签可视化服务
|
|
260
|
+
│ │ ├── entityGraphService.ts # 实体关系图服务
|
|
261
|
+
│ │ └── metadataExtractor.ts # LLM 元数据提取
|
|
262
|
+
│ ├── hooks/ # OpenClaw Hooks
|
|
263
|
+
│ │ ├── message.ts # message:sent Hook
|
|
264
|
+
│ │ └── bootstrap.ts # agent:bootstrap Hook
|
|
265
|
+
│ ├── tools/ # Agent Tools
|
|
266
|
+
│ │ └── memory.ts # memory_save/search/summary 工具
|
|
267
|
+
│ └── types.ts # TypeScript 类型定义
|
|
268
|
+
├── openclaw.plugin.json # OpenClaw 插件清单
|
|
269
|
+
├── tests/ # 测试文件
|
|
270
|
+
├── docs/
|
|
271
|
+
│ └── plans/ # 设计文档
|
|
272
|
+
├── package.json
|
|
273
|
+
├── tsconfig.json
|
|
274
|
+
└── README.md
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## 开发
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
# 安装开发依赖
|
|
281
|
+
npm install
|
|
282
|
+
|
|
283
|
+
# 运行测试
|
|
284
|
+
npm test
|
|
285
|
+
|
|
286
|
+
# 构建
|
|
287
|
+
npm run build
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## 路线图
|
|
291
|
+
|
|
292
|
+
- [x] 核心架构设计
|
|
293
|
+
- [x] SQLite 数据模型
|
|
294
|
+
- [x] 记忆存储/检索
|
|
295
|
+
- [x] LLM 元数据提取
|
|
296
|
+
- [x] 增量摘要更新
|
|
297
|
+
- [x] 定时总结/去重 (scheduler)
|
|
298
|
+
- [x] 层级标签管理
|
|
299
|
+
- [x] 实体关系图查询
|
|
300
|
+
- [x] OpenClaw 插件集成
|
|
301
|
+
- [x] message:sent Hook
|
|
302
|
+
- [x] agent:bootstrap Hook
|
|
303
|
+
- [x] Agent Tools 注册
|
|
304
|
+
- [ ] npm 发布
|
|
305
|
+
- [ ] 优化
|
|
306
|
+
- [ ] 语义搜索(可选)
|
|
307
|
+
- [ ] 性能优化
|
|
308
|
+
|
|
309
|
+
## 许可证
|
|
310
|
+
|
|
311
|
+
[MIT License](LICENSE)
|
|
312
|
+
|
|
313
|
+
## 致谢
|
|
314
|
+
|
|
315
|
+
- [OpenClaw](https://github.com/openclaw) - 无头 AI 智能体框架
|
|
316
|
+
- [Letta/MemGPT](https://github.com/letta-ai/letta) - 记忆管理灵感
|
|
317
|
+
- [LightRAG](https://github.com/HKUDS/LightRAG) - 图结构检索参考
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
<p align="center">
|
|
322
|
+
Made with ❤️ by <a href="https://github.com/openclaw">OpenClaw</a> Community
|
|
323
|
+
</p>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM Configuration Module
|
|
3
|
+
* Supports OpenAI and Anthropic API keys via environment variables
|
|
4
|
+
*/
|
|
5
|
+
export interface LLMConfig {
|
|
6
|
+
format: 'openai' | 'anthropic' | 'openai-compatible';
|
|
7
|
+
baseUrl: string;
|
|
8
|
+
apiKey: string;
|
|
9
|
+
model: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function getLLMConfig(): LLMConfig;
|
|
12
|
+
export declare function generateSummaryWithLLM(report: string, config?: LLMConfig): Promise<string>;
|
|
13
|
+
//# sourceMappingURL=llm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/config/llm.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,mBAAmB,CAAC;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AASD,wBAAgB,YAAY,IAAI,SAAS,CAWxC;AAUD,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,SAAS,GACjB,OAAO,CAAC,MAAM,CAAC,CAoBjB"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM Configuration Module
|
|
3
|
+
* Supports OpenAI and Anthropic API keys via environment variables
|
|
4
|
+
*/
|
|
5
|
+
// Default configuration map for LLM providers
|
|
6
|
+
const LLM_DEFAULTS = {
|
|
7
|
+
anthropic: { baseUrl: 'https://api.anthropic.com', model: 'claude-3-haiku-20240307' },
|
|
8
|
+
openai: { baseUrl: 'https://api.openai.com/v1', model: 'gpt-4o-mini' },
|
|
9
|
+
'openai-compatible': { baseUrl: 'https://api.openai.com/v1', model: 'gpt-4o-mini' }
|
|
10
|
+
};
|
|
11
|
+
export function getLLMConfig() {
|
|
12
|
+
const format = process.env.LLM_FORMAT || 'openai';
|
|
13
|
+
const baseUrl = process.env.LLM_BASE_URL || getDefaultBaseUrl(format);
|
|
14
|
+
const apiKey = process.env.LLM_API_KEY || process.env.OPENAI_API_KEY || '';
|
|
15
|
+
const model = process.env.LLM_MODEL || getDefaultModel(format);
|
|
16
|
+
if (!apiKey) {
|
|
17
|
+
throw new Error('No LLM API key configured. Set LLM_API_KEY environment variable.');
|
|
18
|
+
}
|
|
19
|
+
return { format, baseUrl, apiKey, model };
|
|
20
|
+
}
|
|
21
|
+
function getDefaultBaseUrl(format) {
|
|
22
|
+
return LLM_DEFAULTS[format]?.baseUrl ?? LLM_DEFAULTS.openai.baseUrl;
|
|
23
|
+
}
|
|
24
|
+
function getDefaultModel(format) {
|
|
25
|
+
return LLM_DEFAULTS[format]?.model ?? LLM_DEFAULTS.openai.model;
|
|
26
|
+
}
|
|
27
|
+
export async function generateSummaryWithLLM(report, config) {
|
|
28
|
+
const llmConfig = config || getLLMConfig();
|
|
29
|
+
const systemPrompt = `你是一个智能助手,负责根据用户记忆数据生成周报总结。
|
|
30
|
+
请根据提供的统计数据,从多个维度分析用户的记忆内容,并生成一段简洁、有价值的自然语言总结。
|
|
31
|
+
总结应该:
|
|
32
|
+
1. 概括本周的记忆活动概况
|
|
33
|
+
2. 指出用户最关注的话题和标签
|
|
34
|
+
3. 识别重要的记忆内容
|
|
35
|
+
4. 给出有洞察力的观察
|
|
36
|
+
|
|
37
|
+
请用中文输出总结,保持简洁但有信息量。`;
|
|
38
|
+
if (llmConfig.format === 'anthropic') {
|
|
39
|
+
return generateWithAnthropic(systemPrompt, report, llmConfig);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// openai 或 openai-compatible 都使用 generateWithOpenAI
|
|
43
|
+
const prefix = llmConfig.format === 'openai-compatible' ? 'OpenAI Compatible' : 'OpenAI';
|
|
44
|
+
return generateWithOpenAI(systemPrompt, report, llmConfig, prefix);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async function generateWithAnthropic(systemPrompt, userPrompt, config) {
|
|
48
|
+
// Ensure v1 path for Anthropic API
|
|
49
|
+
const baseUrl = config.baseUrl.includes('/anthropic') && !config.baseUrl.includes('/v1')
|
|
50
|
+
? `${config.baseUrl}/v1`
|
|
51
|
+
: config.baseUrl;
|
|
52
|
+
const response = await fetch(`${baseUrl}/messages`, {
|
|
53
|
+
method: 'POST',
|
|
54
|
+
headers: {
|
|
55
|
+
'Content-Type': 'application/json',
|
|
56
|
+
'x-api-key': config.apiKey,
|
|
57
|
+
'anthropic-version': '2023-06-01'
|
|
58
|
+
},
|
|
59
|
+
body: JSON.stringify({
|
|
60
|
+
model: config.model,
|
|
61
|
+
max_tokens: 1024,
|
|
62
|
+
system: systemPrompt,
|
|
63
|
+
messages: [{ role: 'user', content: userPrompt }]
|
|
64
|
+
})
|
|
65
|
+
});
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
const error = await response.text();
|
|
68
|
+
throw new Error(`Anthropic API error: ${error}`);
|
|
69
|
+
}
|
|
70
|
+
const data = await response.json();
|
|
71
|
+
return data.content[0]?.text || '总结生成失败';
|
|
72
|
+
}
|
|
73
|
+
async function generateWithOpenAI(systemPrompt, userPrompt, config, errorPrefix = 'OpenAI') {
|
|
74
|
+
const response = await fetch(`${config.baseUrl}/chat/completions`, {
|
|
75
|
+
method: 'POST',
|
|
76
|
+
headers: {
|
|
77
|
+
'Content-Type': 'application/json',
|
|
78
|
+
'Authorization': `Bearer ${config.apiKey}`
|
|
79
|
+
},
|
|
80
|
+
body: JSON.stringify({
|
|
81
|
+
model: config.model,
|
|
82
|
+
max_tokens: 1024,
|
|
83
|
+
messages: [
|
|
84
|
+
{ role: 'system', content: systemPrompt },
|
|
85
|
+
{ role: 'user', content: userPrompt }
|
|
86
|
+
]
|
|
87
|
+
})
|
|
88
|
+
});
|
|
89
|
+
if (!response.ok) {
|
|
90
|
+
const error = await response.text();
|
|
91
|
+
throw new Error(`${errorPrefix} API error: ${error}`);
|
|
92
|
+
}
|
|
93
|
+
const data = await response.json();
|
|
94
|
+
return data.choices[0]?.message?.content || '总结生成失败';
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=llm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../../src/config/llm.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface PluginConfig {
|
|
2
|
+
enabled: boolean;
|
|
3
|
+
autoSave: boolean;
|
|
4
|
+
saveMode: 'qa' | 'full';
|
|
5
|
+
dataDir: string;
|
|
6
|
+
scheduler: {
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
deduplicateTime: string;
|
|
9
|
+
dailyTime: string;
|
|
10
|
+
weeklyTime: string;
|
|
11
|
+
monthlyTime: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export declare function getConfig(config?: any): PluginConfig;
|
|
15
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/config/plugin.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,IAAI,GAAG,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,eAAe,EAAE,MAAM,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,wBAAgB,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,YAAY,CAgCpD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export function getConfig(config) {
|
|
2
|
+
const defaultConfig = {
|
|
3
|
+
enabled: true,
|
|
4
|
+
autoSave: true,
|
|
5
|
+
saveMode: 'qa',
|
|
6
|
+
dataDir: '~/.openclaw/claw-memory',
|
|
7
|
+
scheduler: {
|
|
8
|
+
enabled: true,
|
|
9
|
+
deduplicateTime: '01:00',
|
|
10
|
+
dailyTime: '02:00',
|
|
11
|
+
weeklyTime: '03:00',
|
|
12
|
+
monthlyTime: '04:00'
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
if (!config) {
|
|
16
|
+
return defaultConfig;
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
enabled: config.enabled ?? defaultConfig.enabled,
|
|
20
|
+
autoSave: config.autoSave ?? defaultConfig.autoSave,
|
|
21
|
+
saveMode: config.saveMode ?? defaultConfig.saveMode,
|
|
22
|
+
dataDir: config.dataDir ?? defaultConfig.dataDir,
|
|
23
|
+
scheduler: {
|
|
24
|
+
enabled: config.scheduler?.enabled ?? defaultConfig.scheduler.enabled,
|
|
25
|
+
deduplicateTime: config.scheduler?.deduplicateTime ?? defaultConfig.scheduler.deduplicateTime,
|
|
26
|
+
dailyTime: config.scheduler?.dailyTime ?? defaultConfig.scheduler.dailyTime,
|
|
27
|
+
weeklyTime: config.scheduler?.weeklyTime ?? defaultConfig.scheduler.weeklyTime,
|
|
28
|
+
monthlyTime: config.scheduler?.monthlyTime ?? defaultConfig.scheduler.monthlyTime
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/config/plugin.ts"],"names":[],"mappings":"AAcA,MAAM,UAAU,SAAS,CAAC,MAAY;IACpC,MAAM,aAAa,GAAiB;QAClC,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE,yBAAyB;QAClC,SAAS,EAAE;YACT,OAAO,EAAE,IAAI;YACb,eAAe,EAAE,OAAO;YACxB,SAAS,EAAE,OAAO;YAClB,UAAU,EAAE,OAAO;YACnB,WAAW,EAAE,OAAO;SACrB;KACF,CAAC;IAEF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,aAAa,CAAC,OAAO;QAChD,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,aAAa,CAAC,QAAQ;QACnD,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,aAAa,CAAC,QAAQ;QACnD,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,aAAa,CAAC,OAAO;QAChD,SAAS,EAAE;YACT,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,IAAI,aAAa,CAAC,SAAS,CAAC,OAAO;YACrE,eAAe,EAAE,MAAM,CAAC,SAAS,EAAE,eAAe,IAAI,aAAa,CAAC,SAAS,CAAC,eAAe;YAC7F,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,IAAI,aAAa,CAAC,SAAS,CAAC,SAAS;YAC3E,UAAU,EAAE,MAAM,CAAC,SAAS,EAAE,UAAU,IAAI,aAAa,CAAC,SAAS,CAAC,UAAU;YAC9E,WAAW,EAAE,MAAM,CAAC,SAAS,EAAE,WAAW,IAAI,aAAa,CAAC,SAAS,CAAC,WAAW;SAClF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import type { Entity } from '../types.js';
|
|
3
|
+
export interface CreateEntityInput {
|
|
4
|
+
name: string;
|
|
5
|
+
type: Entity['type'];
|
|
6
|
+
parentId?: string | null;
|
|
7
|
+
level?: number;
|
|
8
|
+
metadata?: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
export declare class EntityRepository {
|
|
11
|
+
private db;
|
|
12
|
+
constructor(db: Database.Database);
|
|
13
|
+
create(input: CreateEntityInput): Entity;
|
|
14
|
+
findById(id: string): Entity | null;
|
|
15
|
+
findByName(name: string): Entity | null;
|
|
16
|
+
findByType(type: Entity['type']): Entity[];
|
|
17
|
+
findChildren(parentId: string): Entity[];
|
|
18
|
+
findOrCreate(input: CreateEntityInput): Entity;
|
|
19
|
+
private mapRowToEntity;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=entityRepository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entityRepository.d.ts","sourceRoot":"","sources":["../../src/db/entityRepository.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,EAAE,CAAoB;gBAElB,EAAE,EAAE,QAAQ,CAAC,QAAQ;IAIjC,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM;IAoBxC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAMnC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAMvC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE;IAK1C,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAKxC,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM;IAM9C,OAAO,CAAC,cAAc;CAYvB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
+
export class EntityRepository {
|
|
3
|
+
db;
|
|
4
|
+
constructor(db) {
|
|
5
|
+
this.db = db;
|
|
6
|
+
}
|
|
7
|
+
create(input) {
|
|
8
|
+
const id = uuidv4();
|
|
9
|
+
const now = new Date();
|
|
10
|
+
this.db.prepare(`
|
|
11
|
+
INSERT INTO entities (id, name, type, parent_id, level, metadata, created_at)
|
|
12
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
13
|
+
`).run(id, input.name, input.type, input.parentId || null, input.level ?? 0, input.metadata ? JSON.stringify(input.metadata) : null, now.toISOString());
|
|
14
|
+
return this.findById(id);
|
|
15
|
+
}
|
|
16
|
+
findById(id) {
|
|
17
|
+
const row = this.db.prepare('SELECT * FROM entities WHERE id = ?').get(id);
|
|
18
|
+
if (!row)
|
|
19
|
+
return null;
|
|
20
|
+
return this.mapRowToEntity(row);
|
|
21
|
+
}
|
|
22
|
+
findByName(name) {
|
|
23
|
+
const row = this.db.prepare('SELECT * FROM entities WHERE name = ?').get(name);
|
|
24
|
+
if (!row)
|
|
25
|
+
return null;
|
|
26
|
+
return this.mapRowToEntity(row);
|
|
27
|
+
}
|
|
28
|
+
findByType(type) {
|
|
29
|
+
const rows = this.db.prepare('SELECT * FROM entities WHERE type = ?').all(type);
|
|
30
|
+
return rows.map(row => this.mapRowToEntity(row));
|
|
31
|
+
}
|
|
32
|
+
findChildren(parentId) {
|
|
33
|
+
const rows = this.db.prepare('SELECT * FROM entities WHERE parent_id = ?').all(parentId);
|
|
34
|
+
return rows.map(row => this.mapRowToEntity(row));
|
|
35
|
+
}
|
|
36
|
+
findOrCreate(input) {
|
|
37
|
+
const existing = this.findByName(input.name);
|
|
38
|
+
if (existing)
|
|
39
|
+
return existing;
|
|
40
|
+
return this.create(input);
|
|
41
|
+
}
|
|
42
|
+
mapRowToEntity(row) {
|
|
43
|
+
return {
|
|
44
|
+
id: row.id,
|
|
45
|
+
name: row.name,
|
|
46
|
+
type: row.type,
|
|
47
|
+
parentId: row.parent_id,
|
|
48
|
+
level: row.level,
|
|
49
|
+
embedding: row.embedding,
|
|
50
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : null,
|
|
51
|
+
createdAt: new Date(row.created_at)
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=entityRepository.js.map
|