WindowedSpendBudgetPolicy
Defined in the protocols module.AI Agent Config-driven cumulative per-identity spend-budget policy. Intended as the default the wrapper will wire onto a forthcoming
gateway.budget config block and a spend_budget_policy= gateway
constructor argument (neither of which exists in the repo yet — this PR
ships only the core decision primitive; the CLI/YAML and constructor
surfaces are a follow-up wrapper change). It is intentionally minimal and
dependency-free so the decision lives in core and is provable in isolation,
exactly like :class:SlidingWindowRateLimitPolicy.
The decision, given the amount spent_usd already accumulated for the
identity+scope in the current window and the pending_usd estimated cost
of the turn being admitted:
allowedwhilespent_usd + pending_usdis belowlimit_usd.- Otherwise the turn is denied with a
retry_after_secondshint equal to the time until enough spend rolls out of the window. Whenoldest_spend_tsis supplied the hint is computed precisely (oldest_spend_ts + window_seconds - now); without it the policy falls back to the fullwindow_secondsas a safe upper bound.
pending_usd lets a caller reserve budget for the turn’s
estimated cost before the LLM call so a single expensive turn cannot
overshoot the cap; leaving it at the default 0.0 preserves the simpler
“gate on spend so far” behaviour.
A limit_usd of 0 (or negative) disables the budget entirely (every
turn is allowed) — the legacy default when no budget is configured.
Unlike :class:SlidingWindowRateLimitPolicy this policy is stateless: the
cumulative spend is owned by a durable
:class:~praisonaiagents.telemetry.protocols.TokenUsageSinkProtocol, so the
same budget survives restarts and is shared across processes.
Example::
Methods
enabled()
Whether budgeting is active (a positive limit is set).
window_start()
Start timestamp of the current window for a
now timestamp.check()
Instance method.
Source
View on GitHub
praisonaiagents/gateway/protocols.py at line 4369
