Skip to main content

AgentLedger Treasury

A financial clearinghouse and dynamic credit-allocation middleware for stateful, hierarchical multi-agent workflows.

AgentLedger Treasury treats a multi-agent session's token budget not as a static ceiling handed down to each node, but as a fluid corporate treasury: agents draw allocations against it, unspent capital yields back automatically, agents that are close to finishing but running tight can borrow against the pool's collective savings, and when the whole session's burn rate outpaces its actual progress, AgentLedger Treasury forces a downshift to cheaper models rather than letting the session blow its budget or stall out.

Built for LangGraph, LangChain Runnables, and CrewAI -- but the core (agentledger_treasury.core) has zero dependency on any of them, so it works with any orchestration framework that can call an async function around a sub-task.

Why

Static per-agent budgets are wasteful in either direction: set them too tight and agents crash mid-task the moment a plan needs an extra reasoning pass; set them too loose and a runaway sub-agent can burn the entire session's budget before a supervisor ever notices. AgentLedger Treasury's answer is a shared, mutable pool with rules:

  • Give Back -- an agent that finishes under its allocated ceiling immediately returns the unused delta to the shared pool.
  • Micro-Lending -- an agent that is verifiably close to finishing (tracked via a progress hook) but hits its local ceiling can request a credit-line extension, funded only by capital other agents have already yielded back or that was never committed.
  • ROI-Driven Degradation -- if the pool's remaining budget drops below a critical threshold and the session's spend is outpacing its actual step-by-step progress, AgentLedger Treasury transparently swaps subsequent LLM calls to a cheaper model tier instead of letting the session fail outright.

Install

pip install -e .                  # core only
pip install -e ".[langchain]"     # + langchain-core / langgraph
pip install -e ".[crewai]"        # + crewai
pip install -e ".[postgres]"      # + asyncpg, for the distributed PostgreSQL backend
pip install -e ".[dev]"           # + pytest, mypy, ruff

Architecture

Module Responsibility
agentledger_treasury.core.treasury Module A -- the thread-safe, atomic, async-native central ledger. Treasury.request_allocation / .release_allocation / .grant_extension.
agentledger_treasury.core.reallocator Module B -- the Give-Back pattern and micro-lending negotiation logic (Reallocator.give_back, .request_credit_extension, progress hooks).
agentledger_treasury.core.degrader Module C -- burn-rate monitoring and forced model downgrades (DegradationEngine.resolve_model, BudgetVelocityTracker).
agentledger_treasury.pricing LiteLLM-style per-token pricing table with configurable degrade_to chains (e.g. claude-3-5-sonnet -> claude-3-5-haiku).
agentledger_treasury.usage Shared token-usage extraction / cost settlement helpers used by every integration wrapper.
agentledger_treasury.integrations.langgraph Module D -- the @ledger_guard decorator for LangGraph nodes / plain state -> state callables.
agentledger_treasury.integrations.langchain_runnable Module D -- LedgerGuardedRunnable wrapping any LangChain-compatible Runnable.
agentledger_treasury.integrations.crewai Module D -- LedgerGuardedCrewTask wrapping a CrewAI task execution callable.
agentledger_treasury.backends.postgres Module E -- PostgresTreasury, a drop-in, PostgreSQL-backed Treasury for multi-worker/multi-host deployments.

Distributed deployment with PostgreSQL

The in-memory Treasury lives inside a single process, so it can't be shared across multiple workers (pods, hosts, or processes) working the same session. PostgresTreasury stores all ledger state in PostgreSQL instead, using SELECT ... FOR UPDATE row locking so that concurrent request_allocation / release_allocation / grant_extension calls from any worker sharing the same session_id and connection pool are serialized and can never oversubscribe the pool.

pip install "agentledger_treasury[postgres]"
import asyncpg
from agentledger_treasury import PostgresTreasury

pool = await asyncpg.create_pool(dsn="postgresql://...")
treasury = PostgresTreasury(
    pool=pool,
    session_id="distributed-session-1",
    total_session_budget_usd="10.00",  # required the first time a session is created
    create_tables=True,                # lazily creates the schema on first use (default)
)

Reallocator and DegradationEngine work unmodified against a PostgresTreasury -- they only touch the Treasury's public surface. A few methods necessarily differ from the in-memory Treasury because they now involve real I/O:

  • get_token, snapshot, and ledger_history are async def on PostgresTreasury (they are synchronous on the in-memory Treasury, which never does I/O).
  • available_usd, committed_usd, settled_spent_usd, utilization_ratio, and remaining_ratio stay synchronous properties (so Reallocator/DegradationEngine can keep calling them without await), backed by a small local cache that is refreshed on every allocation/release/extension this instance performs. Because other workers can mutate the same session between two of this instance's operations, treat them as eventually consistent -- call await treasury.refresh() first if a decision needs a guaranteed-fresh read.

The in-memory Treasury remains the recommended choice for single-process or demo use; reach for PostgresTreasury once you need multiple workers sharing one ledger.

Quick start

import asyncio
from agentledger_treasury import Treasury, Reallocator, DegradationEngine, BudgetVelocityTracker
from agentledger_treasury.integrations import ledger_guard

treasury = Treasury(session_id="sess-1", total_session_budget_usd="1.00")
reallocator = Reallocator(treasury)
velocity = BudgetVelocityTracker(expected_total_steps=5)
degrader = DegradationEngine(treasury, velocity, critical_remaining_threshold="0.20")

@ledger_guard("researcher", treasury, max_usd_ceiling="0.20",
              reallocator=reallocator, degradation_engine=degrader)
async def researcher_node(state: dict) -> dict:
    # ... call your LLM here, return state including a `usage` dict
    # (prompt_tokens / completion_tokens / model), LiteLLM-style.
    return {**state, "usage": {"prompt_tokens": 300, "completion_tokens": 200, "model": state["model"]}}

async def main():
    result = await researcher_node({"input": "...", "model": "claude-3-5-sonnet"})
    print(treasury.snapshot())

asyncio.run(main())

Run the full end-to-end rescue scenario (a supervisor with two workers, where one worker's savings bail out the other's overrun) with no external dependencies or API keys:

python examples/supervisor_worker_example.py

Testing

pip install -e ".[dev]"
pytest tests/ -v

Design notes

  • Decimal everywhere. All USD amounts are decimal.Decimal, never float, to avoid drift across thousands of micro-transactions in a long-running session.
  • Concurrency. Ledger bookkeeping is pure, in-memory, non-blocking arithmetic, so it is guarded by a single threading.RLock that is safe to acquire from both plain OS threads (CrewAI's default executor) and async def methods on an event loop -- while the public API remains fully async/await-native as required by highly parallel agent execution paths. See the docstring in agentledger_treasury/core/treasury.py for the full rationale.
  • Single source of truth. Treasury is the only component that mutates ledger state. Reallocator and DegradationEngine are pure orchestration/policy layers on top of it, and every integration wrapper funnels cost extraction through agentledger_treasury.usage so pricing logic lives in exactly one place.
  • No silent overcharging. If an integration wrapper cannot extract usage metadata from a call's result, the settled cost defaults to $0, and the full ceiling is yielded back -- AgentLedger Treasury never guesses at spend it can't verify.

Contributing

Contributions are welcome -- see CONTRIBUTING.md for the development setup, code style, and pull request process.

License

MIT -- see LICENSE.

Metadata

Release files for agentledger-treasury 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agentledger-treasury 0.1.0
File Size Uploaded Provenance
agentledger_treasury-0.1.0.tar.gz 33.9 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for agentledger-treasury 0.1.0
File Interpreter ABI Platform
agentledger_treasury-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 70.4 kB

Release files / agentledger_treasury-0.1.0.tar.gz

Download URL agentledger_treasury-0.1.0.tar.gz
Size 33.9 kB
Tags Source
SHA-256 checksum
How to use checksums
b55ea906fda00e33441b2da672166ea367a02b86bc19434cd6c4bd576a5f57be
BLAKE2b-256 checksum
How to use checksums
1c90761edd8ef030bd3ed2482d735d4bec8ab246810076724b5ff66a241c2fb6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.5

Release files / agentledger_treasury-0.1.0-py3-none-any.whl

Download URL agentledger_treasury-0.1.0-py3-none-any.whl
Size 36.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e72be81836515e531781c80aea372178a7fc7253d7980522f367e3229dccfd8f
BLAKE2b-256 checksum
How to use checksums
8b7988d73334b06ecb22019b815e78ce6d70bda367bd4d632dadb8ead02733c9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.5

Security for agentledger-treasury 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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