Fences
Runtime governance for AI agents. Budget limits, loop protection, token governance, and a decision audit trail — in three lines of code.
import agentfences
from agentfences import governed, checkpoint, log_decision
agentfences.init(local_only=True)
@governed(budget_usd=0.50, max_iterations=20, max_tokens=50_000)
async def run_agent(query: str, messages: list):
while True:
log_decision(reasoning="calling LLM", action="llm_call")
response = call_llm(messages)
result = await checkpoint(
cost_delta_usd=compute_cost(response.usage),
tokens_used=response.usage.total_tokens,
)
if result.breached:
# Agent handles the limit gracefully — no exception, no crash
messages.append({"role": "system", "content": result.system_prompt})
return call_llm(messages) # LLM summarises what it found
if response.is_done():
return response
Install
pip install agentfences
How it works
checkpoint() returns a CheckpointResult after every call — not an exception. The agent reads it and decides what to do: stop, summarise, ask for more budget. No try/catch in your orchestration layer.
result = await checkpoint(cost_delta_usd=0.02, tokens_used=450)
result.ok # True if within all limits
result.breached # True if a limit was crossed
result.breach_type # "budget_exceeded" | "iteration_limit" | "time_limit" | "token_limit"
result.message # "I've reached my budget limit... I'll summarise what I found."
result.system_prompt # ready to inject into LLM conversation context
Quickstart — no backend needed
import agentfences
from agentfences import governed, checkpoint, log_decision
agentfences.init(local_only=True) # no account, no API key
@governed(budget_usd=0.10, max_iterations=5, max_tokens=2000)
async def my_agent(query: str):
for step in range(100):
log_decision(reasoning=f"step {step}: searching", action="search")
result = await checkpoint(cost_delta_usd=0.02, tokens_used=200)
if result.breached:
return result.message # or inject result.system_prompt into your LLM
return "done"
Limits
| Limit | Parameter | result.breach_type |
|---|---|---|
| Spend | budget_usd |
budget_exceeded |
| Iterations | max_iterations |
iteration_limit |
| Duration | max_duration_ms |
time_limit |
| Tokens | max_tokens |
token_limit |
Legacy exception mode
If you prefer exceptions over result objects:
@governed(budget_usd=0.50, raise_on_breach=True)
async def my_agent():
...
await checkpoint(cost_delta_usd=0.02) # raises BudgetExceeded, IterationLimitReached, etc.
Modes
Local (free) — governance runs entirely in-process. No account, no backend, no API key.
agentfences.init(local_only=True)
Cloud (coming soon) — persistent audit trails, live dashboard, server-authoritative enforcement. Same code, one line changes.
agentfences.init(api_key="fc_...", endpoint="https://your-fences-instance.com")
License
MIT
Metadata
Release files for agentfences 0.1.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| agentfences-0.1.5.tar.gz | 8.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| agentfences-0.1.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 15.9 kB
Release files / agentfences-0.1.5.tar.gz
| Download URL | agentfences-0.1.5.tar.gz |
|---|---|
| Size | 8.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7527b7c2d7710f180c2d2b149f1c7c8c58acd414ddd02992d6f00b46f983c758
|
|
BLAKE2b-256 checksum How to use checksums |
866eefecc253a0b5a83e76d91661375d0a2b38625e02e38fb53441f19510843b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.3
|
Release files / agentfences-0.1.5-py3-none-any.whl
| Download URL | agentfences-0.1.5-py3-none-any.whl |
|---|---|
| Size | 7.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6720d8f55a5868cd63312e301f30ad56759ea11830770b41ffcf7c496098dd99
|
|
BLAKE2b-256 checksum How to use checksums |
5ca221e70d0066f3e73c6d6d58e6852ca5acf129de580137802f26d2282c05e8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.3
|