Skip to main content
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 both MaxTokens 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 an ApprovalRequest 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, a CUSTOM 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:
The SDK does not include built-in provider price tables. Set the rates to match the model you are using. If a provider does not report token counts, MaxCostUSD will not trigger (use MaxTokens instead).

Validation

NewAgent returns an error if WithBudget is misconfigured:
  • Neither MaxTokens nor MaxCostUSD is non-zero.
  • MaxCostUSD > 0 but PromptUSDPer1M or CompletionUSDPer1M is zero.
  • OnExceeded is BudgetWaitForApproval but no WithApprovalHandler is set.
  • OnExceeded is an unrecognised value.

Example

Budget Config

Stop run and wait-for-approval scenarios

Observability

Metrics

Budget events emit the following counters (see MetricBudget* constants in the SDK):

OnBudgetExceeded hook

Register an OnBudgetExceeded hook for custom alerting, audit logging, or metrics:
The hook fires before the action (stop or pause) is taken and is fire-and-forget.

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