Approval¶
Human-in-the-loop gate for AI agents. One decorator, full loop.
Decorator¶
from primitif.approval import require_approval
@require_approval
def deploy(service, branch):
run_pipeline(service, branch)
req = deploy("api-gateway", "main")
print(req.status) # "pending"
print(req.approval_url) # share with a human
The function doesn't run. Instead, it returns an ApprovalRequest with a URL for a human to approve or reject.
Dispatch on webhook¶
When the human decides, your webhook handler runs the original function:
from flask import Flask, request
from primitif import approval, verify_webhook
app = Flask(__name__)
@app.post("/webhook/approval")
def handle():
event = verify_webhook(
body=request.data,
signature=request.headers["X-Webhook-Signature"],
secret="whsec_...",
)
approval.dispatch(event) # runs deploy() with original args
return "", 200
Without decorator¶
from primitif import approval
req = approval.create_request(
"Delete user account #1234",
context={"user_id": 1234, "reason": "GDPR request"},
callback_url="https://myapp.com/webhooks/approval",
)
print(req.approval_url)
Check status¶
status = approval.get_request(req.id)
print(status.status) # "pending", "approved", "rejected", "expired"