⚓ Sayay — AI Agent Cost Guardrails (Python)
Budget enforcement middleware for LLM calls. Prevent runaway AI costs with per-user daily/monthly/session budgets or credit systems. Zero dependencies.
Python port of @carloscortezcloud/sayay-guard.
Install
pip install sayay
# Redis storage (optional):
pip install 'sayay[redis]'
Quick Start
import asyncio
from sayay import SayayGuard, MemoryStorage
guard = SayayGuard(
storage=MemoryStorage(),
budget={"daily_usd": 5.0, "monthly_usd": 50.0},
on_exceeded="block",
degrade_to_model="meta-llama/llama-3.3-70b-instruct:free",
)
async def main():
# Before LLM call:
decision = await guard.check("user-123", estimated_cost=0.003)
if decision.action == "block":
raise RuntimeError(f"Budget exceeded: {decision.reason}")
if decision.action == "degrade":
# use decision.suggested_model instead of the expensive model
pass
# ... make the LLM call ...
# After LLM call:
await guard.record("user-123", actual_cost=0.004)
usage = await guard.get_usage("user-123")
print(usage.daily, usage.monthly)
asyncio.run(main())
Storage Backends
| Backend | When to use |
|---|---|
MemoryStorage |
Tests, scripts, single-process agents |
FileStorage |
Local CLI agents that must survive restarts |
RedisStorage |
Production, shared across workers/pods |
Implement SayayStorage (get/increment/reset) for your infra (KV, D1, DynamoDB, Firestore).
Budget options
daily_usd/monthly_usd/session_usd— USD limits (resets UTC midnight / month start)per_call_max_usd— blocks a single expensive callcredits+credits_per_call— credit-based system
Actions
allow → proceed · warn (≥80%) → proceed + warn · degrade (≥95%) → use suggested_model · block → stop.
Examples
examples/strands_agent.py— Strands-style agent hooking check/record per stepexamples/langchain_callback.py— LangChainBaseCallbackHandlerwiring
Tests
uv venv --python 3.12 .venv && uv pip install -e '.[redis]' pytest pytest-asyncio
uv run pytest
License
Apache 2.0
Metadata
Release files for sayay 0.1.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 | Provenance | |
|---|---|---|---|---|
| sayay-0.1.0.tar.gz | 8.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sayay-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 16.4 kB
Release files / sayay-0.1.0.tar.gz
| Download URL | sayay-0.1.0.tar.gz |
|---|---|
| Size | 8.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
85d4c10bb298a8d8f9e15d217f1c0fc9eef8321861cfbbd61aee00c54412f402
|
|
BLAKE2b-256 checksum How to use checksums |
58176cd38191f152e2b72c3f3d7b9ba60463289b1e6faaf126af4cd51e16c4bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.17
|
Release files / sayay-0.1.0-py3-none-any.whl
| Download URL | sayay-0.1.0-py3-none-any.whl |
|---|---|
| Size | 7.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1c1e1b929520204096b8a48ef91405cbc79ee13793cc030e815cc4aa520d3a0e
|
|
BLAKE2b-256 checksum How to use checksums |
03fa9e3fb71c422eead8cbb3e80d6b3dcdd64b243d4dae9e2d90471bbaafa5a9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.17
|
Security for sayay 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.