ActionGate
Deterministic, pre-execution gating for semantic actions (e.g. tool calls) in agent systems.
Source of Truth
The canonical source is github.com/actiongate-oss/actiongate. PyPI distribution is a convenience mirror—verify against the repo if provenance matters to you.
Install
pip install actiongate # PyPI
pip install actiongate[redis] # with Redis support
pip install -e . # from source
Vendoring encouraged. This is a small, stable primitive. Copy it into your codebase, fork it, reimplement it in Rust/Go/whatever. See SEMANTICS.md for the behavioral contract if you reimplement.
Quick Start
from actiongate import Engine, Gate, Policy, Blocked
engine = Engine()
@engine.guard(
Gate("api", "search", "user:123"),
Policy(max_calls=5, window=60)
)
def search(query: str) -> list[str]:
return api.search(query)
try:
results = search("hello")
except Blocked as e:
print(f"Rate limited: {e.decision.message}")
Core Concepts
Gate
Identifies what's being rate-limited:
Gate(namespace, action, principal)
Gate("billing", "refund", "user:123") # per-user
Gate("support", "escalate", "agent:42") # per-agent
Gate("api", "search", "global") # global limit
Policy
Policy(
max_calls=5, # allow N calls per window
window=60, # rolling window (seconds)
cooldown=2, # min seconds between calls
mode=Mode.HARD, # HARD raises, SOFT returns Result
on_store_error=StoreErrorMode.FAIL_CLOSED
)
Two Decorator Styles
@engine.guard(gate, policy) # returns T, raises Blocked
@engine.guard_result(gate, policy) # returns Result[T], never raises
Scope & Non-Goals
ActionGate does:
- Pre-execution rate limiting (allow N, block N+1)
- Cooldown enforcement (min time between calls)
- Atomic check-and-reserve for correctness under concurrency
- Deterministic decisions with full explainability
ActionGate does not:
- Make LLM calls or consume tokens
- Do semantic/intent analysis
- Manage cost, budgets, or billing
- Orchestrate multi-agent workflows
- Provide authentication or authorization
- Replace circuit breakers, retries, or backpressure
See SEMANTICS.md for the formal behavioral contract.
Distributed: Redis Backend
import redis
from actiongate import Engine, RedisStore
client = redis.Redis(host='localhost', port=6379, decode_responses=True)
engine = Engine(store=RedisStore(client))
- Atomic via Lua script
- Keys auto-expire at
max(window, cooldown) × 1.5 - Member format
{timestamp}:{nonce}prevents collision
Observability
engine.on_decision(lambda d: logger.info(f"{d.status}: {d.gate}"))
Every decision includes: status, reason, gate, policy, calls_in_window, time_since_last. See examples.py for Prometheus/StatsD patterns.
Benchmarks
python -m actiongate.bench
python -m actiongate.bench --redis localhost:6379
Results from local benchmark on Apple M1, Python 3.12. Run to reproduce on your hardware.
| Store | p50 | p95 | p99 | Throughput |
|---|---|---|---|---|
| MemoryStore | ~2μs | ~3μs | ~5μs | ~400k ops/s |
| RedisStore (localhost) | ~200μs | ~300μs | ~500μs | ~4k ops/s |
API Reference
| Type | Purpose |
|---|---|
Engine |
Core gating logic |
Gate |
Action identity tuple |
Policy |
Rate limit configuration |
Decision |
Evaluation result with full context |
Result[T] |
Wrapper for guard_result |
Blocked |
Exception from guard |
MemoryStore |
Single-process backend |
RedisStore |
Distributed backend |
| Enum | Values |
|---|---|
Mode |
HARD, SOFT |
StoreErrorMode |
FAIL_CLOSED, FAIL_OPEN |
Status |
ALLOW, BLOCK |
BlockReason |
RATE_LIMIT, COOLDOWN, STORE_ERROR |
License
Apache License 2.0. See LICENSE for the full text.
Metadata
Release files for actiongate 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 | Provenance | Actions |
|---|---|---|---|---|
| actiongate-0.3.0.tar.gz | 27.8 kB | Without provenance | Details for actiongate-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| actiongate-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for actiongate-0.3.0-py3-none-any.whl |
Total release size: 45.6 kB
Release files / actiongate-0.3.0.tar.gz
| Download URL | actiongate-0.3.0.tar.gz |
|---|---|
| Size | 27.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a95ef35f99fe9089c60673973ee4185946bdd72fcca58cbc3cf2887f875a9b87
|
|
BLAKE2b-256 checksum How to use checksums |
77dc3818e2f8dfb7a5e28e55f1e9ae93337ee3489aa1e80bbd2c12d20815e2f5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|
Release files / actiongate-0.3.0-py3-none-any.whl
| Download URL | actiongate-0.3.0-py3-none-any.whl |
|---|---|
| Size | 17.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
37143b9da9f4205c8388216edc8f043674cbffa8dda5e9d89e44ef83d81668f6
|
|
BLAKE2b-256 checksum How to use checksums |
24a776f12d7a8b3887de5a8e32307f986ae9eac22b63ac5f1518660b963c0eb6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|
Security for actiongate 0.3.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.