Token Budget¶
Token budget controller — unified cost management and TOS-aware LLM routing.
Cluster: Uncategorised | Type: component | MCP Tools: 11
Overview¶
Drop-in LLMProtocol replacement with persistent budget tracking and TOS-aware routing. Wraps an inner LLMBlock and transparently routes requests to Codex, Claude Code, OpenRouter, or Ollama based on budget degradation level and task complexity.
Supports context compression when approaching token limits and provides a BudgetSnapshot for monitoring usage across all backends. The MCP surface also exposes budget_capabilities for read-only discovery of backend availability, TOS gates, OpenRouter model mapping, compression threshold, billing enforcement, degradation level, and public tool inventory.
When to use:
- Enforcing token budgets across multi-step agent workflows without modifying each step
- Automatically degrading from paid to local backends as budget is consumed
- Monitoring cumulative token usage and cost across Claude Code, Codex, and OpenRouter
Example:
from mvp.token_budget import TokenBudgetBlock
block = TokenBudgetBlock()
result = block.complete(
prompt="Explain the solver pipeline",
model="openrouter/anthropic/claude-sonnet-4-20250514",
max_tokens=500,
)
# result.value -> str (LLM response); budget ledger updated
# inspect block.last_ledger_status and block.last_compression after each call
snapshot = block.get_snapshot()
# snapshot.degradation_level, snapshot.claude_usage_pct, snapshot.openrouter_cost
Caveats and known limitations:
- Inner LLMBlock is typed as
Anyto avoid circular imports; no compile-time verification of the wrapped block - Task classification and backend selection logic is internal; no user-facing config for routing rules
infer()andcomplete()returnResult[str]; they do not carrycompletion_state,warning_card,evidence,request_id,task_id, orrun_id- Callers that own the block must inspect
last_ledger_statusafter each call; values likeledger_write_failed:RuntimeErrorshould be lifted into the caller-ownedqualified-draftwarning card and evidence envelope - Callers must inspect
last_compressionafter each call; when present, lift its before/after token counts and reason into the caller-ownedwarning_cardandevidence context_compressor.estimate_tokensis an approximation based onlen(text) // 4; non-English or code-heavy prompts can be over- or under-estimated- Context compression fires automatically when approaching limits; the model receives a truncation notice, but the caller sees it only through
last_compression - Usage recording is best-effort; ledger failures are surfaced through
last_ledger_status, not hidden as silent success - Degradation level routing (PAID_FIRST to LOCAL_FIRST to HARD_LIMIT) is not configurable per request
- The MCP envelope uses only
verified,qualified-draft, andblocked-escalated; degraded MCP success isqualified-draft, while blocked MCP failures serialize asblocked-escalated
Works well with: work_loop, learning_layer, payments_x402, llm_router
Public API¶
BudgetAwareLLMBlock(AIBlock[str, str, None])¶
Wraps an inner LLMBlock with persistent budget tracking and TOS-aware routing.
| Field | Type | Default |
|---|---|---|
name | str | 'budget_aware_llm' |
inner | Any | None |
ledger | TokenBudgetLedger \| None | None |
config | BudgetConfig | field(default_factory=lambda: BudgetConfig(billing_enforcement_required=_detect_server_mode())) |
component_name | str | '' |
last_ledger_status | str | field(default='ok', init=False, repr=False) |
last_compression | dict \| None | field(default=None, init=False, repr=False) |
last_routing_advisory | dict \| None | field(default=None, init=False, repr=False) |
Methods:
infer(data: str | dict) -> Result[str]¶
complete(prompt: str, model: str | None = None, max_tokens: int = 4096, temperature: float = 0.7, system_prompt: str | None = None, **kwargs: Any) -> Result[str]¶
Satisfy LLMProtocol.
budget_status() -> BudgetSnapshot¶
learned_routing_priors(days: int = 7, limit: int = 1000) -> list[dict]¶
BO §13: ADVISORY learned-routing priors from the real usage log.
backend_cost_telemetry(days: int = 7, limit: int = 1000) -> list[dict]¶
BO §1: measured per-backend cost telemetry from the real usage log.
TokenBudgetLedger¶
Persistent SQLite ledger for cross-session token/cost tracking.
Constructor:
| Parameter | Type | Default |
|---|---|---|
db_path | str \| None | None |
config | BudgetConfig \| None | None |
Methods:
default() -> TokenBudgetLedger¶
reset_default() -> None¶
close() -> None¶
record_usage(event: UsageEvent) -> None¶
record_outcome(outcome: RouteOutcome) -> None¶
Record a per-route OUTCOME observation (BO §13 outcome learning).
tokens_by_backend(backend: str, window_seconds: float) -> int¶
calls_by_backend(backend: str, window_seconds: float) -> int¶
Count recorded calls for a backend in the trailing window (BO §8 / 8-3).
cost_by_backend(backend: str, window_seconds: float) -> float¶
total_cost(window_seconds: float) -> float¶
tokens_by_component(component: str, window_seconds: float) -> int¶
weekly_usage_fraction(backend: str) -> float¶
session_tokens(session_id: str) -> int¶
save_pause(pause: BudgetPause) -> None¶
get_pending_pauses() -> list[BudgetPause]¶
mark_resumed(pause_id: str) -> None¶
get_config_value(key: str) -> str | None¶
set_config_value(key: str, value: str) -> None¶
apply_config_updates(updates: dict[str, Any]) -> BudgetConfig¶
Validate, persist, and activate runtime budget configuration updates.
snapshot(session_id: str = '') -> BudgetSnapshot¶
usage_history(backend: str = '', days: int = 7, limit: int = 100) -> list[dict]¶
outcome_history(backend: str = '', days: int = 7, limit: int = 1000) -> list[dict]¶
Recorded per-route OUTCOME rows (BO §13). Mirrors :meth:
usage_history.
BackendType(str, Enum)¶
BackendEligibility(str, Enum)¶
DegradationLevel(IntEnum)¶
UsageEvent(BaseModel)¶
| Field | Type | Default |
|---|---|---|
backend | BackendType | required |
model | str | required |
component | str | required |
task_type | str | '' |
input_tokens | int | 0 |
output_tokens | int | 0 |
cost_usd | float | 0.0 |
session_id | str | '' |
degradation_level | int | 0 |
BudgetSnapshot(BaseModel)¶
| Field | Type | Default |
|---|---|---|
claude_weekly_usage_pct | float | 0.0 |
claude_session_tokens | int | 0 |
codex_weekly_usage_pct | float | 0.0 |
openrouter_daily_cost_usd | float | 0.0 |
openrouter_monthly_cost_usd | float | 0.0 |
total_cost_today_usd | float | 0.0 |
total_cost_this_week_usd | float | 0.0 |
degradation_level | DegradationLevel | DegradationLevel.NORMAL |
alerts | list[str] | Field(default_factory=list) |
BudgetConfig(BaseModel)¶
| Field | Type | Default |
|---|---|---|
enabled | bool | True |
db_path | str | '' |
claude_weekly_token_limit | int | 45000000 |
codex_weekly_token_limit | int | 45000000 |
claude_session_context_limit | int | 200000 |
openrouter_daily_budget_usd | float | 5.0 |
openrouter_monthly_budget_usd | float | 50.0 |
alert_threshold | float | 0.8 |
context_compression_threshold | int | 50000 |
prefer_codex_over_claude | bool | True |
ollama_coding_eligible | bool | False |
billing_enforcement_required | bool | False |
default_llm_call_cost_cents | int | 1 |
local_fallback_billable | bool | False |
coding_agent_rate_limit | int | 0 |
coding_agent_rate_window_seconds | int | 3600 |
BudgetPause(BaseModel)¶
| Field | Type | Default |
|---|---|---|
id | str | required |
task_id | str | '' |
component_name | str | '' |
prompt_snapshot | str | '' |
context_snapshot | str | '' |
backend_exhausted | BackendType | BackendType.CLAUDE_CODE |
degradation_level | DegradationLevel | DegradationLevel.HARD_LIMIT |
estimated_reset_at | str | '' |
BackendSelection(BaseModel)¶
| Field | Type | Default |
|---|---|---|
backend | BackendType | required |
model | str | required |
reason | str | '' |
degradation_level | DegradationLevel | DegradationLevel.NORMAL |
constraints_applied | list[str] | Field(default_factory=list) |
deterministic_recommended | bool | False |
advisory | str | '' |
scored_plan | dict | Field(default_factory=dict) |
bandit_plan | dict | Field(default_factory=dict) |
BillingContext(BaseModel)¶
| Field | Type | Default |
|---|---|---|
customer_id | int | 0 |
tier | str | '' |
api_key_id | int | 0 |
request_id | str | '' |
trace_id | str | '' |
user_email | str | '' |
BillingAuthorization(BaseModel)¶
| Field | Type | Default |
|---|---|---|
allowed | bool | required |
customer_id | int | 0 |
tier | str | '' |
amount_cents | int | 0 |
reservation_id | str | '' |
error | str | '' |
spend_source | str | 'platform' |
MCP Tools¶
| Operation | Source |
|---|---|
get_status | token_budget_mcp |
get_history | token_budget_mcp |
configure | token_budget_mcp |
list_paused | token_budget_mcp |
resume_task | token_budget_mcp |
backend_status | token_budget_mcp |
capabilities | token_budget_mcp |
reset_ledger | token_budget_mcp |
verified | token_budget_mcp |
qualified-draft | token_budget_mcp |
blocked-escalated | token_budget_mcp |