Skip to Content
MissionsBudgets

Budgets

Missions and tasks can declare spending limits in a budget block. When a limit is reached, the current task fails and the whole mission fails — in-flight commanders and agents unwind immediately.

Both a token cap and a dollar cap are supported. Either one alone is valid; the first limit reached wins.

mission "expensive_research" { budget { tokens = 5000000 # cumulative across every task dollars = 25.00 } task "crawl" { budget { tokens = 500000 } # per-task cap objective = "Crawl the target domain" } }

Why both tokens and dollars?

Models without declared pricing — local models served via Ollama, self-hosted endpoints, anything Squadron doesn’t have rates for — always report $0 cost. That means a dollar-only budget cannot constrain them, no matter how many tokens they consume. If you run mixed fleets, always include a token cap as a safety net.

Conversely, a dollar-only budget is useful when you want one number that naturally scales across model choices: switching from a cheap model to an expensive one just means fewer tokens fit under the same cap.

Scope

Mission budget

Sums tokens and cost across every task in the mission — commanders, agents they spawn, every iteration of every iterated task. The first limit reached fails the mission.

Task budget

Sums across that task’s commander and every agent it spawns. Iteration suffixes are strippedcrawl[0], crawl[1], crawl[2] all contribute to the same crawl counter. That means a task-level budget caps the whole iterated task, not each iteration.

Validation

At least one of tokens or dollars must be set. Empty budget { } blocks are rejected at config load.

What happens when a budget trips

  1. The breach latches — subsequent usage checks return the same breach without double-counting.
  2. The mission-scoped context is canceled, so in-flight LLM calls and tool calls return promptly.
  3. A mission_issue event is emitted with severity=fatal, category=budget_exceeded, and structured details (scope, kind, used, limit).
  4. The task transitions to failed (not stopped) with the breach message as its error.
  5. The mission transitions to failed.

Issues are purely advisory — authoritative failure still comes from the returned error — so the event and the mission status can never disagree.

Examples

Cap the whole mission in dollars, no per-task limits

mission "sweep" { budget { dollars = 2.00 } # ... tasks ... }

Cap an expensive iteration but let the rest run free

mission "research" { task "crawl_pages" { iterator { dataset = datasets.urls parallel = true } budget { tokens = 1000000 # the parallel fan-out is the risky part } objective = "Fetch and summarize ${item.url}" } task "summarize" { depends_on = [tasks.crawl_pages] objective = "Produce an executive summary" } }

Belt-and-suspenders: cap dollars overall, tokens per expensive task

mission "thorough" { budget { dollars = 10.00 # hard spend ceiling regardless of model } task "deep_analysis" { budget { tokens = 2000000 } objective = "Analyze the full corpus" } }

Zero overhead when unused

If neither the mission nor any task declares a budget, no tracker is created and no per-turn accounting happens.

Last updated on