bonsai

Context management

bonsai treats the context window as a managed budget: cache-stable prefixes, token estimation per provider family, continuous garbage collection, graduated compaction, and default-on task episodes that archive finished work into compact, recallable cards. /ctx shows exactly where the window is going and gives you manual control.

How context is assembled

The system message is: static persona prompt + a project context block + optional operator suffix. Project context is split deliberately:

Connections with rolling-history caching (and Codex always) instead receive volatile state appended to history, keeping the entire prefix append-only. Memory is deliberately not in the system prompt — recalled entries arrive as per-turn background data notes.

Token accounting

A per-model estimator drives context-pressure decisions (billing truth stays with provider-reported usage): local tiktoken or Qwen tokenizers, the Anthropic count_tokens API, or a chars/4 heuristic — each tagged with a confidence. Over-budget bails only trust high-confidence estimates; image payloads are redacted before counting. See Models.

Thresholds (percent of usable window = budget − a 16k output reserve):

Trigger Default Smol
Continuous GC reclaim 75% 35%
Automatic compaction 95% 50%
Compaction target 50% 35%

Continuous GC

Every turn, existing stubs are re-asserted and pinned rows restored — byte-identically, so the provider prompt cache stays warm. Under pressure (the GC trigger), a reclaim pass introduces new stubs for:

Every rewrite must pay for itself: new stubs require ≥8,000 tokens or ≥8% saved (rewriting history invalidates the provider cache, so small savings are worse than nothing). Stubbed originals are restorable from /ctx.

Read reuse. A repeated read of unchanged content collapses to a compact pointer ([reused previous read]) instead of resending bytes — but an explicit re-request after that returns real bytes; reads are annotated, never withheld. Guards watch for pathological loops: repeated identical inspections, read storms on one target, repeated failed calls, and implementation stalls each get escalating nudges and, where warranted, a hard stop.

Compaction

When the automatic trigger fires (or you run /compact), a graduated draft is built:

Always protected: the system message, the last three message groups, the two latest user messages, and read-reuse pointer targets. Summaries carry a trust guard marking them lossy reference data. Every compaction records a telemetry event (tokens before/after, prefix hashes, cache impact) visible in /ctx.

/compact [preview] [target=<tokens>] [fallback|provider|deterministic] runs or previews one manually.

Task episodes

Enabled by default; BONSAI_EPISODES=0 is the emergency opt-out (zero tracking, byte-identical disabled tool arrays, no persistence).

Smol mode

/smol (or the Context row in /settings) switches to a compact profile for small models: lower compaction thresholds and reserve, a reduced system prompt (bash/terminal/todowrite/set_session_title tools), no repo map or built-in skill/subagent/memory indices, 2 KiB steering cap, deterministic compaction summaries only, and memory recall off.

/ctx

The context modal breaks the window down node by node with three views (ledger / wire / turns): token counts, inclusion state, stub reasons, compaction events, and episode reports, reconciled against actual provider usage. Keys in the ledger view: p pin (never GC), d drop, s stub, r restore, Enter/arrows expand. The header’s context chip (fill bar + percent) is the always-visible summary; click it to open /ctx.

Where this lives in the code

Concern Location
Preflight, thresholds, compaction src/agent/compaction/ (mod, draft, gc, summary)
Read evidence & reuse src/agent/read_persistence.rs, src/tool/read_evidence.rs
Episodes src/episode.rs, src/agent/episodes/
Project context block src/context.rs
Estimators src/provider/token.rs
Smol profile src/smol.rs, src/agent/controls/smol.rs
/ctx report & modal src/context_view/, src/tui/widgets/modal/context.rs