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:
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.