WithBudget sets token and cost limits on an agent for each run. When a limit is reached, the SDK either stops the run and returns ErrBudgetExceeded, or pauses and waits for human approval to continue. Limits reset when a new run starts.
When an agent delegates to sub-agents, all sub-agent token and cost usage is included in the parent run’s total. The parent budget governs the entire run tree. A WithBudget configured directly on a sub-agent is silently ignored when that sub-agent is invoked from a parent — a warning is logged at runtime to flag this.
Configuration
BudgetConfig fields
Limit precedence
When bothMaxTokens and MaxCostUSD are set, the token limit is checked first on every LLM call. If tokens are exceeded, a token breach error is returned even if the cost limit is also exceeded. Set only one limit if you need to distinguish which triggered.
OnExceeded actions
BudgetStopRun
When the limit is reached,agentRun.Get (or agentStream.Events) returns ErrBudgetExceeded. Check with errors.Is:
result.Telemetry.Run.FinishReason is set to "budget_exceeded" when the run is stopped by the budget. result is always non-nil on budget stop; result.Content holds any partial response from the last completed LLM call.
BudgetWaitForApproval
When the limit is reached, the run pauses and delivers anApprovalRequest with name ApprovalRequestNameBudget. Decode with ParseBudgetApproval for TotalTokens / CostUSD / ApprovalToken.
Call req.Respond(agent.ApprovalStatusApproved) to continue, or req.Respond(agent.ApprovalStatusRejected) to stop with ErrBudgetExceeded.
Approving does not reset run totals. The next pause fires when usage grows by another ApprovalExtraTokens / ApprovalExtraCostUSD measured from the totals at the time of approval. After MaxApprovals approvals (default 5) the next breach stops the run.
If the approval cannot be delivered because no stream subscriber is connected, the run stops with ErrBudgetApprovalUnavailable (a separate sentinel from ErrBudgetExceeded). Check with errors.Is(err, agent.ErrBudgetApprovalUnavailable) and retry.
Run
WithApprovalHandler must be provided at the Run() call site. It is not required at NewAgent, so stream-only agents are not forced to register a no-op handler:
Stream
When the limit is reached during a stream run, aCUSTOM event with name AgentCustomEventNameBudget is emitted. Parse with ParseCustomEventBudget, then call AgentStream.Approve:
Cost calculation
MaxCostUSD is estimated from accumulated token counts using the rates you supply:
MaxCostUSD will not trigger (use MaxTokens instead).
Validation
NewAgent returns an error if WithBudget is misconfigured:
- Neither
MaxTokensnorMaxCostUSDis non-zero. MaxCostUSD > 0butPromptUSDPer1MorCompletionUSDPer1Mis zero.OnExceededisBudgetWaitForApprovalbut noWithApprovalHandleris set.OnExceededis an unrecognised value.
Example
Budget Config
Stop run and wait-for-approval scenarios
Observability
Metrics
Budget events emit the following counters (seeMetricBudget* constants in the SDK):
OnBudgetExceeded hook
Register anOnBudgetExceeded hook for custom alerting, audit logging, or metrics:
Related
Token Usage
Aggregate token counts per run
Approvals
Same Run handler and Stream Approve path for BudgetWaitForApproval
Hooks
OnBudgetExceeded and per-LLM-call hooks for cost observability