@memtensor/memos-local-openclaw-plugin 0.1.7 → 0.1.8
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/README.md +25 -25
- package/index.ts +45 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -305,23 +305,23 @@ Query → FTS5 + Vector dual recall → RRF Fusion → MMR Rerank
|
|
|
305
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
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
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)
|
|
308
|
+
4. **Search results** — `memory_search` returns **excerpts** (original content snippets) and IDs (`chunkId`, `task_id`), not summaries. The agent uses `memory_get(chunkId)` for full original text, `task_summary(taskId)` for structured task context, `memory_timeline(chunkId)` for surrounding conversation, and `skill_get(skillId|taskId)` for reusable experience guides.
|
|
309
309
|
|
|
310
310
|
## Agent Tools
|
|
311
311
|
|
|
312
|
-
The plugin
|
|
312
|
+
The plugin provides **8 smart tools** (7 registered tools + auto-recall) and auto-installs the **memos-memory-guide** skill:
|
|
313
313
|
|
|
314
314
|
| Tool | Purpose | When to Use |
|
|
315
315
|
|------|---------|-------------|
|
|
316
|
-
| `
|
|
316
|
+
| `auto_recall` | Automatically injects relevant memories into agent context each turn (via `before_agent_start` hook) | Runs automatically — no manual call needed |
|
|
317
|
+
| `memory_search` | Search memories; returns excerpts + `chunkId` / `task_id` | When auto-recall returned nothing or you need a different query |
|
|
318
|
+
| `memory_get` | Get full original text of a memory chunk | When you need to verify exact details from a search hit |
|
|
319
|
+
| `memory_timeline` | Surrounding conversation around a chunk | When you need the exact dialogue before/after a hit |
|
|
317
320
|
| `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
321
|
| `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
322
|
| `skill_install` | Install a skill into the agent workspace | When the skill should be permanently available for future turns |
|
|
321
323
|
| `memory_viewer` | Get the URL of the Memory Viewer web UI | When the user asks where to view or manage their memories |
|
|
322
324
|
|
|
323
|
-
There is no `memory_get`; search returns excerpts and IDs; use `task_summary` or `memory_timeline` for deeper context.
|
|
324
|
-
|
|
325
325
|
### Search Parameters
|
|
326
326
|
|
|
327
327
|
| Parameter | Default | Range | Description |
|
|
@@ -427,40 +427,40 @@ Then restart the gateway.
|
|
|
427
427
|
|
|
428
428
|
## Troubleshooting
|
|
429
429
|
|
|
430
|
-
###
|
|
430
|
+
### Common Issues
|
|
431
431
|
|
|
432
|
-
1.
|
|
432
|
+
1. **Note the exact error** — e.g. `plugin not found`, `Cannot find module 'xxx'`, `Invalid config`.
|
|
433
433
|
|
|
434
|
-
2.
|
|
434
|
+
2. **Check plugin status**
|
|
435
435
|
```bash
|
|
436
436
|
openclaw plugins list
|
|
437
437
|
```
|
|
438
|
-
- Status
|
|
439
|
-
-
|
|
438
|
+
- Status is **error** → note the error message
|
|
439
|
+
- Not listed → not installed or not placed in `~/.openclaw/extensions/memos-local`
|
|
440
440
|
|
|
441
|
-
3.
|
|
441
|
+
3. **Check gateway logs**
|
|
442
442
|
```bash
|
|
443
443
|
tail -50 ~/.openclaw/logs/gateway.log
|
|
444
444
|
```
|
|
445
|
-
|
|
445
|
+
Search for `memos-local`, `failed to load`, `Error`, `Cannot find module`.
|
|
446
446
|
|
|
447
|
-
4.
|
|
448
|
-
- Node
|
|
449
|
-
-
|
|
450
|
-
-
|
|
451
|
-
|
|
447
|
+
4. **Check environment**
|
|
448
|
+
- Node version: `node -v` (requires **>= 18**)
|
|
449
|
+
- Plugin directory exists: `ls ~/.openclaw/extensions/memos-local/package.json`
|
|
450
|
+
- Dependencies installed: `ls ~/.openclaw/extensions/memos-local/node_modules/@sinclair/typebox`
|
|
451
|
+
If missing: `cd ~/.openclaw/extensions/memos-local && npm install --omit=dev`
|
|
452
452
|
|
|
453
|
-
5.
|
|
454
|
-
- `agents.defaults.memorySearch.enabled` = `false
|
|
453
|
+
5. **Check configuration** — Open `~/.openclaw/openclaw.json` and verify:
|
|
454
|
+
- `agents.defaults.memorySearch.enabled` = `false` (disable built-in memory)
|
|
455
455
|
- `plugins.slots.memory` = `"memos-local"`
|
|
456
456
|
- `plugins.entries.memos-local.enabled` = `true`
|
|
457
457
|
|
|
458
|
-
6.
|
|
458
|
+
6. **Memory conflict with built-in search** — If the agent calls both the built-in memory search and the plugin's `memory_search`, it means `agents.defaults.memorySearch.enabled` is not set to `false`.
|
|
459
459
|
|
|
460
|
-
7.
|
|
461
|
-
- `skillEvolution.enabled`
|
|
462
|
-
-
|
|
463
|
-
-
|
|
460
|
+
7. **Skills not generating** — Check:
|
|
461
|
+
- `skillEvolution.enabled` is `true`
|
|
462
|
+
- Tasks have enough content (default requires >= 6 chunks)
|
|
463
|
+
- Look for `SkillEvolver` output in the gateway log
|
|
464
464
|
|
|
465
465
|
## Data Location
|
|
466
466
|
|
package/index.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* OpenClaw Plugin Entry — memos-local
|
|
3
3
|
*
|
|
4
4
|
* Full-write local memory with hybrid retrieval (RRF + MMR + recency).
|
|
5
|
-
* Provides: memory_search, memory_timeline,
|
|
5
|
+
* Provides: memory_search, memory_get, memory_timeline, task_summary, skill_get, skill_install, memory_viewer
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
@@ -324,15 +324,56 @@ const memosLocalPlugin = {
|
|
|
324
324
|
|
|
325
325
|
return {
|
|
326
326
|
content: [{ type: "text", text: `Timeline (${entries.length} entries):\n\n${text}` }],
|
|
327
|
-
details: { entries, anchorRef: { sessionKey, chunkId, turnId, seq } },
|
|
327
|
+
details: { entries, anchorRef: { sessionKey: anchorChunk.sessionKey, chunkId, turnId: anchorChunk.turnId, seq: anchorChunk.seq } },
|
|
328
328
|
};
|
|
329
329
|
}),
|
|
330
330
|
},
|
|
331
331
|
{ name: "memory_timeline" },
|
|
332
332
|
);
|
|
333
333
|
|
|
334
|
-
//
|
|
335
|
-
|
|
334
|
+
// ─── Tool: memory_get ───
|
|
335
|
+
|
|
336
|
+
api.registerTool(
|
|
337
|
+
{
|
|
338
|
+
name: "memory_get",
|
|
339
|
+
label: "Memory Get",
|
|
340
|
+
description:
|
|
341
|
+
"Get the full original text of a memory chunk. Use to verify exact details from a search hit.",
|
|
342
|
+
parameters: Type.Object({
|
|
343
|
+
chunkId: Type.String({ description: "From search hit ref.chunkId" }),
|
|
344
|
+
maxChars: Type.Optional(
|
|
345
|
+
Type.Number({ description: `Max chars (default ${DEFAULTS.getMaxCharsDefault}, max ${DEFAULTS.getMaxCharsMax})` }),
|
|
346
|
+
),
|
|
347
|
+
}),
|
|
348
|
+
execute: trackTool("memory_get", async (_toolCallId: any, params: any) => {
|
|
349
|
+
const { chunkId, maxChars } = params as { chunkId: string; maxChars?: number };
|
|
350
|
+
const limit = Math.min(maxChars ?? DEFAULTS.getMaxCharsDefault, DEFAULTS.getMaxCharsMax);
|
|
351
|
+
|
|
352
|
+
const chunk = store.getChunk(chunkId);
|
|
353
|
+
if (!chunk) {
|
|
354
|
+
return {
|
|
355
|
+
content: [{ type: "text", text: `Chunk not found: ${chunkId}` }],
|
|
356
|
+
details: { error: "not_found" },
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const content = chunk.content.length > limit
|
|
361
|
+
? chunk.content.slice(0, limit) + "\u2026"
|
|
362
|
+
: chunk.content;
|
|
363
|
+
|
|
364
|
+
const who = chunk.role === "user" ? "USER said" : chunk.role === "assistant" ? "ASSISTANT replied" : chunk.role === "tool" ? "TOOL returned" : chunk.role.toUpperCase();
|
|
365
|
+
|
|
366
|
+
return {
|
|
367
|
+
content: [{ type: "text", text: `[${who}] (session: ${chunk.sessionKey})\n\n${content}` }],
|
|
368
|
+
details: {
|
|
369
|
+
ref: { sessionKey: chunk.sessionKey, chunkId: chunk.id, turnId: chunk.turnId, seq: chunk.seq },
|
|
370
|
+
source: { ts: chunk.createdAt, role: chunk.role, sessionKey: chunk.sessionKey },
|
|
371
|
+
},
|
|
372
|
+
};
|
|
373
|
+
}),
|
|
374
|
+
},
|
|
375
|
+
{ name: "memory_get" },
|
|
376
|
+
);
|
|
336
377
|
|
|
337
378
|
// ─── Tool: task_summary ───
|
|
338
379
|
|
package/package.json
CHANGED