ranxianglei/billion-contextPublic

A context-compression plugin for month-long single sessions (billions of tokens) ,small context windows (a 100K context is enough) and token savings (5x fewer tokens) .上下文压缩插件,月级长会话会话, 兼顾小窗口(100k上下文足矣)省token(省5倍token) . billion-context is all you need

AI summary: A context-compression plugin that acts as a proxy between AI coding agents and LLM APIs, enabling unlimited sessions.

Stars
2.1K
+166 today
Forks
189
Watchers
7
Open issues
75
Open PRs
94
Contributors
~63
Commits
4K
Branches
1.5K
Views (30d)
2

TypeScriptOtherCreated Aug 6, 2026Last push 2d agoLatest release v0.1.191+1K stars this week+1.3K this month

Quick answers

What is billion-context?
A context-compression plugin that acts as a proxy between AI coding agents and LLM APIs, enabling unlimited sessions.
What does billion-context do?
Billion-context acts as a proxy between any AI coding agent and LLM APIs like Anthropic or OpenAI to manage large context windows. It prevents context bloat during long coding sessions by incrementally compressing past interactions into high-fidelity summaries. The tool injects context-management commands that the model uses to compress, decompress, or search through history automatically. This hierarchical compression allows a single session to handle billions of tokens over days without losing essential details. Crucially, the compression is reversible, keeping prefix caching effective while saving significant token costs.
Who is billion-context for?
Developers and teams utilizing AI coding agents for extensive or longitudinal projects. It is essential for those running up against LLM context limits or looking to optimize API costs without sacrificing project state.
How do I get started with billion-context?
bili pi
How popular is billion-context on GitHub?
ranxianglei/billion-context has 2,118 stars and 189 forks on GitHub, and gained 1,034 stars in the last 7 days.
What license does billion-context use?
ranxianglei/billion-context is released under the Other license.

Star history

since Oct 10, 2026
01K2KOct 2026Oct 2026Oct 2026Oct 2026
2.1K stars as of Oct 20, 2026. Measured daily since Oct 10, 2026; GitHub no longer exposes earlier star timestamps.

Update history

2 recorded
  • Oct 20, 2026Description changed from "A context-compression plugin for small context windows (a 100K context is enough), token savings (5x fewer tokens), and " to "A context-compression plugin for month-long single sessions (billions of tokens) ,small context windows (a 100K context ".
  • Oct 10, 2026Description changed from "稳定可用 A context-compression plugin for small context windows (a 100K context is enough), token savings (5x fewer tokens)," to "A context-compression plugin for small context windows (a 100K context is enough), token savings (5x fewer tokens), and ".

Contribution activity

commits per day, last 52 weeks
OctNovDecJanFebMarAprMayJunJulAugSepOctMonWedFri2025-10-12: 0 commits2025-10-13: 0 commits2025-10-14: 0 commits2025-10-15: 0 commits2025-10-16: 0 commits2025-10-17: 0 commits2025-10-18: 0 commits2025-10-19: 0 commits2025-10-20: 0 commits2025-10-21: 0 commits2025-10-22: 0 commits2025-10-23: 0 commits2025-10-24: 0 commits2025-10-25: 0 commits2025-10-26: 0 commits2025-10-27: 0 commits2025-10-28: 0 commits2025-10-29: 0 commits2025-10-30: 0 commits2025-10-31: 0 commits2025-11-01: 0 commits2025-11-02: 0 commits2025-11-03: 0 commits2025-11-04: 0 commits2025-11-05: 0 commits2025-11-06: 0 commits2025-11-07: 0 commits2025-11-08: 0 commits2025-11-09: 0 commits2025-11-10: 0 commits2025-11-11: 0 commits2025-11-12: 0 commits2025-11-13: 0 commits2025-11-14: 0 commits2025-11-15: 0 commits2025-11-16: 0 commits2025-11-17: 0 commits2025-11-18: 0 commits2025-11-19: 0 commits2025-11-20: 0 commits2025-11-21: 0 commits2025-11-22: 0 commits2025-11-23: 0 commits2025-11-24: 0 commits2025-11-25: 0 commits2025-11-26: 0 commits2025-11-27: 0 commits2025-11-28: 0 commits2025-11-29: 0 commits2025-11-30: 0 commits2025-12-01: 0 commits2025-12-02: 0 commits2025-12-03: 0 commits2025-12-04: 0 commits2025-12-05: 0 commits2025-12-06: 0 commits2025-12-07: 0 commits2025-12-08: 0 commits2025-12-09: 0 commits2025-12-10: 0 commits2025-12-11: 0 commits2025-12-12: 0 commits2025-12-13: 0 commits2025-12-14: 0 commits2025-12-15: 0 commits2025-12-16: 0 commits2025-12-17: 0 commits2025-12-18: 0 commits2025-12-19: 0 commits2025-12-20: 0 commits2025-12-21: 0 commits2025-12-22: 0 commits2025-12-23: 0 commits2025-12-24: 0 commits2025-12-25: 0 commits2025-12-26: 0 commits2025-12-27: 0 commits2025-12-28: 0 commits2025-12-29: 0 commits2025-12-30: 0 commits2025-12-31: 0 commits2026-01-01: 0 commits2026-01-02: 0 commits2026-01-03: 0 commits2026-01-04: 0 commits2026-01-05: 0 commits2026-01-06: 0 commits2026-01-07: 0 commits2026-01-08: 0 commits2026-01-09: 0 commits2026-01-10: 0 commits2026-01-11: 0 commits2026-01-12: 0 commits2026-01-13: 0 commits2026-01-14: 0 commits2026-01-15: 0 commits2026-01-16: 0 commits2026-01-17: 0 commits2026-01-18: 0 commits2026-01-19: 0 commits2026-01-20: 0 commits2026-01-21: 0 commits2026-01-22: 0 commits2026-01-23: 0 commits2026-01-24: 0 commits2026-01-25: 0 commits2026-01-26: 0 commits2026-01-27: 0 commits2026-01-28: 0 commits2026-01-29: 0 commits2026-01-30: 0 commits2026-01-31: 0 commits2026-02-01: 0 commits2026-02-02: 0 commits2026-02-03: 0 commits2026-02-04: 0 commits2026-02-05: 0 commits2026-02-06: 0 commits2026-02-07: 0 commits2026-02-08: 0 commits2026-02-09: 0 commits2026-02-10: 0 commits2026-02-11: 0 commits2026-02-12: 0 commits2026-02-13: 0 commits2026-02-14: 0 commits2026-02-15: 0 commits2026-02-16: 0 commits2026-02-17: 0 commits2026-02-18: 0 commits2026-02-19: 0 commits2026-02-20: 0 commits2026-02-21: 0 commits2026-02-22: 0 commits2026-02-23: 0 commits2026-02-24: 0 commits2026-02-25: 0 commits2026-02-26: 0 commits2026-02-27: 0 commits2026-02-28: 0 commits2026-03-01: 0 commits2026-03-02: 0 commits2026-03-03: 0 commits2026-03-04: 0 commits2026-03-05: 0 commits2026-03-06: 0 commits2026-03-07: 0 commits2026-03-08: 0 commits2026-03-09: 0 commits2026-03-10: 0 commits2026-03-11: 0 commits2026-03-12: 0 commits2026-03-13: 0 commits2026-03-14: 0 commits2026-03-15: 0 commits2026-03-16: 0 commits2026-03-17: 0 commits2026-03-18: 0 commits2026-03-19: 0 commits2026-03-20: 0 commits2026-03-21: 0 commits2026-03-22: 0 commits2026-03-23: 0 commits2026-03-24: 0 commits2026-03-25: 0 commits2026-03-26: 0 commits2026-03-27: 0 commits2026-03-28: 0 commits2026-03-29: 0 commits2026-03-30: 0 commits2026-03-31: 0 commits2026-04-01: 0 commits2026-04-02: 0 commits2026-04-03: 0 commits2026-04-04: 0 commits2026-04-05: 0 commits2026-04-06: 0 commits2026-04-07: 0 commits2026-04-08: 0 commits2026-04-09: 0 commits2026-04-10: 0 commits2026-04-11: 0 commits2026-04-12: 0 commits2026-04-13: 0 commits2026-04-14: 0 commits2026-04-15: 0 commits2026-04-16: 0 commits2026-04-17: 0 commits2026-04-18: 0 commits2026-04-19: 0 commits2026-04-20: 0 commits2026-04-21: 0 commits2026-04-22: 0 commits2026-04-23: 0 commits2026-04-24: 0 commits2026-04-25: 0 commits2026-04-26: 0 commits2026-04-27: 0 commits2026-04-28: 0 commits2026-04-29: 0 commits2026-04-30: 0 commits2026-05-01: 0 commits2026-05-02: 0 commits2026-05-03: 0 commits2026-05-04: 0 commits2026-05-05: 0 commits2026-05-06: 0 commits2026-05-07: 0 commits2026-05-08: 0 commits2026-05-09: 0 commits2026-05-10: 0 commits2026-05-11: 0 commits2026-05-12: 0 commits2026-05-13: 0 commits2026-05-14: 0 commits2026-05-15: 0 commits2026-05-16: 0 commits2026-05-17: 0 commits2026-05-18: 0 commits2026-05-19: 0 commits2026-05-20: 0 commits2026-05-21: 0 commits2026-05-22: 0 commits2026-05-23: 0 commits2026-05-24: 0 commits2026-05-25: 0 commits2026-05-26: 0 commits2026-05-27: 0 commits2026-05-28: 0 commits2026-05-29: 0 commits2026-05-30: 0 commits2026-05-31: 0 commits2026-06-01: 0 commits2026-06-02: 0 commits2026-06-03: 0 commits2026-06-04: 0 commits2026-06-05: 0 commits2026-06-06: 0 commits2026-06-07: 0 commits2026-06-08: 0 commits2026-06-09: 0 commits2026-06-10: 0 commits2026-06-11: 0 commits2026-06-12: 0 commits2026-06-13: 0 commits2026-06-14: 0 commits2026-06-15: 0 commits2026-06-16: 0 commits2026-06-17: 0 commits2026-06-18: 0 commits2026-06-19: 0 commits2026-06-20: 0 commits2026-06-21: 0 commits2026-06-22: 0 commits2026-06-23: 0 commits2026-06-24: 0 commits2026-06-25: 0 commits2026-06-26: 0 commits2026-06-27: 0 commits2026-06-28: 0 commits2026-06-29: 0 commits2026-06-30: 0 commits2026-07-01: 0 commits2026-07-02: 0 commits2026-07-03: 0 commits2026-07-04: 0 commits2026-07-05: 0 commits2026-07-06: 0 commits2026-07-07: 0 commits2026-07-08: 0 commits2026-07-09: 0 commits2026-07-10: 0 commits2026-07-11: 0 commits2026-07-12: 0 commits2026-07-13: 0 commits2026-07-14: 0 commits2026-07-15: 0 commits2026-07-16: 0 commits2026-07-17: 0 commits2026-07-18: 0 commits2026-07-19: 0 commits2026-07-20: 0 commits2026-07-21: 0 commits2026-07-22: 0 commits2026-07-23: 0 commits2026-07-24: 0 commits2026-07-25: 0 commits2026-07-26: 0 commits2026-07-27: 0 commits2026-07-28: 0 commits2026-07-29: 0 commits2026-07-30: 0 commits2026-07-31: 0 commits2026-08-01: 0 commits2026-08-02: 0 commits2026-08-03: 0 commits2026-08-04: 0 commits2026-08-05: 0 commits2026-08-06: 8 commits2026-08-07: 7 commits2026-08-08: 93 commits2026-08-09: 46 commits2026-08-10: 33 commits2026-08-11: 41 commits2026-08-12: 36 commits2026-08-13: 12 commits2026-08-14: 15 commits2026-08-15: 14 commits2026-08-16: 13 commits2026-08-17: 5 commits2026-08-18: 6 commits2026-08-19: 16 commits2026-08-20: 0 commits2026-08-21: 5 commits2026-08-22: 12 commits2026-08-23: 23 commits2026-08-24: 31 commits2026-08-25: 32 commits2026-08-26: 22 commits2026-08-27: 20 commits2026-08-28: 17 commits2026-08-29: 29 commits2026-08-30: 8 commits2026-08-31: 21 commits2026-09-01: 7 commits2026-09-02: 9 commits2026-09-03: 36 commits2026-09-04: 19 commits2026-09-05: 23 commits2026-09-06: 22 commits2026-09-07: 28 commits2026-09-08: 12 commits2026-09-09: 10 commits2026-09-10: 30 commits2026-09-11: 25 commits2026-09-12: 21 commits2026-09-13: 22 commits2026-09-14: 22 commits2026-09-15: 33 commits2026-09-16: 52 commits2026-09-17: 32 commits2026-09-18: 40 commits2026-09-19: 56 commits2026-09-20: 43 commits2026-09-21: 19 commits2026-09-22: 31 commits2026-09-23: 36 commits2026-09-24: 72 commits2026-09-25: 61 commits2026-09-26: 95 commits2026-09-27: 82 commits2026-09-28: 77 commits2026-09-29: 76 commits2026-09-30: 49 commits2026-10-01: 78 commits2026-10-02: 47 commits2026-10-03: 70 commits2026-10-04: 103 commits2026-10-05: 78 commits2026-10-06: 115 commits2026-10-07: 94 commits2026-10-08: 85 commits2026-10-09: 65 commits2026-10-10: 42 commits
2,482 commits in the last yearLessMore

Signals and awards

derived from tracked data
  • Rising fast

    +1,034 stars this week

  • Very active

    2,482 commits in 52 weeks

  • Continuous integration

    Automated checks passing

  • Repeat trending

    7 trending appearances

What billion-context does

Billion-context acts as a proxy between any AI coding agent and LLM APIs like Anthropic or OpenAI to manage large context windows. It prevents context bloat during long coding sessions by incrementally compressing past interactions into high-fidelity summaries. The tool injects context-management commands that the model uses to compress, decompress, or search through history automatically. This hierarchical compression allows a single session to handle billions of tokens over days without losing essential details. Crucially, the compression is reversible, keeping prefix caching effective while saving significant token costs.

Developers and teams utilizing AI coding agents for extensive or longitudinal projects. It is essential for those running up against LLM context limits or looking to optimize API costs without sacrificing project state.

  • Incremental compression: Compresses past conversations incrementally to keep token consumption manageable without arbitrary truncation.
  • Reversible summaries: Allows models to restore exact details from summarized historical ranges when needed.
  • Prefix-cache compatibility: Maintains a healthy 95-97% prefix-cache hit rate, keeping compression overhead under 2%.
  • Model-driven management: Provides tools like compress, decompress, and search_context directly to the LLM to manage its own context.
  • Universal agent support: Sits cleanly between numerous coding agents (like Claude Code, Cursor, Aider) and the backend API.

Where teams use it

Long-running coding sessions

Extend a single AI coding agent session across multiple days without exhausting the model's context window.

Cost reduction

Minimize token expenditure on large context histories by actively compressing older messages while retaining high-level knowledge.

Agent integration

Plug into existing tools like pi, opencode, or Cursor simply by rewriting their base URL to point at the proxy.

Context retrieval

Allow the LLM to perform keyword searches over compressed summaries when it needs to recall specific historical details.

Getting started: bili pi

README

master branch

billion-context

English | 中文

Context-compression plugin — billion-context is all you need.

small context windows (100K is enough) · 5× fewer tokens · month-long single sessions (billions of tokens) · high compression quality

npm license GitHub

npm install -g billion-context --prefix=~/.local

Claude Code  Codex  OpenCode  pi  Gemini CLI  Kimi  Qwen Code  GitHub Copilot CLI  TRAE  CodeBuddy  Qoder  iFlow CLI  MiniMax Code  deepseek-harness  Amp  Crush  Zed  aider  goose  hermes  zcode  omp  jcode


Cache health at a glance: a healthy session keeps a 95–97% prefix-cache hit rate — compression itself costs ≤2%. Sustained lower? Check attribution with /acp or /acp-cache (see FAQ); usual causes, in order: upstream cache TTL expiry · model switch · a bili bug (please report) · other/unknown.

Community

QQ Group: 1056132097 (full) 1108730198 (open)


📄 Paper / Preprint

📝 The paper itself is open-sourced under the MIT License as part of the codebase (paper/). It is a living document — anyone may edit it; improvements are welcome via pull request.

A production-scale longitudinal study: 4.5 months, three hosts, 174,327 model calls, 18.76B cumulative input tokens (~24.7B across all hosts), zero window violations on 204,800-token models, marathon sessions of 8,584–12,049 calls.


billion-context sits between any agent and its model API, rewriting Anthropic/OpenAI streams with acp-kernel compression. The model decides when and what to compress into high-fidelity summaries — not a hard truncation limit.

Why

Long coding sessions blow up context. Each provider charges per token, and once you pass the context window the session degrades or dies. billion-context compresses consumed conversation into layered summaries so you can run a single session for days — billions of tokens through one context window.

Unlike a host's built-in summarizer, compression here is incremental, reversible, and prefix-cache friendly: summaries are written in small ranges, can be decompressed on demand, and the cache prefix stays intact.

How it works

Agent (Claude Code / Codex / Cursor / Aider ...)
        │  you point the agent's base URL at the proxy
        ▼
┌─────────────────┐
│  billion-context│   1. parse the request (Anthropic or OpenAI shape)
│     proxy       │   2. run acp-kernel compression on the conversation
│                 │   3. inject a `compress` tool + compression philosophy
│                 │   4. forward to the real model API
│                 │   5. rewrite the streaming response
└─────────────────┘
        │
        ▼
   real model API (Anthropic / OpenAI / compatible)

Context-management tools

The proxy injects four context-management tools into the conversation; the model calls them itself as context grows, and the proxy executes compress server-side so folded ranges stay summarized in history until restored:

  • compress — fold a message range into a detailed summary.
  • decompress — restore a compressed range when exact details are needed again.
  • search_context — keyword search over compressed summaries and visible messages.
  • acp_status — context-usage overview plus which ranges are still compressible.

Which do I need?

Pick by your client:

Client Use
pi billion-context — bili pi (launcher) or bili plugin install pi (native); standalone billion-context-pi remains usable — details: CLIENTS.md
opencode (1.x / 2.x) billion-context — bili opencode (launcher) or bili plugin install opencode (native); standalone opencode-acp remains usable on 1.x — full guide: OpenCode
omp billion-context via bili omp (built-in plugin) or bili plugin install omp (self-spawning native plugin, no launcher)
dsh bili dsh (launcher — full native plugin via --patch) or bili plugin install dsh ≡ dsh plugin --profile <name> add billion-context (one unified lane) — details: CLIENTS.md
kimi bili plugin install kimi (self-spawning native, Kimi Code ≥ 2.0.0) or bili kimi (cert-MITM) or /bili/ prefix — details: CLIENTS.md
hermes bili plugin install hermes (self-spawning native, Python plugin #958) or bili hermes (cert-MITM)
zcode (Z.ai / bigmodel coding plan) bili plugin install zcode (self-spawning native, #1145) or cert-MITM via the GUI's Settings → Network or /bili/ prefix — details: CLIENTS.md
claude bili claude (launcher) or bili plugin install claude (native posture, #964 — managed settings block + session-owned proxy; see the notes below)
codex bili codex (launcher — the full zero-config posture) or bili plugin install codex (MCP-shell tools companion: start bili first — the shell never spawns a proxy and never routes codex's own traffic) — details: CLIENTS.md
jcode billion-context via bili jcode (cert-MITM) or /bili/ prefix — no native mode (compiled Rust binary, no plugin seam, #962)
gemini (Gemini CLI) bili gemini (launcher, GOOGLE_GEMINI_BASE_URL /bili/ rewrite) or /bili/ prefix — launcher-only (no in-loop tool seam, #1043)
iflow (iFlow CLI) bili iflow (launcher, IFLOW_BASE_URL /bili/ rewrite) or /bili/ prefix
qwen (Qwen Code) bili qwen (launcher, cert-MITM) or /bili/ prefix
antigravity (Antigravity CLI / agy, Google) bili antigravity (launcher, CLOUD_CODE_URL /bili/ rewrite of cloudcode-pa.googleapis.com) or /bili/ prefix — no plugin seam (closed Go language_server; its user-plugin surface is additive-only, #2115) — details: CLIENTS.md
mcode (MiniMax Code) billion-context via bili mcode (cert-MITM) or /bili/ prefix — no native mode (event hooks only, no model-request seam, #1050)
aider billion-context via bili aider (cert-MITM) or /bili/ prefix — no native mode (shell-command-only hooks, no tool-injection seam, #1048)
copilot (GitHub Copilot CLI) bili copilot (launcher, cert-MITM) — closed Go binary, no plugin seam (#1049)
amp (Amp CLI) bili amp (launcher, cert-MITM) — closed Go binary, no plugin seam (#1049)
crush (Charm Crush) bili crush (launcher, cert-MITM) — open-source Go binary, no plugin seam; built-in provider hosts whitelisted, custom base_urls auto-discovered from crush.json (#2340)
zed (Zed editor) bili zed (launcher, cert-MITM) — open-source Rust editor, no plugin seam; reqwest honors HTTPS_PROXY, CA via SSL_CERT_FILE (Linux env probing); built-in provider hosts whitelisted, custom api_urls auto-discovered from settings.json; loopback providers (ollama/lmstudio) stay direct via NO_PROXY (#2340)
goose (Goose CLI) bili goose (launcher) — rustls trusts no CA file, so no cert-MITM: openai/anthropic legs via OPENAI_HOST/ANTHROPIC_HOST, custom providers via a regenerated GOOSE_PATH_ROOT overlay (#1049)
everything else (no context hook) billion-context — bili <client> (launcher, preferred) or /bili/ prefix

Native mode vs standalone extensions. The host-native plugins (bili plugin install …) and the standalone in-process extensions (billion-context-pi, opencode-acp) are mutually exclusive — both active means double compression. The installer makes the switch: it replaces the legacy entries (bare name, npm: alias, versioned, path form; array or object shape) and snapshots the original config to .bili-bak once; a project-local install is not touched — remove that one by hand. As a runtime safety net for manual installs, the native entries set BILLION_CONTEXT_NATIVE=<host> synchronously at load so a standalone extension can stand down at action time. On the pi side the marker needs billion-context-pi 0.1.72+, and the pi-native entry scans both pi settings files once its proxy is up and warns loudly when it spots a co-resident legacy entry the installer never saw — that warning is the only visible signal while an old billion-context-pi silently double-compresses.

Install

Linux / macOS — install with a user-level prefix (no sudo, no npm config changes, and bili's self-update never hits permission errors):

npm install -g billion-context --prefix=~/.local

The bili command lands in ~/.local/bin — already on PATH in most distros; if not, add export PATH="$HOME/.local/bin:$PATH" to ~/.bashrc or ~/.zshrc. On nvm or Homebrew Node the default prefix is already user-owned — a plain npm install -g billion-context works as-is. On Windows the default prefix (%APPDATA%\npm) is also user-writable — plain npm install -g billion-context.

This installs the bili command (bili-proxy is kept as an alias). Hitting EACCES with an old root-owned prefix? Reinstall with --prefix=~/.local (pass the flag again on any future npm reinstall of bili) — that is the permanent fix; avoid sudo.

Quickstart

Three ways to use it — pick one:

  • Native plugin (most native): bili plugin install <client> — bili becomes a plugin inside the client; start the client as usual.
  • Launcher (config-free): one bili <client> command brings up the proxy and the client together — no real config file is ever touched.
  • URL change (most universal): prefix your client's baseURL with the proxy origin + /bili/.

Mechanism details behind these three options (plugin lifecycle, runtime-info protocol, injection priority) live in TECHNICAL-NOTES.md.

Ports, briefly (#1660): bili start (manual) owns 8787. Everything a lane spawns for you (native hooks, launcher lanes) lives in a separate self-managed zone starting at 18787 — collisions hop +1 and each lane remembers its drift, so zero-config installs never fight you for a port, and a deliberate bili start daemon is attached by default. An upgrade-restart that finds the previous build still draining on the lane's port waits for it to release (up to 5s) and rebinds the SAME port instead of drifting (#1723); only a genuinely occupied port hops +1 — and that hop is now logged loudly.

Option 1 — Native plugin (bili plugin install pi / omp / opencode / dsh / kimi / hermes / zcode)

The proxy lives inside the client: install once, then start the client exactly as you always do — no launcher command, no env vars, no fixed port, no URL edits. Supported today for pi, omp, opencode (1.x and 2.x), dsh, kimi, hermes and zcode:

bili plugin install pi          # registers a "billion-context" entry in pi's settings (npm form when bili itself was npm-installed)
bili plugin install omp         # registers an extensions entry in omp's config.yml (~/.omp/agent/config.yml)
bili plugin install opencode    # registers the plugin in opencode's real config + disables native auto-compaction
bili plugin install dsh         # runs 'dsh plugin --profile <name> add billion-context' for every existing profile
bili plugin install kimi        # writes $KIMI_CODE_HOME/plugins/managed/billion-context/kimi.plugin.json (+ installed.json record); per-session routing block lands in config.toml on first start (Kimi Code >= 2.0.0)
bili plugin install hermes      # copies the Python plugin into ~/.hermes/plugins/billion-context/ (+ machine-owned bili.json sidecar) and enables it via `hermes plugins enable billion-context`
bili plugin install zcode       # writes hooks.enabled + a SessionStart hook + mcp.servers.bili into ~/.zcode/cli/config.json; per-session routing lands in the bigmodel provider store on first start
bili plugin remove <client>     # undo (dsh removes through the same channel; config snapshots go to .bili-bak)

Where a client has its own plugin channel you can also install natively, skipping bili commands entirely:

  • dsh: dsh plugin --profile <name> add billion-context is the very command bili plugin install dsh drives per profile (npm form only; a git checkout has no published entry — pasting a GitHub address installs source without dist/ and the bundle never loads) — same end state either way (pnpm into the profile, bundled patch layer mounted by dsh itself); remove through the same channel. See the dsh section below.
  • opencode: add the bare npm name to your real config's plugin list — "plugin": ["billion-context"] (npm form only; a git checkout has no published entry). The package publishes exports["./server"] → dist/agent/opencode-native.js, so opencode loads it through its own Npm.add machinery and the plugin self-spawns exactly like the bili-installed form. Do the two things the bili installer would have done for you too: set "compaction": { "auto": false } in the same config (otherwise OpenCode's native auto-compaction double-compresses) and keep a manual backup of the file first.
  • claude: this repository doubles as a Claude Code plugin marketplace — /plugin marketplace add ranxianglei/billion-context, then /plugin install billion-context@billion-context, then run /billion-context:bili-setup (it drives bili plugin install claude for you and tells you to restart). Same end state as the bili installer; the plugin ships no hooks or MCP entries of its own, so nothing double-registers.

For pi / omp / kimi / claude there is no client-side channel — bili plugin install <client> writes their config entries for you (kimi's declarative kimi.plugin.json + registry record, claude's managed settings block, …).

Notes:

  • Native mode is mutually exclusive with the standalone in-process extensions (billion-context-pi, opencode-acp) — the installer swaps the entries and snapshots the original config (.bili-bak).
  • pi: native installs wire in built-in subagents by default (acp_delegate / acp_delegate_wait / acp_delegate_cancel) — how to disable them while keeping context compression: Pi built-in subagents.
  • OpenCode legacy sessions, V1/V2 shapes and caveats: OpenCode.
  • kimi reports runtime-info at bootstrap only (static headers can't carry per-request window/model values); subagent tool calls are routed by the proxy's outbound tool-use witness ring (#1685) — no model-visible conversation id.
  • hermes's native plugin is Python: it points hermes' httpx stack at the proxy via env vars after a health check and stamps per-request headers through an llm_request middleware.
  • codex is the one client a plugin install cannot make self-sufficient: codex routes model traffic via env only (no config-file routing seam for the default ChatGPT-login provider — a managed model_providers block would force API-key auth and drop subscription login), and an MCP server cannot inject env into its parent. bili plugin install codex writes a single [mcp_servers.bili] block into ~/.codex/config.toml (command = node, args = dist/mcp.js) exposing the four ACP tools; at session start the shell resolves a proxy — env BILI_MCP_PROXY > the live-instance record (any lane's proxy or a bili start daemon) > the 8787 user-zone default (#1660 removed the install-time origin bake, #403) — nothing reachable → tools/list fails with -32003. So: start bili first (bili start or any client's lane proxy), export HTTPS_PROXY yourself if you also want compression, or use bili codex for the zero-config full posture. Mechanics: CLIENTS.md.
  • claude has a native posture (#964): managed settings block + SessionStart hook + MCP shell; the hook rides the self-managed port zone (#1660) and re-pins the managed URL to the live origin each session, so port drift self-heals. Opt out with BILI_NATIVE_CLAUDE=0 (passthrough). Mechanics: TECHNICAL-NOTES.md. Known limitation (#2290): the Claude Desktop app's Code tab (CLAUDE_CODE_ENTRYPOINT=claude-desktop) sets its own ANTHROPIC_BASE_URL on its embedded Claude Code, overriding the managed one — desktop sessions bypass the proxy entirely while the managed block's DISABLE_AUTO_COMPACT=1 still applies, so they get neither bili compression nor native auto-compaction. The hook warns loudly at session start (and records it for bili doctor, which also flags machines where Claude Desktop is installed alongside the native lane); terminal sessions are unaffected. Field-tested 2026-10-06 (#2290): putting HTTPS_PROXY in the settings env block produced zero CONNECT traffic to a live MITM-enabled proxy on Claude Desktop 2.19675.1 / embedded CC 2.1.288 (Windows 11) — the variable reaches no network stack there, consistent with the CLI finding that CC's undici ignores proxy env vars (why bili claude uses the /bili/ base-URL rewrite instead). As of that version there is no usable routing seam on the desktop Code tab; the lane stays tracked in #2290 in case upstream changes behavior. Desktop-only users can restore native auto-compact with bili plugin remove claude.
  • zcode has a native posture (#1145): managed ~/.zcode/cli/config.json block + per-session provider baseURL rewrite. Full mechanics: CLIENTS.md.
  • jcode and aider have no native mode (no plugin/MCP/tool-injection seam: #962, #1048) — use bili jcode / bili aider.
  • copilot, amp and goose are launcher-only (#1049); goose cannot be cert-MITMed (rustls trusts no CA file) and rides plain-HTTP base-URL redirects instead.

Option 2 — Launcher (bili pi / bili codex / bili claude / bili omp / bili opencode / bili hermes / bili dsh / bili codebuddy / bili qoder / bili trae / bili jcode / bili kimi / bili gemini / bili iflow / bili qwen / bili antigravity / bili mcode / bili aider / bili copilot / bili amp / bili goose)

The launcher wraps a client in one command: it starts a proxy on an independent port (a fresh instance is always spawned — a port is never reused), then points the client at it — certificate-based MITM where the client honors proxy/CA env vars, or an isolated /bili/ config rewrite where it doesn't. No real config file is ever edited; the client's own config is READ to discover which HTTPS upstream hosts it talks to, and those hosts are whitelisted for MITM so the proxy can TLS-terminate exactly them and blind-tunnel everything else.

bili pi                               # launch pi through the proxy — file-free (#535): env + extension registerProvider, real ~/.pi untouched
bili codex                            # launch codex through the proxy
bili claude                           # launch claude through the proxy
bili omp                              # pi-style, file-free (#535): env + extension registerProvider + compaction cancel, real ~/.omp untouched
bili opencode                         # OpenCode (1.x & 2.x): full guide in the [OpenCode](CLIENTS.md#opencode) section below
bili hermes                           # file-free (#535): hermes proxy env (HTTPS_PROXY + combined CA bundle via SSL_CERT_FILE) — https via CONNECT MITM, http via absolute-form forward proxy; real ~/.hermes untouched
bili dsh                              # deepseek-harness: full native plugin injected via --patch (#941) — real dsh tools, session-bound /acp + /acp-cache (plugin mode); non-loopback upstreams ride proxy envs, loopback keeps the overlay DSH_HOME rewrite (#535); dsh auto-compaction off outside web profiles, and switchable off there via a profile-level full-snapshot override of preset-standard (#1772/#2474)
bili codebuddy                        # Tencent CodeBuddy Code CLI: CODEBUDDY_BASE_URL /bili/ rewrite (OpenAI chat completions wire), budget aligned via CODEBUDDY_AUTO_COMPACT_WINDOW; real ~/.codebuddy untouched
bili qoder                            # qoder: model endpoint is hardcoded https (no /bili/ rewrite possible) — cert-MITM via HTTPS_PROXY + NODE_EXTRA_CA_CERTS, default model hosts whitelisted (#653)
bili trae                             # Trae CLI (ByteDance, closed Go binary, no base-URL override) — cert-MITM via HTTPS_PROXY + SSL_CERT_FILE, model host from TRAE_CLI_API_HOST or the default enterprise gateway (#655)
bili jcode                            # jcode (Rust agent harness) — env-only cert-MITM launch: HTTPS_PROXY + SSL_CERT_FILE, model host api.z.ai whitelisted, local loopback providers stay direct via NO_PROXY
bili kimi                             # Kimi Code CLI (Moonshot): standard proxy envs except an unconditional loopback bypass — https via cert-MITM, http via absolute-form forward proxy; loopback endpoints inventoried with a manual /bili/ hint (#757)
bili gemini                           # Gemini CLI (Google): GOOGLE_GEMINI_BASE_URL /bili/ rewrite to generativelanguage.googleapis.com (Google native wire), real ~/.gemini untouched
bili iflow                            # iFlow CLI: IFLOW_BASE_URL /bili/ rewrite to apis.iflow.cn/v1 (OpenAI chat-completions wire), real ~/.iflow untouched
bili qwen                             # Qwen Code (multi-protocol gemini-cli fork, no base-URL hook): cert-MITM via HTTPS_PROXY + NODE_EXTRA_CA_CERTS, default DashScope/Qwen model hosts whitelisted, custom relays via --mitm-domain
bili antigravity                      # Antigravity CLI (agy, Google): CLOUD_CODE_URL /bili/ rewrite of cloudcode-pa.googleapis.com (undocumented language-server env override, v2.19.1 binary-verified); wire recognized as Google native by path (#2115)
bili mcode                            # MiniMax Code CLI: same shape as kimi (proxy envs, unconditional loopback bypass, cert-MITM/absolute-form); session bound via X-Mavis-Session-Id (#1050)
bili aider                            # Aider (Python pair programmer): cert-MITM via HTTPS_PROXY + SSL_CERT_FILE/REQUESTS_CA_BUNDLE; endpoint from OPENAI_API_BASE / ANTHROPIC_BASE_URL / --openai-api-base / .aider.conf.yml (#1048)
bili copilot                          # Copilot CLI (GitHub, closed Go binary) — cert-MITM via HTTPS_PROXY + SSL_CERT_FILE, api.githubcopilot.com + per-plan subdomains whitelisted (#1049)
bili amp                              # Amp CLI (Sourcegraph, closed Go binary) — cert-MITM via HTTPS_PROXY + SSL_CERT_FILE, ampcode.com whitelisted (#1049)
bili goose                            # Goose (Block, Rust/reqwest): rustls release builds trust no CA file — openai/anthropic legs via OPENAI_HOST/ANTHROPIC_HOST, custom providers via a regenerated GOOSE_PATH_ROOT overlay (/bili/ rewrites, real config untouched) (#1049)
bili pi --mitm-domain api.foo.com     # add a domain to the MITM whitelist

Option 3 — URL change (/bili/ prefix)

Start the proxy:

bili

Then just prefix your client's existing baseURL with http://localhost:8787/bili/. The full upstream URL is embedded in the path, so the proxy knows where to forward without any config:

client baseURL before:  https://api.openai.com/v1
client baseURL after:   http://localhost:8787/bili/https://api.openai.com/v1

For more per-client configuration examples, see the web UI guide at http://localhost:8787.

Verify. With the proxy running and your config saved, check it answers and that your first real request shows compression activity in the log:

# Health check (proxy up + where it forwards)
curl -s http://localhost:8787/__bili/health
# → {"ok":true,"upstream":"https://api.anthropic.com"}

# Live session stats (after a real request)
curl -s http://localhost:8787/__bili/stats

Then send one message from your client and watch the log (~/.local/state/billion-context/bili.log, also printed to stderr). You should see a processTurn line per request, and once the conversation grows, [acp-usage] round N input=X cached=Y (cache hit Z%) + a compress event.

Client deep dives

Everything that doesn't fit in one Quickstart line — how each client's lanes attach, what gets written where, and known limitations — lives in CLIENTS.md: dsh · Kimi Code · Hermes · ZCode · Gemini family (Gemini CLI / iFlow CLI / Qwen Code / Antigravity) · cert-MITM clients that never compress (CONNECT blind tunnels, #897) · unrecognized endpoints going direct (#1290) · OpenCode (launcher / native / pure proxy, /acp status & rules, legacy opencode-acp sessions #920).

FAQ

How do I check my cache hit rate? Don't dig through logs — /acp-cache prints a text summary report right in the client, headed by a clickable Web UI link: open it for the web version of the session page — the cache hit-rate line chart plus per-break attribution:

web session page: cache hit-rate chart + attribution The report has four blocks that pin things down at a glance: GRAND LEDGER (totals + hit% with an explicit HEALTHY verdict; misses decomposed into new content / compress re-pay / upstream-ttl-or-client-rewrite) · FOLD ECONOMICS (per-fold economics: net tokens saved, paid-back verdicts) · LINE ITEMS (anomalies only: hit<85% or miss≥5000). Rule of thumb: compression itself costs ≤2% — a healthy session sits at 95–97%. When you see less, the attribution tells you which of the usual suspects it was, in this order: ① upstream cache TTL expiry (shows up as stable-prefix misses — the top-spikes line names idle times), ② a model switch, ③ a bili bug (report it with the page attached), ④ other/unknown. /acp-cache [full] lists every fold & line; same report over Since #1535 the report ends with a MODEL SWITCHES section: a mid-session model change invalidates the provider's prefix cache, so the whole stable prefix is re-billed on the next request — each switch's unexplained residual (its ttl bucket minus new content) is charged to the switch instead of masquerading as TTL expiry; per-event from → to, hit %, and attributed tokens are listed (full lists every event, the summary the last 8), and the web sessions table gains a matching model-switch column. Since #2131 the same machinery fingerprints the outbound credential (a 12-hex sha256 of the authorization/x-api-key-family headers — the raw key is never stored) and attributes a key switch — the relay behind a stable URL rotated to a different account — in a dedicated KEY SWITCHES section, a key switch: line in CACHE INVALIDATION, and a 🔑 badge in the web sessions column. HTTP: GET /__bili/cache-report; the raw per-request [acp-usage] lines still land in the log file for deep dives.

What does /acp show? In clients with the native plugin (opencode, dsh), /acp renders the ACP status panel of the current conversation straight from the proxy (session, blocks, compressible ranges, usage); before the first model request it shows an idle notice instead. /acp-cache [full] prints the cache report above.

Can I query sessions and config over the web? Yes — open http://localhost:8787: an overview dashboard, session list with per-session detail, live logs, a config editor, and an upstream connectivity test. Everything is also plain JSON for scripting (/__bili/stats, /__bili/sessions, /__bili/config, …).

When does compression happen? It is model-driven: the injected context tools are called by the model as context grows, gentle growth nudges (~50K-token steps by design, adjustable via compress.nudgeGrowthTokens) prompt it along the way, and preflight fires as a hard backstop when the input alone exceeds the window (#470). Watch it live with /acp or the web UI.

Why does the first compaction wait until ~200k? Compaction does not trigger on absolute window position but on growth intervals: by default the first soft compaction fires 50k tokens past the boot content (compress.nudgeGrowthTokens, flat and window-independent). With a boot around 100k — or with the growth step set to ~100k — the first compaction may wait until ~200k. To make it fire earlier: 1) trim the system prompt, disable unneeded tools, prune skills; 2) lower compress.nudgeGrowthTokens to ~50k; 3) enable lean mode. Worked example in CONFIGURATION.md.

Is bili transparent? How do I turn it off? Unrecognized endpoints forward unchanged (CLIENTS.md), and every mode reverses cleanly: bili plugin remove <client> for native installs, stop using the launcher command / env vars / /bili/ prefix for the other two — traffic goes direct again immediately.

Where are logs and session data stored? Log: ~/.local/state/billion-context/bili.log (also mirrored to stderr); session state: ~/.local/share/billion-context/ (XDG-overridable; Windows AV exclusion #362, opt-in cleanup #1082) — full paths in CONFIGURATION.md.

Running the proxy

Flags

bili --port 9000              # change listen port
bili --host 0.0.0.0           # listen on all interfaces (see host note below)
bili --debug                 # verbose logging (also: set "debug": true in config)
bili --passthrough           # forward without compression (smoke-test mode)
bili --config ~/my-bili.json # use a different config file
bili update                  # check & install a newer version now (bypasses throttle)
bili --no-auto-update        # disable self-update for this run
bili --auto-restart-on-update   # self-restart when a new version is installed (default off)

Flags override env vars and the config file. bili --help lists them all.

Remote agents (--host)

By default the proxy binds 127.0.0.1 and only accepts loopback connections. To serve agents on other machines: bili --host 0.0.0.0 (or your LAN IP); remote agents point their model baseURL at http://<this-host>:<port>/bili/….

  • MITM-mode CONNECT then also accepts remote clients — for whitelisted model hosts only. Blind tunnels to arbitrary hosts stay loopback-only, so the proxy can never be used as an open relay.
  • /bili/<absolute-url> destination admission (#409): the proxy itself and link-local/metadata addresses are always denied; loopback/private destinations are allowed for local clients (self-hosted upstreams) and denied for remote clients unless listed in BILI_TUNNEL_ALLOWED_HOSTS (host or host:port, comma-separated). One exception (#1073): a local client relaying a management path (/__bili/*, /__acp/*) to a loopback IP-literal destination is forwarded unmarked; remote peers and hostname destinations keep the internal tunnel marker unconditionally, and management paths stay unreachable through the tunnel even via NAT hairpin. An absolute-form request addressed to the instance's own endpoint on a management path is served locally instead of tunneled (a forward-proxy-style health probe gets a real answer).
  • There is no authentication: only do this on a trusted LAN or behind a firewall. The /__bili/ management endpoints remain loopback-only. A startup [security] warning reminds you of the above.

Debugging

bili --debug (or env ACP_DEBUG=1, or "debug": true in config — flag > env > config) logs every processTurn (tag counts, token usage), the nudge decision (growth/usage/pendingT1/shouldInject), client headers, and SSE rewrites.

Log file

All logs tee to ~/.local/state/billion-context/bili.log by default (XDG state dir) and still print to stderr. Override with "logFile" in config or ACP_LOG_FILE (off disables the file). Auto-rotates at 10 MB (bili.log.old). Per-request cache-hit stats log as [acp-usage] round N input=X cached=Y (cache hit Z%) so you can measure prefix-cache health directly from the log.

Connection lifecycle tuning (#1982)

Client-facing connections close gracefully after the final response: when the proxy initiates the close (Connection: close), it waits up to BILI_POST_RESPONSE_LINGER_MS (default 5000) for the client's close signal before releasing the socket, so pooled clients see a clean EOF instead of a possible RST from racing bytes. Related knobs: BILI_KEEP_ALIVE_TIMEOUT_MS (idle-reap budget, default 5000) and BILI_CLIENT_ERROR_BACKSTOP_MS (terminal backstop for the error-drain path, default 30000) — full semantics in CONFIGURATION.md.

Self-update

The proxy checks npm on startup and every 3 minutes; a newer version is installed in place and a notice is logged — restart bili to pick it up, unless you enable opt-in self-restart (--auto-restart-on-update flag, env ACP_AUTO_RESTART_ON_UPDATE=1, or "autoRestartOnUpdate": true in config — default OFF): with zero in-flight requests it verifies the new install, stops accepting connections, drains, spawns a replacement on the same port, and exits once it accepts connections (clients reconnect automatically; session state survives on disk). Safety gates: zero in-flight through the drain window, an install sanity check before re-exec, and a 10-minute cooldown marker so a flapping version can never loop-restart; any failure resumes the original listener and falls back to the plain reminder.

While the running process is behind the on-disk install ("stale"), the web UI shows a banner (running vs installed version, auto-restart state) and GET /__bili/status returns {version, diskVersion, stale, autoRestartOnUpdate, advisory, inFlight} for scripting (advisory is the active critical-defect entry or null, see below). Disable permanently via "autoUpdate": false in config or ACP_AUTO_UPDATE=0.

In plugin mode (bili opencode / bili pi / bili dsh — the proxy runs embedded in a long-lived host), "restart bili" means restarting the host: the embedded process cannot exit on its own, so a host left open keeps serving whatever code it started with, silently missing every fix auto-update reports as installed (#1603). Enable --auto-restart-on-update to have it self-restart at a safe point, or run /acp (OpenCode hosts today — pi/dsh coverage tracked in #2084) — the status panel appends a one-line staleness warning (running vs installed version) whenever the on-disk install is ahead of the live process.

Update visibility is silent by default since v0.1.183 (#1977): routine/recommended releases no longer render an update line on the /acp panel footer or in acp_status — only a critical-tier release surfaces there (CRITICAL UPDATE READY/AVAILABLE). The standing ways to check an installed-but-not-restarted release are the stale cues above: web UI banner, the /acp one-line warning, and GET /__bili/status. Deliberately no always-on nag; the advisory channel (#1481) remains the only auto-visible critical path.

When an install keeps failing (unwritable or host-managed dir, network error, …), auto-update no longer re-downloads and retries on every 3-minute cycle forever. After three consecutive failures it backs off exponentially (5 min → 10 → 20 …, capped at 6 h), logs a one-time actionable hint (fix permissions / npm prefix, reinstall user-level, or disable via "autoUpdate": false / ACP_AUTO_UPDATE=0), and logs nothing further about the failure while cooling down (no download, no retry line); it resumes as soon as the failure clears or a different version is targeted (#1603).

The same bounded retry now covers the owner-managed lanes the global self-update drives instead of writing the copy itself — the dsh desktop in-place copy, the dsh profile bundles, and pi's npm copy (#2192). Each lane keeps its own failure streak keyed by lane + target version, so a persistently broken desktop layout no longer re-downloads the full tarball every cycle (up to ~480 downloads/day per affected machine before the fix); three strikes arms the same exponential cooldown, and the one-time hint names the failing lane and its manual fix (dsh plugin --profile <name> add …, pi update --extension …, or recreate the desktop profile). Host-managed instances additionally check on their own slower cadence — 30 minutes plus up to 15 minutes of jitter, tracked under a separate throttle marker — instead of consuming the global 3-minute budget. Failure streaks are shared across every bili process on the machine through a small state file in the cache dir (.install-backoff.json), so several running instances don't each burn their own retry budget; a clean bili plugin update disarms the dsh profile lane immediately. The file is written atomically (tmp+rename) and every writer merges with what is already on disk, so concurrent instances cooperate instead of overwriting each other's streaks; long-lived processes re-read it when it changes, so a manual disarm by one copy is visible to the others on their next check. It is fail-safe in the retry direction — a corrupt file or jumped clock is dropped, never allowed to silence a lane for long. bili plugin update clears the dsh-profile lane's key; a repaired desktop lane clears its own key on its next successful in-place refresh.

Critical-defect advisories (forced updates)

Independent of auto-update (#1481): even with autoUpdate off, the proxy polls a small companion npm package (billion-context-advisories, published by CI from this repo's advisories/ directory) on the same 3-minute cadence. Each advisory names a semver range of broken versions (affected), the exact version to install (target — which may be older than the current one, i.e. a rollback), and a user-facing reason. When the local version falls inside affected, bili force-installs target through the self-updater's full safety chain (cross-process lock, backup + verify + rollback; source checkouts and host-managed installs are refused with manual instructions instead) and warns prominently: a one-time [advisory] ⚠️ … log line per process per advisory id, a banner on the web UI showing the reason and the exact manual upgrade command, and the active entry under advisory in /__bili/status. The check is fail-open by design: an unreachable or malformed advisory source only produces a warning — model traffic is never blocked by it. Disable via config ("advisoryCheck": false) or env (BILI_ADVISORY_CHECK=0); point at a custom document with "advisoryUrl" / BILI_ADVISORY_URL.

Configuration

The full configuration reference — config file location, top-level keys, providers, compression tuning, environment variables — lives in CONFIGURATION.md.

Config file

One JSON document at ~/.config/billion-context/billion-context.json ($XDG_CONFIG_HOME/billion-context/; override the path with BILI_CONFIG_FILE). Precedence when several sources set the same knob: CLI flag (where one exists) > env var > config file > built-in default — every env var keeps working as the override tier.

What's inside (details in CONFIGURATION.md):

  • providers — per-provider routing table: upstream override, model context windows, per-provider/model compress tuning, wire-protocol declaration, compaction opt-in.
  • compress — three-level compression tuning (global → provider → model): thresholds, nudge cadence, preservation rules, prompts, tiers.
  • Server-level blocks — process-wide behavior, including the #2030 additions: network (timeouts / retry / keep-alive / preflight cadence), persist (session persistence format + tail), sessions (cap + GC policy), update (registry mirror + check interval), diagnostics (dumps, render-tag mode, injection switches), fakeCompletion, plus scalars codexCompact / ccrRetrievalTtlMs / decompressTmpCap and extensions mitm.handshakeTimeoutMs, compat.noCacheControl, compat.keepResponseId.

Minimal example:

{
  "network": { "upstreamTimeoutMs": 900000 },
  "persist": { "zstd": true },
  "sessions": { "gc": { "enabled": true, "maxAgeDays": 14 } }
}

Knobs people look for first:

  • Upstream proxy (firewall/GFW) — routing the proxy's own outbound traffic through v2rayA/clash: full resolution order, empty-string = explicit direct, SOCKS5 rejection, both egress paths, and the mitm:// vs https:// key schemes live in CONFIGURATION.md (Server Settings → proxy; Providers → key schemes).
  • Wire-compat role rewrite (compat.roles) — an upstream that rejects the developer role? Covered by CONFIGURATION.md (Server Settings → compat) — including the learn-on-failure auto-fix that needs no configuration at all.
  • Signed upstreams (body-covering signatures) — a gateway whose requests carry a body-covering signature (CodeArts APIG's SDK-HMAC-SHA256, or gateway-invented headers like x-ofm-signature): the built-in scheme re-signs transparently on dsh; every other detected scheme is ALWAYS refused locally — signed requests are either re-signed+compressed or refused, never passed through unsigned — and bili keeps reminding at startup and in the web UI until it ships the scheme's re-signer (#1884/#2090). Detection rules, per-scheme overrides, and BILI_RESIGN / BILI_RESIGN_PASSTHROUGH / BILI_CODEARTS_REF live in CONFIGURATION.md (Server Settings → resign).

Pi built-in subagents

Using bili pi or the native pi plugin (bili plugin install pi) includes built-in subagent support, enabled by default: acp_delegate, acp_delegate_wait, and acp_delegate_cancel. This additional tool surface is specific to pi.

Keep only one subagent implementation enabled. If you use the built-in support, remove or disable other pi subagent plugins (for example, pi-subagents or a separately installed billion-context-pi-subagents) in both user and project settings to avoid overlapping tools, prompts, or behavior. If you prefer another subagent plugin, disable the built-in support instead. A project-scope pi-subagents install makes the built-in delegate stand down by default, but a user-scope-only install does not; do not rely on that guard for every installation.

To disable the built-in subagents while keeping context compression, merge this into ~/.config/billion-context/billion-context.json (or the file selected by BILI_CONFIG_FILE), preserving your other settings:

{
  "pi": {
    "subagents": false
  }
}

Restart pi and start a new session for the change to take effect. This disables the three delegate tools, their system-prompt section, and the fleet keyboard shortcut; context compression remains enabled. It does not disable independently installed subagent plugins. More options: subagent configuration.

How sessions work

The proxy keys compression state on the conversation value the client itself provides, verbatim (src/session-id.ts) — no hashing, no protocol/upstream/API-key dimensions (those mutate mid-conversation and orphaned state exactly when users kept talking, #280/#286). The id stays inside the proxy (state store, persistence, UI label); it is never sent upstream.

Where the value comes from, first hit wins: the plugin's x-bili-plugin-conversation (honored only alongside the x-bili-plugin marker header), then per-client headers (x-claude-code-session-id, x-grok-session-id/x-grok-conv-id, x-mavis-session-id), then generic headers (x-session-affinity, x-acp-session, x-session-id, x-opencode-session, session-id/session_id), then body fields: session_id / metadata.session_id on the Responses wire, and prompt_cache_key promoted over the content-fingerprint fallback on the Responses/OpenAI/Anthropic wires.

Client Sends conversation id? Source
Codex ✅ yes body.session_id / turn-metadata thread id
OpenCode ✅ yes x-session-affinity / x-opencode-session header (ses_…)
Claude Code ✅ yes x-claude-code-session-id header
omp (via plugin) ✅ yes prompt_cache_key promoted over any fingerprint (#268)
pi (bare) ❌ no nothing → anonymous prefix affinity below

Header-less clients (pi-like): anonymous prefix affinity. With no conversation signal at all, the proxy resolves the session from the replayed history itself (src/prefix-affinity.ts, #309): a request reattaches to a stored session only when its history reproduces that session's message chain byte-exactly from position 0; otherwise it gets its own deterministic pfa-… session. Consequences (#1262): a resumed conversation reattaches to its own session (even after a proxy restart, #499); a new task with an identical opener does NOT inherit another conversation's blocks — it mints a fresh, fully separate session; a request with no usable signal at all gets an explicit 400 instead of silently colliding.

Design record and threat model: SESSION-IDENTITY.md. The message-granularity sibling (why identity is content-derived, not an assigned id) is MESSAGE-IDENTITY.md.

For upstream sticky-routing, the proxy forwards only identity values the client already supplied (e.g. a body session_id is forwarded upstream as x-session-id); it never synthesizes one itself.

Recommendation: explicit-id clients are safe to run concurrently. For header-less multi-agent use, prefer the client plugin (stamps a stable id per conversation) or pass an explicit x-acp-session header — otherwise prefix affinity still keeps distinct tasks apart (a diverged fork costs one raw resend plus a compression-ladder restart).

Derived (child) sessions inherit the parent's compressed context (#1333, #1362)

A child session (subagent/fork starting from an empty history) reports its lineage at birth — its identity registration carries parentConversationId and the proxy records a read-only derivedFrom link — so decompress / search_context fall back along the parent chain for content the child never saw itself (cycle-guarded, depth cap 8). Nothing is copied into the child, the parent is never modified; if the parent is unknown the child simply starts fresh. Per-lane parent signals (pi/omp parentSession header, OpenCode V1/V2 parentID): SESSION-IDENTITY.md. claude/codex/dsh need nothing here: they share one session id across subagents or have no child-session concept at all.

Windows: exclude the sessions dir from antivirus (#362)

The proxy rewrites each session's state file every turn of a long session; on Windows, real-time AV (Defender), the search indexer, or a sync tool (OneDrive) can lock the sessions dir mid-write, so persists fail with EPERM until the lock clears. Fix at the root: add %USERPROFILE%\.local\share\billion-context\ to your antivirus exclusions (Defender steps included) and keep sync tools off that path — CONFIGURATION.md.

Session file cleanup (#1082)

Short-lived sessions leave small state files behind that are never resumed. Cleanup is opt-in (BILI_SESSION_GC=1; off by default — session files are user data, no silent deletion policy): when enabled, bili sweeps the sessions dir at boot and hourly and deletes a file only when BOTH hold — older than BILI_SESSION_GC_MAX_AGE_DAYS (default 7 days) AND never compressed with its newest request body ≤ BILI_SESSION_GC_MAX_TOKENS tokens (default 1M) — so deletion loses nothing but bytes. CCR content stores follow their session file's lifecycle; compressed sessions are never deleted; every deletion is audit-logged. Full policy: CONFIGURATION.md.

Status

Early. Protocol handling and compression work against mock tests (500+ passing). Real-model integration testing is the next milestone. Expect rough edges.

Client-side plugins for pi / omp / opencode ship inside billion-context (dist/agent/*.js) for the cooperative-proxy path. See the "Which do I need?" section above for how billion-context, the standalone billion-context-pi, and opencode-acp relate.

Attribution requirement (one term on top of MIT)

This project is MIT-licensed plus one additional term: any product or service (commercial or open source) whose users can see or interact with it and which uses this software must attribute it — stating that it uses billion-context with a link back to this repository — on its home page, documentation, or About/Credits page. Pure server-side/embedded use satisfies this via shipped documentation. See the Additional Term at the end of LICENSE.

If you build on this project, we'd love to hear about it: open an issue (no obligation) so we can track where it's used.

License

MIT

View on GitHub

Recent activity

commits and pull requests

Releases and announcements

184 total
  1. v0.1.191v0.1.191Oct 10, 2026

    ## What's Changed * fix: route dsh title-gen requests through the side lane on dsh 0.2.1-alpha.2 (#2503) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2554 * feat: opt-in size/age retention for debug dump dirs (#2412) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2575 * fix: pi fork adoption — bounded snapshot diagnostics, seeding-evidence gate, pre-network wire gate by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2472 * fix: receipt fingerprint says full summary, steers search-before-decompress (#2544) by @YunzhouLi-hub in https://github.com/ranxianglei/billion-context/pull/2586 * fix(#2565): scrub unpaired surrogate escapes out of every outgoing body by @sorasoras in https://github.com/ranxianglei/billion-context/pull/2566 * feat: offline-auditability lines for window/metering/reconcile decisions (#2283) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2423 * fix: per-entry agent-providers intake — one refused entry no longer discards the report (#2585) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2590 * fix: 用 Codex 当前可用窗口替代过期的 272K 对齐回退 by @overFloweee in htt

  2. v0.1.190v0.1.190Oct 10, 2026

    ## What's Changed * fix: bind web canvas to color scheme so the embed face stays readable in dark theme (#2473) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2475 * feat: web notice for high-cost dsh auto-review plugin (#2462) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2466 * fix: honor Windows ProxyOverride mid-token wildcards (127.*, 192.168.*) in upstream bypass by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2505 * fix: keep unsigned thinking blocks out of client history on truncation re-fetch (#2501) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2516 * fix(#2500): route Claude Code WebSearch sub-requests through the side passthrough by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2508 * fix: anthropic proxy-mode round-2 preserves client cache_control (#2499) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2515 * fix: routed /bili/ recovery landing on the same origin retries instead of giving up (#2496) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2498 * fix: detect stream-mandating upstreams by 400 shape, n

  3. v0.1.189v0.1.189Oct 9, 2026

    ## What's Changed * feat: vendor billion-context-pi-subagents in-repo under pi-subagents/ (#2384) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2386 * docs: explain pi built-in subagents and how to disable them by @xiaozhu1337 in https://github.com/ranxianglei/billion-context/pull/2380 * fix: promptPack=lean actually reaches the proxy system prompt (kernel/packs) (#2335) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2337 * feat: model-decided nudge timing (compress.nudgeModelDecided) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2243 * fix: enforce the fold-anchor cap while building — no recompute-and-drop past 16K covered ids (#2334) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2338 * fix: scale-gate fake-completion detection and strip self-closing render tags (#2348) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2353 * fix: intrinsic termination gate for runaway enumeration (#2346) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2363 * fix: expose billed input in acp_status + two-way estimator calibration (#2366) by @ranxianglei in h

  4. v0.1.188v0.1.188Oct 8, 2026

    ## What's Changed * feat: Claude Code plugin marketplace entry — /plugin install billion-context@billion-context by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2312 * docs(#2146): neutral JSDoc on noteCompressLoopFailure (content scanners read source that agents open) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2319 * feat(pi): capability-aware proxy-style ACP channel for pi-subagents children (#2268) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2276 * fix: dsh settings panel follows the live proxy origin instead of freezing on the boot snapshot (#2288) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2289 * fix: dsh persona fingerprint parity for the Responses wire (#2203) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2232 * feat: 统一外部摘要模型、顺序故障转移与多客户端压缩接线 by @yingzhongshuoqi in https://github.com/ranxianglei/billion-context/pull/2167 * fix(#2308): preflight Responses summary extraction excludes reasoning items/parts by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2310 * fix: reject incomplete/failed Responses JSON summaries in preflight

  5. v0.1.187v0.1.187Oct 7, 2026

    ## What's Changed * fix(#2241): continuity-aware dsh persona anchor — model switches migrate the anchor instead of forking the main lane by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2247 * session self-heal: zombie plugin lanes degrade to proxy tools, idle nudges suppress, 524 summaries learn streaming (#2155) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2246 * fix: stop labeling first-party siblings as third-party compressors in conflict alarms by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2262 * fix(#2260): v0.1.186 review follow-ups — dsh spawn leak, inert resign keys named at config load, codex arg/TOML fixes, web pristine root, misc by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2263 * fix: wait for both disconnect-fault log lines before asserting (#2212) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2213 * fix: calibrate the output clamp's input estimate by learned per-route k̂ (#2122) by @ranxianglei in https://github.com/ranxianglei/billion-context/pull/2123 * feat: simhash chain-alignment adoption for anonymous affinity (#2265) by @ranxianglei in ht

Commits per week

last 52 weeks
5820Week of 2025-10-12: 0 commitsWeek of 2025-10-19: 0 commitsWeek of 2025-10-26: 0 commitsWeek of 2025-11-02: 0 commitsWeek of 2025-11-09: 0 commitsWeek of 2025-11-16: 0 commitsWeek of 2025-11-23: 0 commitsWeek of 2025-11-30: 0 commitsWeek of 2025-12-07: 0 commitsWeek of 2025-12-14: 0 commitsWeek of 2025-12-21: 0 commitsWeek of 2025-12-28: 0 commitsWeek of 2026-01-04: 0 commitsWeek of 2026-01-11: 0 commitsWeek of 2026-01-18: 0 commitsWeek of 2026-01-25: 0 commitsWeek of 2026-02-01: 0 commitsWeek of 2026-02-08: 0 commitsWeek of 2026-02-15: 0 commitsWeek of 2026-02-22: 0 commitsWeek of 2026-03-01: 0 commitsWeek of 2026-03-08: 0 commitsWeek of 2026-03-15: 0 commitsWeek of 2026-03-22: 0 commitsWeek of 2026-03-29: 0 commitsWeek of 2026-04-05: 0 commitsWeek of 2026-04-12: 0 commitsWeek of 2026-04-19: 0 commitsWeek of 2026-04-26: 0 commitsWeek of 2026-05-03: 0 commitsWeek of 2026-05-10: 0 commitsWeek of 2026-05-17: 0 commitsWeek of 2026-05-24: 0 commitsWeek of 2026-05-31: 0 commitsWeek of 2026-06-07: 0 commitsWeek of 2026-06-14: 0 commitsWeek of 2026-06-21: 0 commitsWeek of 2026-06-28: 0 commitsWeek of 2026-07-05: 0 commitsWeek of 2026-07-12: 0 commitsWeek of 2026-07-19: 0 commitsWeek of 2026-07-26: 0 commitsWeek of 2026-08-02: 108 commitsWeek of 2026-08-09: 197 commitsWeek of 2026-08-16: 57 commitsWeek of 2026-08-23: 174 commitsWeek of 2026-08-30: 123 commitsWeek of 2026-09-06: 148 commitsWeek of 2026-09-13: 257 commitsWeek of 2026-09-20: 357 commitsWeek of 2026-09-27: 479 commitsWeek of 2026-10-04: 582 commitsOct 12, 2025Oct 4, 2026
2.5K commits in the last 52 weeks.

When work happens

weekday and hour
SunMonTueWedThuFriSat036912151821Sun 0:00 — 8 commitsSun 1:00 — 8 commitsSun 2:00 — 4 commitsSun 3:00 — 2 commitsSun 4:00 — 4 commitsSun 5:00 — 1 commitsSun 6:00 — 2 commitsSun 7:00 — 1 commitsSun 8:00 — 10 commitsSun 9:00 — 15 commitsSun 10:00 — 13 commitsSun 11:00 — 12 commitsSun 12:00 — 31 commitsSun 13:00 — 22 commitsSun 14:00 — 21 commitsSun 15:00 — 20 commitsSun 16:00 — 19 commitsSun 17:00 — 12 commitsSun 18:00 — 22 commitsSun 19:00 — 22 commitsSun 20:00 — 35 commitsSun 21:00 — 26 commitsSun 22:00 — 34 commitsSun 23:00 — 18 commitsMon 0:00 — 13 commitsMon 1:00 — 18 commitsMon 2:00 — 10 commitsMon 3:00 — 5 commitsMon 4:00 — 2 commitsMon 5:00 — 1 commitsMon 6:00 — 0 commitsMon 7:00 — 2 commitsMon 8:00 — 6 commitsMon 9:00 — 24 commitsMon 10:00 — 17 commitsMon 11:00 — 10 commitsMon 12:00 — 6 commitsMon 13:00 — 16 commitsMon 14:00 — 12 commitsMon 15:00 — 6 commitsMon 16:00 — 21 commitsMon 17:00 — 11 commitsMon 18:00 — 26 commitsMon 19:00 — 21 commitsMon 20:00 — 16 commitsMon 21:00 — 14 commitsMon 22:00 — 16 commitsMon 23:00 — 41 commitsTue 0:00 — 27 commitsTue 1:00 — 25 commitsTue 2:00 — 12 commitsTue 3:00 — 3 commitsTue 4:00 — 0 commitsTue 5:00 — 0 commitsTue 6:00 — 0 commitsTue 7:00 — 2 commitsTue 8:00 — 10 commitsTue 9:00 — 15 commitsTue 10:00 — 16 commitsTue 11:00 — 11 commitsTue 12:00 — 11 commitsTue 13:00 — 21 commitsTue 14:00 — 17 commitsTue 15:00 — 15 commitsTue 16:00 — 20 commitsTue 17:00 — 15 commitsTue 18:00 — 33 commitsTue 19:00 — 14 commitsTue 20:00 — 16 commitsTue 21:00 — 27 commitsTue 22:00 — 17 commitsTue 23:00 — 26 commitsWed 0:00 — 24 commitsWed 1:00 — 23 commitsWed 2:00 — 4 commitsWed 3:00 — 0 commitsWed 4:00 — 1 commitsWed 5:00 — 2 commitsWed 6:00 — 0 commitsWed 7:00 — 3 commitsWed 8:00 — 7 commitsWed 9:00 — 21 commitsWed 10:00 — 10 commitsWed 11:00 — 11 commitsWed 12:00 — 17 commitsWed 13:00 — 16 commitsWed 14:00 — 18 commitsWed 15:00 — 7 commitsWed 16:00 — 12 commitsWed 17:00 — 11 commitsWed 18:00 — 20 commitsWed 19:00 — 21 commitsWed 20:00 — 24 commitsWed 21:00 — 21 commitsWed 22:00 — 24 commitsWed 23:00 — 29 commitsThu 0:00 — 31 commitsThu 1:00 — 32 commitsThu 2:00 — 10 commitsThu 3:00 — 9 commitsThu 4:00 — 5 commitsThu 5:00 — 1 commitsThu 6:00 — 1 commitsThu 7:00 — 1 commitsThu 8:00 — 8 commitsThu 9:00 — 23 commitsThu 10:00 — 22 commitsThu 11:00 — 14 commitsThu 12:00 — 14 commitsThu 13:00 — 15 commitsThu 14:00 — 7 commitsThu 15:00 — 8 commitsThu 16:00 — 12 commitsThu 17:00 — 22 commitsThu 18:00 — 30 commitsThu 19:00 — 16 commitsThu 20:00 — 11 commitsThu 21:00 — 16 commitsThu 22:00 — 26 commitsThu 23:00 — 40 commitsFri 0:00 — 31 commitsFri 1:00 — 9 commitsFri 2:00 — 1 commitsFri 3:00 — 9 commitsFri 4:00 — 0 commitsFri 5:00 — 1 commitsFri 6:00 — 0 commitsFri 7:00 — 2 commitsFri 8:00 — 2 commitsFri 9:00 — 16 commitsFri 10:00 — 19 commitsFri 11:00 — 12 commitsFri 12:00 — 12 commitsFri 13:00 — 15 commitsFri 14:00 — 13 commitsFri 15:00 — 15 commitsFri 16:00 — 20 commitsFri 17:00 — 13 commitsFri 18:00 — 9 commitsFri 19:00 — 11 commitsFri 20:00 — 16 commitsFri 21:00 — 27 commitsFri 22:00 — 24 commitsFri 23:00 — 24 commitsSat 0:00 — 26 commitsSat 1:00 — 9 commitsSat 2:00 — 14 commitsSat 3:00 — 6 commitsSat 4:00 — 11 commitsSat 5:00 — 3 commitsSat 6:00 — 5 commitsSat 7:00 — 2 commitsSat 8:00 — 15 commitsSat 9:00 — 28 commitsSat 10:00 — 30 commitsSat 11:00 — 14 commitsSat 12:00 — 19 commitsSat 13:00 — 27 commitsSat 14:00 — 21 commitsSat 15:00 — 27 commitsSat 16:00 — 21 commitsSat 17:00 — 25 commitsSat 18:00 — 22 commitsSat 19:00 — 28 commitsSat 20:00 — 35 commitsSat 21:00 — 24 commitsSat 22:00 — 16 commitsSat 23:00 — 28 commits
Commit volume by weekday and hour (UTC). Larger dots mean more commits.

Who is committing

last 52 weeks
Maintainer commits1,960 (50%)
Community commits1,935 (50%)

3,895 commits in total over the last year.

DateListRankStars gained
Oct 19, 2026weekly#7+888
Oct 18, 2026weekly#7+888
Oct 17, 2026weekly#6+779
Oct 16, 2026weekly#5+659
Oct 12, 2026weekly#10+259
Oct 11, 2026weekly#10+259
Oct 10, 2026weekly#9+246
  • freeCodeCamp/freeCodeCamp

    freeCodeCamp.org's open-source codebase and curriculum. Learn math, programming, and computer science for free.

    457.8K stars · TypeScript

  • openclaw/openclaw

    The AI that really does things. Any OS. Any Platform. The lobster way. 🦞

    392.8K stars · TypeScript

  • morluto/rea

    Reverse engineer anything with agents, from app behavior down to native binaries.

    369.7K stars · TypeScript

  • anomalyco/opencode

    The open source coding agent.

    220.4K stars · TypeScript

  • n8n-io/n8n

    Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.

    208.4K stars · TypeScript

  • firecrawl/firecrawl

    Supercharge your AI agents with data from the web and beyond. Building the library for superintelligence. 🔥

    194.5K stars · TypeScript