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;
- requested output reserve;
- 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.
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§
- 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).
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.