Skip to main content

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:
  • allowed while spent_usd + pending_usd is below limit_usd.
  • Otherwise the turn is denied with a retry_after_seconds hint equal to the time until enough spend rolls out of the window. When oldest_spend_ts is supplied the hint is computed precisely (oldest_spend_ts + window_seconds - now); without it the policy falls back to the full window_seconds as a safe upper bound.
Passing 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