Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 41 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,46 @@ Defaults to a local `SQLite + sqlite-vec` backend.

Once enabled, TencentDB Agent Memory automatically handles conversation capture, memory extraction, scene aggregation, persona generation, and recall before the next turn.

### 1.3 Enable short-term compression (optional, requires version ≥ 0.3.4)
### 1.3 Use PostgreSQL as the memory store

To store L0/L1/profile data in PostgreSQL with `pgvector`, `vectorscale`, and `pg_textsearch`:

```jsonc
{
"memory-tencentdb": {
"enabled": true,
"config": {
"storeBackend": "postgres",
"postgres": {
"host": "127.0.0.1",
"port": 5432,
"database": "postgres",
"user": "postgres",
"schema": "agent_memory",
"textConfig": "simple",
"vectorIndex": "hnsw"
}
}
}
}
```

Requirements: `CREATE EXTENSION vector`, `CREATE EXTENSION vectorscale`, and `CREATE EXTENSION pg_textsearch` must be available in the target database; `pg_textsearch` must also be listed in `shared_preload_libraries`.

For an existing local store, migrate with:

```bash
npm run build:migrate-sqlite-to-postgres
node ./bin/migrate-sqlite-to-postgres.mjs \
--plugin-data-dir ~/.openclaw/data/memory-tencentdb \
--sqlite-path ~/.openclaw/data/memory-tencentdb/vectors.db \
--pg-host 127.0.0.1 --pg-port 5432 --pg-database postgres --pg-user postgres \
--pg-schema agent_memory --dry-run
```

Re-run with `--yes` to apply after checking the dry-run summary.

### 1.4 Enable short-term compression (optional, requires version ≥ 0.3.4)

```jsonc
{
Expand Down Expand Up @@ -401,7 +440,7 @@ If `MEMORY_TENCENTDB_GATEWAY_API_KEY` is unset, the plugin also looks at `TDAI_G
| Field | Default | Description |
| :--- | :--- | :--- |
| `timezone` | `"system"` | Timezone for user/LLM-facing timestamps: `"system"` (follow process tz) / IANA name (`Asia/Shanghai`) / offset string (`+08:00`) |
| `storeBackend` | `"sqlite"` | Storage backend: `sqlite` |
| `storeBackend` | `"sqlite"` | Storage backend: `sqlite` / `tcvdb` / `postgres` |
| `recall.strategy` | `"hybrid"` | Recall strategy: `keyword` / `embedding` / `hybrid` (RRF fusion, recommended) |
| `recall.maxResults` | `5` | Number of items returned per recall |
| `recall.maxCharsPerMemory` | `0` | Max characters injected for one recalled L1 memory; `0` disables this guard |
Expand Down
42 changes: 40 additions & 2 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,46 @@ openclaw gateway restart

启用后,TencentDB Agent Memory 会自动完成对话录制、记忆提取、场景归纳、用户画像生成和下一轮对话前召回。

### 1.3 使用 PostgreSQL 作为记忆存储

### 1.3 启用短期记忆压缩(可选,要求版本 ≥ 0.3.4)
如果希望用 PostgreSQL + `pgvector` + `vectorscale` + `pg_textsearch` 存储 L0/L1/profile 数据,可配置:

```jsonc
{
"memory-tencentdb": {
"enabled": true,
"config": {
"storeBackend": "postgres",
"postgres": {
"host": "127.0.0.1",
"port": 5432,
"database": "postgres",
"user": "postgres",
"schema": "agent_memory",
"textConfig": "simple",
"vectorIndex": "hnsw"
}
}
}
}
```

目标数据库需可用 `vector`、`vectorscale`、`pg_textsearch` 扩展;其中 `pg_textsearch` 还需要加入 `shared_preload_libraries` 后重启数据库。

已有 SQLite 数据可先 dry-run 迁移:

```bash
npm run build:migrate-sqlite-to-postgres
node ./bin/migrate-sqlite-to-postgres.mjs \
--plugin-data-dir ~/.openclaw/data/memory-tencentdb \
--sqlite-path ~/.openclaw/data/memory-tencentdb/vectors.db \
--pg-host 127.0.0.1 --pg-port 5432 --pg-database postgres --pg-user postgres \
--pg-schema agent_memory --dry-run
```

确认摘要无误后,加 `--yes` 执行真实迁移。

### 1.4 启用短期记忆压缩(可选,要求版本 ≥ 0.3.4)

```jsonc
{
Expand Down Expand Up @@ -404,7 +442,7 @@ export MEMORY_TENCENTDB_GATEWAY_API_KEY="<与 Gateway 同一份密钥>"
| 字段 | 默认 | 说明 |
| :--- | :--- | :--- |
| `timezone` | `"system"` | 时区:`"system"`(跟随系统)/ IANA 名(`Asia/Shanghai`)/ offset 串(`+08:00`) |
| `storeBackend` | `"sqlite"` | 存储后端:`sqlite` |
| `storeBackend` | `"sqlite"` | 存储后端:`sqlite` / `tcvdb` / `postgres` |
| `recall.strategy` | `"hybrid"` | 召回策略:`keyword` / `embedding` / `hybrid`(RRF 融合,推荐) |
| `recall.maxResults` | `5` | 每次召回条数 |
| `recall.maxCharsPerMemory` | `0` | 单条 L1 记忆注入的最大字符数;`0` 表示不限制 |
Expand Down
12 changes: 12 additions & 0 deletions bin/migrate-sqlite-to-postgres.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env node

// Thin wrapper: runs the pre-compiled PostgreSQL migration CLI entry.
// Build first: npm run build:migrate-sqlite-to-postgres

import path from "node:path";
import { fileURLToPath } from "node:url";

const thisDir = path.dirname(fileURLToPath(import.meta.url));
const entryScript = path.resolve(thisDir, "../scripts/migrate-sqlite-to-postgres/dist/scripts/migrate-sqlite-to-postgres/cli-entry.js");

import(entryScript);
95 changes: 95 additions & 0 deletions codebuddy-plugin/memory-tencentdb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# memory-tencentdb — CodeBuddy Skill

把 **TencentDB Agent Memory** 的四层长期记忆能力(L0 对话捕获 → L1 结构化记忆 → L2 场景块 → L3 用户画像)封装为一个 **CodeBuddy Skill**,让 CodeBuddy 在对话中具备与原 OpenClaw 记忆插件等价的体验:自动召回历史记忆、自动捕获本轮对话、按需检索记忆与历史会话。

## 它如何工作

```
CodeBuddy Agent ──(遵循 SKILL.md)──> scripts/memory-client.mjs ──HTTP──> Gateway(:8420) ──> L0~L3 管线 ──> PostgreSQL(pgvector)
└──(会话首次)──> scripts/gateway-up.sh ──探测/拉起──> scripts/memory-tencentdb-ctl.sh start ──> npx tsx src/gateway/server.ts
```

- **薄封装**:不改动 `src/` 核心记忆逻辑,仅复用既有的、与宿主解耦的 Gateway HTTP 服务和 `memory-tencentdb-ctl.sh` 守护脚本。
- **全自动语义驱动**:CodeBuddy 无 `agent_end`/`before_prompt_build` 钩子,记忆的召回/捕获由 `SKILL.md` 指令约束 Agent 行为来模拟——回答前 `recall`、回答后 `capture`。
- **Gateway 自动托管**:先探测本机 8420 端口,已存在则复用,不存在则自动拉起并健康检查。
- **PostgreSQL 默认后端**:默认使用 PostgreSQL(pgvector)。

## 目录结构

```
memory-tencentdb/
├── SKILL.md # Skill 入口:触发场景 + 全自动 recall/capture 工作流 + session_key 约定
├── scripts/
│ ├── memory-client.mjs # Gateway HTTP 客户端 CLI(内置 fetch,零依赖)
│ ├── gateway-up.sh # 探测 8420 / 健康检查 / 自动拉起(幂等)
│ └── install-codebuddy-skill.sh # 安装脚本(--user / --project,引导写 PG/LLM/Embedding 配置)
├── references/
│ ├── configuration.md # 配置说明:PG/LLM/Embedding、扩展依赖、用户级/项目级差异、安全
│ └── troubleshooting.md # 故障排查
└── README.md # 本文件
```

## 安装

> 前置:`node >= 22.16`、`npx`、`python3`;一个可用的 PostgreSQL(建议装 `pgvector`)。

### 用户级(跨项目共享记忆)

```bash
bash scripts/install-codebuddy-skill.sh --user \
--pg-database mydb --pg-user myuser --pg-password 'secret' \
--llm-base-url https://api.openai.com/v1 --llm-api-key 'sk-...' --llm-model gpt-4o \
--emb-provider openai --emb-base-url https://api.openai.com/v1 \
--emb-api-key 'sk-...' --emb-model text-embedding-3-small --emb-dimensions 1536 \
--restart
```

安装到 `~/.codebuddy/skills/memory-tencentdb`,`session_key=codebuddy:global`。

### 项目级(按项目隔离记忆)

```bash
bash scripts/install-codebuddy-skill.sh --project /path/to/workspace \
--pg-database mydb --pg-user myuser --pg-password 'secret'
```

安装到 `<workspace>/.codebuddy/skills/memory-tencentdb`,`session_key=codebuddy:proj:<workspace 路径哈希>`。

> 配置参数可省略,安装脚本会打印后续手动配置指引(见 `references/configuration.md`)。
> 开发调试可加 `--link` 软链源目录(改源码即时生效);`--dry-run` 预演。

### 验证

```bash
bash <dest>/scripts/gateway-up.sh
node <dest>/scripts/memory-client.mjs health # 期望 ok(或 degraded=向量库未配)
```

## 卸载

```bash
bash scripts/install-codebuddy-skill.sh --user --uninstall
# 或
bash scripts/install-codebuddy-skill.sh --project /path/to/workspace --uninstall
```

仅移除安装的 Skill 目录,不删除 Gateway 数据(PostgreSQL 中的记忆保留)。如需清理 Gateway 配置/数据,手动处理 `~/.memory-tencentdb/`。

## 与 Hermes / OpenClaw 形态的关系

| 形态 | 接入方式 | 位置 |
|------|----------|------|
| OpenClaw 插件 | 原生插件 + 钩子(agent_end / before_prompt_build) | 仓库根(`index.ts` 等) |
| Hermes | HTTP 客户端 + 进程守护 | `hermes-plugin/` |
| **CodeBuddy Skill(本目录)** | HTTP 客户端 + 进程守护 + SKILL.md 指令驱动 | `codebuddy-plugin/` |

三者共享同一个宿主无关的 Gateway(`src/gateway/server.ts`)与守护脚本(`scripts/memory-tencentdb-ctl.sh`),仅"如何触发召回/捕获"的方式不同。

## 安全

- 密钥/口令以 0600 权限写入 `tdai-gateway.json`,`config show` 自动脱敏。
- Gateway 默认仅绑定 `127.0.0.1`;暴露到非回环地址前务必设 `TDAI_GATEWAY_API_KEY` 并让客户端用 `--api-key` 传 Bearer。
- 客户端 recall/capture 失败静默降级,不回显密钥与堆栈。

更多细节见 `references/configuration.md` 与 `references/troubleshooting.md`。
124 changes: 124 additions & 0 deletions codebuddy-plugin/memory-tencentdb/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
---
name: memory-tencentdb
description: 为 CodeBuddy 提供基于 TencentDB Agent Memory 的长期记忆能力(L0 对话→L1 结构化记忆→L2 场景→L3 画像)。当用户希望"记住偏好/记住我说过的话/长期记忆/跨会话记忆",或希望"召回历史记忆/检索之前的对话/想起上次聊过什么",或提到"记忆插件/memory/记住这个/别忘了"时应触发。此 Skill 通过本地 Gateway(HTTP 127.0.0.1:8420)在每轮对话开始时自动召回相关记忆、对话结束后自动捕获本轮内容,并支持按需检索结构化记忆与历史会话。
version: 1.0.0
---

## 目的

让 CodeBuddy 具备与原 OpenClaw 记忆插件等价的长期记忆体验:

- **自动召回**:每轮回答前,从历史记忆中检索与当前问题相关的上下文并融入回答。
- **自动捕获**:每轮回答后,把本轮 user/assistant 内容写入记忆管线(L0→L1→L2→L3)。
- **按需检索**:用户明确要求"想起/翻一下之前"时,检索结构化记忆或历史会话。

底层复用仓库既有的、与宿主解耦的 Gateway HTTP 服务(`src/gateway/server.ts`),本 Skill 仅作薄封装:用 `scripts/memory-client.mjs` 调用 Gateway,用 `scripts/gateway-up.sh` 自动托管 Gateway 进程。

## 适用场景

- 用户表达希望被"记住"的偏好、约定、事实(如技术栈、命名习惯、项目背景)。
- 用户希望召回之前对话或之前定下的结论。
- 用户明确要求检索记忆 / 历史会话。

## 不适用场景

- 一次性、无需跨会话保留的纯计算/查询类问答(可不触发,避免额外开销)。
- Gateway 依赖(PostgreSQL / LLM / Embedding)尚未配置完成时——应先引导用户运行安装脚本(见"首次安装")。

## 关键约定

### session_key(记忆命名空间)

`session_key` 决定记忆如何分组与隔离,必须在 recall 与 capture 间保持一致:

- **用户级安装(跨项目共享记忆)**:使用固定全局命名空间 `codebuddy:global`。
- **项目级安装(按项目隔离记忆)**:使用 `codebuddy:proj:<workspace-hash>`,其中 hash 由工作区绝对路径稳定派生。

安装时由 `install-codebuddy-skill.sh` 写入 `scripts/.session-scope`(内容为最终 session_key),客户端会自动读取。也可在调用时用 `--session <key>` 显式覆盖。

### Gateway 端点(由 memory-client.mjs 封装,无需手写 HTTP)

- `POST /recall` `{query, session_key}` → `{context, strategy, memory_count}`
- `POST /capture` `{user_content, assistant_content, session_key, session_id?}` → `{l0_recorded, scheduler_notified}`
- `POST /search/memories` `{query, limit?, type?, scene?}`
- `POST /search/conversations` `{query, limit?, session_key?}`
- `GET /health`

默认地址 `http://127.0.0.1:8420`;若 Gateway 启用了鉴权,需通过 `--api-key`(或环境变量 `TDAI_GATEWAY_API_KEY`)传 Bearer token。

## 标准工作流(全自动语义驱动)

CodeBuddy 没有 `agent_end` / `before_prompt_build` 钩子,记忆的召回与捕获改由以下指令驱动 Agent 行为。**所有命令都在 Skill 的 `scripts/` 目录下执行。**

### 步骤 0:确保 Gateway 在线(每个会话仅需一次)

会话内首次涉及记忆时,先确保 Gateway 可用(幂等,可重复调用):

```bash
bash scripts/gateway-up.sh
```

- 已有实例 → 直接复用;无实例 → 自动拉起并做健康检查。
- 若返回非 0(启动失败),跳过记忆步骤、正常回答,并提示用户查看 `references/troubleshooting.md`。

### 步骤 1:回答前自动召回(recall)

在生成回答**之前**执行(短超时,失败静默降级,绝不阻塞回答):

```bash
node scripts/memory-client.mjs recall --query "<用户本轮问题>" --timeout 3000
```

- 有输出 → 把返回的记忆上下文作为背景知识融入本轮回答(不要原文复述,自然引用即可)。
- 无输出 / 超时 / 失败 → 直接正常回答,不向用户暴露错误。

### 步骤 2:回答后自动捕获(capture)

在回答**之后**执行(可容忍较长耗时):

```bash
node scripts/memory-client.mjs capture --user "<用户本轮原话>" --assistant "<本轮最终回答>"
```

- `--user` / `--assistant` 传本轮实际文本。
- 失败不影响用户,记录到 stderr 即可。

### 步骤 3:按需检索(仅用户明确要求时)

```bash
# 检索结构化记忆(L1)
node scripts/memory-client.mjs search-memories --query "<关键词>" --limit 5
# 检索历史原始会话(L0)
node scripts/memory-client.mjs search-conversations --query "<关键词>" --limit 5
```

## 首次安装

若 Gateway 依赖未配置(health 为 down / degraded、或 recall 持续为空),引导用户运行安装脚本:

```bash
# 用户级(跨项目共享记忆)
bash scripts/install-codebuddy-skill.sh --user
# 或项目级(按项目隔离记忆)
bash scripts/install-codebuddy-skill.sh --project
```

安装脚本会:拷贝/软链 Skill 到对应 skills 目录、引导写入 PostgreSQL / LLM / Embedding 配置、设定 session_key 范围。详见 `references/configuration.md`。

## 安全约束

- 绝不在回答或日志中明文回显 PG 口令、API key、Bearer token。
- 配置文件以 0600 权限写入;密钥优先用环境变量注入。
- recall/capture 失败一律静默降级,不向用户暴露内部错误细节与堆栈。

## 完成定义

- `scripts/gateway-up.sh` 健康检查通过。
- 回答前能 recall、回答后能 capture(或在依赖缺失时优雅跳过且不影响回答)。
- 用户的偏好/约定能在后续会话被召回。

## 参考资料

- `references/configuration.md` — PG/LLM/Embedding 配置、扩展依赖、用户级/项目级差异。
- `references/troubleshooting.md` — Gateway 未起、召回为空、扩展缺失、鉴权 401、端口占用等排查。
- `README.md` — 总览、安装与卸载、与 Hermes/OpenClaw 形态的关系。
Loading