Feature request: add lean-ctx as a Token Saver (external /v1/compress — verified compatible with the Headroom slot)
Summary
Add lean-ctx (https://github.com/yvgude/lean-ctx) as another external token saver in the Dashboard → Endpoint → Token Saver slot, alongside Headroom. It exposes the same POST /v1/compress messages-in/messages-out surface that open-sse/rtk/headroom.js already calls, so the integration reuses the existing code path instead of adding a new architecture.
- License Apache-2.0, Rust single binary, runs fully locally (nothing leaves the machine)
- Compression is deterministic + reversible (content-addressed recovery of every rewrite), prompt-cache-safe by contract
- v3.10.2 verified today, live, against the exact payload shape 9Router sends
Compatibility (measured, not assumed)
What open-sse/rtk/headroom.js sends today:
const payload = { messages, model };
if (compressUserMessages) payload.config = { compress_user_messages: true };
fetch(`${url}/v1/compress`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) });
// requires: res.ok && Array.isArray(data.messages)What lean-ctx returns for that exact call (real output, v3.10.2):
{"messages":[…],"stats":{"original_tokens":10778,"compressed_tokens":492,"saved_tokens":10286,"saved_pct":95.4,"tokenizer":"llama","model":"…"},"tokens_before":10778,"tokens_after":492,"compression_ratio":0.05}messages[]is present → passes the only structural check in the caller. ✅- Extra fields are tolerated: sending
config: { compress_user_messages: true }returns 200 (ignored, no error). ✅ - Fail-open is already covered by the existing code path (
nullon any error). ✅
Measured savings on the exact workload RTK targets — a 400-line grep -rn result (~29 KB, 10,778 tokens):
without: 10,778 tokens
with: 492 tokens → 95.4% saved, output still readable ("400 lines → 400 unique" stub + sample lines)Short user/system messages are left untouched by default (0% change on a 2-line prompt) — compression targets tool results and history.
Two small adapters it needs
- Auth header (optional). lean-ctx's
/v1/compressrequires a Bearer (its own proxy token) and returns401without it — the current caller sends onlyContent-Type. Either add an optional API-key field to the Token Saver config, or run lean-ctx auth-less for loopback/trusted-network deployments (proxy_loopback_open). - Stats key mapping (3 lines).
formatHeadroomLog()readsstats.tokens_before / tokens_after / tokens_saved; lean-ctx reportsstats.original_tokens / compressed_tokens / saved_tokens(plus top-leveltokens_before/tokens_after). Without mapping, the "reported token delta" log line reads 0 (functional impact: none). The byte-levelformatHeadroomSizeLogkeeps working unchanged.
Deployment
- Single static binary —
install.sh,cargo install lean-ctx,npm i -g lean-ctx-bin,brew; no Dockerfile in the repo yet, so a thin sidecar image would be needed (same pattern as the Headroom service in the Docker network). - Service:
lean-ctx proxy start --port=4444.
Positioning vs the existing savers
| What it compresses | Where | |
|---|---|---|
| RTK | tool_result content | built-in |
| Headroom | external /v1/compress |
built-in slot |
| lean-ctx | messages-in/messages-out (tool results + history), AST-aware file reads and 95+ shell-output patterns on its own path | same external slot as Headroom — users choose |
| Caveman / Ponytail | output tokens | prompt injection |
No conflict with the built-ins: it is one more option in the same slot.
Happy to run a build against my setup (9Router in Docker on a small homelab, Claude Code / Codex clients) if a first cut lands.
Source: decolua/9router