From ee2ae4ba0e1d49777276941d2f5eeb4d9c5c1f56 Mon Sep 17 00:00:00 2001 From: chrishuan Date: Sat, 11 Apr 2026 17:40:11 +0800 Subject: [PATCH 1/3] Update README.md --- README.md | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++ README_CN.md | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 401 insertions(+) create mode 100644 README.md create mode 100644 README_CN.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..a445c7b --- /dev/null +++ b/README.md @@ -0,0 +1,200 @@ +[中文](README_CN.md) + +

TencentDB Agent Memory

+ +

AI without memory is just a tool. AI with memory becomes an asset.

+ +

+ OpenClaw Plugin + MIT License +

+ + +**TencentDB Agent Memory is an Agent memory system built by the Tencent Cloud Database team**, adding persistent long-term memory to OpenClaw. Through a 4-layer progressive memory pyramid, it automatically handles memory capture, layered distillation, on-demand recall and injection — turning an Agent from "chat-only" into a long-term, cross-session AI assistant that continuously learns and understands its users. + +## Benchmark + +Evaluated on [PersonaMem](https://github.com/jiani-huang/PersonaMem) (UPenn, COLM 2025) — 589 questions, 20 actors. + +| Category | OpenClaw Native Memory | TencentDB Agent Memory | +| :--- | :---: | :---: | +| Recall Update Reason | 70.97% | **88.89%** | +| Preference Evolution | 66.67% | **83.45%** | +| Personalized Recommendation | 46.67% | **76.36%** | +| Scenario Generalization | 31.58% | **78.95%** | +| Recall User Facts | 29.63% | **79.07%** | +| Recall Facts | 25.00% | **76.47%** | +| Creative Suggestion | 24.00% | **45.16%** | +| **Overall** | **47.85%** | **76.10%** | + +## Highlights + +- **OpenClaw native plugin** — package name `@tencentdb-agent-memory/memory-tencentdb`, one command to install +- **4-layer memory pipeline**: L0 Raw Dialogue → L1 Structured Memory → L2 Scenario Synthesis → L3 User Profile +- **Hybrid recall**: supports `keyword`, `embedding`, and `hybrid` strategies +- **Two retrieval tools**: `tdai_memory_search` (structured memory) and `tdai_conversation_search` (raw conversations) +- **Local-first storage**: JSONL + SQLite, data is directly inspectable on disk +- **Operational features**: deduplication, checkpoint, backup, scheduled cleanup, metrics logging +- **MIT License** + +## Quick Start + +### Requirements + +- Node.js `>= 22.16.0` +- OpenClaw `>= 2026.3.13` + +### Install + +```bash +openclaw plugins install @tencentdb-agent-memory/memory-tencentdb +``` + +Once installed, the plugin hooks into the OpenClaw conversation lifecycle and automatically handles conversation capture, memory recall, and L1/L2/L3 processing. + +### Development from Source + +No build step required. Node.js 22.16+ natively supports TypeScript type stripping, and OpenClaw loads `.ts` source files directly. + +```bash +git clone https://github.com/TencentCloud/TencentDB-Agent-Memory.git +cd TencentDB-Agent-Memory +npm install +openclaw plugins install --link . +``` + +`install --link` registers the current directory as a local plugin in OpenClaw. Source changes take effect after restarting the Gateway. + +### Optional: Enable Embedding Recall + +To use vector retrieval or hybrid recall, add an embedding configuration. Currently supports remote embedding services compatible with the OpenAI API. + +```jsonc +{ + "plugins": { + "entries": { + "memory-tencentdb": { + "enabled": true, + "config": { + "embedding": { // Embedding model config (not LLM model) + "enabled": true, // Enable vector search + "provider": "openai", // Only OpenAI-compatible API is supported + "baseUrl": "https://xxx", // API Base URL + "apiKey": "xxx", // API Key + "model": "text-embedding-3-large", // Model name + "dimensions": 1024 // Vector dimensions (must match the chosen model) + } + } + } + } + } +} +``` + + +## Architecture + +```text + ┌─────────────────┐ + │ L3 Profile │ Preferences & behavioral patterns + ├─────────────────┤ + │ L2 Scenarios │ Cross-session task / scenario blocks + ├─────────────────┤ + │ L1 Structured │ Facts, constraints, preferences, decisions + ├─────────────────┤ + │ L0 Dialogue │ Complete conversation records + └─────────────────┘ +``` + +Each layer serves a different purpose: + +- **L0** preserves raw conversations for replay and precise retrieval +- **L1** extracts high-value information for direct recall +- **L2** organizes scattered memories into scenario blocks across sessions +- **L3** maintains a user profile for long-term preference modeling + +## Lifecycle + +| Stage | Trigger | Action | +|---|---|---| +| Recall | `before_prompt_build` | Recall relevant memory and inject into context | +| L0 | `agent_end` | Write raw conversation logs | +| L1 | Scheduled | Extract structured memory, deduplicate, persist | +| L2 | After L1 | Update scenario blocks | +| L3 | Threshold reached | Generate or refresh user profile | +| Shutdown | `gateway_stop` | Clean up resources | + +The plugin also registers two tools for the Agent to call directly: + +- `tdai_memory_search`: queries L1 structured memory. Useful for questions like "what does the user prefer" or "what constraints were confirmed earlier". +- `tdai_conversation_search`: queries L0 raw conversations. Useful when exact original wording is needed. + +## Retrieval + +Three recall strategies: + +| Strategy | Implementation | +|---|---| +| `keyword` | FTS5 full-text search with jieba for Chinese tokenization | +| `embedding` | sqlite-vec vector similarity search | +| `hybrid` | Merged keyword and vector results | + +All backed by SQLite. + +## Configuration + +Grouped by capability: + +| Config Group | Purpose | +|---|---| +| `capture` | L0 conversation capture, exclusion rules, retention | +| `extraction` | L1 extraction, deduplication, per-run limit | +| `persona` | L2/L3 trigger frequency, scenario limit, backup count | +| `pipeline` | L1/L2/L3 scheduling | +| `recall` | Auto-recall toggle, result count, threshold, strategy | +| `embedding` | Vector retrieval service configuration | +| `report` | Metrics logging | + +Minimum configuration is just installing the plugin. Add `embedding` and scheduling parameters for better recall quality. + +## Data Directory + +```text +/ +├── conversations/ # L0 raw conversations +├── records/ # L1 structured memory +├── scene_blocks/ # L2 scenario blocks +├── .metadata/ # checkpoints, indexes, metadata +└── .backup/ # backups +``` + +## Scope + +This repository is the core OpenClaw plugin implementation. + +**Includes**: plugin entry and lifecycle hooks, 4-layer memory pipeline, retrieval tools and auto-recall, JSONL + SQLite local storage, checkpoint / backup / cleanup / logging. + +### Code Structure + +```text +TencentDB-Agent-Memory/ +├── index.ts # Plugin registration, tool registration, lifecycle hooks +├── openclaw.plugin.json +├── package.json +├── CHANGELOG.md +└── src/ + ├── hooks/ # Auto-recall and auto-capture + ├── conversation/ # L0 conversation management + ├── record/ # L1 extraction and persistence + ├── scene/ # L2 scenario synthesis + ├── persona/ # L3 user profile + ├── store/ # SQLite / FTS / vector retrieval + ├── tools/ # Retrieval tool registration + ├── prompts/ # Prompt templates + ├── report/ # Metrics reporting + └── utils/ +``` + +## License + +MIT. See [LICENSE](LICENSE). diff --git a/README_CN.md b/README_CN.md new file mode 100644 index 0000000..57adef6 --- /dev/null +++ b/README_CN.md @@ -0,0 +1,201 @@ +[English](README.md) + +

TencentDB Agent Memory

+ +

没有记忆的AI,只是工具;有记忆的AI,才是资产。

+ +

+ OpenClaw Plugin + MIT License +

+ + +**TencentDB Agent Memory是腾讯云数据库团队自研的 Agent 记忆系统**,为 OpenClaw 补上长期连续的记忆。通过四层渐进式记忆金字塔架构,自动完成记忆写入、分层提炼、按需召回与注入,让 Agent 从“只能聊天对话”进化为“持续学习、更懂你、跨会话不断线的长期可依赖 AI 助理”。 + +## 评测 + +基于 [PersonaMem](https://github.com/jiani-huang/PersonaMem)(UPenn,COLM 2025)评测集,589 道题,20 个角色。 + +| 题型 | OpenClaw 原生记忆 | TencentDB Agent Memory | +| :----------- | :---------------: | :---------: | +| 召回更新原因 | 70.97% | **88.89%** | +| 偏好演变跟踪 | 66.67% | **83.45%** | +| 个性化推荐 | 46.67% | **76.36%** | +| 场景泛化 | 31.58% | **78.95%** | +| 召回用户事实 | 29.63% | **79.07%** | +| 召回事实 | 25.00% | **76.47%** | +| 创意建议 | 24.00% | **45.16%** | +| **总计** | **47.85%** | **76.10%** | + +## 主要特点 + +- **OpenClaw 原生插件**,包名 `@tencentdb-agent-memory/memory-tencentdb`,一行命令即可安装 +- **四层记忆链路**:L0 原始对话 → L1 结构化记忆 → L2 场景归纳 → L3 用户画像 +- **混合召回**:支持 `keyword`、`embedding`、`hybrid` 三种策略 +- **两类检索工具**:`tdai_memory_search`(查结构化记忆)和 `tdai_conversation_search`(查原始对话) +- **本地优先存储**:JSONL + SQLite,数据在本地可直接查看和排查 +- **工程化能力**:去重、checkpoint、备份、定时清理、指标日志 +- **MIT 许可证** + +## 快速开始 + +### 环境要求 + +- Node.js `>= 22.16.0` +- OpenClaw `>= 2026.3.13` + +### 安装 + +```bash +openclaw plugins install @tencentdb-agent-memory/memory-tencentdb +``` + +安装完成后,插件接入 OpenClaw 对话生命周期,自动执行对话捕获、记忆召回和 L1/L2/L3 后续处理。 + +### 从源码开发 + +本项目无需编译。Node.js 22.16+ 原生支持 TypeScript 类型剥离,OpenClaw 直接加载 `.ts` 源码运行。 + +```bash +git clone https://github.com/TencentCloud/TencentDB-Agent-Memory.git +cd TencentDB-Agent-Memory +npm install +openclaw plugins install --link . +``` + +`install --link` 会将当前目录作为本地插件注册到 OpenClaw,修改源码后重启 Gateway 即可生效。 + +### 可选:开启 embedding 召回 + +如果需要向量检索或混合召回,补充 embedding 配置即可。当前支持兼容 OpenAI API 的远程 embedding 服务。 + +```jsonc +{ + "plugins": { + "entries": { + "memory-tencentdb": { + "enabled": true, + "config": { + "embedding": { // 需配置自定义Embedding模型信息,非LLM模型 + "enabled": true, // 是否启用向量搜索 + "provider": "openai", // 暂只支持OpenAI兼容的协议 + "baseUrl": "https://xxx", // API Base URL + "apiKey": "xxx", // API Key + "model": "text-embedding-3-large", // 模型名称 + "dimensions": 1024 // 向量维度(需与所选模型匹配) + } + } + } + } + } +} + +``` + + +## 架构 + +```text + ┌─────────────────┐ + │ L3 用户画像 │ 偏好与行为模式 + ├─────────────────┤ + │ L2 场景归纳 │ 跨会话的任务 / 场景块 + ├─────────────────┤ + │ L1 结构化记忆 │ 事实、约束、偏好、决策 + ├─────────────────┤ + │ L0 原始对话 │ 完整对话记录 + └─────────────────┘ +``` + +各层各有侧重: + +- **L0** 保留原始对话,用于回溯和精确检索 +- **L1** 抽取高价值信息,直接用于召回 +- **L2** 将零散记忆整理成场景块,跨会话聚合 +- **L3** 维护用户画像,用于长期偏好建模 + +## 生命周期 + +| 阶段 | 触发时机 | 动作 | +|---|---|---| +| Recall | `before_prompt_build` | 召回相关记忆,注入上下文 | +| L0 | `agent_end` | 写入原始对话 | +| L1 | 调度触发 | 提取结构化记忆,去重,持久化 | +| L2 | L1 完成后 | 更新场景块 | +| L3 | 达到阈值 | 生成或刷新用户画像 | +| Shutdown | `gateway_stop` | 清理资源 | + +插件还注册了两个 tool 供 Agent 主动调用: + +- `tdai_memory_search`:查 L1 结构化记忆。适合"用户偏好什么""之前确认过哪些约束"类问题。 +- `tdai_conversation_search`:查 L0 原始对话。适合需要原始措辞的场景。 + +## 检索实现 + +三种召回策略: + +| 策略 | 实现 | +|---|---| +| `keyword` | FTS5 全文检索,中文分词基于 jieba | +| `embedding` | sqlite-vec 向量相似度检索 | +| `hybrid` | 融合关键词与向量结果 | + +底层存储统一用 SQLite。 + +## 配置 + +按能力分组: + +| 配置组 | 作用 | +|---|---| +| `capture` | L0 对话捕获、排除规则、保留时间 | +| `extraction` | L1 提取、去重、单次上限 | +| `persona` | L2/L3 触发频率、场景上限、备份数量 | +| `pipeline` | L1/L2/L3 调度节奏 | +| `recall` | 自动召回开关、结果数、阈值、策略 | +| `embedding` | 向量检索服务配置 | +| `report` | 指标日志 | + +最小配置只需要安装插件。如果需要更好的召回效果,再加 `embedding` 和调度参数。 + +## 数据目录 + +```text +/ +├── conversations/ # L0 原始对话 +├── records/ # L1 结构化记忆 +├── scene_blocks/ # L2 场景块 +├── .metadata/ # checkpoint、索引、元数据 +└── .backup/ # 备份 +``` + +## 仓库范围 + +当前仓库是 OpenClaw 插件的核心实现。 + +**包含**:插件入口与生命周期钩子、四层记忆链路、检索工具与自动召回、JSONL + SQLite 本地存储、checkpoint / 备份 / 清理 / 日志。 + +### 代码结构 + +```text +TencentDB-Agent-Memory/ +├── index.ts # 插件注册、工具注册、生命周期接入 +├── openclaw.plugin.json +├── package.json +├── CHANGELOG.md +└── src/ + ├── hooks/ # 自动召回与自动捕获 + ├── conversation/ # L0 对话管理 + ├── record/ # L1 提取与持久化 + ├── scene/ # L2 场景归纳 + ├── persona/ # L3 用户画像 + ├── store/ # SQLite / FTS / 向量检索 + ├── tools/ # 检索工具注册 + ├── prompts/ # prompt 模板 + ├── report/ # 指标上报 + └── utils/ +``` + +## 许可证 + +MIT。详见 [LICENSE](LICENSE)。 \ No newline at end of file From 7433bdbbb1b39f4a8215527a22189e01d4bde1d2 Mon Sep 17 00:00:00 2001 From: chrishuan Date: Mon, 13 Apr 2026 20:28:49 +0800 Subject: [PATCH 2/3] ci: add PR CI workflow for basic checks --- .github/workflows/pr-ci.yml | 134 ++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 .github/workflows/pr-ci.yml diff --git a/.github/workflows/pr-ci.yml b/.github/workflows/pr-ci.yml new file mode 100644 index 0000000..e8d9609 --- /dev/null +++ b/.github/workflows/pr-ci.yml @@ -0,0 +1,134 @@ +name: CI + +on: + pull_request: + branches: [main] + +# Cancel previous runs for the same PR / branch +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + # ── 1. Install dependencies ──────────────────────────────── + install: + name: Install + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: "22" + + - name: Cache node_modules + uses: actions/cache@v4 + id: cache-deps + with: + path: node_modules + key: deps-${{ runner.os }}-${{ hashFiles('package.json') }} + + - name: npm install + if: steps.cache-deps.outputs.cache-hit != 'true' + run: npm install --ignore-scripts + + # ── 2. Pack validation ───────────────────────────────────── + pack: + name: Pack + needs: install + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: "22" + + - name: Restore node_modules + uses: actions/cache@v4 + with: + path: node_modules + key: deps-${{ runner.os }}-${{ hashFiles('package.json') }} + + - name: npm pack (dry-run) + run: npm pack --dry-run + + - name: npm pack + run: npm pack + + - name: Upload .tgz artifact + uses: actions/upload-artifact@v4 + with: + name: package-tarball + path: "*.tgz" + retention-days: 7 + + # ── 5. Plugin manifest validation ────────────────────────── + manifest: + name: Manifest + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Validate openclaw.plugin.json + run: | + echo "── Checking openclaw.plugin.json exists ──" + test -f openclaw.plugin.json || { echo "❌ openclaw.plugin.json not found"; exit 1; } + + echo "── Checking valid JSON ──" + node -e "JSON.parse(require('fs').readFileSync('openclaw.plugin.json','utf8'))" || { echo "❌ Invalid JSON"; exit 1; } + + echo "── Checking required fields ──" + node -e " + const m = JSON.parse(require('fs').readFileSync('openclaw.plugin.json','utf8')); + const errors = []; + if (!m.id || typeof m.id !== 'string') errors.push('missing or invalid \"id\"'); + if (m.configSchema && typeof m.configSchema !== 'object') errors.push('\"configSchema\" must be an object'); + if (errors.length) { console.error('❌ Manifest errors:', errors.join(', ')); process.exit(1); } + console.log('✅ id:', m.id); + if (m.name) console.log(' name:', m.name); + if (m.configSchema) console.log(' configSchema: present (' + Object.keys(m.configSchema.properties || {}).length + ' top-level props)'); + " + + echo "── Checking package.json openclaw metadata ──" + node -e " + const pkg = JSON.parse(require('fs').readFileSync('package.json','utf8')); + const oc = pkg.openclaw || {}; + const errors = []; + if (!oc.extensions || !oc.extensions.length) errors.push('missing openclaw.extensions'); + if (!oc.compat?.pluginApi) errors.push('missing openclaw.compat.pluginApi'); + if (!oc.build?.openclawVersion) errors.push('missing openclaw.build.openclawVersion'); + if (errors.length) { console.error('❌ Package metadata errors:', errors.join(', ')); process.exit(1); } + console.log('✅ openclaw metadata OK'); + console.log(' pluginApi:', oc.compat.pluginApi); + console.log(' openclawVersion:', oc.build.openclawVersion); + " + + # ── 6. Package size guard ────────────────────────────────── + size: + name: Size Guard + needs: pack + runs-on: ubuntu-latest + steps: + - name: Download tarball + uses: actions/download-artifact@v4 + with: + name: package-tarball + + - name: Check package size + run: | + TGZ=$(ls *.tgz | head -1) + SIZE=$(stat -c%s "$TGZ" 2>/dev/null || stat -f%z "$TGZ") + SIZE_KB=$((SIZE / 1024)) + MAX_KB=512 + + echo "📦 Package: $TGZ" + echo " Size: ${SIZE_KB} KB (limit: ${MAX_KB} KB)" + + if [ "$SIZE_KB" -gt "$MAX_KB" ]; then + echo "❌ Package exceeds ${MAX_KB} KB size limit!" + echo " Consider checking if large files were accidentally included." + exit 1 + else + echo "✅ Size OK" + fi From 76451838b8198a833af9f87b32017d369f71bc4f Mon Sep 17 00:00:00 2001 From: chrishuan Date: Thu, 23 Apr 2026 10:58:52 +0800 Subject: [PATCH 3/3] feat: release v0.1.4 --- CHANGELOG.md | 34 ++++++++++++++++++++++++++++++++++ package.json | 2 +- src/hooks/auto-recall.ts | 4 +++- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5c8195..74cbbfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,40 @@ --- +## [0.1.4] - 2026-04-10 + +### 🚀 Features + +- *(auto-recall)* Add recall hint text before memories + +## [0.1.3] - 2026-04-09 + +### 🚀 功能 + +- *(memory-tdai)* 用 reporter 抽象替换 emitMetric +- *(L3)* L3 使用读写工具,防止模型输出 CoT +- *(memory)* 添加 embedding 截断、召回超时,以及从 L0 捕获中剔除代码块 +- *(config)* Embedding 超时支持配置 +- *(report)* 在 schema 中暴露 report 配置项,默认值改为 false + +### 🐛 修复 + +- *(capture)* 跳过心跳/定时任务/自动化/调度类消息 +- *(recall)* 召回完成时清除超时定时器,避免误报超时警告 + +### 💼 Other + +- 重命名包名为 memory-tencentdb +- *(deps)* 将 node-llama-cpp 改为可选依赖 + +### ⚡ 性能 + +- *(auto-capture)* 将 L0 向量嵌入移至后台以降低延迟 + +### 📚 文档 + +- 添加 allowPromptInjection 配置警告说明 + ## [0.1.2] — 2026-03-26 ### 更新内容 diff --git a/package.json b/package.json index ad39271..ba22a31 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tencentdb-agent-memory/memory-tencentdb", - "version": "0.1.1", + "version": "0.1.4", "description": "Four-layer local memory system plugin for OpenClaw — auto-captures, structures, and profiles conversational knowledge using local LLM + SQLite vector search (L0→L1→L2→L3 pipeline)", "type": "module", "main": "index.ts", diff --git a/src/hooks/auto-recall.ts b/src/hooks/auto-recall.ts index f36222d..045c8d1 100644 --- a/src/hooks/auto-recall.ts +++ b/src/hooks/auto-recall.ts @@ -199,7 +199,9 @@ async function performAutoRecallInner(params: { systemParts.push(`\n${sceneNavigation}\n\n${pathHint}\n`); } if (memoryLines.length > 0) { - systemParts.push(`\n${memoryLines.join("\n")}\n`); + systemParts.push( + `\n以下是当前对话召回的相关记忆,不代表当前任务进程,仅作为参考:\n\n${memoryLines.join("\n")}\n` + ); } // Append memory tools usage guide so the agent knows how to actively