ADR 0047: Context usage inspector with exact and estimated token sources
- Status: Accepted
- Date: 2026-08-02
- Related: D103 · D183 · D184 · IPC protocol · Component spec
Context
The first context-usage ring exposed only a percentage and a small aggregate breakdown. It did not answer why a turn became large, which tool contributed the most context, or how quickly the model generated its output. The runtime already has provider usage, tool arguments/results, and a model stream timing anchor, but providers do not expose exact per-tool allocation.
Decision
- Replace the standalone ring with a compact Codex-style context inspector trigger. Hover and keyboard focus reveal one scrollable, non-modal panel.
- Keep provider-reported input/output/cache/reasoning usage authoritative and show aggregate output throughput as
outputTokens / responseDurationMson completed turns only; active streams do not render a live estimate. - Estimate each tool's argument and result footprint with the existing pi-agent-core token heuristic. Persist the estimate on the tool message, mark it as estimated in the UI, and never add it to the provider total.
- Carry
responseDurationMson assistant messages andtoolUsageon tool messages. AddtoolUsagetotool_endas an optional event field so live, persisted, and restored transcripts use the same values. - Preserve additive compatibility: missing fields use the renderer fallback estimate or omit throughput when no stream duration is available.
- Render the inspector panel through
document.bodyas a fixed viewport overlay. Measure the trigger and panel rectangles, choose the side with available space, clamp the result to a viewport margin, and update the placement on transcript scroll, window resize, or panel-size changes. Keep hover, focus, and Escape dismissal behavior independent from the transcript scroll container. - Aggregate repeated tool rows by their exact tool name, preserving the first-seen order. Each row shows the number of calls and sums argument, result, token, and known duration estimates across those calls.
- Resolve the context-window total from the same
pi-aimodel record that Electron passes to the agent sidecar, and enrich cached/discovered model rows with that value. Use provider metadata and the 128K default only when the selected model is absent from thepi-aicatalog.
Consequences
- Users can inspect exact model usage and see each tool type's relative context footprint without opening logs, while repeated calls stay compact and auditable through their call counts.
- Historical tool rows remain useful through a deterministic fallback estimate.
- Tool estimates are transparent but cannot claim billing precision.
- The transcript protocol and storage shape gain optional fields, while the existing protocol version remains compatible.
- The panel is no longer constrained by the transcript's overflow clipping or stacking context; collision-aware placement keeps its complete contents visible at viewport edges.
Alternatives
- Keep the ring-only UI: rejected because it hides the source of large turns.
- Claim exact per-tool provider usage: rejected because the provider response does not contain that attribution.
- Calculate throughput from wall-clock turn time: rejected because tool wait and provider wait would distort model generation speed.