Skip to main content
Human-in-the-loop (HITL) is the pattern where the agent pauses execution to request approval or input from a human operator before proceeding with a sensitive action. This is critical for any agent that can take destructive or irreversible actions — deleting data, modifying production systems, sending communications, or spending money. AFK implements HITL through two components: a 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. Use interaction_mode="interactive" with a custom InteractionProvider:

Headless vs interactive modes

AFK supports three interaction modes, configured via RunnerConfig.interaction_mode:

How the policy flow works

  1. The agent calls a tool (e.g., drop_table).
  2. Before executing, the runner sends a PolicyEvent to the PolicyEngine.
  3. The engine evaluates all rules. If a rule matches, it returns a PolicyDecision with the configured action.
  4. If the action is request_approval:
    • In headless mode: the runner auto-resolves using approval_fallback.
    • In interactive mode: the runner creates an ApprovalRequest and sends it to the InteractionProvider. Execution pauses until the provider returns an ApprovalDecision.
  5. If approved (kind="allow"): the tool executes normally.
  6. If denied (kind="deny"): the tool execution is skipped and the model receives a denial message as the tool result.
  7. A policy_decision event is emitted in the run event stream for audit purposes.

Policy decision actions