Skip to main content

Overview

The workflow-level budget: block sets cumulative ceilings on a run. The executor checks the running totals after every node and enforces the limits you declare. At least one of max_tokens, max_cost_usd, or max_duration_s must be set — an empty budget: block is rejected at validation time.
This complements the per-node max_tokens_per_call ceiling: max_tokens_per_call bounds a single response, while budget: bounds the whole run.

Fields


on_exceeded actions

BudgetExceededError is exported from the top-level package and carries the violation reason, tokens used, and the USD estimate at the point of the violation:

Cost estimation

USD estimates come from a bundled LiteLLM pricing snapshot, refreshed from a local cache when available. Models without a pricing entry (Ollama and other local backends) report estimated_usd: null, and a max_cost_usd ceiling is effectively unenforced for those models — use max_tokens or max_duration_s instead when running locally.

Budget status in the trace

When a budget: block is configured, the trace summary includes a budget object:

Reading budget state in when: expressions

Budget state is also exposed to edge conditions as _budget, so you can route around expensive work as the run approaches its ceiling:
_budget exposes total_tokens (int) and estimated_usd (float or None). See YAML Reference → when expressions.

When to use a budget

Use a budget when:
  • Running untrusted or open-ended input where token usage is hard to predict.
  • Enforcing a hard cost ceiling per run in production.
  • Bounding wall-clock time for latency-sensitive integrations.
Pair it with:

Cookbook recipe

  • Budget Guarded — a workflow that aborts when its USD ceiling is reached.
See the YAML Reference for the full field listing.