← Back to Plugins
Tools

Episodic Claw

YoshiaKefasu By YoshiaKefasu ⭐ 4 stars 👁 6 views ▲ 0 votes

Long-term episodic memory for OpenClaw agents

GitHub

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)

[![version](https://img.shields.io/badge/version-0.2.0-blue)](./CHANGELOG.md)
[![license](https://img.shields.io/badge/License-MPL_2.0-brightgreen.svg)](./LICENSE)
[![platform](https://img.shields.io/badge/platform-OpenClaw-orange)](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
```

![Sequence diagram: episodic recall flow](docs/sequenceDiagram.png)

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]
```

![Flowchart: episode save pipeline](docs/flowchart.png)

---

## <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

Loading comments...