@memtensor/memos-local-openclaw-plugin 0.1.3 → 0.1.5
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/.env.example +13 -5
- package/README.md +283 -91
- package/dist/capture/index.d.ts +5 -7
- package/dist/capture/index.d.ts.map +1 -1
- package/dist/capture/index.js +72 -43
- package/dist/capture/index.js.map +1 -1
- package/dist/ingest/dedup.d.ts +8 -0
- package/dist/ingest/dedup.d.ts.map +1 -1
- package/dist/ingest/dedup.js +21 -0
- package/dist/ingest/dedup.js.map +1 -1
- package/dist/ingest/providers/anthropic.d.ts +16 -0
- package/dist/ingest/providers/anthropic.d.ts.map +1 -1
- package/dist/ingest/providers/anthropic.js +214 -1
- package/dist/ingest/providers/anthropic.js.map +1 -1
- package/dist/ingest/providers/bedrock.d.ts +16 -5
- package/dist/ingest/providers/bedrock.d.ts.map +1 -1
- package/dist/ingest/providers/bedrock.js +210 -6
- package/dist/ingest/providers/bedrock.js.map +1 -1
- package/dist/ingest/providers/gemini.d.ts +16 -0
- package/dist/ingest/providers/gemini.d.ts.map +1 -1
- package/dist/ingest/providers/gemini.js +202 -1
- package/dist/ingest/providers/gemini.js.map +1 -1
- package/dist/ingest/providers/index.d.ts +31 -0
- package/dist/ingest/providers/index.d.ts.map +1 -1
- package/dist/ingest/providers/index.js +134 -4
- package/dist/ingest/providers/index.js.map +1 -1
- package/dist/ingest/providers/openai.d.ts +24 -0
- package/dist/ingest/providers/openai.d.ts.map +1 -1
- package/dist/ingest/providers/openai.js +255 -1
- package/dist/ingest/providers/openai.js.map +1 -1
- package/dist/ingest/task-processor.d.ts +65 -0
- package/dist/ingest/task-processor.d.ts.map +1 -0
- package/dist/ingest/task-processor.js +354 -0
- package/dist/ingest/task-processor.js.map +1 -0
- package/dist/ingest/worker.d.ts +3 -1
- package/dist/ingest/worker.d.ts.map +1 -1
- package/dist/ingest/worker.js +131 -23
- package/dist/ingest/worker.js.map +1 -1
- package/dist/recall/engine.d.ts +1 -0
- package/dist/recall/engine.d.ts.map +1 -1
- package/dist/recall/engine.js +22 -11
- package/dist/recall/engine.js.map +1 -1
- package/dist/recall/mmr.d.ts.map +1 -1
- package/dist/recall/mmr.js +3 -1
- package/dist/recall/mmr.js.map +1 -1
- package/dist/skill/bundled-memory-guide.d.ts +6 -0
- package/dist/skill/bundled-memory-guide.d.ts.map +1 -0
- package/dist/skill/bundled-memory-guide.js +95 -0
- package/dist/skill/bundled-memory-guide.js.map +1 -0
- package/dist/skill/evaluator.d.ts +31 -0
- package/dist/skill/evaluator.d.ts.map +1 -0
- package/dist/skill/evaluator.js +194 -0
- package/dist/skill/evaluator.js.map +1 -0
- package/dist/skill/evolver.d.ts +22 -0
- package/dist/skill/evolver.d.ts.map +1 -0
- package/dist/skill/evolver.js +193 -0
- package/dist/skill/evolver.js.map +1 -0
- package/dist/skill/generator.d.ts +25 -0
- package/dist/skill/generator.d.ts.map +1 -0
- package/dist/skill/generator.js +477 -0
- package/dist/skill/generator.js.map +1 -0
- package/dist/skill/installer.d.ts +16 -0
- package/dist/skill/installer.d.ts.map +1 -0
- package/dist/skill/installer.js +89 -0
- package/dist/skill/installer.js.map +1 -0
- package/dist/skill/upgrader.d.ts +19 -0
- package/dist/skill/upgrader.d.ts.map +1 -0
- package/dist/skill/upgrader.js +263 -0
- package/dist/skill/upgrader.js.map +1 -0
- package/dist/skill/validator.d.ts +29 -0
- package/dist/skill/validator.d.ts.map +1 -0
- package/dist/skill/validator.js +227 -0
- package/dist/skill/validator.js.map +1 -0
- package/dist/storage/sqlite.d.ts +141 -1
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +664 -7
- package/dist/storage/sqlite.js.map +1 -1
- package/dist/types.d.ts +93 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -1
- package/dist/viewer/html.d.ts +1 -1
- package/dist/viewer/html.d.ts.map +1 -1
- package/dist/viewer/html.js +2391 -159
- package/dist/viewer/html.js.map +1 -1
- package/dist/viewer/server.d.ts +16 -0
- package/dist/viewer/server.d.ts.map +1 -1
- package/dist/viewer/server.js +346 -3
- package/dist/viewer/server.js.map +1 -1
- package/index.ts +572 -89
- package/openclaw.plugin.json +20 -45
- package/package.json +3 -4
- package/skill/memos-memory-guide/SKILL.md +86 -0
- package/src/capture/index.ts +85 -45
- package/src/ingest/dedup.ts +29 -0
- package/src/ingest/providers/anthropic.ts +258 -1
- package/src/ingest/providers/bedrock.ts +256 -6
- package/src/ingest/providers/gemini.ts +252 -1
- package/src/ingest/providers/index.ts +156 -8
- package/src/ingest/providers/openai.ts +304 -1
- package/src/ingest/task-processor.ts +396 -0
- package/src/ingest/worker.ts +145 -34
- package/src/recall/engine.ts +23 -12
- package/src/recall/mmr.ts +3 -1
- package/src/skill/bundled-memory-guide.ts +91 -0
- package/src/skill/evaluator.ts +220 -0
- package/src/skill/evolver.ts +169 -0
- package/src/skill/generator.ts +506 -0
- package/src/skill/installer.ts +59 -0
- package/src/skill/upgrader.ts +257 -0
- package/src/skill/validator.ts +227 -0
- package/src/storage/sqlite.ts +802 -7
- package/src/types.ts +96 -0
- package/src/viewer/html.ts +2391 -159
- package/src/viewer/server.ts +346 -3
- package/SKILL.md +0 -43
- package/www/index.html +0 -632
package/.env.example
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
# Embedding API
|
|
2
|
-
# Use any OpenAI-compatible embedding service, or leave blank for local offline model
|
|
1
|
+
# ─── Embedding API ───
|
|
2
|
+
# Use any OpenAI-compatible embedding service, or leave blank for local offline model (Xenova/all-MiniLM-L6-v2)
|
|
3
|
+
EMBEDDING_PROVIDER=openai_compatible
|
|
3
4
|
EMBEDDING_API_KEY=your-embedding-api-key
|
|
4
|
-
EMBEDDING_ENDPOINT=https://api.
|
|
5
|
-
EMBEDDING_MODEL=
|
|
5
|
+
EMBEDDING_ENDPOINT=https://your-embedding-api.com/v1
|
|
6
|
+
EMBEDDING_MODEL=bge-m3
|
|
6
7
|
|
|
7
|
-
# Summarizer API
|
|
8
|
+
# ─── Summarizer API ───
|
|
9
|
+
# OpenAI-compatible LLM for one-sentence chunk summaries
|
|
8
10
|
# Leave blank to use rule-based fallback (no LLM needed)
|
|
11
|
+
SUMMARIZER_PROVIDER=openai_compatible
|
|
9
12
|
SUMMARIZER_API_KEY=your-summarizer-api-key
|
|
10
13
|
SUMMARIZER_ENDPOINT=https://api.openai.com/v1
|
|
11
14
|
SUMMARIZER_MODEL=gpt-4o-mini
|
|
15
|
+
SUMMARIZER_TEMPERATURE=0
|
|
16
|
+
|
|
17
|
+
# ─── Memory Viewer ───
|
|
18
|
+
# Port for the web-based Memory Viewer (default: 18799)
|
|
19
|
+
# VIEWER_PORT=18799
|
package/README.md
CHANGED
|
@@ -1,18 +1,62 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 🧠 MemOS Local — OpenClaw Memory Plugin
|
|
2
2
|
|
|
3
|
-
Persistent local conversation memory for [OpenClaw](https://github.com/nicepkg/openclaw) AI Agents. Every conversation is automatically captured, semantically indexed, and instantly recallable
|
|
3
|
+
Persistent local conversation memory for [OpenClaw](https://github.com/nicepkg/openclaw) AI Agents. Every conversation is automatically captured, semantically indexed, and instantly recallable — with **smart task summarization** and **automatic skill evolution**.
|
|
4
4
|
|
|
5
|
-
**Full-write | Hybrid Search
|
|
5
|
+
**Full-write | Hybrid Search | Task Summarization | Skill Evolution | Memory Viewer**
|
|
6
|
+
|
|
7
|
+
## Why MemOS Local
|
|
8
|
+
|
|
9
|
+
| Problem | Solution |
|
|
10
|
+
|---------|----------|
|
|
11
|
+
| Agent forgets everything between sessions | **Persistent memory** — every conversation auto-captured to local SQLite |
|
|
12
|
+
| Fragmented memory chunks lack context | **Smart task summarization** — conversations organized into structured tasks with goals, steps, results |
|
|
13
|
+
| Agent repeats past mistakes on similar tasks | **Skill evolution** — reusable skills auto-generated from real executions, continuously upgraded |
|
|
14
|
+
| No visibility into what the agent remembers | **Memory Viewer** — full visualization of all memories, tasks, and skills |
|
|
15
|
+
| Privacy concerns with cloud storage | **100% local** — zero cloud uploads, zero telemetry, password-protected |
|
|
6
16
|
|
|
7
17
|
## Features
|
|
8
18
|
|
|
9
|
-
|
|
10
|
-
- **
|
|
19
|
+
### Memory Engine
|
|
20
|
+
- **Auto-capture** — Stores user, assistant, and tool messages after each agent turn via `agent_end` event (consecutive assistant messages merged into one)
|
|
21
|
+
- **Smart deduplication** — Exact content-hash skip; then Top-5 similar chunks (threshold 0.75) with LLM judge: DUPLICATE (skip), UPDATE (merge summary + append content), or NEW (create). Evolved chunks track merge history.
|
|
22
|
+
- **Semantic chunking** — Splits by code blocks, function bodies, paragraphs; never cuts mid-function
|
|
11
23
|
- **Hybrid retrieval** — FTS5 keyword + vector semantic dual-channel search with RRF fusion
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
|
|
24
|
+
- **MMR diversity** — Maximal Marginal Relevance reranking prevents near-duplicate results
|
|
25
|
+
- **Recency decay** — Configurable time-based decay (half-life: 14 days) biases recent memories
|
|
26
|
+
- **Multi-provider embedding** — OpenAI-compatible, Gemini, Cohere, Voyage, Mistral, or local offline (Xenova/all-MiniLM-L6-v2)
|
|
27
|
+
|
|
28
|
+
### Task Summarization
|
|
29
|
+
- **Auto task boundary detection** — LLM topic judgment + 2-hour idle timeout segments conversations into tasks
|
|
30
|
+
- **Structured summaries** — LLM generates Goal, Key Steps, Result, Key Details for each completed task
|
|
31
|
+
- **Key detail preservation** — Code, commands, URLs, file paths, error messages retained in summaries
|
|
32
|
+
- **Quality filtering** — Tasks with too few chunks, too few turns, or trivial content are auto-skipped
|
|
33
|
+
- **Task status** — `active` (in progress), `completed` (with LLM summary), `skipped` (too brief, excluded from search)
|
|
34
|
+
|
|
35
|
+
### Skill Evolution
|
|
36
|
+
- **Automatic evaluation** — After task completion, rule filter + LLM evaluates if the task is worth distilling into a skill
|
|
37
|
+
- **Skill generation** — Multi-step LLM pipeline creates SKILL.md + scripts + references + evals from real execution records
|
|
38
|
+
- **Skill upgrading** — When similar tasks appear, existing skills are auto-upgraded (refine / extend / fix)
|
|
39
|
+
- **Quality scoring** — 0-10 quality assessment; scores below 6 marked as draft
|
|
40
|
+
- **Version management** — Full version history with changelog, change summary, and upgrade type tracking
|
|
41
|
+
- **Auto-install** — Generated skills can be auto-installed into the workspace for immediate use
|
|
42
|
+
- **Dedicated model** — Optional separate LLM model for skill generation (e.g., Claude 4.6 for higher quality)
|
|
43
|
+
|
|
44
|
+
### Memory Viewer
|
|
45
|
+
- **6 management pages** — Memories, Tasks, Skills, Analytics, **Logs**, Settings
|
|
46
|
+
- **Full CRUD** — Create, edit, delete, search memories; evolution badges and merge history on memory cards
|
|
47
|
+
- **Task browser** — Status filters, chat-bubble chunk view, structured summaries, skill generation status
|
|
48
|
+
- **Skill browser** — Version history, quality scores, one-click download as ZIP
|
|
49
|
+
- **Analytics dashboard** — Daily read/write activity, memory breakdown charts
|
|
50
|
+
- **Logs** — Tool call log (memory_search, auto_recall, memory_add, etc.) with input/output and duration; filter by tool, auto-refresh
|
|
51
|
+
- **Online configuration** — Modify embedding, summarizer, skill evolution settings via web UI
|
|
52
|
+
- **Security** — Password-protected, localhost-only (127.0.0.1), session cookies
|
|
53
|
+
- **i18n** — Chinese / English toggle
|
|
54
|
+
- **Themes** — Light / Dark mode
|
|
55
|
+
|
|
56
|
+
### Privacy & Security
|
|
57
|
+
- **100% on-device** — All data in local SQLite, no cloud uploads, no telemetry
|
|
58
|
+
- **Viewer security** — Binds to 127.0.0.1 only, password-protected with session cookies
|
|
59
|
+
- **Auto-recall + Skill** — Each turn, relevant memories are injected via `before_agent_start` hook (invisible to user). When nothing is recalled (e.g. long or unclear query), the agent is prompted to call `memory_search` with a self-generated short query. The bundled skill `memos-memory-guide` documents all tools and when to use them.
|
|
16
60
|
|
|
17
61
|
## Quick Start
|
|
18
62
|
|
|
@@ -24,9 +68,9 @@ Persistent local conversation memory for [OpenClaw](https://github.com/nicepkg/o
|
|
|
24
68
|
openclaw plugins install @memtensor/memos-local-openclaw-plugin
|
|
25
69
|
```
|
|
26
70
|
|
|
27
|
-
The plugin is installed under `~/.openclaw/extensions
|
|
71
|
+
The plugin is installed under `~/.openclaw/extensions/memos-local` and registered as `memos-local`.
|
|
28
72
|
|
|
29
|
-
> **Important:**
|
|
73
|
+
> **Important:** The Memory Viewer starts only when the **OpenClaw gateway** is running. After install, **configure** `openclaw.json` (step 2) and **start the gateway** (step 3); the viewer will then be available at `http://127.0.0.1:18799`.
|
|
30
74
|
|
|
31
75
|
**From source (development):**
|
|
32
76
|
|
|
@@ -43,6 +87,14 @@ Add the plugin config to `~/.openclaw/openclaw.json`:
|
|
|
43
87
|
|
|
44
88
|
```jsonc
|
|
45
89
|
{
|
|
90
|
+
"agents": {
|
|
91
|
+
"defaults": {
|
|
92
|
+
// IMPORTANT: Disable OpenClaw's built-in memory to avoid conflicts
|
|
93
|
+
"memorySearch": {
|
|
94
|
+
"enabled": false
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
},
|
|
46
98
|
"plugins": {
|
|
47
99
|
"slots": {
|
|
48
100
|
"memory": "memos-local"
|
|
@@ -71,6 +123,8 @@ Add the plugin config to `~/.openclaw/openclaw.json`:
|
|
|
71
123
|
}
|
|
72
124
|
```
|
|
73
125
|
|
|
126
|
+
> **Critical:** You must set `agents.defaults.memorySearch.enabled` to `false`. Otherwise OpenClaw's built-in memory search runs alongside this plugin, causing duplicate retrieval and wasted tokens.
|
|
127
|
+
|
|
74
128
|
#### Embedding Provider Options
|
|
75
129
|
|
|
76
130
|
| Provider | `provider` value | Example `model` | Notes |
|
|
@@ -95,6 +149,30 @@ Add the plugin config to `~/.openclaw/openclaw.json`:
|
|
|
95
149
|
|
|
96
150
|
> **No summarizer config?** A rule-based fallback generates summaries from the first sentence + key entities. Good enough to start.
|
|
97
151
|
|
|
152
|
+
#### Skill Evolution Configuration (Optional)
|
|
153
|
+
|
|
154
|
+
You can optionally configure a dedicated model for skill generation (for higher quality skills):
|
|
155
|
+
|
|
156
|
+
```jsonc
|
|
157
|
+
{
|
|
158
|
+
"config": {
|
|
159
|
+
"skillSummarizer": {
|
|
160
|
+
"provider": "anthropic",
|
|
161
|
+
"apiKey": "sk-ant-xxx",
|
|
162
|
+
"model": "claude-sonnet-4-20250514",
|
|
163
|
+
"temperature": 0
|
|
164
|
+
},
|
|
165
|
+
"skillEvolution": {
|
|
166
|
+
"enabled": true,
|
|
167
|
+
"autoEvaluate": true,
|
|
168
|
+
"autoInstall": false
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
If `skillSummarizer` is not configured, the plugin uses the regular `summarizer` model for skill generation.
|
|
175
|
+
|
|
98
176
|
#### Environment Variable Support
|
|
99
177
|
|
|
100
178
|
Use `${ENV_VAR}` placeholders in config to avoid hardcoding keys:
|
|
@@ -107,8 +185,6 @@ Use `${ENV_VAR}` placeholders in config to avoid hardcoding keys:
|
|
|
107
185
|
|
|
108
186
|
### 3. Start or Restart the Gateway
|
|
109
187
|
|
|
110
|
-
The Memory Viewer and all plugin features only run when the OpenClaw gateway is running. After installing and configuring the plugin, start (or restart) the gateway:
|
|
111
|
-
|
|
112
188
|
```bash
|
|
113
189
|
openclaw gateway stop # if already running
|
|
114
190
|
openclaw gateway install # ensure LaunchAgent is installed (macOS)
|
|
@@ -120,7 +196,6 @@ Once the gateway is up, the plugin loads and starts the Memory Viewer at `http:/
|
|
|
120
196
|
### 4. Verify Installation
|
|
121
197
|
|
|
122
198
|
```bash
|
|
123
|
-
# Check the gateway log
|
|
124
199
|
tail -20 ~/.openclaw/logs/gateway.log
|
|
125
200
|
```
|
|
126
201
|
|
|
@@ -145,105 +220,146 @@ memos-local: started (embedding: openai_compatible)
|
|
|
145
220
|
**Step C** — In a new conversation, ask the agent to recall what you discussed:
|
|
146
221
|
|
|
147
222
|
```
|
|
148
|
-
You:
|
|
149
|
-
Agent: (calls memory_search)
|
|
223
|
+
You: 你还记得我之前让你帮我处理过什么事情吗?
|
|
224
|
+
Agent: (calls memory_search) 是的,我们之前讨论过...
|
|
150
225
|
```
|
|
151
226
|
|
|
152
|
-
|
|
227
|
+
## How It Works
|
|
153
228
|
|
|
154
|
-
|
|
155
|
-
|
|
229
|
+
### Three Intelligent Pipelines
|
|
230
|
+
|
|
231
|
+
MemOS Local operates through three interconnected pipelines that form a continuous learning loop:
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
Conversation → Memory Write Pipeline → Task Generation Pipeline → Skill Evolution Pipeline
|
|
235
|
+
↓
|
|
236
|
+
Smart Retrieval Pipeline ← ← ← ← ← ← ← ← ←
|
|
156
237
|
```
|
|
157
238
|
|
|
158
|
-
|
|
239
|
+
### Pipeline 1: Memory Write (auto on every agent turn)
|
|
159
240
|
|
|
160
241
|
```
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
242
|
+
Conversation → Capture (filter roles, strip system prompts)
|
|
243
|
+
→ Semantic chunking (code blocks, paragraphs, error stacks)
|
|
244
|
+
→ Content hash dedup → LLM summarize each chunk
|
|
245
|
+
→ Vector embedding → Store (SQLite + FTS5 + Vector)
|
|
164
246
|
```
|
|
165
247
|
|
|
166
|
-
|
|
248
|
+
- System messages are skipped; tool results from the plugin's own tools are not re-stored
|
|
249
|
+
- Evidence wrapper blocks (`[STORED_MEMORY]...[/STORED_MEMORY]`) are stripped to prevent feedback loops
|
|
250
|
+
- Content hash (SHA-256, first 16 hex chars) prevents duplicate chunk ingestion within the same session+role
|
|
167
251
|
|
|
168
|
-
|
|
252
|
+
### Pipeline 2: Task Generation (auto after memory write)
|
|
169
253
|
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
254
|
+
```
|
|
255
|
+
New chunks → Task boundary detection (LLM topic judge / 2h idle / session change)
|
|
256
|
+
→ Boundary crossed? → Finalize previous task
|
|
257
|
+
→ Chunks ≥ 4 & turns ≥ 2? → LLM structured summary → status = "completed"
|
|
258
|
+
→ Otherwise → status = "skipped" (excluded from search)
|
|
175
259
|
```
|
|
176
260
|
|
|
177
|
-
|
|
261
|
+
**Why Tasks matter:**
|
|
262
|
+
- Raw memory chunks are fragmented — a single conversation about "deploying Nginx" might span 20 chunks
|
|
263
|
+
- Task summarization organizes these fragments into a structured record: Goal → Steps → Result → Key Details
|
|
264
|
+
- When the agent searches memory, it can quickly locate the complete experience via `task_summary`, not just fragments
|
|
265
|
+
- Task summaries preserve code, commands, URLs, configs, and error messages
|
|
178
266
|
|
|
179
|
-
###
|
|
267
|
+
### Pipeline 3: Skill Evolution (auto after task completion)
|
|
180
268
|
|
|
181
|
-
|
|
269
|
+
```
|
|
270
|
+
Completed task → Rule filter (min chunks, non-trivial content)
|
|
271
|
+
→ Search for related existing skills
|
|
272
|
+
→ Related skill found (confidence ≥ 0.7)?
|
|
273
|
+
→ Evaluate upgrade (refine/extend/fix) → Merge new experience → Version bump
|
|
274
|
+
→ No related skill (or confidence < 0.3)?
|
|
275
|
+
→ Evaluate create → Generate SKILL.md + scripts + evals
|
|
276
|
+
→ Quality score (0-10) → Install if score ≥ 6
|
|
277
|
+
```
|
|
182
278
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
```
|
|
189
|
-
If your `openclaw.json` already has `plugins.slots.memory: "memos-local"` and `plugins.entries.memos-local`, the config check may fail with "plugin not found" before install runs. In that case use Option B.
|
|
279
|
+
**Why Skills matter:**
|
|
280
|
+
- Without skills, agents rediscover solutions every time they encounter similar problems
|
|
281
|
+
- Skills crystallize successful executions into reusable guides with steps, pitfall warnings, and verification checks
|
|
282
|
+
- Skills auto-upgrade when new tasks bring improved approaches — getting faster, more accurate, and more token-efficient
|
|
283
|
+
- The evolution is automatic: task completes → evaluate → create/upgrade → install
|
|
190
284
|
|
|
191
|
-
|
|
192
|
-
Delete the folder, then install from npm and extract:
|
|
193
|
-
```bash
|
|
194
|
-
rm -rf ~/.openclaw/extensions/memos-local
|
|
195
|
-
cd /tmp
|
|
196
|
-
npm pack @memtensor/memos-local-openclaw-plugin
|
|
197
|
-
tar -xzf memtensor-memos-local-openclaw-plugin-*.tgz
|
|
198
|
-
mv package ~/.openclaw/extensions/memos-local
|
|
199
|
-
```
|
|
200
|
-
**No need to run `npm install`** — on first load the plugin will install dependencies automatically. Then restart the gateway: `openclaw gateway stop` then `openclaw gateway start`.
|
|
285
|
+
### Pipeline 4: Smart Retrieval
|
|
201
286
|
|
|
202
|
-
**
|
|
203
|
-
If auto-install failed (e.g. `npm` not in PATH when the gateway runs), install dependencies manually once:
|
|
287
|
+
**Auto-recall (every turn):** The plugin hooks `before_agent_start`, runs a memory search with the user's message, then uses an LLM to filter which candidates are relevant and whether they are sufficient to answer. The filtered memories are injected into the agent's system context (invisible to the user). If no memories are found or the query is long/unclear, the agent is prompted to call `memory_search` with a self-generated short query.
|
|
204
288
|
|
|
205
|
-
|
|
206
|
-
|
|
289
|
+
**On-demand search (`memory_search`):**
|
|
290
|
+
```
|
|
291
|
+
Query → FTS5 + Vector dual recall → RRF Fusion → MMR Rerank
|
|
292
|
+
→ Recency Decay → Score Filter → Top-K (e.g. 20)
|
|
293
|
+
→ LLM relevance filter (minimum information) → Dedup by excerpt overlap
|
|
294
|
+
→ Return excerpts + chunkId / task_id (no summaries)
|
|
295
|
+
→ sufficient=false → suggest task_summary(taskId), skill_get(taskId), memory_timeline(chunkId)
|
|
207
296
|
```
|
|
208
297
|
|
|
209
|
-
|
|
298
|
+
- **RRF (Reciprocal Rank Fusion):** Merges FTS5 and vector search rankings into a unified score
|
|
299
|
+
- **MMR (Maximal Marginal Relevance):** Re-ranks to balance relevance with diversity
|
|
300
|
+
- **Recency Decay:** Recent memories get a boost (half-life: 14 days by default)
|
|
301
|
+
- **LLM filter:** Only memories that are genuinely useful for the query are returned; sufficiency determines whether follow-up tool tips are appended
|
|
302
|
+
|
|
303
|
+
## Retrieval Strategy
|
|
304
|
+
|
|
305
|
+
1. **Auto-recall (hook)** — On every turn, the plugin runs a memory search using the user's message and injects LLM-filtered relevant memories into the agent's context (via `before_agent_start`). The agent sees this as system context; the user does not.
|
|
306
|
+
2. **When nothing is recalled** — If the user's message is long, vague, or no matches are found, the plugin injects a short hint telling the agent to call **`memory_search`** with a **self-generated short query** (e.g. key topics or a rephrased question).
|
|
307
|
+
3. **Bundled skill** — The plugin installs `memos-memory-guide` into `~/.openclaw/workspace/skills/memos-memory-guide/` and `~/.openclaw/skills/memos-memory-guide/`. This skill documents all memory tools, when to call them, and how to write good search queries. Add `skills.load.extraDirs: ["~/.openclaw/skills"]` in `openclaw.json` if you want the skill to appear in the OpenClaw skills dashboard.
|
|
308
|
+
4. **Search results** — `memory_search` returns **excerpts** (original content snippets) and IDs (`chunkId`, `task_id`), not summaries. The agent uses `task_summary(taskId)`, `memory_timeline(chunkId)`, and `skill_get(skillId|taskId)` to drill down when needed. There is no `memory_get`; full context is obtained via `task_summary` or `memory_timeline`.
|
|
210
309
|
|
|
211
310
|
## Agent Tools
|
|
212
311
|
|
|
213
|
-
The plugin registers
|
|
312
|
+
The plugin registers **6 tools** and auto-installs the **memos-memory-guide** skill:
|
|
214
313
|
|
|
215
|
-
| Tool | Purpose |
|
|
216
|
-
|
|
217
|
-
| `memory_search` | Search memories
|
|
218
|
-
| `
|
|
219
|
-
| `
|
|
220
|
-
| `
|
|
314
|
+
| Tool | Purpose | When to Use |
|
|
315
|
+
|------|---------|-------------|
|
|
316
|
+
| `memory_search` | Search memories; returns excerpts + `chunkId` / `task_id` | When auto-recall returned nothing or you need a different query; use a short, self-generated query if the user's message was long or unclear |
|
|
317
|
+
| `task_summary` | Full structured summary of a completed task | When a hit has `task_id` and you need the full story (goal, steps, result) |
|
|
318
|
+
| `memory_timeline` | Surrounding conversation around a chunk | When you need the exact dialogue before/after a hit; pass `chunkId` from the hit |
|
|
319
|
+
| `skill_get` | Get skill content by `skillId` or `taskId` | When a hit has a linked task/skill and you want the reusable experience guide |
|
|
320
|
+
| `skill_install` | Install a skill into the agent workspace | When the skill should be permanently available for future turns |
|
|
321
|
+
| `memory_viewer` | Get the URL of the Memory Viewer web UI | When the user asks where to view or manage their memories |
|
|
322
|
+
|
|
323
|
+
There is no `memory_get`; search returns excerpts and IDs; use `task_summary` or `memory_timeline` for deeper context.
|
|
221
324
|
|
|
222
|
-
|
|
325
|
+
### Search Parameters
|
|
326
|
+
|
|
327
|
+
| Parameter | Default | Range | Description |
|
|
328
|
+
|-----------|---------|-------|-------------|
|
|
329
|
+
| `query` | — | — | Natural language search query (keep it short and focused) |
|
|
330
|
+
| `maxResults` | 20 | 1–20 | Maximum candidates before LLM filter |
|
|
331
|
+
| `minScore` | 0.45 | 0.35–1.0 | Minimum relevance score |
|
|
332
|
+
| `role` | — | `user` / `assistant` / `tool` | Filter by message role (e.g. `user` to find what the user said) |
|
|
223
333
|
|
|
224
334
|
## Memory Viewer
|
|
225
335
|
|
|
226
|
-
Open `http://127.0.0.1:18799` in your browser
|
|
336
|
+
Open `http://127.0.0.1:18799` in your browser after starting the gateway.
|
|
227
337
|
|
|
228
|
-
**
|
|
338
|
+
**Pages:**
|
|
229
339
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
340
|
+
| Page | Features |
|
|
341
|
+
|------|----------|
|
|
342
|
+
| **Memories** | Timeline view, pagination, session/role/kind/date filters, CRUD, semantic search; evolution badges and merge history on cards |
|
|
343
|
+
| **Tasks** | Task list with status filters (active/completed/skipped), chat-bubble chunk view, structured summaries, skill generation status |
|
|
344
|
+
| **Skills** | Skill list with status badges, version history with changelogs, quality scores, related tasks, one-click ZIP download |
|
|
345
|
+
| **Analytics** | Daily write/read activity charts, memory/task/skill totals, role breakdown |
|
|
346
|
+
| **Logs** | Tool call log (memory_search, auto_recall, memory_add, etc.) with input/output, duration, and tool filter; auto-refresh |
|
|
347
|
+
| **Settings** | Online configuration for embedding model, summarizer model, skill evolution settings, viewer port |
|
|
234
348
|
|
|
235
|
-
|
|
236
|
-
- Browse, search, create, edit, delete memories
|
|
237
|
-
- Filter by role (user/assistant/tool), type, time range (down to seconds)
|
|
238
|
-
- Pagination (30 per page)
|
|
349
|
+
**Viewer won't open?**
|
|
239
350
|
|
|
240
|
-
|
|
351
|
+
- The viewer is started by the plugin when the **gateway** starts. It does **not** run at install time.
|
|
352
|
+
- Ensure the gateway is running: `openclaw gateway start`
|
|
353
|
+
- Ensure the plugin is enabled in `~/.openclaw/openclaw.json`
|
|
354
|
+
- Check the log: `tail -30 ~/.openclaw/logs/gateway.log` — look for `MemOS Memory Viewer`
|
|
355
|
+
|
|
356
|
+
**Forgot password?** Click "Forgot password?" on the login page and use the reset token:
|
|
241
357
|
|
|
242
358
|
```bash
|
|
243
|
-
|
|
244
|
-
grep "password reset token:" /tmp/openclaw/openclaw-*.log ~/.openclaw/logs/gateway.log 2>/dev/null | tail -1
|
|
359
|
+
grep "password reset token:" ~/.openclaw/logs/gateway.log 2>/dev/null | tail -1
|
|
245
360
|
```
|
|
246
|
-
|
|
361
|
+
|
|
362
|
+
Copy the 32-character hex string after `password reset token:`.
|
|
247
363
|
|
|
248
364
|
## Advanced Configuration
|
|
249
365
|
|
|
@@ -262,41 +378,117 @@ All optional — shown with defaults:
|
|
|
262
378
|
"recencyHalfLifeDays": 14 // Time decay half-life
|
|
263
379
|
},
|
|
264
380
|
"dedup": {
|
|
265
|
-
"similarityThreshold": 0.
|
|
381
|
+
"similarityThreshold": 0.75, // Cosine similarity for smart-dedup candidates (Top-5)
|
|
382
|
+
"enableSmartMerge": true, // LLM judge: DUPLICATE / UPDATE / NEW
|
|
383
|
+
"maxCandidates": 5 // Max similar chunks to send to LLM
|
|
384
|
+
},
|
|
385
|
+
"skillEvolution": {
|
|
386
|
+
"enabled": true, // Enable skill evolution
|
|
387
|
+
"autoEvaluate": true, // Auto-evaluate tasks for skill generation
|
|
388
|
+
"minChunksForEval": 6, // Min chunks for a task to be evaluated
|
|
389
|
+
"minConfidence": 0.7, // Min LLM confidence to create/upgrade skill
|
|
390
|
+
"autoInstall": false // Auto-install generated skills
|
|
266
391
|
},
|
|
267
392
|
"viewerPort": 18799 // Memory Viewer port
|
|
268
393
|
}
|
|
269
394
|
}
|
|
270
395
|
```
|
|
271
396
|
|
|
272
|
-
##
|
|
397
|
+
## Reinstall / Upgrade
|
|
273
398
|
|
|
274
|
-
**
|
|
399
|
+
If you see **"plugin already exists"** or **"plugin not found"**:
|
|
275
400
|
|
|
401
|
+
**Option A — Clean reinstall via OpenClaw CLI:**
|
|
402
|
+
```bash
|
|
403
|
+
rm -rf ~/.openclaw/extensions/memos-local
|
|
404
|
+
openclaw plugins install @memtensor/memos-local-openclaw-plugin
|
|
405
|
+
cd ~/.openclaw/extensions/memos-local && npm install --omit=dev
|
|
406
|
+
openclaw gateway stop && openclaw gateway start
|
|
276
407
|
```
|
|
277
|
-
|
|
278
|
-
|
|
408
|
+
|
|
409
|
+
**Option B — Manual install (when config already references memos-local):**
|
|
410
|
+
```bash
|
|
411
|
+
rm -rf ~/.openclaw/extensions/memos-local
|
|
412
|
+
cd /tmp
|
|
413
|
+
npm pack @memtensor/memos-local-openclaw-plugin
|
|
414
|
+
tar -xzf memtensor-memos-local-openclaw-plugin-*.tgz
|
|
415
|
+
mv package ~/.openclaw/extensions/memos-local
|
|
416
|
+
cd ~/.openclaw/extensions/memos-local && npm install --omit=dev
|
|
417
|
+
openclaw gateway stop && openclaw gateway start
|
|
279
418
|
```
|
|
280
419
|
|
|
281
|
-
**
|
|
420
|
+
**Plugin shows as "error" in `openclaw plugins list`?** (e.g. `Cannot find module '@sinclair/typebox'`)
|
|
282
421
|
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
→ Recency Decay → Score Filter → Top-K Results
|
|
422
|
+
```bash
|
|
423
|
+
cd ~/.openclaw/extensions/memos-local && npm install --omit=dev
|
|
286
424
|
```
|
|
287
425
|
|
|
288
|
-
|
|
426
|
+
Then restart the gateway.
|
|
289
427
|
|
|
290
|
-
##
|
|
428
|
+
## Troubleshooting
|
|
429
|
+
|
|
430
|
+
### 常见问题排查
|
|
291
431
|
|
|
292
|
-
|
|
432
|
+
1. **确认报错内容** — 记下完整报错,例如:`plugin not found`、`Cannot find module 'xxx'`、`Invalid config` 等。
|
|
433
|
+
|
|
434
|
+
2. **看插件状态**
|
|
435
|
+
```bash
|
|
436
|
+
openclaw plugins list
|
|
437
|
+
```
|
|
438
|
+
- Status 为 **error** → 记下错误信息
|
|
439
|
+
- 列表中没有 MemOS Local → 未安装或未放到 `~/.openclaw/extensions/memos-local`
|
|
440
|
+
|
|
441
|
+
3. **看网关日志**
|
|
442
|
+
```bash
|
|
443
|
+
tail -50 ~/.openclaw/logs/gateway.log
|
|
444
|
+
```
|
|
445
|
+
搜索 `memos-local`、`failed to load`、`Error`、`Cannot find module`。
|
|
446
|
+
|
|
447
|
+
4. **检查环境**
|
|
448
|
+
- Node 版本:`node -v`(需要 **>= 18**)
|
|
449
|
+
- 插件目录存在:`ls ~/.openclaw/extensions/memos-local/package.json`
|
|
450
|
+
- 依赖已安装:`ls ~/.openclaw/extensions/memos-local/node_modules/@sinclair/typebox`
|
|
451
|
+
若不存在:`cd ~/.openclaw/extensions/memos-local && npm install --omit=dev`
|
|
452
|
+
|
|
453
|
+
5. **检查配置** — 打开 `~/.openclaw/openclaw.json`,确认:
|
|
454
|
+
- `agents.defaults.memorySearch.enabled` = `false`(关闭内置记忆)
|
|
455
|
+
- `plugins.slots.memory` = `"memos-local"`
|
|
456
|
+
- `plugins.entries.memos-local.enabled` = `true`
|
|
457
|
+
|
|
458
|
+
6. **记忆和 OpenClaw 内置记忆冲突** — 如果看到 agent 同时调用了内置的 memory 搜索和插件的 `memory_search`,说明 `agents.defaults.memorySearch.enabled` 没有设为 `false`。
|
|
459
|
+
|
|
460
|
+
7. **技能不生成** — 检查:
|
|
461
|
+
- `skillEvolution.enabled` 是否为 `true`
|
|
462
|
+
- 任务是否有足够内容(默认需要 ≥ 6 chunks)
|
|
463
|
+
- 查看日志中 `SkillEvolver` 相关输出
|
|
464
|
+
|
|
465
|
+
## Data Location
|
|
293
466
|
|
|
294
467
|
| File | Path |
|
|
295
468
|
|---|---|
|
|
296
469
|
| Database | `~/.openclaw/memos-local/memos.db` |
|
|
297
|
-
| Viewer auth | `~/.openclaw/viewer-auth.json` |
|
|
470
|
+
| Viewer auth | `~/.openclaw/memos-local/viewer-auth.json` |
|
|
298
471
|
| Gateway log | `~/.openclaw/logs/gateway.log` |
|
|
299
|
-
| Plugin code
|
|
472
|
+
| Plugin code | `~/.openclaw/extensions/memos-local/` |
|
|
473
|
+
| Memory-guide skill | `~/.openclaw/workspace/skills/memos-memory-guide/SKILL.md` (and `~/.openclaw/skills/memos-memory-guide/`) |
|
|
474
|
+
| Generated skills | `~/.openclaw/memos-local/skills-store/<skill-name>/` |
|
|
475
|
+
| Installed skills | `~/.openclaw/workspace/skills/<skill-name>/` |
|
|
476
|
+
|
|
477
|
+
## Testing
|
|
478
|
+
|
|
479
|
+
Run the test suite:
|
|
480
|
+
|
|
481
|
+
```bash
|
|
482
|
+
cd MemOS/apps/memos-local-openclaw
|
|
483
|
+
npm test
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
Test coverage includes:
|
|
487
|
+
- **Policy tests** — Verifies retrieval strategy, search filtering, evidence extraction, instruction stripping
|
|
488
|
+
- **Recall tests** — RRF fusion, recency decay correctness
|
|
489
|
+
- **Capture tests** — Message filtering, evidence block stripping, self-tool exclusion
|
|
490
|
+
- **Storage tests** — SQLite CRUD, FTS5, vector storage, content hash dedup
|
|
491
|
+
- **Task processor tests** — Task boundary detection, skip logic, summary generation
|
|
300
492
|
|
|
301
493
|
## License
|
|
302
494
|
|
package/dist/capture/index.d.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import type { ConversationMessage, Logger } from "../types";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Extract writable messages from a conversation turn.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* - Truncate long tool results to avoid storage bloat
|
|
9
|
-
* - Strip injected evidence blocks wrapped in [STORED_MEMORY]...[/STORED_MEMORY]
|
|
5
|
+
* Stores the user's actual text — strips only OpenClaw's injected metadata
|
|
6
|
+
* prefixes (Sender info, conversation context, etc.) which are not user content.
|
|
7
|
+
* Only skips: system prompts and our own memory tool results (prevents loop).
|
|
10
8
|
*/
|
|
11
9
|
export declare function captureMessages(messages: Array<{
|
|
12
10
|
role: string;
|
|
13
11
|
content: string;
|
|
14
12
|
toolName?: string;
|
|
15
|
-
}>, sessionKey: string, turnId: string,
|
|
13
|
+
}>, sessionKey: string, turnId: string, _evidenceTag: string, log: Logger): ConversationMessage[];
|
|
16
14
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/capture/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAQ,MAAM,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/capture/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAQ,MAAM,EAAE,MAAM,UAAU,CAAC;AA0BlE;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EACrE,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,MAAM,GACV,mBAAmB,EAAE,CAgCvB"}
|