Escrow-based settlement for LiteLLM A2A agent calls.
A single LiteLLM callback handler that wraps every A2A agent call with escrow — tokens are held before the call, released on success, and refunded on failure. Settlement runs against the live A2A Settlement Exchange.
LiteLLM Proxy
│
├── async_pre_call_hook → create_escrow (hold tokens)
│ ↓
│ A2A Agent call
│ ↓
├── async_log_success_event → release_escrow (pay the agent)
└── async_log_failure_event → refund_escrow (return tokens)
This package is a thin integration layer. The settlement protocol, exchange, and SDK all live in a2a-settlement/a2a-settlement. This package wires that SDK into LiteLLM's callback system.
| Concern | Package |
|---|---|
| Settlement protocol & spec | a2a-settlement |
| Exchange (the running service) | sandbox.a2a-settlement.org (default for testing), production at exchange.a2a-settlement.org |
| Python SDK | a2a-settlement (pip) |
| LiteLLM integration | litellm-a2a-settlement (this package) |
pip install litellm-a2a-settlement1. Register your payer account on the exchange (one-time):
from a2a_settlement.client import SettlementExchangeClient
c = SettlementExchangeClient("https://sandbox.a2a-settlement.org")
r = c.register_account(
bot_name="MyProxy",
developer_id="myorg",
developer_name="My Org",
contact_email="me@example.com",
)
print("API key:", r["api_key"])
print("Account:", r["account"]["id"])2. Register each downstream A2A agent and note their account IDs.
3. Set environment variables:
export A2A_EXCHANGE_URL=https://sandbox.a2a-settlement.org
export A2A_PAYER_API_KEY=<your payer api key>4. Add to proxy_config.yaml:
model_list:
- model_name: a2a/web-scraper
litellm_params:
model: a2a/web-scraper
base_url: http://localhost:10001
litellm_settings:
callbacks: litellm_a2a_settlement.handler.handler_instance5. Start the proxy:
litellm --config proxy_config.yamlEvery call to a2a/* models now automatically settles.
from litellm_a2a_settlement import SettlementHandler, SettlementConfig, AgentSettlementConfig
import litellm
config = SettlementConfig(
payer_api_key="your_api_key",
default_tokens_per_call=10,
agents={
"a2a/web-scraper": AgentSettlementConfig(
account_id="acc_abc123",
tokens_per_call=25,
ttl_minutes=30,
task_type="web-scraping",
),
},
)
litellm.callbacks = [SettlementHandler(config)]Settlement fires when both conditions are true:
- The model string starts with
a2a/or is explicitly listed inagents. payer_api_keyis set andenabledisTrue.
Standard LLM calls (gpt-4o, claude-3-5-sonnet, etc.) are never settled.
| Variable | Default | Description |
|---|---|---|
A2A_EXCHANGE_URL |
https://sandbox.a2a-settlement.org |
Exchange base URL (no /v1) |
A2A_PAYER_API_KEY |
— | Payer account API key (required) |
A2A_DEFAULT_TOKENS_PER_CALL |
10 |
Tokens escrowed per call |
A2A_DEFAULT_TTL_MINUTES |
60 |
Escrow expiry |
A2A_SETTLEMENT_ENABLED |
true |
Set to false to pause settlement |
Settlement failures are non-blocking. If the exchange is unreachable the agent call proceeds normally and a warning is logged.
pip install -e ".[dev]"
pytest -q| Project | Description |
|---|---|
| a2a-settlement | Core exchange + SDK |
| a2a-settlement-auth | OAuth economic authorization |
| a2a-settlement-mediator | AI-powered dispute resolution |
| a2a-settlement-mcp | MCP server for any client |
| settlebridge-ai | SettleBridge Gateway — trust/policy enforcement |
| mcp-trust-gateway | MCP trust layer above OAuth |
| otel-agent-provenance | OpenTelemetry provenance conventions |
| a2a-federation-rfc | Federation protocol specification |
| langgraph-a2a-settlement | LangGraph integration |
| crewai-a2a-settlement | CrewAI integration |
| adk-a2a-settlement | Google ADK integration |
MIT