Tools
Episodic Claw
Long-term episodic memory for OpenClaw agents
Install
openclaw plugins install clawhub:episodic-claw
README
# <img src="./assets/icons/brain-circuit.svg" width="22" alt="" /> episodic-claw
**Long-term episodic memory for OpenClaw agents.**
> English | [日本語](./README.ja.md) | [中文](./README.zh.md)
[](./CHANGELOG.md)
[](./LICENSE)
[](https://openclaw.ai)
This plugin saves conversations locally, finds related memories by meaning, and adds the right ones back into the prompt before the model answers. That helps OpenClaw remember useful context without extra commands or manual cleanup.
`v0.2.0` is the release where the memory pipeline gets meaningfully smarter: topics-aware recall, Bayesian segmentation, more human-like D1 consolidation, and replay scheduling are all part of the picture now.
Release docs: [v0.2.0 bundle](./docs/v0.2.0/README.md)
---
## <img src="./assets/icons/cog.svg" width="18" alt="" /> Why TypeScript + Go?
Most plugins are written in one language. This one uses two on purpose.
Think of it like a store with a front desk and a back room.
**TypeScript is the front desk.** It talks to OpenClaw, registers tools, connects hooks, and keeps the plugin wiring simple.
**Go is the back room.** It handles the heavy work: embeddings, vector search, replay state, and Pebble DB storage. That keeps the slow part away from Node.js, so the agent stays responsive.
So the rule is simple: **TypeScript coordinates, Go does the heavy lifting, and the agent does not have to wait around.**
---
## <img src="./assets/icons/workflow.svg" width="18" alt="" /> How It Works
> **TL;DR:** Every message triggers a memory check. Relevant past episodes are added to the prompt before the model replies.
**Step 1 — You send a message.**
**Step 2 — `assemble()` fires.** The plugin takes the last few messages and builds a search query from them.
**Step 3 — The Go sidecar embeds that query.** It calls the Gemini Embedding API to turn text into a vector, which is just a list of numbers representing meaning.
**Step 4 — HNSW finds the top-K most similar past episodes.** HNSW is a fast approximate nearest-neighbor algorithm. In plain English: it is the thing that lets the system ask "which old memory feels most similar to this?" without scanning everything slowly.
**Step 5 — Matching episodes are reranked and injected into the system prompt.** The AI sees them before reading your message, so the reply naturally includes historical context.
```mermaid
sequenceDiagram
participant You
participant OpenClaw
participant TS as Plugin (TypeScript)
participant Go as Go Sidecar
participant DB as Pebble DB + HNSW
You->>OpenClaw: Send a message
OpenClaw->>TS: assemble() fires
TS->>TS: Build query from recent messages
TS->>Go: RPC: recall(query, k=5)
Go->>Go: Gemini Embedding API
Go->>DB: Vector search, top-K episodes
DB-->>Go: Matching episode bodies
Go-->>TS: Results
TS->>OpenClaw: Prepend episodes to system prompt
OpenClaw->>You: AI replies with historical context
```

And in the background, new episodes are also being saved:
**Step A — Surprise Score watches for topic change.** After each turn, the plugin asks: did the conversation just shift enough to count as a new episode?
**Step B — Text chunks become stored memory.** If the answer is yes, the current buffer is sealed, embedded, and saved into Pebble DB, with HNSW updated for future recall.
```mermaid
flowchart LR
A[New messages arrive] --> B[EventSegmenter checks Surprise Score]
B -->|Score above threshold OR buffer too large| C[Episode boundary detected]
C --> D[Buffer split into chunks]
D --> E[Go sidecar: Gemini Embedding]
E --> F[Pebble DB stores episode\nHNSW indexes the vector]
B -->|Score low| G[Keep buffering messages]
```

---
## <img src="./assets/icons/layers-3.svg" width="18" alt="" /> Memory Hierarchy (D0 / D1)
> **TL;DR:** D0 is a raw diary entry. D1 is the book summary you would read instead of the whole diary.
### <img src="./assets/icons/file-text.svg" width="16" alt="" /> D0 — Raw Episodes
Every time the conversation crosses a meaningful boundary, the current buffer is saved as a D0 episode. These are close to verbatim conversation logs: detailed, timestamped, and still noisy in the useful way raw memory often is.
- Stored in Pebble DB with a full vector embedding
- Auto-tagged with boundary hints like `auto-segmented`, `surprise-boundary`, or `size-limit`
- Instantly retrievable via HNSW vector search
### <img src="./assets/icons/moon.svg" width="16" alt="" /> D1 — Summarized Long-Term Memory
Over time, groups of D0 episodes get compressed into D1 summaries by the LLM. This is the part inspired by sleep consolidation in human memory research: the gist stays, the clutter fades.
- D1 nodes link back to their source D0 episodes
- `ep-expand` can drill from a D1 summary back to the raw D0 details
- Token cost drops while long-range meaning survives
### <img src="./assets/icons/zap.svg" width="16" alt="" /> What is Surprise Score?
The plugin computes a Bayesian-style surprise signal by comparing incoming content with the current buffer. A high score means: "this is no longer the same thread of experience, close the old episode and start a new one."
```text
Buffer: "let's build a todo app in React"
Incoming: "what's the best approach to database indexing?"
Result: surprise is high -> boundary -> save previous episode
```
That is one of the big reasons the memory feels structured instead of turning into one giant blob.
---
## <img src="./assets/icons/rocket.svg" width="18" alt="" /> What v0.2.0 changes in practice
v0.2.0 is where the system starts acting less like a flat memory bucket and more like a real memory pipeline.
- `topics` now help both storage and recall
- Bayesian segmentation makes boundaries less arbitrary
- D1 clustering is more context-aware and boundary-aware
- replay scheduling gives important memories a way to stay reinforced
- recall calibration keeps usefulness and replay signals from overpowering semantic fit
So the system is not just "remembering more." It is getting better at deciding **what kind of memory this is**, **how long it should matter**, and **when it should come back**.
---
## <img src="./assets/icons/package.svg" width="18" alt="" /> Install
```bash
openclaw plugins install clawhub:episodic-claw
```
That is the entry point. The plugin auto-wires on startup, and the Go sidecar uses the Gemini API key already configured in your OpenClaw environment.
---
## <img src="./assets/icons/bot.svg" width="18" alt="" /> Agent Install Prompt
If you want another agent to perform the full technical setup for you, hand it this prompt.
This is intentionally an execution prompt, not a product explanation.
```text
Install `episodic-claw` into my OpenClaw setup and complete the technical setup for me end to end.
Do the work, do not stop at explaining.
Required steps:
1. Run:
`openclaw plugins install clawhub:episodic-claw`
2. Check whether the plugin installed cleanly:
`openclaw plugins list`
3. Open my real OpenClaw config file and make sure `episodic-claw` is enabled.
The usual file is `~/.openclaw/openclaw.json`.
If needed, edit the config so OpenClaw can load `episodic-claw`.
4. Confirm the required Gemini API key exists in the OpenClaw runtime environment.
If the plugin depends on `GEMINI_API_KEY`, verify that OpenClaw can actually read it where it runs.
5. Before restarting OpenClaw, send the user a message in your own natural wording that says this:
"I need to restart the OpenClaw gateway next. I will wait 6 minutes before restarting it. The install is not fully verified yet, and when the restart happens my current working context may cut off. Please send me a message after the restart to wake me back up so I can finish the verification."
6. After sending that message, deliberately wait 6 minutes.
Use a real sleep or wait, not just a short pause.
7. Restart OpenClaw:
`openclaw gateway restart`
8. Verify that the plugin is active after restart.
Check plugin status, startup logs, and whether the memory plugin is loaded without errors.
9. If the install pulls a platform-specific sidecar binary, confirm that it downloaded correctly and exists in the plugin directory.
10. At the end, give me a short report with:
- what changed
- whether the plugin is loaded
- any warnings or manual follow-up I still need
Important:
- Prefer editing the real config instead of only describing what should be changed.
- If something fails, debug it and keep going until the plugin is working or clearly blocked by a concrete missing dependency.
- Do not stop after installation alone. Finish verification too.
```
---
## <img src="./assets/icons/wrench.svg" width="18" alt="" /> The 3 Memory Tools
### `ep-recall` — Manual memory search
Ask the AI to deliberately dig up a memory by topic or meaning.
Use it when auto-retrieval is not surfacing the right context, or when you explicitly want the agent to search further back.
### `ep-save` — Manual memory save
Tell the AI "remember this" and it stores it immediately.
Use it for preferences, decisions, constraints, or facts that should stick right away.
### `ep-expand` — Expand a summary back into detail
When the AI only has a compressed summary but needs the full story, this fetches the raw material behind it.
---
## <img src="./assets/icons/cog.svg" width="18" alt="" /> Configuration
All keys are optional. Defaults work well for most agents.
| Key | Type | Default | Description |
|---|---|---|---|
| `enabled` | boolean | `true` | Enable or disable the plugin entirely |
| `reserveTokens` | integer | `6144` | Max tokens reserved for in
... (truncated)
tools
Comments
Sign in to leave a comment