Context Statistics API¶
Context statistics report an estimated token breakdown of the request a session would send: the system prompt, request-local instructions, tool definitions, skill text, conversation history, and media. They are meant for budgeting and for understanding which part of a request dominates.
These are estimates, not tokenizer counts
Values use the same heuristic as context compaction: roughly four characters per token for text, plus a size-based approximation for base64 media. Cached tokens, provider-specific framing, and attachment tokenization are approximate. Do not treat them as billed usage.
estimate_context_stats is a pure function over already-assembled inputs. The
Agent.context_stats(session_id) method assembles the same system prompt, tool
schemas, skill catalog, and persisted history the next text request would use,
without calling the provider or changing session state. Explicit $skill
activation text is request-local and never persisted, so an idle estimate does
not include it.
Components¶
Components always appear in a stable order with stable keys and labels, even
when their estimate is zero. Component estimates sum exactly to
total_tokens.
| Key | Label |
|---|---|
system_prompt |
System prompt |
instructions |
Request instructions |
tools |
Tool definitions |
skills |
Skills |
history_user |
Conversation history (user) |
history_assistant |
Conversation history (assistant) |
history_tool |
Conversation history (tool) |
history_other |
Conversation history (other) |
media |
Media and attachments |
Loaded skill bodies returned through the skill(name) tool are reported under
skills; their media (if any) remains under media.
Python¶
from pathlib import Path
from nagents import Agent, Provider, ProviderType, SessionManager
agent = Agent(
provider=Provider(ProviderType.OPENAI_COMPATIBLE, "sk-...", "gpt-4o"),
session_manager=SessionManager(Path("sessions.db")),
system_prompt="You are a helpful assistant.",
)
# ...after some runs...
stats = await agent.context_stats("session-123")
for component in stats.components:
print(f"{component.label}: {component.tokens}")
print(f"Total: {stats.total_tokens}")
if stats.context_window is not None:
print(f"Remaining: {stats.remaining_tokens} of {stats.context_window}")
if stats.observed_prompt_tokens is not None:
print(f"Last provider-reported input: {stats.observed_prompt_tokens}")
The model context window comes from
get_model_context_limit; it is None when the window is not
known. The window is reported only for reference and never changes model
behavior.
nagents.context_stats.ContextStats
dataclass
¶
Estimated breakdown of what a request carries.
Attributes:
| Name | Type | Description |
|---|---|---|
components |
tuple[ContextComponent, ...]
|
Stable, ordered components that sum to |
total_tokens |
int
|
Estimated input tokens for the assembled request. |
context_window |
int | None
|
Provider/model context window when known, else |
remaining_tokens |
int | None
|
|
observed_prompt_tokens |
int | None
|
Last provider-reported input tokens, when the agent has seen a real usage event for the session. |
observed_completion_tokens |
int | None
|
Last provider-reported output tokens. |
provider |
str
|
Provider identifier the estimate was computed for. |
model |
str
|
Model identifier the estimate was computed for. |
estimate_method |
str
|
Human-readable note describing the heuristic. |
Source code in src/nagents/context_stats.py
as_dict()
¶
Return a JSON-serializable mapping for HTTP or logging surfaces.
Source code in src/nagents/context_stats.py
component(key)
¶
Return the component with key, or None when it is absent.
nagents.context_stats.ContextComponent
dataclass
¶
nagents.estimate_context_stats(*, system_prompt='', instructions='', tools=(), skill_manifest='', skill_text='', messages=(), context_window=None, provider='', model='', observed=None)
¶
Estimate a request breakdown from its assembled inputs.
Callers pass the same values they would send to the provider: the system
prompt, request-local instructions, tool schemas, rendered skill text (the
catalog manifest and any loaded bodies), and the conversation history. Skill
tool results in messages are counted under skills instead of history.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system_prompt
|
str
|
The agent's base system prompt. |
''
|
instructions
|
str
|
Request-local instructions separable from the system prompt. |
''
|
tools
|
Sequence[ToolDefinition]
|
Tool definitions whose JSON schemas are sent to the provider. |
()
|
skill_manifest
|
str
|
Rendered available-skills catalog text. |
''
|
skill_text
|
str
|
Loaded skill body text included in the request. |
''
|
messages
|
Sequence[Message]
|
Conversation history, excluding the base system prompt. |
()
|
context_window
|
int | None
|
Known model context window, or |
None
|
provider
|
str
|
Provider identifier for reporting. |
''
|
model
|
str
|
Model identifier for reporting. |
''
|
observed
|
TokenUsage | None
|
Last real provider usage for comparison with the estimate. |
None
|
Source code in src/nagents/context_stats.py
nagents.estimate_tool_tokens(tools)
¶
Estimate tokens for the JSON tool schemas sent to the provider.
The neutral name/description/parameters payload is used for every
provider. Provider-specific wrapper keys add a constant, negligible overhead.