Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ jobs:
node-version: 22
- name: Install plugin deps
run: cd plugin && npm ci
- name: Install tiktoken for core engine
run: cd plugin && npm install tiktoken
- name: Run plugin tests (36 tests)
- name: Run plugin tests (54 tests)
run: cd plugin && node --test

core-tests:
Expand All @@ -26,5 +24,5 @@ jobs:
run: npm ci
- name: Build core
run: cd packages/core && npx tsc
- name: Run core tests (30 tests)
- name: Run core tests (51 tests)
run: cd packages/core && npx vitest run
263 changes: 151 additions & 112 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,162 +1,201 @@
# 🧠 ContextClaw
# ContextClaw

[![CI](https://github.com/dodge1218/contextclaw/actions/workflows/ci.yml/badge.svg)](https://github.com/dodge1218/contextclaw/actions/workflows/ci.yml)

**Stop sending Dockerfiles to your LLM 30 turns after you read them. Stop hitting 429 rate limits because your context is 3x bigger than it needs to be.**
ContextClaw is an OpenClaw-first context and spend control plane for long-running agent sessions.

Context management plugin for [OpenClaw](https://github.com/openclaw/openclaw). Classifies every item in your context window by content type and applies retention policies. Files get truncated. Command output gets tailed. Your conversation stays intact. Your API bill stays low.
The user pain is simple:

> Why did four prompts eat $25?

> **Part of the Token-Optimized Agentic Architecture.**
> ContextClaw is Layer 1 (Real-Time Compression). See also: [Task-RAG MCP (Layer 2)](https://github.com/dodge1218/task-rag-mcp) | [Architecture Manifesto](https://github.com/dodge1218/agentic-efficiency)
The answer is usually not just "the model is expensive." It is stale context, retries, provider failover, repeated tool output, hidden subagent spend, and a runtime that cannot explain what it was about to send before the expensive call.

## Live Dogfooding Results
ContextClaw is the seatbelt for that path. It trims stale dynamic context before the model call, preserves the full removed content in cold storage, and writes auditable receipts for what happened.

Running on our own OpenClaw instance (11,300 items across 6 real sessions):
## What It Is

| Content Type | Items | Original | Stored | Reduction |
|---|---|---|---|---|
| JSON schema blobs | 1,192 | 17.6M chars | 0.8M | **95.5%** |
| File reads | 2,471 | 8.8M | 0.7M | **91.8%** |
| Assistant replies | 4,000 | 8.6M | 2.4M | **71.4%** |
| Generic tool output | 1,158 | 4.5M | 0.7M | **84.2%** |
| Config dumps | 1,647 | 3.2M | 0.5M | **84.4%** |
| Error traces | 326 | 1.9M | 0.1M | **93.6%** |
| **Total** | **11,300** | **45.5M** | **5.5M** | **87.9%** |
ContextClaw plugs into OpenClaw's `contextEngine` slot.

![ContextClaw saving 956K tokens in OpenClaw TUI](assets/tui-tokens-saved.png)
*Live savings counter running in the OpenClaw TUI footer*
```text
OpenClaw messages
-> classify by content type
-> apply deterministic retention policy
-> cold-store removed bulky content
-> write request ledger / pricing snapshot
-> return leaner context to OpenClaw
```

The key insight: **JSON schemas and file reads are 55% of all context waste**, and they compress at 92-95% with zero information loss.
It is not a new agent runtime. OpenClaw remains the runtime. ContextClaw is the governor, not the muzzle.

### Controlled Eval (4 real sessions, .reset files)
It does not replace native compaction. Native compaction handles late-session pressure. ContextClaw targets the dynamic middle before each model call: stale file reads, command output, config dumps, JSON/schema blobs, error traces, media payloads, and repeated tool envelopes.

| Session | Messages | Original | Output | Reduction | Truncated |
|---------|----------|----------|--------|-----------|----------|
| Session A | 681 | 870K | 186K | **78.7%** | 166 |
| Session B | 253 | 465K | 108K | **76.8%** | 37 |
| Session C | 190 | 323K | 206K | **36.2%** | 29 |
| Session D | 688 | 1.2M | 227K | **81.2%** | 153 |
| **Total** | **1,812** | **2.9M** | **727K** | **74.6%** | **385** |
## What Is Proven Right Now

Methodology: `ContextClawEngine.assemble()` against uncompacted `.reset` session backups. No synthetic data.
The clean current evidence is an OpenClaw-native dogfood batch captured on 2026-05-12 after enabling ContextClaw as the context engine and restarting the gateway.

## How It Works
One repeated OpenClaw `proceed` workflow, same session:

```
Message arrives → Classify content type → Check retention policy → Truncate or keep
```
- 10 post-baseline ContextClaw assemblies
- 436,460 estimated input tokens after compression
- 3,854,677 chars saved
- 749 ledger-recorded truncations
- $1.6166 estimated compressed-prompt spend
- $2.89 estimated savings

11 content types, each with its own retention rule:
These are estimate/receipt metrics, not provider-billed before/after measurements.

| Type | Rule |
|------|------|
| `system-prompt` | Never touch |
| `user-message` | Keep last 5 turns full, metadata-strip older |
| `assistant-reply` | Keep last 3 turns, trim narration |
| `tool-file-read` | Keep 1 turn, then truncate to bookends (first/last lines) |
| `tool-cmd-output` | Exit code + last 20 lines after 1 turn |
| `image/media` | Pointer only, drop base64 immediately |
| `config-dump` | Truncate to 500 chars |
| `error-trace` | Keep 2 turns, then discard |
| `json/schema` | Truncate to 500 chars |
| `tool-search-result` | Summary after 1 turn |
| `tool-generic` | Tail after 2 turns |
Evidence:

No LLM calls. No embeddings. Pure pattern matching + byte counting. Zero latency, zero cost.
- [Dogfood packet](docs/openclaw-dogfood-2026-05-12.md)
- [Measurement definitions](docs/MEASUREMENT.md)
- [Dogfood run files](dogfood-runs/2026-05-12-proceed-loop/)
- [Maintainer triage](docs/MAINTAINER_TRIAGE_2026-05-12.md)

## Install
## Why This Is Different From Autocompact

```bash
npm install contextclaw
```
Autocompact says:

### Quick Start — Try on Your Session
> The context got too full. Summarize it.

```bash
# Check your current session's context health
npx cc status
ContextClaw says:

# Watch and auto-alert when context is bloated
npx cc watch
> Before the expensive call, trim stale bulky context, keep the real conversation, cold-store the original, and write down what changed.

# Analyze token usage across all sessions
npx cc analyze
```
Autocompact is a cliff. ContextClaw is preflight.

## Content Types

ContextClaw's current plugin classifies and applies policy to:

- `system-prompt`
- `user-message`
- `assistant-reply`
- `tool-file-read`
- `tool-cmd-output`
- `tool-search-result`
- `tool-generic`
- `config-dump`
- `json/schema`
- `error-trace`
- `image/media`

Representative policies:

- system prompts are pinned;
- recent user/assistant turns stay hot;
- old file reads become bookends;
- old command output becomes exit signal plus tail;
- config/schema blobs get aggressively shortened;
- media payloads become pointers;
- truncated originals are written to cold storage.

### As an OpenClaw Plugin
No LLM call. No embedding lookup. No semantic magic.

## Request Ledger

ContextClaw records a local JSONL estimate at the context-assembly boundary:

```bash
cd ~/.openclaw/workspace/contextclaw/plugin && npm install
# Enable in openclaw.json → plugins.slots.contextEngine: "contextclaw"
~/.openclaw/contextclaw/ledger.jsonl
```

> **v1 is an OpenClaw plugin.** Standalone adapters for LangChain, Cline, etc. are on the roadmap. The classification and policy engine in `packages/core/` is framework-agnostic TypeScript.
Each entry can include:

- session kind and session key;
- provider/model/auth profile;
- prompt hash and context hash;
- estimated input/output tokens;
- captured pricing snapshot;
- estimated compressed-prompt spend;
- compression chars saved;
- truncation count;
- duplicate-context / budget flags.

## Project Structure
Actual provider-billed usage is only reconciled where OpenClaw exposes usage receipts. Until then, cost savings are estimates derived from chars removed, token heuristic, and captured model input pricing.

## OpenClaw Setup

Path-based plugin setup:

```bash
cd ~/.openclaw/workspace/contextclaw/plugin
npm ci
```
plugin/ # Production OpenClaw plugin (~700 lines, 36 tests)
├── classifier.js # Content type classification (11 types)
├── policy.js # Retention rules + truncation engine
├── index.js # OpenClaw context engine integration
└── __tests__/ # node:test suite

packages/core/ # Framework-agnostic core (TypeScript, 30 tests)
├── src/ # Budget, eviction, memory, orchestrator, watcher
└── __tests__/ # vitest suite

eval/ # Benchmarks + real-world eval on production sessions
docs/ # Multi-agent shared context protocol RFC

Use `npm ci` when the lockfile is present so local setup matches CI.

Representative OpenClaw config shape:

```json
{
"plugins": {
"entries": {
"contextclaw": {
"enabled": true,
"config": {
"enableTelemetry": false,
"ledger": {
"enabled": true,
"path": "~/.openclaw/contextclaw/ledger.jsonl",
"printReceipt": true
},
"coldStorageDir": "~/.openclaw/workspace/memory/cold"
}
}
},
"load": {
"paths": ["/absolute/path/to/contextclaw/plugin"]
},
"slots": {
"contextEngine": "contextclaw"
}
}
}
```

## Why Not Just Use Prompt Caching?
Restart the OpenClaw gateway after changing plugin registration or slot config.

## Local Checks

```bash
npm test
npm run test:plugin
git diff --check
```

| | Anthropic Caching | ContextClaw |
|---|---|---|
| What it does | Caches static prefix (system prompt, tools) | Removes stale content from the dynamic portion |
| Conversation history | Still re-sent in full every turn | Truncated by content type + age |
| Token reduction | 0% on conversation | 55-88% on real sessions |
| Works with | Anthropic only | Any provider (via plugin adapter) |
Current local result from this checkout:

They're complementary. Caching reduces cost on the static prefix. ContextClaw reduces what's in the dynamic payload. Use both.
- core tests: 51 passed
- plugin tests: 54 passed
- whitespace diff check: clean

## Limitations (Honest)
## Doctrine

- **v1 is OpenClaw-only.** The plugin API is OpenClaw's `contextEngine` interface. Standalone use requires `packages/core/`.
- **Eval is context-sufficiency judged, not full A/B.** Our LLM-judged eval scores whether compressed context preserves enough information for equivalent responses. At 80% budget: 44% equivalence rate. We're iterating.
- **No rehydration yet.** Truncated content goes to cold storage but there's no auto-rehydration path when the agent needs it again.
- **Aggressive on long sessions.** The 87.9% number is from very long sessions. Short sessions (<20 turns) see 10-30% savings.
The broader doctrine is that modern agent loops are economic systems, not just reasoning loops. One human prompt can trigger provider routing, retries, sibling failover, replayed session context, subagents, and multiple billing surfaces.

## Roadmap
Relevant docs:

- [x] Content-type classification (11 types)
- [x] Per-type retention policies with age decay
- [x] Real-world eval on production sessions
- [x] CI pipeline (66 tests across plugin + core)
- [x] Live dogfooding with telemetry
- [x] Cold storage for evicted content
- [x] npm publish (`contextclaw` on npm) ✅ v1.0.1
- [ ] Auto-rehydration from cold storage
- [ ] Sticker system — task-scoped context retrieval (v2)
- [ ] Content-addressable dedup (hash-based, same file = store once)
- [ ] Studio dashboard (real-time token visualization)
- [ ] Multi-agent shared context protocol ([RFC](docs/MULTI_AGENT_PROTOCOL.md))
- [Agent loop economics](docs/DOCTRINE_AGENT_LOOP_ECONOMICS.md)
- [Founder vision](docs/FOUNDER_VISION_CONTEXTCLAW.md)
- [Control-plane PRD](PRD-CONTROL-PLANE.md)
- [Autocompaction policy PRD](docs/AUTOCOMPACTION_POLICY_PRD.md)

### 🤝 Wanted: Framework Adapter Maintainers
External validation signal: Eric Milgram, PhD (`ScientificProgrammer`) described a real OpenClaw quota cascade on `openclaw/openclaw#64127`. That validates the control-plane/circuit-breaker problem, not ContextClaw compression metrics.

The core engine (`packages/core/`) is framework-agnostic TypeScript. We'd love community-maintained adapters for:
## Future Work

- **LangChain** / LangGraph
- **Cline**
- **CrewAI**
- **AutoGen**
These are intentionally not the first maintainer-review claim:

If you use one of these and want to help, open an issue or PR. The adapter interface is ~50 lines.
- task bucket / sticker retrieval;
- auto-rehydration from cold storage;
- multi-agent shared context;
- framework adapters for Claude Code, Codex, Cline, CrewAI, AutoGen, LangChain;
- quality A/B runs against uncompressed baselines;
- provider-billed before/after savings reconciliation.

## Contributing
The first maintainer ask is smaller:

See [CONTRIBUTING.md](CONTRIBUTING.md).
> Does this deterministic `contextEngine` plugin shape fit OpenClaw, and what API or loader changes would make it safer?

## License

Expand Down
Loading
Loading