Human Approval
Human approval gates pause the agent before sensitive actions and require a human to explicitly approve or reject the proposed action.
8 min•By Priygop Team•Updated 2026
Approval Gate Implementation
Approval Gate Implementation
# Human approval gate for sensitive agent actions
from datetime import datetime, timedelta
class ApprovalGate:
def __init__(self, timeout_hours: int = 24):
self.pending = {} # approval_id -> request
self.decisions = {} # approval_id -> decision
self.timeout = timedelta(hours=timeout_hours)
def request_approval(
self,
agent_id: str,
action: str,
action_details: dict,
notify_email: str
) -> str:
"""Submit an action for human approval. Returns an approval ID."""
approval_id = f"APR-{datetime.now().strftime('%Y%m%d%H%M%S')}"
expires_at = datetime.now() + self.timeout
request = {
"approval_id": approval_id,
"agent_id": agent_id,
"action": action,
"details": action_details,
"requested_at": datetime.now().isoformat(),
"expires_at": expires_at.isoformat(),
"notify": notify_email,
"status": "pending"
}
self.pending[approval_id] = request
# In production: send email/Slack notification to notify_email
print(f" [APPROVAL REQUESTED] ID: {approval_id}")
print(f" Action: {action}")
print(f" Details: {action_details}")
print(f" Notify: {notify_email}")
print(f" Expires: {expires_at.strftime('%Y-%m-%d %H:%M')}")
return approval_id
def wait_for_decision(self, approval_id: str, poll_interval: int = 5) -> dict:
"""
Wait for a human decision. In production, this is async/event-driven.
Here we simulate an immediate approval.
"""
if approval_id not in self.pending:
return {"status": "error", "error": "Approval ID not found"}
# Check for timeout
request = self.pending[approval_id]
expires = datetime.fromisoformat(request["expires_at"])
if datetime.now() > expires:
return {"status": "timeout",
"reason": f"No decision received within {self.timeout.total_seconds()/3600:.0f} hours"}
# Simulate human approval (in production: poll a database or listen for webhook)
simulated_decision = {
"decision": "approved",
"approved_by": "manager@example.com",
"notes": "Approved — customer has valid claim",
"decided_at": datetime.now().isoformat()
}
return {**simulated_decision, "approval_id": approval_id,
"action": request["action"]}
gate = ApprovalGate(timeout_hours=24)
approval_id = gate.request_approval(
"support_agent", "issue_refund",
{"order_id": "ORD-123", "amount": 249.99, "reason": "Defective product"},
"manager@example.com"
)
decision = gate.wait_for_decision(approval_id)
print(f"\nDecision: {decision['decision']} by {decision['approved_by']}")