Overview
Tool Guards are decorators for protecting tool functions (the functions your agent can invoke). v0.1 includes:@actguard.rate_limitfor call-rate control.@actguard.circuit_breakerfor dependency-health protection.@actguard.max_attemptsfor per-run attempt caps.@actguard.timeoutfor wall-clock execution limits.@actguard.idempotentfor at-most-once behavior by idempotency key.@actguard.provefor minting verified facts from read-tool results.@actguard.enforcefor checking chain-of-custody rules before writes.@actguard.tool(...)as a unified decorator that composes guards.
actguard.configure()
Config fields
| Field | Type | Description |
|---|---|---|
agent_id | str | Identifier for this agent instance |
gateway_url | str | None | ActGuard gateway endpoint |
api_key | str | None | API key for the gateway |
RunContext
max_attempts and idempotent require an active run-scoped state:
RunContext also supports async:
RunContext, these decorators raise MissingRuntimeContextError.
@actguard.rate_limit
| Parameter | Type | Default | Description |
|---|---|---|---|
max_calls | int | 10 | Maximum calls in the window |
period | float | 60.0 | Window length in seconds |
scope | str | None | None | Function argument name used as key; None means global counter |
FailureKind and presets
@circuit_breaker uses typed FailureKind values:
TRANSPORTTIMEOUTOVERLOADEDTHROTTLEDAUTHINVALIDNOT_FOUNDCONFLICTUNKNOWN
FAIL_ON_DEFAULT = {TRANSPORT, TIMEOUT, OVERLOADED}IGNORE_ON_DEFAULT = {INVALID, NOT_FOUND, CONFLICT}FAIL_ON_STRICT = FAIL_ON_DEFAULT | {AUTH, THROTTLED}FAIL_ON_INFRA_ONLY = {TRANSPORT, TIMEOUT}
@actguard.circuit_breaker
| Parameter | Type | Default | Description |
|---|---|---|---|
name | str | required | Dependency name shown in open-circuit errors |
max_fails | int | 3 | Number of counted failures before opening |
reset_timeout | float | 60.0 | Seconds before calls are allowed again |
fail_on | set[FailureKind] | FAIL_ON_DEFAULT | Kinds that increment/open |
ignore_on | set[FailureKind] | IGNORE_ON_DEFAULT | Kinds that do not affect breaker state |
@actguard.max_attempts
RunContext.
| Parameter | Type | Default | Description |
|---|---|---|---|
calls | int | required | Maximum number of allowed attempts per run |
callsmust be an integer>= 1.- Attempt count increments before the tool body runs.
- Failed executions still consume an attempt.
@actguard.timeout
| Parameter | Type | Default | Description |
|---|---|---|---|
seconds | float | required | Timeout threshold in seconds |
executor | Executor | None | None | Optional custom executor for sync functions |
- Raises
ToolTimeoutErroron timeout. - Generator and async-generator functions are rejected at decoration time.
- For sync functions, execution is submitted to an executor and timeout includes queue wait time.
- If called inside
RunContext, timeout errors include the currentrun_id.
@actguard.idempotent
(tool_id, idempotency_key) within a RunContext.
| Parameter | Type | Default | Description |
|---|---|---|---|
ttl_s | float | 3600 | Lifetime of stored idempotency outcome |
on_duplicate | "return" | "raise" | "return" | Return cached result or raise on duplicates |
safe_exceptions | tuple | () | Exceptions that clear state and allow retry |
- Decorated function must declare an
idempotency_keyparameter. - Caller must provide a non-empty
idempotency_key. - Duplicate behavior for completed calls:
on_duplicate="return": returns cached result.on_duplicate="raise": raisesDuplicateIdempotencyKey.
- If a prior attempt failed with an exception not in
safe_exceptions, retries raiseIdempotencyOutcomeUnknownuntil TTL expiry. - Concurrent in-flight duplicate calls raise
IdempotencyInProgress.
Chain-of-custody guards
actguard.session()
prove and enforce require an active chain-of-custody session:
session() also supports async:
prove and enforce raise GuardError(code="NO_SESSION").
@actguard.prove
| Parameter | Type | Default | Description |
|---|---|---|---|
kind | str | required | Fact kind/category (for example order_id) |
extract | str | Callable | required | Field/attribute name, or callable that extracts value(s) from result |
ttl | float | 300 | Fact lifetime in seconds |
max_items | int | 200 | Maximum minted values per tool invocation |
on_too_many | "block" | "truncate" | "block" | Block with GuardError or mint first max_items only |
- Supports sync and async tool functions.
- Requires an active
actguard.session(...). - Minted values are normalized to strings.
on_too_many="block"raisesGuardError(code="TOO_MANY_RESULTS").
@actguard.enforce
GuardError.
Notes:
- Supports sync and async tool functions.
- Requires an active
actguard.session(...). - Uses function argument binding (including defaults) before rule evaluation.
Rule classes
RequireFact
Threshold
BlockRegex
Prove-then-enforce pattern
In-memory store semantics
- Verified facts are stored in-memory, in-process, and are ephemeral.
- Facts are scoped by session id and scope hash.
- Data does not survive process restart and is not shared across processes.
@actguard.tool (unified decorator)
idempotent -> max_attempts -> circuit_breaker -> rate_limit -> timeout -> fn
Example:
Name collision note: Many frameworks export their own@tool. Preferimport actguardand@actguard.tool(...).@actguard.tool(...)currently composesrate_limit,circuit_breaker,max_attempts,timeout, andidempotent. Use@actguard.proveand@actguard.enforceas separate decorators.
Exceptions
ToolGuardError
GuardError
@prove / @enforce when chain-of-custody checks fail.
Common code values:
NO_SESSIONMISSING_FACTTOO_MANY_RESULTSTHRESHOLD_EXCEEDEDPATTERN_BLOCKED
ToolExecutionError
RateLimitExceeded
Raised when call rate exceedsmax_calls in period.
| Attribute | Type | Description |
|---|---|---|
func_name | str | Decorated function name |
scope_value | str | None | Runtime scope value (or global scope) |
max_calls | int | Configured call limit |
period | float | Configured window |
retry_after | float | Seconds until next call is safe |
CircuitOpenError
Raised when a breaker is OPEN and a call is short-circuited.| Attribute | Type | Description |
|---|---|---|
dependency_name | str | Breaker dependency name |
reset_at | float | Epoch seconds when calls may resume |
retry_after | float | Seconds remaining until reset |
MissingRuntimeContextError
Raised whenmax_attempts or idempotent runs without an active RunContext.
MaxAttemptsExceeded
Raised when calls exceedmax_attempts limit in a run.
| Attribute | Type | Description |
|---|---|---|
run_id | str | Active run id |
tool_name | str | Tool identifier (module:qualname) |
limit | int | Allowed calls |
used | int | Attempts already consumed |
ToolTimeoutError
Raised whentimeout is exceeded. Inherits ToolExecutionError.
| Attribute | Type | Description |
|---|---|---|
tool_name | str | Tool qualname |
timeout_s | float | Configured timeout in seconds |
run_id | str | None | Run id if called inside RunContext |
InvalidIdempotentToolError
Raised at decoration time if the function lacks anidempotency_key parameter.
MissingIdempotencyKeyError
Raised whenidempotency_key is missing, empty, or None.
IdempotencyInProgress
Raised when same(tool, key) is already running.
DuplicateIdempotencyKey
Raised when duplicate key is encountered andon_duplicate="raise".
IdempotencyOutcomeUnknown
Raised when a previous unsafe failure left outcome unknown until TTL expiry.Stacking order with frameworks
Keep framework decorators outermost and actguard decorators innermost.max_attempts or idempotent, execute tools under RunContext.
