fn __budget_envelope(opts: dict) {
return opts?.budget
}
/**
* agent_budget_pre_call_blocked.
*
* @effects: [host]
* @errors: []
* @api_stability: experimental
*/
pub fn agent_budget_pre_call_blocked(agent: HarnessAgent, session: dict, opts: dict) {
const envelope = __budget_envelope(opts)
if envelope == nil {
return false
}
return agent.budget_pre_call_blocked(session.session_id, envelope)
}
/**
* agent_budget_post_call_stop_reason.
*
* Which post-call ceiling stopped the loop, or "" when none did. Callers that
* end a run on this answer must record the reason they were given: a stop
* attributed to the wrong ceiling reads as an ordinary iteration cap and hides
* the spend guard that actually fired.
*
* @effects: []
* @errors: []
* @api_stability: experimental
*/
pub fn agent_budget_post_call_stop_reason(totals: dict, opts: dict) -> string {
const envelope = __budget_envelope(opts)
if envelope == nil && opts?.token_budget == nil {
return ""
}
if opts?.token_budget != nil && totals?.tokens_used != nil {
if totals.tokens_used >= opts.token_budget {
return "token_budget"
}
}
// A configured USD ceiling spends against the worst case: everything priced
// plus a price-table bound on every unpriced attempt. A call that recovered
// from a discarded attempt therefore no longer stops the loop on its first
// retry. A call whose worst case cannot be computed at all still does, at
// the same post-call boundary, instead of treating unknown spend as zero.
if envelope?.total_budget_usd != nil {
const projected = totals?.projected_cost_usd
if projected != nil {
if projected >= envelope.total_budget_usd {
return "total_cost"
}
} else if (totals?.unpriced_calls ?? 0) > 0 {
return "unpriced_call"
} else if totals?.cost_usd != nil && totals.cost_usd >= envelope.total_budget_usd {
return "total_cost"
}
}
return ""
}
/**
* agent_budget_post_call_blocked.
*
* @effects: []
* @errors: []
* @api_stability: experimental
*/
pub fn agent_budget_post_call_blocked(totals: dict, opts: dict) -> bool {
return agent_budget_post_call_stop_reason(totals, opts) != ""
}