Skip to main content
Documentation menu

Operations

Spend guard

The spend guard watches for work that multiplies cost, says so before and while it happens, and explains it afterwards. It never changes anything on its own: every mitigation is something you pick.

Before fan-out. When a turn is about to start several subagents (Task calls in one batch, or one next to agents already running, e.g. from /batch), when you start a /team, or when you start a /loop, Chanto estimates the cost first:

estimate = the context each agent starts with × the calls it's expected to make × agents × the model's price

Each agent starts with the system prompt and tools plus its task, and grows by about 3k tokens a call. Its first call writes that prompt to the provider's cache and later calls read it back, at the cache-read and cache-write rates where the provider has them (input rates otherwise). Calls per agent default to 15, and once you've run a few subagents Chanto uses the average of your own (kept in ~/.chanto/cache/spend.json). Agents run on the subagent model: the agent definition's model, subagent_model, or the main model. A /loop is priced as six calls on the current context per run, times the runs in a day; a self-paced loop is assumed to run every 10 minutes.

Prices that aren't known are never guessed. Those estimates show tokens, and on a plan that reports usage windows (ChatGPT) the share of the window. Chanto learns that share from how fast the window fills as the session uses tokens: e.g. ~2.1M tokens, ~14% of your 5h window. Local models are free and never asked about.

Above confirm_over_usd (default $2), or confirm_over_plan_percent of a plan window (default 10%), or confirm_over_tokens when neither is known (default 5M), the TUI asks:

Spend check: starting 4 subagents on anthropic/claude-opus-5-5 (~15 calls each): ~$3.10 (2.3M tokens), over your $2.00 confirm threshold.
❯ Continue (~$3.10 (2.3M tokens))
  Use anthropic/claude-sonnet-5-5 for the agents (~$1.40 (2.3M tokens))
  Run at most 2 at a time (same total, slower to burn, easier to stop)
  Cancel
  • Use a cheaper model is offered when [spend] cheap_model, or the next tier down of the same family (Opus → Sonnet → Haiku, GPT-6 Astra → Sol → Luna, …), has a known, lower price. Subagents then run on it for the rest of the session.
  • Run at most N at a time caps how many agents run at once for the rest of the session (limit_agents, default 2). The total is the same; it burns slower and is easier to stop part-way.
  • Cancel doesn't start them; the model is told why and does the work directly or with fewer agents.

After you continue, a similar fan-out within 10 minutes isn't asked about again unless it's more than twice as big. -p and background runs follow non_interactive: "warn" (default) prints the estimate as a warning and continues, and "stop" refuses to start the fan-out and says so. Neither is silent. /team shows the estimate in its plan approval, next to the team budget that caps it.

While it runs. The guard tracks $/min (or plan-% an hour) for the session and each agent, over a rolling 5-minute window. It flags each of these once per session, with a one-line note in the transcript and a $ … marker in the footer:

PatternExample notice
many agents at once (parallel_agents, default 4)Spend: 5 agents running in parallel; each resends its own context on every call, so cost grows with the count. /cost limit 2 caps how many run at once.
the same large file (4k+ tokens) read again and again (repeated_reads, default 3)Spend: src/parser.rs (~12k tokens) has been read 3 times; every copy stays in context and is resent on each call. Read the part you need (offset/limit) or keep one summary.
a context above resent_context_percent of the window (default 50%) resent on five calls in a rowSpend: the main agent's context is ~150k tokens (75% of the window) and is resent on every call, ~$0.05 a call even with most of it cached. /compact or a fresh session cuts that.
the same tool call with the same result four times in an agent's last dozenSpend: the same Grep call ran 4 times in the Explore: map the parser with the same result: no progress, but each repeat is another model call over the whole context.
spend above burn_usd_per_min (default $0.50) or burn_plan_percent_per_hour (default 25%)Spend: ~$0.62/min over the last 3m across 6 agents (above $0.50/min). /cost shows where it goes.

notices = false turns them off. Detection works on counters the agent loop already keeps, so it adds no model calls.

Afterwards: /cost. Besides the totals, budgets and plan limits, /cost breaks the session down by agent (model, calls, tokens in and cached, out, cost, $/min), by model (including cache writes), by tool (tokens their results added to the context) and by the large files read more than once. It ends with suggestions from what it saw:

  • Subagents ran on anthropic/claude-opus-5-5 for $4.12 (63% of this session's spend); anthropic/claude-sonnet-5-5 would have cut that by ~50%.
  • Context was resent 340 times at ~180k tokens (90%+ of the window): /compact or start fresh when a task is done.
  • Up to 8 agents ran in parallel: /cost limit 2 caps that.

/cost today adds up every session's model calls today, by model, from the log. /cost cheaper [model] runs subagents on a cheaper model for the rest of the session (/cost cheaper off undoes it), and /cost limit [N] caps agents at once (/cost limit off). /compact shrinks the context.

Budgets. session_usd, day_usd and month_usd cap spend per session, per local calendar day (from the model-call log) and per calendar month (saved sessions last active this month, plus this one). They're the same budgets as max_cost_usd and max_cost_usd_per_day (which win when both are set), and the same checks: /goal's max_cost_usd, background runs' and the runner's budgets all count against them too. A note at 50% and 80% of the tightest budget, and at 100% the turn stops before its next model call: interactively you're asked whether to continue, and -p and background runs stop.

toml
[spend]
confirm_over_usd = 2.0
confirm_over_plan_percent = 10
confirm_over_tokens = 5000000
non_interactive = "warn"        # or "stop"
# calls_per_agent = 15          # default: learned
# cheap_model = "anthropic/claude-haiku-5-5"
limit_agents = 2
notices = true
burn_usd_per_min = 0.5
burn_plan_percent_per_hour = 25
parallel_agents = 4
repeated_reads = 3
resent_context_percent = 50
# session_usd = 5.0
# day_usd = 20.0
# month_usd = 200.0

Edit this page on GitHub Report a problem

Commands, settings, errors: type a few words.