Approvals
When a tool is in a policy's Review list, guard() returns requires_human_review=True and the action pauses. A human approves or denies via the Gavrun dashboard.
Polling for approval
python
result = client.guard(
action="send_outreach_email",
execute=lambda: None, # deferred
tools=["send_outreach_email"],
prompt=f"Send email to {contact_email}",
attachments=[{"type": "email_draft", "subject": subject, "body": body}],
)
if result.requires_human_review:
approval_id = result.decision.get("approval_id")
decision_id = result.decision.get("decision_id")
print(f"Waiting for approval: https://agentmanager.gavrun.ai/approvals")
while True:
status = client.get_approval_status(approval_id=approval_id)
if status["status"] == "approved":
# Execute the action now
send_email(contact_email, subject, body)
break
elif status["status"] == "denied":
raise PermissionError("Email send denied by reviewer")
time.sleep(3)get_approval_status()
python
def get_approval_status(
self,
*,
approval_id: str | None = None,
decision_id: str | None = None,
request_id: str | None = None,
) -> dict[str, Any]At least one parameter is required.
Response fields
| Field | Type | Description |
|---|---|---|
status | str | "pending" | "approved" | "denied" |
metadata | dict | Original attachments + any edited_attachments from reviewer |
reviewer_note | str | None | Optional note left by the reviewer |
decided_at | str | None | ISO timestamp when the decision was made |
Reviewer edits
If the reviewer edits the action (e.g. modifies an email draft before approving), the edited version is available in metadata["edited_attachments"]:
python
status = client.get_approval_status(approval_id=approval_id)
if status["status"] == "approved":
meta = status.get("metadata", {})
edited = meta.get("edited_attachments")
if edited:
# Use reviewer's version
draft = edited[0]
else:
# Use original draft
draft = meta["attachments"][0]
send_email(contact_email, draft["subject"], draft["body"])Attachments
Pass attachments to guard() to show context to the reviewer:
python
client.guard(
action="send_email",
execute=lambda: None,
tools=["send_email"],
attachments=[{
"type": "email_draft",
"subject": "Q3 update",
"body": "Dear ...",
}],
)The dashboard renders email_draft attachments with an editable subject/body.