Context & Usage

API reference for Context, the dependency-injection container auto-injected into tools, and Usage, the per-run token and cost tracker.


Context is the dependency-injection container AgentRoute hands to your tools, and Usage is the cumulative token and cost record it carries. Neither is ever sent to the LLM — they live entirely on your side of the wire.

For the concepts and patterns behind these types, see Context & usage.

Context

Context — a dataclass passed to tools that ask for it. It carries your run-scoped dependencies (deps), the running Usage tally, the message transcript, loop state, and an optional handle to memory.

from agentroute import Context
from dataclasses import dataclass, field
from typing import Any
 
@dataclass
class Context:
    deps: Any = None
    usage: Usage = field(default_factory=Usage)
    messages: list[dict[str, Any]] = field(default_factory=list)
    retry: int = 0
    step: int = 0
    session_id: str | None = None
    memory: MemoryProto | None = None
ParameterTypeDefaultDescription
depsAnyNoneWhatever you passed as deps= to agent.run(...) / agent.arun(...). Your own dependency object — a database handle, an HTTP client, a settings bundle, a current-user record. AgentRoute never inspects it; it just hands it back to your tools.
usageUsageUsage()The cumulative token and cost tally for this run, accumulated across every model call. See Usage.
messageslist[dict[str, Any]][]The running transcript for the current run, in OpenAI-compatible message-dict form. Read it to inspect what the conversation looks like at the moment your tool fires.
retryint0The current retry count. Incremented when a Retry signal is raised from a tool or an output validator, up to agent.retries.
stepint0The current turn index in the agentic loop, starting at 0.
session_idstr | NoneNoneAn optional identifier for the session this run belongs to. Useful for correlating runs with persisted memory.
memoryMemoryProto | NoneNoneThe agent's memory backend, if one was attached via Agent(memory=...). Tools can call ctx.memory.remember(...) and ctx.memory.recall(...) through it.
Context is never sent to the LLM

Context exists purely on your side. It is not serialized into any prompt, and a parameter annotated Context is stripped from the model-visible tool schema — the model never knows it exists.

Auto-injection

If a tool's first parameter is annotated Context, AgentRoute injects the live context as that argument at call time. You do not pass it yourself, and it does not appear in the schema the model sees, so the model never supplies it.

weather.py
from agentroute import Agent, Context, tool
 
@tool
def lookup(ctx: Context, city: str) -> str:
    """Look up the weather for a city."""
    db = ctx.deps              # your injected dependency object
    return db.weather_for(city)
 
agent = Agent(name="meteorologist", model="claude-sonnet-4", tools=[lookup])
result = agent.run("What's the weather in Lisbon?", deps=my_db)

The model only sees a lookup(city: str) tool. The ctx parameter is filled in by the runtime.

Usage

Usage — a dataclass holding the cumulative token counts and cost for a single run. It lives at ctx.usage during a run and at result.usage afterwards.

from agentroute import Usage
from dataclasses import dataclass
 
@dataclass
class Usage:
    input_tokens: int = 0
    output_tokens: int = 0
    total_cost_usd: float = 0.0
    model_calls: int = 0
ParameterTypeDefaultDescription
input_tokensint0Total prompt tokens sent to the model across every call in the run.
output_tokensint0Total completion tokens received from the model across the run.
total_cost_usdfloat0.0Accumulated cost of the run in US dollars. This is the figure compared against Agent(max_cost=...).
model_callsint0Number of model completions made during the run — one per turn of the agentic loop.

add

Accumulate another Usage into this one, in place. AgentRoute calls this after each model completion to roll per-call usage into the run total; you can call it yourself to combine usage across runs.

def add(self, other: Usage) -> None: ...
ParameterTypeDefaultDescription
otherrequiredUsageThe usage record to add. Each field of other is added to the corresponding field of self.
ReturnsNone
Mutates self in place and returns nothing.

Examples

Reading usage after a run

from agentroute import Agent
 
agent = Agent(name="assistant", model="claude-sonnet-4")
result = agent.run("Summarize the plot of Hamlet in one sentence.")
 
print(result.output)
print(result.usage.input_tokens, "in /", result.usage.output_tokens, "out")
print(f"${result.usage.total_cost_usd:.6f} across {result.usage.model_calls} call(s)")
# Hamlet, a prince haunted by his father's murder, ...
# 412 in / 38 out
# $0.001650 across 1 call(s)

Inspecting usage from inside a tool

Because ctx.usage is the live, running tally, a tool can read it mid-run to make budget-aware decisions.

from agentroute import Agent, Context, tool
 
@tool
def expensive_lookup(ctx: Context, query: str) -> str:
    """Run a costly lookup, but bail if the run is already pricey."""
    if ctx.usage.total_cost_usd > 0.50:
        return "Budget nearly exhausted; skipping the expensive lookup."
    return run_lookup(query)
 
agent = Agent(name="researcher", model="claude-sonnet-4", tools=[expensive_lookup])

Combining usage across runs

from agentroute import Agent, Usage
 
agent = Agent(name="assistant", model="claude-sonnet-4")
 
total = Usage()
for prompt in ["Define entropy.", "Define enthalpy.", "Define enthalpy of fusion."]:
    result = agent.run(prompt)
    total.add(result.usage)
 
print(f"{total.model_calls} calls, ${total.total_cost_usd:.6f} total")

Passing dependencies through deps

from dataclasses import dataclass
from agentroute import Agent, Context, tool
 
@dataclass
class Deps:
    api_key: str
    http: object
 
@tool
def fetch_price(ctx: Context, ticker: str) -> str:
    """Fetch the latest price for a ticker symbol."""
    deps: Deps = ctx.deps
    return deps.http.get(f"/quote/{ticker}", key=deps.api_key).text
 
agent = Agent(name="quotes", model="claude-sonnet-4", tools=[fetch_price])
result = agent.run("What's AAPL trading at?", deps=Deps(api_key="...", http=my_client))

Source

context.py