Skip to main content

assurance-budget

tests PyPI License

Your agent didn't fail. It just kept going.

The expensive runs are rarely the ones that crash. They are the ones that retried the same failing call fourteen times, or spent nineteen model calls summarising something nobody read, and finished with a plausible answer and a bill.

Point this at a run log and find out which ones did that.

pip install assurance-budget
assurance-budget runs.jsonl

On a system Python you may hit error: externally-managed-environment (PEP 668). That is your OS protecting its packages, not this failing: python3 -m venv .venv && .venv/bin/pip install assurance-budget

1 of 4 runs hit a limit — 1 was going nowhere first — 1 ran past the clock

  r-002
      Stopped: 3 rounds repeating fetch(url=api/invoices) and failing the same way (timeout)
      with nothing new read and no part of the goal closer.
  r-003
      Stopped after 20 frontier calls
  r-004
      Ran 660s against a 600s cap

  Not tested by this log: iterations, retries. The log carries no events of that kind, so this
  is silence rather than a pass.

That last paragraph is the part most tools leave out. A limit your log cannot exercise has not passed — it has not been tested, and reporting those the same way is how a green check comes to mean nothing.

A limit a caller can raise is a suggestion

The ceilings are constants in the library, and every budget is clamped to them at construction. Ask for more and you do not get more:

assurance-budget runs.jsonl --tool-calls 5000 --json | grep tool_calls
#   "tool_calls": 40

It clamps rather than erroring, on purpose. A caller asking for 5000 is expressing a preference the runtime declines — that is not a reason to abort somebody's task. Lower values pass straight through, because a caller may always be more conservative: that is how a cheap plan or an untrusted worker gets a shorter leash.

Raising a ceiling is a deliberate edit to a source file, which is the point.

The log

JSONL, one event per line. Field names are matched loosely — run/run_id/session, action/tool/name, and so on — so most existing logs work without being rewritten.

{"run": "r-002", "action": "fetch(url=api/invoices)", "error": "timeout", "kind": "tool", "ts": 41.0}

kind is one of tool, frontier, retry, iteration and defaults to tool. Anything else is refused rather than counted as something it isn't.

As a library — the half that prevents rather than reports

The audit tells you it already happened. This stops it happening:

from assurance_core.run_budget import Budget, ProgressWatch, Progress, Spend

spend = Spend(budget=Budget.allowing(tool_calls=20))
watch = ProgressWatch()

for step in range(100):
    stopped = spend.charge_tool_call()
    if stopped:
        print(stopped.message)
        break
    stalled = watch.observe(Progress(action="fetch(url=api/invoices)", error="timeout"))
    if stalled:
        print(stalled.message)
        break

assert spend.tool_calls <= 20

Two different stops, and the difference matters. Exhausted means the budget ran out. Stalled means budget remains and spending it is the mistake — three rounds repeating the same action, failing the same way, with nothing new read and no part of the goal closer.

In a pipeline

assurance-budget runs.jsonl --fail-on-exhausted
exit means
0 audited, and nothing hit a limit or stalled
1 audited, and --fail-on-exhausted found a run that did
2 refused — the log could not be read, so there is no audit

Honest limits

  • It reads what your log records. A run that burned money in a way the log does not mention is invisible here, and no amount of analysis fixes that.
  • There is no dollar limit. Frontier calls are the cost proxy. Prices change per model, per provider and per week; a number that goes stale silently is worse than a count that does not pretend to be money.
  • Stall detection needs three rounds and both halves — identical action, error and result, and flat progress. A repeated action while evidence accumulates is a loop doing work, and stopping that would be the bug.

As an agent skill

skills/run-budget/ — drop it in and an agent reads your run logs the right way. Its real content is that a limit the log cannot exercise has not passed, and that a run which stalled is an agent bug while one which was exhausted may just be a job too big.

Where the rules live

assurance_core.run_budget, in assurance-core — pure Python, no dependencies, no model involved in any of it. This package reads logs and calls it.

Licence

Apache-2.0.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

assurance_budget-0.1.1.tar.gz (17.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

assurance_budget-0.1.1-py3-none-any.whl (14.4 kB view details)

Uploaded Python 3

File details

Details for the file assurance_budget-0.1.1.tar.gz.

File metadata

  • Download URL: assurance_budget-0.1.1.tar.gz
  • Upload date:
  • Size: 17.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for assurance_budget-0.1.1.tar.gz
Algorithm Hash digest
SHA256 b74c81d66143d19a166c94d03a9ff9ddbe8946e783c0f0d2c1c40f33b0608f7b
MD5 ac8c283276aa8a4a6974c997d6b57b77
BLAKE2b-256 4756f96d953dd35dee718e06c8cbe52ba83b8157ba83722ec625639d3147f956

See more details on using hashes here.

Provenance

The following attestation bundles were made for assurance_budget-0.1.1.tar.gz:

Publisher: publish.yml on i-ops-hq/assurance-budget

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file assurance_budget-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for assurance_budget-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4e5ddfbae0493395a7311e5684716dc746c81672c4dc631d483e127714c326d5
MD5 7ffa272f507fd83ebd564f99b77c4d22
BLAKE2b-256 1ae5a0e22c55143e7560b2dd5ac038db91559964d6c6c811c7f0ed3f5f60f0b6

See more details on using hashes here.

Provenance

The following attestation bundles were made for assurance_budget-0.1.1-py3-none-any.whl:

Publisher: publish.yml on i-ops-hq/assurance-budget

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.1.2

2 files

This release

0.1.1 This release

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page