PolicyEngine that decides which actions require human intervention, and an InteractionProvider that routes the approval request to a human and returns their decision.
Basic example
Interactive mode with an InteractionProvider
In production, you typically want a real human to review approval requests. Useinteraction_mode="interactive" with a custom InteractionProvider:
Headless vs interactive modes
AFK supports three interaction modes, configured viaRunnerConfig.interaction_mode:
| Mode | Behavior | When to Use |
|---|---|---|
"headless" | Approval requests are auto-resolved using approval_fallback (default: "deny"). No human is involved. | CI/CD pipelines, batch processing, testing, automated workflows where no human is available. |
"interactive" | Approval requests are routed to the configured InteractionProvider. The runner pauses until a decision is returned or approval_timeout_s expires. | Production applications with human operators, chat UIs with approval buttons, Slack-based approval workflows. |
"external" | Similar to interactive, but designed for use in external orchestration systems where the approval mechanism is managed outside AFK. | Enterprise systems with external approval platforms. |
How the policy flow works
- The agent calls a tool (e.g.,
drop_table). - Before executing, the runner sends a
PolicyEventto thePolicyEngine. - The engine evaluates all rules. If a rule matches, it returns a
PolicyDecisionwith the configured action. - If the action is
request_approval:- In headless mode: the runner auto-resolves using
approval_fallback. - In interactive mode: the runner creates an
ApprovalRequestand sends it to theInteractionProvider. Execution pauses until the provider returns anApprovalDecision.
- In headless mode: the runner auto-resolves using
- If approved (
kind="allow"): the tool executes normally. - If denied (
kind="deny"): the tool execution is skipped and the model receives a denial message as the tool result. - A
policy_decisionevent is emitted in the run event stream for audit purposes.
Policy decision actions
| Action | Effect |
|---|---|
"allow" | Proceed with execution. No human interaction needed. |
"deny" | Block execution immediately. The denial reason is reported to the model. |
"request_approval" | Pause and request human approval through the InteractionProvider. |
"request_user_input" | Pause and request freeform text input from a human operator. |