tbay
Execution safety for AI agent tool calls: idempotency, TTL and semantic caching, singleflight deduplication, risk-tiered policy, spend budgets, a cross-process kill switch, human approval gating (optionally cryptographically signed), crash recovery, lifecycle events with optional OpenTelemetry spans, and a reasoning- and agent-linked audit log. A library you install, not a service you depend on.
from tbay import TbayClient, guarded
client = TbayClient("postgresql://postgres:tbay@localhost:5432/tbay")
# also: "sqlite:///~/.tbay/db.sqlite" or "redis://localhost:6379/0"
@guarded(client, policy="readonly")
def github_search(query: str) -> dict:
return real_github_api_call(query)
@guarded(client, policy="destructive")
def refund_customer(customer_id: str, amount: float) -> dict:
return stripe_refund(customer_id, amount)
github_search now caches and collapses concurrent duplicates;
refund_customer never double-runs and pauses for a human before
executing. @guarded only wraps a plain callable, so it drops in under
LangChain's @tool, the OpenAI Agents SDK's @function_tool, CrewAI
tools, an MCP server's tool handlers, or bare functions
(recipes).
When something goes wrong anyway, you have an emergency brake and a ceiling on the damage:
# policy.yaml: refunds may total at most $1000/day, across every process
policies:
destructive:
approval_required: true
budget: {arg: amount, max: 1000, per: 1d}
$ tbay pause --reason "agent runaway" # stop every guarded call, everywhere, now
$ tbay resume
Agent frameworks solve planning and orchestration; none of them solve execution safety. Once a tool is selected, nothing stops it from being called twice, called too often, or fired on a destructive action without a human in the loop. tbay sits underneath any framework and handles that, durably, across processes, in whatever database you already run. Not a hosted service: state lives entirely in a database you own; nothing calls home.
Install
pip install tbay # SQLite backend, stdlib only
pip install tbay[postgres] # + Postgres
pip install tbay[redis] # + Redis
# or: uv add tbay / "tbay[postgres]" / "tbay[redis]"
Documentation
| Guide | What it covers |
|---|---|
| Quickstart | First guarded tool, the dev container, running the demo |
| Tutorial | 13 runnable, narrated scripts: every feature, step by step, SQLite-only |
| Design rationale | Why each mechanism works the way it does |
| Policies | The four risk tiers, the YAML file, every policy field |
| Caching and idempotency | Idempotency keys, TTL, singleflight, semantic caching, volatile calls, rate limits |
| Approvals | Pause/approve flow, signed webhooks, bypass thresholds, signed approvals, rejection reasons |
| Runtime controls | The kill switch (tbay pause), spend budgets, stale-lease crash recovery |
| Observability | Audit log, lifecycle events, OpenTelemetry, reasoning traces, agent identity, the CLI, the dashboard |
| Integrations | LangChain, OpenAI Agents SDK, CrewAI, MCP servers, guard_tools |
| Storage backends | SQLite, Postgres, Redis: guarantees, schema, migrations, clearing data |
| API reference | Every public function and class, with examples |
Try it in two minutes
Open the repo in VS Code, run "Dev Containers: Reopen in Container" (bundles Python + Postgres + Redis, nothing to install), then:
uv run python dashboard/app.py # terminal 1: live dashboard on port 8787
uv run python examples/demo.py # terminal 2: every feature, one run
The demo ends blocked on a $500 refund; approve or reject it from the dashboard and watch the blocked call resume or learn why it was refused. Details in the Quickstart.
Development
uv sync --extra dev
uv run pytest
Postgres- and Redis-backed tests need TBAY_TEST_PG_DSN /
TBAY_TEST_REDIS_URL; CI and the dev container provide both.
License
MIT
Release files for tbay 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tbay-0.3.0.tar.gz | 61.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tbay-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 114.7 kB
Release files / tbay-0.3.0.tar.gz
| Download URL | tbay-0.3.0.tar.gz |
|---|---|
| Size | 61.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f933625b87882f355e4a1be8b1c3db01391e1b720044c663d48610760a51850c
|
|
BLAKE2b-256 checksum How to use checksums |
336f89f2fc2a0404f822151aa8d64be64e3caf91d91168d8a13ccd89892fc96f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / tbay-0.3.0-py3-none-any.whl
| Download URL | tbay-0.3.0-py3-none-any.whl |
|---|---|
| Size | 52.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9792ac100809c96d0b03c88fb3394a172382fee88edf39a5ac6701ce9f3eb06e
|
|
BLAKE2b-256 checksum How to use checksums |
be8a7706cf1de745a51a95b7dc033acf4ed92e791d1f5d7ef51aa840e8e56de0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|