guard()
The primary method for gating a risky action. Runs a preflight check against your policy and executes the action only if allowed.
python
client = gavrun.get_client()
result = client.guard(
action="send_email",
execute=lambda: send_email(to, subject, body),
tools=["send_email"],
prompt=f"Send email to {to}: {subject}",
)Signature
python
def guard(
self,
*,
action: str,
execute: Callable[[], Any],
target: str | None = None,
context: dict[str, Any] | None = None,
prompt: str | None = None,
agent_id: str | None = None,
request_id: str | None = None,
session_id: str | None = None,
user_id: str | None = None,
user_role: str | None = None,
tools: list[str] | None = None,
models: list[str] | None = None,
max_tokens: int = 1000,
environment: str | None = None,
context_labels: list[str] | None = None,
steps: list[dict[str, str]] | None = None,
attachments: list[dict[str, Any]] | None = None,
resume_decision_id: str | None = None,
resume_approval_id: str | None = None,
resume_request_id: str | None = None,
) -> GuardResultParameters
| Parameter | Type | Description |
|---|---|---|
action | str | Name of the action being guarded (e.g. "delete_user"). Used as the tool name in the policy check. |
execute | Callable[[], Any] | Zero-argument callable that performs the action. Called only on allow. |
target | str | What the action targets (e.g. "user_database"). Used to build the prompt. |
context | dict | Additional context dict included in the audit record. |
prompt | str | Plain-English description of the action. Auto-generated from action/target/context if omitted. |
session_id | str | Groups related tool calls in the audit log and quota tracking. |
user_id | str | The end user triggering the action. |
user_role | str | Role of the user (e.g. "admin", "operator"). |
tools | list[str] | Tools being used. Defaults to [action]. |
models | list[str] | Models in use for this request. |
max_tokens | int | Estimated token budget. Default 1000. |
attachments | list[dict] | Arbitrary data shown to human reviewers in the approval queue. |
resume_* | str | Resume a previously paused human-review decision. |
Returns
Outcomes
python
result = client.guard(action="delete_user", execute=lambda: delete_user(id), tools=["delete_user"])
if result.executed:
# Policy allowed it — execute() was called, result.result holds the return value
print(result.result)
elif result.requires_human_review:
# Paused — poll for approval
approval_id = result.decision.get("approval_id")
while True:
status = client.get_approval_status(approval_id=approval_id)
if status["status"] == "approved":
# Re-run with resume
result = client.guard(
action="delete_user",
execute=lambda: delete_user(id),
tools=["delete_user"],
resume_approval_id=approval_id,
)
break
elif status["status"] == "denied":
raise PermissionError("Denied by reviewer")
time.sleep(3)
elif result.denied:
raise PermissionError("Blocked by policy")Deferred execution
Pass execute=lambda: None when you want to control execution yourself after the preflight:
python
result = client.guard(
action="refund_order",
execute=lambda: None, # deferred
tools=["refund_order"],
prompt=f"Refund order {order_id}",
)
if not result.denied and not result.requires_human_review:
actual_result = process_refund(order_id)