Prefer actual input tokens returned by the provider; use local estimates only when no measurement is available.
Accounting rules
For users and implementers: defines how the bottom Context panel reports actual totals, categorized content and differences that cannot be reconstructed directly.
01 · The result must answer three questions
Show system, tools, MCP, skills, memory and messages as mutually exclusive categories; never count them twice.
Show the positive difference between the measured total and categorized estimates as “Other context (estimated)”; do not hide it.
02 · A single snapshot
Read compacted rendered history, the latest system prompt and the frozen tool set.
Calculate message structure, tool schemas, Skills and Memory; subtract nested items from their parent categories.
Combine the latest measured total for the same HEAD and calculate the uncategorized difference.
Calculate the local breakdown only once per API response. The panel must not reread the dynamic tool registry within that response, or the categories and estimated may refer to different moments.
03 · Mutually exclusive categories
| Category | Source | Accuracy and boundaries |
|---|---|---|
| Messages | Rendered history; visible text, thinking, tool input/result and memory prefetch | Text can be reconstructed; original images that were not persisted contribute to the difference. |
| System prompt | The latest complete system prompt actually recorded | Calculate the full value first, then subtract Skills, resident Memory and the deferred catalog to avoid duplication. |
| Skills / Memory | Indexes and resident blocks actually injected into the system prompt | These are components of the System prompt and must not increase the total again. |
| System tools / MCP tools | Provider schemas for the tool set frozen for this turn | Assign each tool according to its _mcp_server to one of the two categories. |
| Deferred tools | Tool-name catalog within the system prompt | Count the name catalog actually sent, not the full descriptions/schemas. |
| Other context (estimated) | provider total - classified estimate | Includes content that cannot be reconstructed reliably: non-persisted images, provider wrapping overhead and temporary surface prompts. |
04 · Calculation rules
If local category estimates exceed the provider measurement, retain the provider total as the occupancy value and scale displayed categories down proportionally. The response retains raw estimates and the calibration factor; never display a negative difference.
05 · Acceptance criteria
- In the same response,
estimatedand the raw category total come from the same calculation. - When measured, displayed categories sum to
total_used; when estimated, they sum toinput_used. - After a branch switch or graph change, do not reuse the old provider measurement for the new HEAD.
- After a model switch, immediately use its context window and replace the old measurement with a fresh estimate for the current model. Use the new provider measurement after the next request completes.
- Tool input/result, thinking and memory prefetch affect Messages.
- App and Web consume the same
/api/sessions/{id}/contextcontract and do not estimate independently.
06 · Implementation evidence
system_prompt_node.py reads the actual system prompt by branch HEAD; tool_snapshot_node.py stores the frozen tools for the turn and their calculated cost.
session_stats.py handles categorization, deduplication and calibration against the provider total; budget.py estimates the frozen tool schemas.
tree.py calculates the breakdown once; App and Web use context-breakdown-panel.tsx to display the same response.
test_session_stats_accuracy.py Coverage includes structured messages, uncategorized differences, overestimate calibration, branch ancestry, old-snapshot compatibility, child Agents that do not advance HEAD, frozen tools, dynamic registries and model switches; all 51 focused Context tests passed.