Agent cost controls
LLM-driven agents can consume budget unboundedly if a single user message triggers an infinite tool-call loop, or if a long-running conversation crosses a cost ceiling you only want to hit once. Orbit gates every agent run on three independent ceilings, all configurable per agent.The three ceilings
Both cost caps accept
0–10000 cents ($0–$100); 10000 cents ($100) is the maximum — setting either field higher returns a 400 validation error. See Semantics for the full value table.
When any ceiling is exceeded the agent emits a final error event and stops:
COST_LIMIT (per-run cost), CONVERSATION_COST_CAP_REACHED (per-conversation cost), API_CALL_LIMIT (per-run LLM-call cap), TOKEN_LIMIT (per-conversation token aggregate), and TOOL_ITERATION_LIMIT (tool-loop guard).
Configure on agent create
tool_loop_limit is the per-agent tool-iteration knob (bounds 1..50, default 10). It is persisted under config.tool_loop_limit; when unset it falls back to the platform default of 10. The run-wide hard envelope of 50 LLM API calls (AGENT_MAX_API_CALLS_PER_RUN) is always enforced on top of it and cannot be raised by agent config.
Configure on agent update
config.max_cost_per_run_cents / config.max_cost_per_conversation_cents on the agent row.
Semantics
Bothmax_cost_per_run_cents and max_cost_per_conversation_cents accept a whole number of USD cents in the range 0–10000 ($0–$100). 10000 cents ($100) is the maximum accepted value — a request that sets either field above it is rejected with a 400 validation error before the agent is created or updated. This input ceiling is independent of the platform hard cap that silently clamps the resolved per-conversation value (see below).
How accumulated cost is computed
- Per-run: real-time accumulation across the streaming loop. Estimated from prompt + completion tokens at the model’s per-1K rate, plus a flat per-API-call overhead.
- Per-conversation: tracked in Redis under a key keyed off
agent_conversations.id. Each run debits the counter on completion; the next run’s iteration-0 probe reads the counter and refuses if it’s already over the cap. - The counter is reset only by deleting the conversation. Re-using a
conversation_idafter the cap will keep failing until you provision a fresh one.
Which cap participates in the org/env precedence chain
Only the per-conversation cap resolves through a fallback chain. The runtime callsresolveCostCapCents and takes the first non-null value (an explicit 0 kill-switch wins over a null further down):
- Per-agent —
agents.config.max_cost_per_conversation_cents - Per-org —
organizations.settings.agent_runtime_cost_cap_cents - Platform default — the
DEVOTEL_AGENT_COST_CAP_CENTS_DEFAULTenv var
max_cost_per_run_cents) is a per-agent-only knob with no org or env fallback. The runtime enforces it directly off the agent definition (accumulated run cost >= the cap → COST_LIMIT); if you leave it unset on the agent it falls back to the platform default of $1.00 per run (not unbounded), regardless of any org-level or env-level setting. To allow more than $1.00 of spend in a single run, set max_cost_per_run_cents explicitly. There is no agent_runtime_cost_cap_cents equivalent for per-run spend.
Per-conversation token ceiling
In addition to the cost caps above, every conversation is bounded by an aggregate token ceiling. When the running token total for a conversation crosses this value the agent terminates gracefully and the run ends with aTOKEN_LIMIT error code. This guards against runaway loops where token usage grows non-linearly with context length even when the per-token cost is cheap.
The
10000 default is a deliberately conservative back-compat value, not a hard platform cap. Set max_tokens_per_conversation on the agent (create or update) to raise (or lower) it — for example 50000 for long support resolutions or multi-step workflows. Send null to clear an override back to the default. When raising it, also raise max_cost_per_run_cents / max_cost_per_conversation_cents accordingly, since the tenant-configurable spend cap remains the primary ceiling.
config.max_tokens_per_conversation on the agent row; values must be a whole number of tokens between 1 and 1000000.
Hard platform ceilings (always enforced)
These are floor / ceiling values that no agent config can override:
They exist to prevent runaway behaviour even when an agent’s per-run cap is set to a high value.
MAX_TOOL_ITERATIONS_HARD_CEILING (50) is the absolute ceiling on tool_loop_limit — a per-agent override is clamped to this and cannot exceed it. The platform default of 10 (when tool_loop_limit is unset) is not a hard ceiling: it is the overridable starting value described in the tool_loop_limit knob above.
Platform budget governors (operator-facing)
The per-agent / per-conversation knobs above are tenant-configurable via the agents API. Underneath them sit platform-level spend and rate governors set by environment variable (defaults inpackages/shared/src/env.ts, overridden per cluster via Secret Manager). These are the values an SRE greps when paged for a platform-wide 503 LlmPlatformCeilingExceeded or a tenant 429 RATE_LIMIT_EXCEEDED (scope: tenant_tpm). They are listed in .env.example under the LLM budget / cost governors block.
Observability
Cost-cap enforcement is observable through logs and metrics, not webhooks — there is no subscribable cost-cap webhook event. Every per-conversation cap fire emits a structuredwarn log line from the agent runtime carrying a metric field you can alert on:
agent.conversation_cost_cap_hit metric to catch runs that hit the cap. Clients also receive the final error event with the matching code (COST_LIMIT, CONVERSATION_COST_CAP_REACHED, API_CALL_LIMIT, TOKEN_LIMIT, or TOOL_ITERATION_LIMIT) on the aborted run. There is no agent.run.aborted webhook — do not subscribe for one.
Recommended starting values
- Tier-1 customer support agent —
max_cost_per_run_cents=25,max_cost_per_conversation_cents=500. - Voice agent (longer turns, STT/TTS overhead) —
max_cost_per_run_cents=50,max_cost_per_conversation_cents=1000. - Internal QA / sandbox —
max_cost_per_run_cents=10,max_cost_per_conversation_cents=50to catch loops fast.
The voice-agent
max_cost_per_conversation_cents=1000 (5 platform hard cap** (DEVOTEL_LLM_PER_CONVERSATION_MAX_USD). Unless an operator raises that env var, the effective per-conversation ceiling is silently halved to $5 — see the precedence-chain warning. Confirm the platform value is set to at least your intended cap before relying on it.See also
- Creating Agents — full agent-create reference.
- Agents API — schema for
max_cost_per_run_cents/max_cost_per_conversation_cents. - Webhooks → Events — full catalog of subscribable
agent.*events (cost-cap aborts are not among them; use logs/metrics).