Skip to main content
Approval workflows let you require human sign-off before a tool executes. This is useful for destructive operations, external API calls, or any action where you want a human in the loop.

Enabling Approvals

Configure approval on a tool:
from framework.models.approval_models import ApprovalConfig

@tool(
    name="delete_record",
    description="Delete a CRM record",
    agent="RecordsAgent",
    approval_config=ApprovalConfig(
        enabled=True,
        required_approval_count=1,
        approval_timeout_hours=24,
    ),
)
async def delete_record(record_id: str) -> dict: ...

Approval Flow

  1. The agent decides to call an approval-gated tool
  2. An APPROVAL_REQUIRED event is streamed to the client
  3. Execution pauses until a human approves or denies
  4. On approval → tool executes and the agent continues
  5. On denial → the agent receives the denial and adjusts
  6. On timeout → the request expires

Approval Events

{"type": "APPROVAL_REQUIRED", "delta": {
  "tool_name": "delete_record",
  "input_data": {"record_id": "rec_123"},
  "context": "User asked to remove the duplicate record"
}}
After the user responds:
{"type": "APPROVAL_RESOLVED", "delta": {
  "status": "APPROVED"
}}

Escalation

Configure escalation for approvals that aren’t acted on:
ApprovalConfig(
    enabled=True,
    required_approval_count=1,
    approval_timeout_hours=4,
    escalation_config=EscalationConfig(
        escalate_after_hours=2,
        escalation_target="[email protected]",
    ),
)