← Back to Plugins
Tools

Context Distiller

baixiaodev By baixiaodev 👁 53 views ▲ 0 votes

I don't know code at all, and this is my first time to upload my "code" to public. I hope this plugin is useful to you all. Intelligent context distillation plugin for OpenClaw โ€” reduces context noise by compressing verbose tool outputs, patches, and file content. Saves 65-85% tokens on average.

GitHub

Install

npm install
```

Configuration Example

{
  "plugins": {
    // 1. Allow the plugin
    "allow": [
      // ... existing plugins ...
      "context-distiller"
    ],

    // 2. Configure it
    "entries": {
      "context-distiller": {
        "enabled": true,
        "config": {
          "toolOutputMaxTokens": 1200,
          "patchMaxTokens": 600,
          "fileContentMaxTokens": 1000,
          "aggressiveness": "moderate",
          "distillModel": "ollama/qwen3:8b"  // optional, for LLM-powered summarization
        }
      }
    },

    // 3. Register install path
    "installs": {
      "context-distiller": {
        "source": "path",
        "installPath": "/path/to/.openclaw/extensions/context-distiller",
        "version": "0.1.0"
      }
    }
  }
}

README

# context-distiller

> Intelligent context distillation plugin for [OpenClaw](https://github.com/nicepkg/openclaw) โ€” reduces context noise by compressing verbose tool outputs, patches, and file content before they enter the context window.

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![OpenClaw Plugin](https://img.shields.io/badge/OpenClaw-Plugin-blue)](https://github.com/nicepkg/openclaw)

---

## Why context-distiller?

When AI agents work on complex tasks, they generate massive amounts of context: tool outputs, file reads, search results, diffs, and logs. This verbose content fills up the context window fast, causing:

- **Context overflow** โ€” the LLM silently drops important earlier messages
- **Degraded reasoning** โ€” too much noise drowns out the signal
- **Higher costs** โ€” more tokens = more money

**context-distiller** hooks into OpenClaw's message pipeline and compresses verbose content *before* it enters the context engine. Think of it as a smart filter that keeps the important bits and throws away the noise.

### Results from real-world testing (20 research scenarios):

| Metric | Value |
|--------|-------|
| Total distillations | 98 |
| Tokens saved | **636,186** |
| Avg. compression | 65-85% on verbose outputs |
| Rules triggered | 9 different compression strategies |
| False positives | 0 (small content passes through untouched) |

---

## Architecture

```
User Query โ†’ Agent โ†’ Tool Call โ†’ Tool Result
                                      โ†“
                        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                        โ”‚   tool_result_persist    โ”‚  โ† sync hook (primary)
                        โ”‚                         โ”‚
                        โ”‚  1. Content Analysis     โ”‚  detect value: search/API/log/help/error
                        โ”‚  2. Budget Adjustment    โ”‚  high-value โ†’ 4x budget, low-value โ†’ 0.6x
                        โ”‚  3. Rule Pipeline        โ”‚  6 rules sorted by priority
                        โ”‚  4. distillSync()        โ”‚  pure synchronous, no Promises
                        โ”‚                         โ”‚
                        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                     โ†“
                        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                        โ”‚  before_message_write    โ”‚  โ† sync hook (safety net)
                        โ”‚  catches remaining       โ”‚
                        โ”‚  verbose tool messages   โ”‚
                        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                     โ†“
                           Context Engine (LCM)
                         e.g. lossless-claw
```

### Design Principles

1. **Enhance, don't replace** โ€” Works alongside any context engine (lossless-claw, built-in, etc.)
2. **Content-aware intelligence** โ€” Different content types get different treatment. Search results are preserved; install logs are aggressively compressed.
3. **Pure synchronous execution** โ€” Gateway's `tool_result_persist` hook is strictly sync. All distillation runs without async/await/Promise.
4. **Graceful degradation** โ€” If a rule fails, the content passes through unchanged. If stats I/O fails, distillation continues.
5. **Observable** โ€” Persistent statistics survive Gateway restarts. Agent tools let you inspect and tune at runtime.

### Content Intelligence Layer

Before applying any compression rules, the plugin analyzes content to determine its value:

| Content Type | Value | Budget Multiplier | Strategy |
|-------------|-------|-------------------|----------|
| Search results (Tavily/Google/Bing JSON) | Critical | 4.0ร— | Structured JSON summary preserving URLs/titles/snippets |
| API responses (web_fetch, structured JSON) | High | 4.0ร— | JSON summary with leading paragraphs preserved |
| URL-rich content | High | 2.5ร— | Smart truncation |
| Error output | Medium | 1.2ร— | Error line extraction + head/tail |
| Generic tool output | Medium | 1.0ร— | Standard rule pipeline |
| Install/build logs | Low | 0.8ร— | Aggressive head+tail |
| Usage/help text | Low | 0.6ร— | Aggressive head+tail |

### Rule Pipeline (by priority)

| Priority | Rule | Applies To | Strategy |
|----------|------|-----------|----------|
| P4 | `domain-aware` | file_content, tool_output | BibTeX bibliography โ†’ compact listing; CSV/TSV โ†’ stats + samples; Markdown โ†’ heading skeleton |
| P5 | `repetition-elimination` | tool_output, file_content, text | 4-tier dedup: records โ†’ lines โ†’ blocks โ†’ templates. JSON excluded (routed to dedicated JSON summary) |
| P8 | `error-extraction` | tool_output | Preserves error/warning/summary lines from verbose logs. Prevents the "buried error" problem |
| P10 | `tool-output-truncation` | tool_output | JSON summary โ†’ file listing summary โ†’ LLM summary โ†’ head+tail truncation |
| P10 | `patch-distill` | patch | Keeps changed lines (+/-) with configurable context. Falls back to stats-only for huge diffs |
| P10 | `file-content-distill` | file_content | Config JSON โ†’ code structural summary (imports + definitions) โ†’ LLM summary โ†’ truncation |

### Persistent Statistics

Gateway reloads plugins on every request (stateless architecture). To maintain cumulative stats across restarts, context-distiller uses a `.stats.json` sidecar file with:
- Throttled writes (โ‰ค 1 per 5 seconds)
- Atomic POSIX rename for crash safety
- Graceful degradation if disk I/O fails

---

## Installation

### From source (local path)

```bash
# Clone the repo
git clone https://github.com/baixiaodev/context-distiller.git ~/.openclaw/extensions/context-distiller

# Install dependencies (shares with other OpenClaw plugins)
cd ~/.openclaw/extensions/context-distiller
npm install
```

### Register in openclaw.json

Add the following to your `openclaw.json`:

```jsonc
{
  "plugins": {
    // 1. Allow the plugin
    "allow": [
      // ... existing plugins ...
      "context-distiller"
    ],

    // 2. Configure it
    "entries": {
      "context-distiller": {
        "enabled": true,
        "config": {
          "toolOutputMaxTokens": 1200,
          "patchMaxTokens": 600,
          "fileContentMaxTokens": 1000,
          "aggressiveness": "moderate",
          "distillModel": "ollama/qwen3:8b"  // optional, for LLM-powered summarization
        }
      }
    },

    // 3. Register install path
    "installs": {
      "context-distiller": {
        "source": "path",
        "installPath": "/path/to/.openclaw/extensions/context-distiller",
        "version": "0.1.0"
      }
    }
  }
}
```

### Restart Gateway

```bash
openclaw gateway restart
# or: launchctl kickstart -k user/$(id -u)/com.openclaw.gateway
```

### Verify

Check Gateway logs for:
```
[context-distiller] Plugin loaded #1 (enabled=true, aggressiveness=moderate, toolMax=1200, patchMax=600, fileMax=1000, rules=6, lifetime: 0 distillations, 0 tokens saved)
```

Or ask your agent:
```
> Use the distill_status tool
```

---

## Configuration

### Config Parameters

| Parameter | Default | Range | Description |
|-----------|---------|-------|-------------|
| `enabled` | `true` | โ€” | Master switch |
| `toolOutputMaxTokens` | `1200` | 100โ€“5000 | Threshold for tool output distillation |
| `patchMaxTokens` | `600` | 100โ€“3000 | Threshold for diff/patch distillation |
| `fileContentMaxTokens` | `1000` | 200โ€“5000 | Threshold for file content distillation |
| `aggressiveness` | `"moderate"` | conservative / moderate / aggressive | Controls compression intensity |
| `preservePatterns` | `[]` | Array of regex strings | Content matching these patterns is never distilled |
| `distillModel` | `"ollama/qwen3:8b"` | Any model ref | Model for LLM-powered summarization (optional) |
| `distillProvider` | โ€” | Provider ID | Override provider for distill LLM calls |

### Aggressiveness Multipliers

The aggressiveness level applies a multiplier to all token thresholds:

| Level | Multiplier | Effect |
|-------|-----------|--------|
| `conservative` | 1.5ร— | Thresholds 50% higher โ†’ less distillation, more detail preserved |
| `moderate` | 1.0ร— | Thresholds as configured |
| `aggressive` | 0.6ร— | Thresholds 40% lower โ†’ more distillation, maximum token savings |

### Environment Variable Overrides

Environment variables take highest precedence:

```bash
CONTEXT_DISTILLER_ENABLED=true
CONTEXT_DISTILLER_AGGRESSIVENESS=aggressive
CONTEXT_DISTILLER_TOOL_MAX_TOKENS=800
CONTEXT_DISTILLER_PATCH_MAX_TOKENS=400
CONTEXT_DISTILLER_FILE_MAX_TOKENS=600
CONTEXT_DISTILLER_MODEL=ollama/qwen3:8b
CONTEXT_DISTILLER_PROVIDER=ollama
```

### Runtime Configuration

Your agent can adjust settings on the fly:

```
> Use distill_configure to set aggressiveness to aggressive
> Use distill_configure to set toolOutputMaxTokens to 800
```

---

## Agent Tools

### `distill_status`

Shows lifetime and session statistics, rule hit counts, and current configuration.

```
> Show me the distill status

## Context Distiller Status

### ๐Ÿ“Š Lifetime Statistics (across all sessions)
- Total distillations: **98**
- Total tokens saved: **636,186**
- Plugin loaded: 44 time(s)

### Rule Hit Counts (lifetime)
- smart/search-results: 31
- tool-output-truncation/head-tail: 28
- smart/api-response: 15
- tool-output-truncation/listing: 11
- ...
```

Supports `--reset` to zero out all stats.

### `distill_configure`

Adjust configuration at runtime without restarting:

```
> Set the distiller to aggressive mode and lower tool output threshold to 800

Configuration updated: {
  "aggressiveness": "aggressive",
  "toolOutputMaxTokens": 800
}
```

---

## Use Cases

### 1. Research & Analysis Tasks

When agents perform web searches (Tavily, Google, Bing), results are often 3,000โ€“8,000+ tokens of JSON. context-distiller:
- **Detects** search result JSON structure (url + title + snippet pattern)
- **Preserves** URLs, titles, and snippet previews
- **Compresses** 5,000 tokens โ†’ 800โ€“1,200 tokens (75โ€“85% reduction)

### 2. Code Exploration & Refactoring

Reading large source files (1,000+ lines) fills the context fast. context-distiller:
- **Extracts

... (truncated)
tools

Comments

Sign in to leave a comment

Loading comments...