Skip to content

Commit af49d93

Browse files
authored
v0.4.0 (#28)
* v0.4.0 * 0.4.0 * add v2 API * add LocalEmbeddingProvider * Add WAL capture and CLI score filtering. Made-with: Cursor * Add unified request timeout for HTTP and CLI. Made-with: Cursor * Make agent_end tasks async and raise timeout default. Made-with: Cursor * fix * add cross_scope_share * debugPerfLog * fix * fix * fix * fix * fix * fix * fix * fix
1 parent caf78f0 commit af49d93

36 files changed

Lines changed: 16266 additions & 1691 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
node_modules/
22
.pnpm-store/
33
dist/
4+
lib/
45
*.log
56
.env
67
.DS_Store

README.md

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
# OpenClaw Memory (PowerMem) Plugin
1010

11-
This plugin lets [OpenClaw](https://github.com/openclaw/openclaw) use long-term memory via [PowerMem](https://github.com/oceanbase/powermem): intelligent extraction, Ebbinghaus forgetting curve, multi-agent isolation.
11+
This plugin lets [OpenClaw](https://github.com/openclaw/openclaw) use long-term memory via [PowerMem](https://github.com/oceanbase/powermem): intelligent extraction, Ebbinghaus forgetting curve, multi-agent isolation. Supports HTTP v2 (per-request config + agent memory sharing), LLM-based experience extraction, and optional dual-write to local SQLite.
1212

1313
**Default:** **CLI mode** — the plugin runs `pmem` locally (no `powermem-server`). Use **HTTP mode** when you already run a shared PowerMem API (teams / enterprise).
1414

@@ -185,13 +185,13 @@ openclaw plugins install -l /path/to/memory-powermem
185185

186186
**Note:** Running `npm i memory-powermem` in a Node project only adds the package to that project’s `node_modules`; it does **not** register the plugin with OpenClaw. To use this as an OpenClaw plugin, you must run `openclaw plugins install memory-powermem` (or install from a path as above), then restart the gateway.
187187

188-
After install, run `openclaw plugins list` and confirm `memory-powermem` is listed. With **no** `plugins.entries["memory-powermem"].config`, the plugin uses **defaults**: `mode: "cli"`, `envFile` under `~/.openclaw/powermem/powermem.env`, `pmemPath: "pmem"`, plus `autoCapture` / `autoRecall` / `inferOnAdd` enabled. Ensure `pmem` is on PATH (or set `pmemPath`) and the env file exists and is valid.
188+
After install, run `openclaw plugins list` and confirm `memory-powermem` is listed. With **no** `plugins.entries["memory-powermem"].config`, the plugin uses **defaults**: `mode: "cli"`, `pmemPath: "bundled"` (npm `powermem` from plugin dependencies), `useOpenClawModel: true` (SQLite under OpenClaw state + LLM from `agents.defaults.model`), plus `autoCapture` / `autoRecall` / `inferOnAdd` enabled. No separate `powermem.env` is required unless you opt out of OpenClaw model injection.
189189

190190
---
191191

192192
## Step 3: Configure OpenClaw (optional)
193193

194-
If you use **CLI mode** with the default paths and `pmem` on PATH, you can skip this step. Customize for HTTP, a different URL/API key, or a non-default `envFile` / `pmemPath`.
194+
If you use **CLI mode** with defaults (`bundled` + OpenClaw model injection), you can skip this step. Customize for HTTP, a different URL/API key, Python `pmem` (`pmemPath: "auto"` or an absolute path), or a `powermem` `.env` via `envFile`.
195195

196196
**CLI (default):**
197197

@@ -205,7 +205,7 @@ If you use **CLI mode** with the default paths and `pmem` on PATH, you can skip
205205
"config": {
206206
"mode": "cli",
207207
"envFile": "/home/you/.openclaw/powermem/powermem.env",
208-
"pmemPath": "pmem",
208+
"pmemPath": "bundled",
209209
"autoCapture": true,
210210
"autoRecall": true,
211211
"inferOnAdd": true
@@ -222,15 +222,19 @@ If you use **CLI mode** with the default paths and `pmem` on PATH, you can skip
222222
"config": {
223223
"mode": "http",
224224
"baseUrl": "http://localhost:8000",
225+
"httpApiVersion": "v2",
226+
"requestConfig": { "memory_db": { "host": "db-host", "port": 2881 } },
225227
"autoCapture": true,
226228
"autoRecall": true,
229+
"autoExperience": true,
230+
"experienceRecall": true,
227231
"inferOnAdd": true
228232
}
229233
```
230234

231235
Notes:
232236

233-
- **CLI (default):** You may omit `mode` and use CLI when `baseUrl` is empty; use `envFile` + `pmemPath`.
237+
- **CLI (default):** You may omit `mode` and use CLI when `baseUrl` is empty. Default `pmemPath` is `bundled` (npm CLI). Use `envFile` and/or `pmemPath` when you need a custom setup.
234238
- **HTTP:** When `mode` is `http`, `baseUrl` is required; if you set `baseUrl` without `mode`, the plugin treats it as HTTP. Do **not** append `/api/v1` to `baseUrl`. If the server uses API key auth, add `"apiKey"`.
235239
- **Restart the OpenClaw gateway** (or Mac menubar app) after changing config.
236240

@@ -283,16 +287,32 @@ After installing, uninstalling, or changing config, restart the OpenClaw gateway
283287

284288
| Option | Required | Description |
285289
|---------------|----------|-------------|
286-
| `mode` | No | Backend: `"cli"` (default) or `"http"`. If omitted, non-empty `baseUrl` implies `http`. |
287-
| `baseUrl` | Yes (http) | PowerMem API base URL when `mode` is `http`, e.g. `http://localhost:8000`, no `/api/v1` suffix. |
288-
| `apiKey` | No | Set when PowerMem server has API key authentication enabled (http mode). |
289-
| `envFile` | No | CLI: path to PowerMem `.env` (default when using plugin defaults: `~/.openclaw/powermem/powermem.env`). |
290-
| `pmemPath` | No | CLI: path to `pmem` executable; default `pmem`. |
291-
| `userId` | No | User isolation (multi-user); default `openclaw-user`. |
292-
| `agentId` | No | Agent isolation (multi-agent); default `openclaw-agent`. |
293-
| `autoCapture` | No | Auto-store from conversations after agent ends; default `true`. |
294-
| `autoRecall` | No | Auto-inject relevant memories before agent starts; default `true`. |
295-
| `inferOnAdd` | No | Use PowerMem intelligent extraction when adding; default `true`. |
290+
| `mode` | No | Backend: `"cli"` (default) or `"http"`. If omitted, non-empty `baseUrl` implies `http`. |
291+
| `baseUrl` | Yes (http) | PowerMem API base URL when `mode` is `http`, e.g. `http://localhost:8000`, no `/api/v1` suffix. |
292+
| `apiKey` | No | Set when PowerMem server has API key authentication enabled (http mode). |
293+
| `httpApiVersion` | No | HTTP API version: `"v1"` (default) or `"v2"`. |
294+
| `requestConfig` | No | HTTP v2 only: forwarded as `config` in each request (e.g. `memory_db` settings). |
295+
| `envFile` | No | CLI: path to PowerMem `.env` (default when using plugin defaults: `~/.openclaw/powermem/powermem.env`). |
296+
| `pmemPath` | No | CLI: `bundled` (default), `auto`, or path/command for `pmem`. |
297+
| `userId` | No | User isolation (multi-user). If omitted or set to `"auto"`, a stable ID is generated and stored in `<stateDir>/powermem/identity.json`. |
298+
| `agentId` | No | Agent isolation (multi-agent). If omitted or set to `"auto"`, a stable ID is generated and stored in `<stateDir>/powermem/identity.json`. |
299+
| `autoCapture` | No | Auto-store from conversations after agent ends; default `true`. |
300+
| `autoRecall` | No | Auto-inject relevant memories before agent starts; default `true`. |
301+
| `autoExperience` | No | Auto-extract procedural experiences via LLM; default `true`. |
302+
| `experienceRecall` | No | Include experiences in recall results; default `true`. |
303+
| `inferOnAdd` | No | Use PowerMem intelligent extraction when adding; default `true`. |
304+
| `dualWrite` | No | HTTP only: write to remote + local SQLite and queue failed writes. |
305+
| `localDbPath` | No | Local SQLite path for `dualWrite`. |
306+
| `localUserId` | No | Local namespace for `dualWrite` (defaults to `userId`). |
307+
| `localAgentId` | No | Local namespace for `dualWrite` (defaults to `agentId`). |
308+
| `syncOnResume` | No | Whether to sync pending writes on startup; default `true`. |
309+
| `syncBatchSize` | No | Pending sync batch size; default `50`. |
310+
| `syncMinIntervalMs` | No | Minimum interval between sync attempts; default `5000`. |
311+
| `syncBaseDelayMs` | No | Base delay for retry backoff; default `5000`. |
312+
| `syncMaxDelayMs` | No | Max delay for retry backoff; default `60000`. |
313+
| `syncMaxRetries` | No | Max retry count per pending item; default `10`. |
314+
315+
**Memory partitioning and sharing:** Use `userId` / `agentId` for logical isolation. In HTTP v2, `agent_memory_share` supports cross-agent sharing within the same `userId`; use `cross_scope_share` when you need to copy memories across both `userId` and `agentId` scopes.
296316

297317
**Auto-capture:** When a session ends, this round’s user/assistant text is sent to PowerMem (`infer: true`) for extraction and storage. At most 3 items per round, each up to about 6000 characters.
298318

@@ -305,6 +325,13 @@ Exposed to OpenClaw agents:
305325
- **memory_recall** — Search long-term memories by query.
306326
- **memory_store** — Store one memory (optional intelligent extraction on write).
307327
- **memory_forget** — Delete by memory ID or by search query.
328+
- **experience_store** — Store a procedural experience.
329+
- **experience_recall** — Search stored experiences.
330+
- **agent_memory_add** — Add memory to another agent (HTTP v2 only).
331+
- **agent_memory_list** — List an agent’s memories (HTTP v2 only).
332+
- **agent_memory_share** — Share memories across agents (HTTP v2 only).
333+
- **agent_memory_shared** — List memories shared with an agent (HTTP v2 only).
334+
- **cross_scope_share** — Copy memories across `userId`/`agentId` scopes (HTTP v2 only). Parameters: `fromUserId`, `fromAgentId`, `toUserId`, `toAgentId`, `query`; optional `limit`, `scoreThreshold`, `inferOnTarget`.
308335

309336
---
310337

@@ -320,7 +347,7 @@ Exposed to OpenClaw agents:
320347

321348
**1. `openclaw ltm health` fails or cannot connect**
322349

323-
- **CLI:** `pmem` on PATH or correct `pmemPath`; valid `.env` at `envFile`.
350+
- **CLI:** npm `powermem` installed with the plugin (`bundled`), or correct `pmemPath`; optional `.env` at `envFile` if not using OpenClaw model injection.
324351
- **HTTP:** PowerMem is running (HTTP server in a terminal, or Docker); `baseUrl` is correct (e.g. `http://localhost:8000`; watch for `127.0.0.1` vs `localhost` mismatches).
325352
- Remote server: use the host IP or hostname instead of `localhost`.
326353

README_CN.md

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
# OpenClaw Memory (PowerMem) 插件
1010

11-
本插件让 [OpenClaw](https://github.com/openclaw/openclaw) 通过 [PowerMem](https://github.com/oceanbase/powermem) 使用长期记忆:智能抽取、艾宾浩斯遗忘曲线、多 Agent 隔离。
11+
本插件让 [OpenClaw](https://github.com/openclaw/openclaw) 通过 [PowerMem](https://github.com/oceanbase/powermem) 使用长期记忆:智能抽取、艾宾浩斯遗忘曲线、多 Agent 隔离。支持 HTTP v2(按请求配置 + 代理共享)、LLM 经验提炼与本地 SQLite 双写。
1212

1313
**默认:CLI 模式** — 插件在本机执行 `pmem`,无需 `powermem-server`**HTTP 模式** 适合已有共享 PowerMem API 的场景(团队 / 企业)。
1414

@@ -186,13 +186,13 @@ openclaw plugins install -l /path/to/memory-powermem
186186

187187
**说明:** 在某个 Node 项目里执行 `npm i memory-powermem` 只会把包装进该项目的 `node_modules`**不会**在 OpenClaw 里注册插件。若要在 OpenClaw 里使用本插件,必须执行 `openclaw plugins install memory-powermem`(或按上面用本地路径安装),再重启 gateway。
188188

189-
安装成功后,可用 `openclaw plugins list` 确认能看到 `memory-powermem`。若未写 `plugins.entries["memory-powermem"].config`,插件 **默认**`mode: "cli"``envFile``~/.openclaw/powermem/powermem.env``pmemPath: "pmem"`,并开启 `autoCapture``autoRecall``inferOnAdd`请确保 `pmem` 在 PATH 上(或配置 `pmemPath`),且上述 `.env` 有效
189+
安装成功后,可用 `openclaw plugins list` 确认能看到 `memory-powermem`。若未写 `plugins.entries["memory-powermem"].config`,插件 **默认**`mode: "cli"``pmemPath: "bundled"`(优先插件旁的 npm `powermem`,否则用 PATH 上的 `pmem`)、`useOpenClawModel: true`(SQLite 在 OpenClaw 状态目录 + 从 `agents.defaults.model` 注入 LLM),并开启 `autoCapture``autoRecall``inferOnAdd`若不使用 OpenClaw 注入模型,再准备 `powermem``.env``envFile`
190190

191191
---
192192

193193
## 第三步:配置 OpenClaw(可选)
194194

195-
若使用 **CLI 默认路径**`pmem` 已在 PATH,可跳过。需要 HTTP、改 URL/API Key、或自定义 `envFile` / `pmemPath` 时再改配置。
195+
若使用 **CLI 默认**`bundled` + OpenClaw 模型注入),可跳过。需要 HTTP、改 URL/API Key、使用 Python 版 `pmem``pmemPath: "auto"` 或绝对路径)、或通过 `envFile` 时再改配置。
196196

197197
**CLI(默认):**
198198

@@ -206,7 +206,7 @@ openclaw plugins install -l /path/to/memory-powermem
206206
"config": {
207207
"mode": "cli",
208208
"envFile": "/home/you/.openclaw/powermem/powermem.env",
209-
"pmemPath": "pmem",
209+
"pmemPath": "bundled",
210210
"autoCapture": true,
211211
"autoRecall": true,
212212
"inferOnAdd": true
@@ -223,15 +223,19 @@ openclaw plugins install -l /path/to/memory-powermem
223223
"config": {
224224
"mode": "http",
225225
"baseUrl": "http://localhost:8000",
226+
"httpApiVersion": "v2",
227+
"requestConfig": { "memory_db": { "host": "db-host", "port": 2881 } },
226228
"autoCapture": true,
227229
"autoRecall": true,
230+
"autoExperience": true,
231+
"experienceRecall": true,
228232
"inferOnAdd": true
229233
}
230234
```
231235

232236
说明:
233237

234-
- **CLI(默认):** 可不写 `mode``baseUrl` 为空时走 CLI;使用 `envFile` + `pmemPath`
238+
- **CLI(默认):** 可不写 `mode``baseUrl` 为空时走 CLI。默认 `pmemPath``bundled`(npm CLI)。需要时再配 `envFile` / `pmemPath`
235239
- **HTTP:** `mode``http` 时必须配置 `baseUrl`;若只写 `baseUrl` 不写 `mode`,插件会按 HTTP 处理。**不要**`baseUrl` 上加 `/api/v1`。若服务开了 API Key,加 `"apiKey"`
236240
- 改完配置后**重启 OpenClaw gateway**(或 Mac 菜单栏应用)。
237241

@@ -284,16 +288,32 @@ openclaw ltm search "咖啡"
284288

285289
| 选项 | 必填 | 说明 |
286290
|---------------|------|------|
287-
| `mode` || 后端:`"cli"`(默认)或 `"http"`。不写 `mode` 但填了 `baseUrl` 时按 HTTP 处理。 |
288-
| `baseUrl` | 是(http) | `mode``http` 时必填,PowerMem API 根地址,如 `http://localhost:8000`,不要带 `/api/v1`|
289-
| `apiKey` || PowerMem 开启 API Key 鉴权时填写(http 模式)。 |
290-
| `envFile` || CLI:PowerMem `.env`;插件默认约定 `~/.openclaw/powermem/powermem.env`|
291-
| `pmemPath` || CLI 模式:`pmem` 可执行路径,默认 `pmem`|
292-
| `userId` || 用于多用户隔离,默认 `openclaw-user`|
293-
| `agentId` || 用于多 Agent 隔离,默认 `openclaw-agent`|
294-
| `autoCapture` || 会话结束后是否自动把对话交给 PowerMem 抽取记忆,默认 `true`|
295-
| `autoRecall` || 会话开始前是否自动注入相关记忆,默认 `true`|
296-
| `inferOnAdd` || 写入时是否用 PowerMem 智能抽取,默认 `true`|
291+
| `mode` || 后端:`"cli"`(默认)或 `"http"`。不写 `mode` 但填了 `baseUrl` 时按 HTTP 处理。 |
292+
| `baseUrl` | 是(http) | `mode``http` 时必填,PowerMem API 根地址,如 `http://localhost:8000`,不要带 `/api/v1`|
293+
| `apiKey` || PowerMem 开启 API Key 鉴权时填写(http 模式)。 |
294+
| `httpApiVersion` || HTTP 版本:`"v1"`(默认)或 `"v2"`|
295+
| `requestConfig` || HTTP v2 专用:按请求透传 `config`(如 `memory_db`)。 |
296+
| `envFile` || CLI:PowerMem `.env`;插件默认约定 `~/.openclaw/powermem/powermem.env`|
297+
| `pmemPath` || CLI:`bundled`(默认)、`auto``pmem` 的路径/命令。 |
298+
| `userId` || 用于多用户隔离。未填或为 `"auto"` 时自动生成并保存到 `<stateDir>/powermem/identity.json`|
299+
| `agentId` || 用于多 Agent 隔离。未填或为 `"auto"` 时自动生成并保存到 `<stateDir>/powermem/identity.json`|
300+
| `autoCapture` || 会话结束后是否自动把对话交给 PowerMem 抽取记忆,默认 `true`|
301+
| `autoRecall` || 会话开始前是否自动注入相关记忆,默认 `true`|
302+
| `autoExperience` || LLM 自动提炼经验,默认 `true`|
303+
| `experienceRecall` || 召回结果是否包含经验,默认 `true`|
304+
| `inferOnAdd` || 写入时是否用 PowerMem 智能抽取,默认 `true`|
305+
| `dualWrite` || 仅 HTTP:远端 + 本地 SQLite 双写,远端失败自动排队补传。 |
306+
| `localDbPath` || 本地 SQLite 路径(`dualWrite`)。 |
307+
| `localUserId` || 本地命名空间(`dualWrite`,默认 `userId`)。 |
308+
| `localAgentId` || 本地命名空间(`dualWrite`,默认 `agentId`)。 |
309+
| `syncOnResume` || 是否启动时补传,默认 `true`|
310+
| `syncBatchSize` || 每批补传数量,默认 `50`|
311+
| `syncMinIntervalMs` || 补传最小间隔,默认 `5000`|
312+
| `syncBaseDelayMs` || 重试基础延迟,默认 `5000`|
313+
| `syncMaxDelayMs` || 重试最大延迟,默认 `60000`|
314+
| `syncMaxRetries` || 单条最大重试次数,默认 `10`|
315+
316+
**记忆划分与分享:** 建议用 `userId` / `agentId` 做逻辑隔离;HTTP v2 可用 `agent_memory_share` 在同一 `userId` 下做跨 Agent 共享。若需跨 `userId` + `agentId`,可用 `cross_scope_share``query` 检索源记忆并复制到目标命名空间。
297317

298318
**自动抓取**:会话结束时,会把本轮用户/助手文本发给 PowerMem(`infer: true`),由 PowerMem 抽取并落库。每轮最多 3 条,每条约 6000 字符以内。
299319

@@ -306,6 +326,13 @@ openclaw ltm search "咖啡"
306326
- **memory_recall** — 按查询搜索长期记忆
307327
- **memory_store** — 写入一条记忆(可选是否智能抽取)
308328
- **memory_forget** — 按记忆 ID 或按搜索条件删除
329+
- **experience_store** — 写入经验
330+
- **experience_recall** — 查询经验
331+
- **agent_memory_add** — 给其它 Agent 增加记忆(HTTP v2)
332+
- **agent_memory_list** — 列出 Agent 记忆(HTTP v2)
333+
- **agent_memory_share** — 共享 Agent 记忆(HTTP v2)
334+
- **agent_memory_shared** — 列出共享记忆(HTTP v2)
335+
- **cross_scope_share** — 跨 `userId` / `agentId` 复制共享记忆(HTTP v2)。参数:`fromUserId``fromAgentId``toUserId``toAgentId``query`,可选 `limit``scoreThreshold``inferOnTarget`
309336

310337
---
311338

@@ -321,7 +348,7 @@ openclaw ltm search "咖啡"
321348

322349
**1. `openclaw ltm health` 报错连不上**
323350

324-
- **CLI:** `pmem` 在 PATH `pmemPath` 正确;`envFile` 指向有效 `.env`
351+
- **CLI:** 插件已安装 npm `powermem``bundled`),`pmemPath` 正确;未用 OpenClaw 注入时再保证 `envFile`
325352
- **HTTP:** PowerMem 已启动(方式 A 终端或 Docker);`baseUrl` 正确(本机常用 `http://localhost:8000`,注意与 `127.0.0.1` 一致性问题)。
326353
- 若 OpenClaw 和 PowerMem 不在同一台机器,把 `localhost` 改成 PowerMem 所在机器的 IP 或域名。
327354

0 commit comments

Comments
 (0)