← Back to Plugins
Integration

Context Cleaner

Mote-Xu By Mote-Xu 👁 26 views ▲ 0 votes

OpenClaw Context Engine plugin that strips thinking blocks and completed tool results from the model context before each API request. Frontier scanning keeps in-progress tool chains intact. ~28% context reduction.

GitHub

README

# OpenClaw Context Cleaner

Context Engine Plugin for [OpenClaw](https://github.com/openclaw/openclaw). Strips thinking blocks and completed tool results from the model context before each API request. Framework-agnostic — works with any LLM provider.

## Why

DeepSeek (and most LLM APIs) are stateless — the full conversation history is sent on every request. Two invisible things accumulate silently:

1. **Thinking blocks** — `{"type":"thinking","thinking":"..."}` blocks stored inside assistant content arrays
2. **Tool results** — completed `toolResult` messages from past turns

Without cleanup, these bloat context past 100K tokens. Nova's main agent hit 1.15M tokens (81% of window) before this plugin.

## How It Works

### Frontier Algorithm

Scans the message array **backwards** from the end to find the current turn boundary:

```
[user][asst+thinking][toolResult]...[user][asst+thinking][toolResult]...
                                                          ↑
                                                       frontier
```

- Ends with `user` → that user message is the frontier
- Ends with `assistant` → that assistant is the frontier
- Ends with `toolResult` → walk back to the parent assistant, that's the frontier

**Everything before the frontier** gets cleaned (thinking blocks stripped, tool results dropped).
**Everything at/after the frontier** stays 100% intact — in-progress tool chains are never touched.

### What Gets Cleaned

- `{"type":"thinking","thinking":"..."}` blocks from assistant content arrays
- `toolResult` messages from completed turns
- Pure tool-call assistant messages (no text content)
- Top-level `reasoning_content` field (DeepSeek API format)

## Deploy

```bash
# 1. Copy plugin files
scp index.js openclaw.plugin.json user@host:/path/to/openclaw/state/plugins/openclaw-context-cleaner/

# 2. Add to openclaw.json
#   "plugins": {
#     "slots": { "contextEngine": "openclaw-context-cleaner" },
#     "load": { "paths": ["/path/to/plugins/openclaw-context-cleaner"] }
#   }

# 3. Restart gateway
systemctl restart openclaw-gateway

# 4. Verify
OPENCLAW_STATE_DIR=/path/to/state openclaw plugins inspect openclaw-context-cleaner --runtime --json
# → "status": "loaded"
```

## Log Format

Only logged when something was actually cleaned:

```
[ctx-cleaner] session=agent:main:tel 108→74 msgs 70200→4964 tok (-65236) \
  cleanedRC=0 cleanedThink=44 dropTool=34 dropAsstTC=0
```

| Field | Meaning |
|-------|---------|
| `N→M msgs` | Messages before → after cleaning |
| `tok (-N)` | Estimated tokens saved |
| `cleanedRC` | Top-level `reasoning_content` fields cleared |
| `cleanedThink` | `{"type":"thinking"}` blocks removed |
| `dropTool` | Completed `toolResult` messages dropped |
| `dropAsstTC` | Pure tool-call assistant messages dropped |

## Real-World Results

| Agent | Model | Messages | Tokens Saved |
|-------|-------|:--------:|:------------:|
| Nova main | DeepSeek V4 Pro | 104→71 | -62,761 (-93%) |
| Nova code | DeepSeek V4 Pro | 57→26 | -116,815 (-96%) |
| Stella DM | DeepSeek V4 Flash | 61→43 | -24,988 (-76%) |

Session running 1 day 16 hours: 51K tokens (5% context), 0 compactions triggered.

## Pitfalls

1. **Plugin ID must match exactly** — `openclaw.plugin.json` `id` must equal `definePluginEntry` `id`. Mismatch → `Context engine not registered`.
2. **Hot reload is not enough** — `openclaw.json` changes trigger config hot reload, but new JS code requires a full `systemctl restart`.
3. **OpenClaw uses `toolResult` not `tool`** — Role is `toolResult`, tool call ID is `toolCallId` (camelCase), not `tool_call_id`.
4. **Thinking is in content blocks, not top-level** — OpenClaw stores reasoning as `{"type":"thinking","thinking":"..."}` inside the `content` array. The `reasoning_content` field is only present in raw API format, not OpenClaw's internal representation.

## Update Procedure

```bash
# Edit index.js locally, then:
scp index.js openclaw.plugin.json user@host:/path/to/state/plugins/openclaw-context-cleaner/

# If deploying to multiple gateways on the same host, copy to each state dir:
scp index.js openclaw.plugin.json user@host:/path/to/second-state/plugins/openclaw-context-cleaner/

# Restart affected gateways
ssh user@host "sudo systemctl restart gateway-one gateway-two"

# Verify
ssh user@host "grep 'ctx-cleaner' /tmp/openclaw/openclaw-\$(date +%F).log | tail -3"
```

## Requirements

- OpenClaw gateway (any version supporting Context Engine plugin API)
- The `openclaw` CLI for plugin inspection (optional, for verification)
integration

Comments

Sign in to leave a comment

Loading comments...