Expand description
Task 29 — centralized request-aware context budgeting (spec §9.1).
The engine — not individual frontends — computes the effective context of the NEXT provider request from the segments that will actually be sent:
- actual effective system segments;
- exposed tool schemas;
- conversation history plus protocol framing;
- loaded skill and memory content;
and carves typed reserves out of the provider window before dispatch:
- reasoning/thinking reserve;
- next likely tool-result reserve;
- expected output reserve: what one round realistically produces
(
EXPECTED_RESPONSE_TOKENSon top of its thinking), bounded by the request’smax_tokens.max_tokensis a ceiling, not headroom the request needs (seeContextReserves::output_tokens); - a documented safety margin of
SAFETY_MARGIN_PERCENT(spec requires 10–15%).
Frontends consume ContextAssessment::should_compact — no per-frontend
token math is allowed on the trigger path (enforced by the phase 5
source-scan test).
§Estimation strategy
Provider tokenizers plug in through estimator_for_model when they are
available in-tree. None is today, so every model resolves to the
CONSERVATIVE estimator, which must never overstate remaining capacity:
- ASCII is charged at 1 token per 2.5 characters — the realistic BPE worst case for high-entropy ASCII (hashes, base64, minified JSON), and a deliberate ~1.6× overcount for English prose;
- non-ASCII is charged at 1 token per UTF-8 byte — the byte-fallback worst case, covering CJK (3 bytes/char), emoji scalars (4 bytes), and two-byte scripts without ever understating.
The estimator therefore errs toward EARLIER compaction, never toward provider exhaustion; the safety margin absorbs residual framing drift.
Structs§
- Context
Assessment - One request-aware budget assessment. Pure data — frontends read the decision, they never recompute it.
- Context
Breakdown - Typed per-segment usage accounting.
- Context
Budget Inputs - Everything the budget calculation needs about the NEXT request. Callers pass the segments they will actually send; the engine never guesses.
- Context
Reserves - Typed reserves carved out of the provider window before any context is admitted.
- Usage
Anchor - The provider-reported input of one request (
input + cache_read + cache_write), kept to measure the requests that follow it.
Enums§
- Thinking
Accounting - How a provider’s wire accounts reasoning/thinking tokens against the request’s output budget (I1, CP-12 review). The reserve model must count thinking exactly once, and provider differences are represented explicitly instead of being summed blindly.
- Token
Estimator - Token-estimation seam. Provider tokenizers register here per model when available; the conservative estimator is the mandatory fallback.
Constants§
- EXPECTED_
RESPONSE_ TOKENS - Visible output (text and tool calls) one round is expected to need on
top of its thinking. The output reserve is this plus the thinking reserve,
capped at the request’s
max_tokens(ContextBudgetInputs::max_output_tokens). - IMAGE_
TOKEN_ ESTIMATE - Flat charge per base64 image block. Anthropic bills ≈ w·h/750 tokens AFTER its 1568-px / ~1.15 MP downscale, so 1,600 is the per-image ceiling (Goose uses the same figure; gemini-cli uses 3,000; Codex subtracts the payload and adds a ~7 KB estimate). Serialized base64 at 2.5 chars/token would charge ~1.9 M tokens for a 3.5 MiB image and trip compaction every turn.
- MIN_
COMPACTION_ MESSAGES - Minimum history length before compaction is meaningful. A freshly compacted session (summary + acknowledgement) sits below this gate, which is what prevents recompaction loops without frontend-local bookkeeping.
- SAFETY_
MARGIN_ PERCENT - Documented pre-dispatch safety margin, as a percentage of the provider window (spec §9.1: target at least 10–15% reserved capacity).
- ZERO_
BUDGET_ THINKING_ RESERVE_ TOKENS - Thinking reserve for a zero thinking budget: the runtime’s adaptive
(“the model decides”) and off levels both carry 0, and the request builder
itself sends a zero budget as this tier on fixed-budget models
(
DEFAULT_LEGACY_ADAPTIVE_FALLBACK, the “high” tier). Reserving it for off errs toward earlier rollover by at most this much.
Functions§
- assess
- Compute the request-aware context assessment. This is THE budget
calculation —
Runtime::assess_contextand every frontend trigger path route through here. - conservative_
token_ estimate - Conservative token estimate for a text segment. See the module docs for the exact charging rule and why it never understates.
- estimator_
for_ model - Resolve the estimator for a model. No provider tokenizer crate is linked today, so every model — Anthropic, OpenAI, Google, unknown — uses the conservative estimator (spec §9.1: tokenizers where available, conservative estimators otherwise).
- thinking_
accounting_ for_ model - Resolve the thinking-accounting semantics for a model from its wire protocol. Unroutable models use the conservative separate-reserve model.