Plugin for human-in-the-loop approval of tool calls.
Sets up an approval handler that intercepts tool calls for specified tools.
The handler is called before each tool execution for tools that have
requires_approval: true, or for tools whose names match the configured list.
Configuration
Store the HITL config in deps under the :hitl_config key:
agent = Agent.new("openai:gpt-4",
plugins: [Nous.Plugins.HumanInTheLoop],
tools: [&MyTools.send_email/2, &MyTools.search/2]
)
{:ok, result} = Agent.run(agent, "Send an email to bob",
deps: %{
hitl_config: %{
tools: ["send_email"],
handler: fn tool_call ->
IO.inspect(tool_call, label: "Approve?")
:approve
end
}
}
)When :tools is provided, those tools are additionally tagged with
requires_approval: true. The handler is always called for every tool that
requires approval — the tagged ones plus any that are inherently gated
(Bash, FileWrite, FileEdit) or gated by the permission policy. It is
never a way to narrow the gate: an approval-required tool outside :tools
still goes to the handler rather than being auto-approved.
Handler Responses
:approve- Proceed with execution:reject- Skip execution, return rejection message{:edit, new_args}- Proceed with modified arguments