Mirror of headroomlabs-ai/headroom (AI context compression proxy)
Find a file
chopratejas a7b197c6ec refactor(proxy): MemoryRanker + ImageCompressionDecision + branch-aware version-sync
Three independent contract-pattern follow-ons bundled into one PR.
Same frozen-dataclass + factory + apply_to_tags + Rust-portable
shape that PR #473 / #477 / #483 established.

## (1) MemoryRanker + RecencyBoostRanker

Pre-this-PR Headroom ranked memory candidates by pure cosine
similarity. Every other memory system we surveyed (Letta, Mem0,
Cognee, Supermemory) re-ranks beyond cosine.

* ``MemoryRanker`` Protocol — pluggable re-ranker; future PRs add
  source-weight + access-count rankers behind the same interface.
* ``RecencyBoostRanker`` — first concrete impl. Final score is
  ``cosine × exp(-age_days / decay_days)``. Default decay 30 days
  (half-life ~21 days; 60-day-old factor 0.135, 90-day-old 0.050).
* ``MemoryCandidate`` — backend-agnostic frozen value type that
  flows through the ranker. ``MemoryCandidate.from_backend_result``
  adapter converts the existing ``MemoryResult`` shape (with nested
  ``memory.created_at``) into the ranker's flatter form.
* Wired into ``memory_handler.search_and_format_context`` as an
  optional ``ranker=`` kwarg — backwards-compat: ``None`` (default)
  preserves the pure-cosine path identically.

Defensive:
* ``created_at=None`` → factor 1.0 (recency-neutral, back-compat with
  legacy rows / migrating backends)
* Negative age (clock skew) → clamped to factor 1.0 (a future-dated
  row can't outrank a real fresh memory)
* Sort is stable on ties — same input → same output every turn, so
  consecutive turns inject memories in the same order (prefix-cache
  friendly)

Performance: O(N) over candidates where N=top_k≈10. One ``math.exp``
per candidate. Sub-microsecond. Zero new I/O.

## (2) ImageCompressionDecision

Mirror of :class:`CompressionDecision` for image compression. Two
sites today (``openai.py:1203``, ``anthropic.py:868``) gate inline;
both already respect bypass (no Gemini-class drift bug like text
compression had), but consolidating into a value type:

* Locks bypass-respect via AST contract test — future sites can't
  drift on it
* Surfaces ``image_skip_reason`` in ``RequestOutcome.tags`` for
  dashboard slicing (same observability surface as
  ``passthrough_reason`` and ``memory_skip_reason``)
* Same Rust-port shape as the other decision types

Precedence: ``bypass_header`` > ``image_optimize_disabled`` >
``no_messages`` > ``should_compress=True``.

Anthropic's extra ``is_cache_mode`` check stays inline because it's
Anthropic-specific (openai/gemini don't have it). Documented in a
code comment.

## (3) Branch-aware sync-plugin-versions hook

Pre-this-fix the pre-commit ``sync-plugin-versions`` hook ran on
every commit and bumped manifests to the predicted-next-release
version. Every PR ended up carrying the prediction as collateral
("Why are we bumping ``.claude-plugin/marketplace.json`` — we
should not, right??" - user, on PR #483).

Fix: the hook is now a NO-OP unless EITHER:
* We're on the ``main`` branch, OR
* ``HEADROOM_SYNC_VERSIONS=1`` is set explicitly (release workflow)

On feature branches the hook prints a single line explaining the
skip and exits cleanly. The release workflow opts in via the env
var; behaviour on main / at release time is unchanged.

## Test coverage

* 16 new tests on ``MemoryRanker`` / ``RecencyBoostRanker``
  (frozen, equal cosine wins by recency, decay configurable, NULL
  timestamp neutral, no-mutation contract, Rust-port shape)
* 17 new tests on ``ImageCompressionDecision`` (frozen, all 3
  skip reasons, precedence, observability fields, apply_to_tags)
* 1 new AST invariant test (extends
  ``test_handler_outcome_tag_invariant.py``) — locks "no raw
  ``if self.config.image_optimize and messages and not _bypass:``
  conjunction in any handler"

All existing memory + cache-stability + handler tests pass (203 ✓).
``make ci-precheck`` clean.

## Rust portability

All three new value types port cleanly to frozen Rust structs +
pure functions. Same migration pattern as ``CompressionDecision``
(already locked in for the SmartCrusher Rust port).

## Zero-regression contract

* Default ``ranker=None`` → memory_handler behaves identically to
  pre-this-PR (pure cosine; no perf change)
* Image decision migration is identity at the bypass/optimize/messages
  gate — no behaviour change, just contract consolidation
* Hook fix is no-op on feature branches (less churn) and unchanged
  on main (release flow preserved)
2026-05-19 12:13:09 -05:00
.claude-plugin fix(proxy): thread tags into 13 outcome sites + synth /v1/models + free-fn _extract_tags 2026-05-15 19:15:48 -07:00
.devcontainer fix(ci): rustls-everywhere — eliminate openssl-sys from build tree 2026-05-03 23:26:04 -07:00
.github fix(proxy): thread tags into 13 outcome sites + synth /v1/models + free-fn _extract_tags 2026-05-15 19:15:48 -07:00
benchmarks fix: B2 — live-zone block dispatcher skeleton 2026-05-02 12:45:43 -07:00
crates Merge pull request #403 from chopratejas/realign-F2_2-policy-tuning 2026-05-12 18:13:21 -07:00
docker feat(docker): forward HEADROOM_WORKSPACE_DIR and HEADROOM_CONFIG_DIR into containers 2026-04-16 19:19:25 -05:00
docs docs: improve discoverability for AI agents and search crawlers 2026-05-13 17:36:06 -07:00
e2e fix(tests): widen wrap-e2e openclaw startup timeout from 5s to 30s 2026-05-14 20:00:29 -07:00
examples Token-level cache hit rate, compression-vs-cache tracking, dashboard SQL, security plan 2026-04-06 18:10:29 -07:00
headroom refactor(proxy): MemoryRanker + ImageCompressionDecision + branch-aware version-sync 2026-05-19 12:13:09 -05:00
plugins fix(proxy): thread tags into 13 outcome sites + synth /v1/models + free-fn _extract_tags 2026-05-15 19:15:48 -07:00
REALIGNMENT docs: add Realignment plan (40 PRs, 9 phases) 2026-05-01 23:34:46 -07:00
scripts refactor(proxy): MemoryRanker + ImageCompressionDecision + branch-aware version-sync 2026-05-19 12:13:09 -05:00
sdk/typescript chore(deps): bump the npm_and_yarn group across 3 directories with 4 updates 2026-04-24 22:15:53 +00:00
sql feat(telemetry): add headroom_stack and install_mode identity fields 2026-04-17 17:12:38 +02:00
tests refactor(proxy): MemoryRanker + ImageCompressionDecision + branch-aware version-sync 2026-05-19 12:13:09 -05:00
wiki Merge pull request #411 from manorit2001/wip 2026-05-08 10:24:22 -07:00
.actrc feat: add act testing config, fix gitignore, make workflow production-ready 2026-04-15 20:28:29 -05:00
.actrc.local.example feat: add act testing config, fix gitignore, make workflow production-ready 2026-04-15 20:28:29 -05:00
.changelog.md fix: use /tmp for changelog artifact to avoid . file matching issues 2026-04-15 22:54:34 -05:00
.commitlintrc.json ci: fix smart_crusher branch CI failures + add make ci-precheck pre-push gate 2026-04-27 11:13:47 -07:00
.dockerignore chore: normalize line endings in init diffs 2026-04-21 20:17:14 -05:00
.env.act.example feat: add act testing config, fix gitignore, make workflow production-ready 2026-04-15 20:28:29 -05:00
.git-blame-ignore-revs chore: add .git-blame-ignore-revs 2026-04-24 15:35:29 +02:00
.gitattributes chore: enforce LF checkout for Python files 2026-04-23 08:43:03 -05:00
.gitguardian.yaml fix(security): allowlist GitGuardian-flagged test fixtures 2026-05-02 18:33:22 -07:00
.gitignore fix(tests): ship scripts/replay_codex_ws_load.py so CI can import it 2026-05-14 13:44:41 -07:00
.pre-commit-config.yaml chore: normalize line endings in init diffs 2026-04-21 20:17:14 -05:00
Cargo.lock Fix Windows ORT builds and Docker signing retries 2026-05-10 20:59:28 -07:00
Cargo.toml fix(build): shrink Rust extension wheels — strip + thin-LTO + single codegen unit 2026-05-14 19:31:23 -07:00
CHANGELOG.md fix: harden release gating and clarify pipx compatibility 2026-05-06 12:41:17 +02:00
claude_analysis_ttl.py chore: add cache TTL cost analysis script 2026-05-13 10:49:17 -07:00
CODE_OF_CONDUCT.md Prepare for OSS release v0.2.0 2026-01-07 11:36:44 -08:00
codecov.yml ci: scope codecov patch coverage 2026-04-22 00:05:47 -05:00
CONTRIBUTING.md feat: add reproducible devcontainers 2026-04-10 12:58:35 -05:00
deny.toml feat(rust): scaffold workspace + parity harness (phase-0) 2026-04-24 13:39:48 -07:00
docker-bake.hcl refactor(docker): migrate to bake with multi-variant distroless images 2026-04-04 21:51:37 +05:30
docker-compose.yml feat: add reproducible devcontainers 2026-04-10 12:58:35 -05:00
Dockerfile fix(ci): rustls-everywhere — eliminate openssl-sys from build tree 2026-05-03 23:26:04 -07:00
Headroom-2.gif Add demo GIF to README 2026-01-20 18:57:17 -08:00
headroom-savings.png docs: rewrite README for clarity and highlight Kompress-base, leaderboard, RTK 2026-04-18 09:36:49 -07:00
headroom_learn.gif docs: add headroom learn demo GIF to README 2026-03-07 17:56:17 -08:00
HeadroomDemo-Fast.gif Replace demo GIF with HeadroomDemo-Fast.gif 2026-04-10 15:05:25 -07:00
LICENSE Prepare for OSS release v0.2.0 2026-01-07 11:36:44 -08:00
llms.txt docs: improve discoverability for AI agents and search crawlers 2026-05-13 17:36:06 -07:00
Makefile fix: A0 — fail-loud rust core deployment smoke test 2026-05-02 17:52:37 -07:00
mkdocs.yml feat: add persistent install lifecycle management 2026-04-11 13:47:05 -05:00
NOTICE Prepare for OSS release v0.2.0 2026-01-07 11:36:44 -08:00
PR.md fix: restore release and compress regressions 2026-04-18 16:01:57 -05:00
pyproject.toml docs: improve discoverability for AI agents and search crawlers 2026-05-13 17:36:06 -07:00
README.md docs: improve discoverability for AI agents and search crawlers 2026-05-13 17:36:06 -07:00
rust-toolchain.toml fix(rust): clippy 1.95 unnecessary_sort_by + pin toolchain 2026-04-27 12:11:49 -07:00
RUST_DEV.md fix: B7 — CCR hardening: persistent backends + always-on tool 2026-05-02 16:52:33 -07:00
SECURITY.md Prepare for OSS release v0.2.0 2026-01-07 11:36:44 -08:00
uv.lock fix(ci): pin public PyPI in pyproject.toml + scrub Netflix URLs from uv.lock 2026-05-03 13:52:16 -07:00

  ██╗  ██╗███████╗ █████╗ ██████╗ ██████╗  ██████╗  ██████╗ ███╗   ███╗
  ██║  ██║██╔════╝██╔══██╗██╔══██╗██╔══██╗██╔═══██╗██╔═══██╗████╗ ████║
  ███████║█████╗  ███████║██║  ██║██████╔╝██║   ██║██║   ██║██╔████╔██║
  ██╔══██║██╔══╝  ██╔══██║██║  ██║██╔══██╗██║   ██║██║   ██║██║╚██╔╝██║
  ██║  ██║███████╗██║  ██║██████╔╝██║  ██║╚██████╔╝╚██████╔╝██║ ╚═╝ ██║
  ╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝╚═════╝ ╚═╝  ╚═╝ ╚═════╝  ╚═════╝ ╚═╝     ╚═╝
                  The context compression layer for AI agents

6095% fewer tokens · library · proxy · MCP · 6 algorithms · local-first · reversible

CI codecov PyPI npm Model: Kompress-base Tokens saved: 60B+ License: Apache 2.0 Docs

Docs · Install · Proof · Agents · Discord · llms.txt

AI agents / LLMs: read /llms.txt here, or fetch the live index / full docs blob.


Headroom compresses everything your AI agent reads — tool outputs, logs, RAG chunks, files, and conversation history — before it reaches the LLM. Same answers, fraction of the tokens.

Headroom in action
Live: 10,144 → 1,260 tokens — same FATAL found.

What it does

  • Librarycompress(messages) in Python or TypeScript, inline in any app
  • Proxyheadroom proxy --port 8787, zero code changes, any language
  • Agent wrapheadroom wrap claude|codex|cursor|aider|copilot in one command
  • MCP serverheadroom_compress, headroom_retrieve, headroom_stats for any MCP client
  • Cross-agent memory — shared store across Claude, Codex, Gemini, auto-dedup
  • headroom learn — mines failed sessions, writes corrections to CLAUDE.md / AGENTS.md
  • Reversible (CCR) — originals never deleted; LLM retrieves on demand

How it works (30 seconds)

 Your agent / app
   (Claude Code, Cursor, Codex, LangChain, Agno, Strands, your own code…)
        │   prompts · tool outputs · logs · RAG results · files
        ▼
    ┌────────────────────────────────────────────────────┐
    │  Headroom   (runs locally — your data stays here)  │
    │  ───────────────────────────────────────────────   │
    │  CacheAligner  →  ContentRouter  →  CCR             │
    │                    ├─ SmartCrusher   (JSON)         │
    │                    ├─ CodeCompressor (AST)          │
    │                    └─ Kompress-base  (text, HF)     │
    │                                                     │
    │  Cross-agent memory  ·  headroom learn  ·  MCP      │
    └────────────────────────────────────────────────────┘
        │   compressed prompt  +  retrieval tool
        ▼
 LLM provider  (Anthropic · OpenAI · Bedrock · …)
  • ContentRouter — detects content type, selects the right compressor
  • SmartCrusher / CodeCompressor / Kompress-base — compress JSON, AST, or prose
  • CacheAligner — stabilizes prefixes so provider KV caches actually hit
  • CCR — stores originals locally; LLM calls headroom_retrieve if it needs them

Architecture · CCR reversible compression · Kompress-base model card

Get started (60 seconds)

# 1 — Install
pip install "headroom-ai[all]"          # Python
npm install headroom-ai                 # Node / TypeScript

# 2 — Pick your mode
headroom wrap claude                    # wrap a coding agent
headroom proxy --port 8787              # drop-in proxy, zero code changes
# or: from headroom import compress      # inline library

# 3 — See the savings
headroom stats

Granular extras: [proxy], [mcp], [ml], [agno], [langchain], [evals]. Requires Python 3.10+.

Proof

Savings on real agent workloads:

Workload Before After Savings
Code search (100 results) 17,765 1,408 92%
SRE incident debugging 65,694 5,118 92%
GitHub issue triage 54,174 14,761 73%
Codebase exploration 78,502 41,254 47%

Accuracy preserved on standard benchmarks:

Benchmark Category N Baseline Headroom Delta
GSM8K Math 100 0.870 0.870 ±0.000
TruthfulQA Factual 100 0.530 0.560 +0.030
SQuAD v2 QA 100 97% 19% compression
BFCL Tools 100 97% 32% compression

Reproduce: python -m headroom.evals suite --tier 1 · Full benchmarks & methodology

60B+ tokens saved — community leaderboard
60B+ tokens saved by the community — live leaderboard →

Agent compatibility matrix

Agent headroom wrap Notes
Claude Code --memory · --code-graph
Codex shares memory with Claude
Cursor prints config — paste once
Aider starts proxy + launches
Copilot CLI starts proxy + launches
OpenClaw installs as ContextEngine plugin

Any OpenAI-compatible client works via headroom proxy. MCP-native: headroom mcp install.

When to use · When to skip

Great fit if you…

  • run AI coding agents daily and want savings without changing your code
  • work across multiple agents and want shared memory
  • need reversible compression — originals always retrievable via CCR

Skip it if you…

  • only use a single provider's native compaction and don't need cross-agent memory
  • work in a sandboxed environment where local processes can't run
Integrations — drop Headroom into any stack
Your setup Hook in with
Any Python app compress(messages, model=…)
Any TypeScript app await compress(messages, { model })
Anthropic / OpenAI SDK withHeadroom(new Anthropic()) · withHeadroom(new OpenAI())
Vercel AI SDK wrapLanguageModel({ model, middleware: headroomMiddleware() })
LiteLLM litellm.callbacks = [HeadroomCallback()]
LangChain HeadroomChatModel(your_llm)
Agno HeadroomAgnoModel(your_model)
Strands Strands guide
ASGI apps app.add_middleware(CompressionMiddleware)
Multi-agent SharedContext().put / .get
MCP clients headroom mcp install
What's inside
  • SmartCrusher — universal JSON: arrays of dicts, nested objects, mixed types.
  • CodeCompressor — AST-aware for Python, JS, Go, Rust, Java, C++.
  • Kompress-base — our HuggingFace model, trained on agentic traces.
  • Image compression — 4090% reduction via trained ML router.
  • CacheAligner — stabilizes prefixes so Anthropic/OpenAI KV caches actually hit.
  • IntelligentContext — score-based context fitting with learned importance.
  • CCR — reversible compression; LLM retrieves originals on demand.
  • Cross-agent memory — shared store, agent provenance, auto-dedup.
  • SharedContext — compressed context passing across multi-agent workflows.
  • headroom learn — plugin-based failure mining for Claude, Codex, Gemini.
Pipeline internals

Headroom exposes one stable request lifecycle across compress(), the SDK, and the proxy:

SetupPre-StartPost-StartInput ReceivedInput CachedInput RoutedInput CompressedInput RememberedPre-SendPost-SendResponse Received

  • Transforms do the work: CacheAligner, ContentRouter, SmartCrusher, CodeCompressor, Kompress-base, IntelligentContext / RollingWindow.
  • Pipeline extensions observe or customize lifecycle stages via on_pipeline_event(...).
  • Compression hooks sit alongside the canonical lifecycle as an additional extension seam.
  • Proxy extensions remain the server/app integration seam for ASGI middleware, routes, and startup policy.

Provider and tool-specific behavior lives under headroom/providers/ so core orchestration stays focused on lifecycle, sequencing, and policy.

  • CLI/tool slices: headroom/providers/claude, copilot, codex, openclaw
  • Provider runtime slices: headroom/providers/claude, gemini, plus shared backend/runtime dispatch in headroom/providers/registry.py
  • Core files stay orchestration-first: wrap.py, client.py, cli/proxy.py, and proxy/server.py delegate provider-specific env shaping, API target normalization, backend selection, and transport dispatch.

Install

pip install "headroom-ai[all]"          # Python, everything
npm install headroom-ai                 # TypeScript / Node
docker pull ghcr.io/chopratejas/headroom:latest

Granular extras: [proxy], [mcp], [ml] (Kompress-base), [agno], [langchain], [evals]. Requires Python 3.10+.

Using pipx? Choose a supported interpreter explicitly:

pipx install --python python3.13 "headroom-ai[all]"

Installation guide — Docker tags, persistent service, PowerShell, devcontainers.

headroom learn

headroom learn in action

headroom learn — mines failed sessions, writes corrections to CLAUDE.md / AGENTS.md / GEMINI.md.

Documentation

Start here Go deeper
Quickstart Architecture
Proxy How compression works
MCP tools CCR — reversible compression
Memory Cache optimization
Failure learning Benchmarks
Configuration Limitations

Compared to

Headroom runs locally, covers every content type, works with every major framework, and is reversible.

Scope Deploy Local Reversible
Headroom All context — tools, RAG, logs, files, history Proxy · library · middleware · MCP Yes Yes
RTK CLI command outputs CLI wrapper Yes No
lean-ctx CLI commands, MCP tools, editor rules CLI wrapper · MCP Yes No
Compresr, Token Co. Text sent to their API Hosted API call No No
OpenAI Compaction Conversation history Provider-native No No

Attribution. Headroom ships with the excellent RTK binary for shell-output rewriting — git show --short, scoped ls, summarized installers. Huge thanks to the RTK team; their tool is a first-class part of our stack, and Headroom compresses everything downstream of it. Headroom can also use lean-ctx as the selected CLI context tool; set HEADROOM_CONTEXT_TOOL=lean-ctx before running headroom wrap ....

Contributing

git clone https://github.com/chopratejas/headroom.git && cd headroom
pip install -e ".[dev]" && pytest

Devcontainers in .devcontainer/ (default + memory-stack with Qdrant & Neo4j). See CONTRIBUTING.md.

Community

License

Apache 2.0 — see LICENSE.