A single step can use step-level HITL (gate the step itself) and executor-level HITL (gate a tool call inside the agent) together. The workflow pauses twice in sequence: once before the step runs, then again during the step when the agent’s HITL tool is called.Documentation Index
Fetch the complete documentation index at: https://agno-v2-feat-executor-hitl-wf.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
- Pause 1 (step-level): user sees
confirmation_message, callsreq.confirm(). - Pause 2 (executor-level): agent calls
send_alert, user approves the specific tool call. - Step finishes.
The Active-Requirement Pattern
step_requirements accumulates across pauses within a single run. The first pause adds the step-level requirement. After resolution and continue, a second pause adds the executor-level requirement on top of it. To detect the current pause type, always look at the last entry.
Resolution Loop
Wrap continue calls in awhile is_paused: loop. Each pause resolves one gate; the workflow either pauses again or completes.
Supported Combinations
Step-level HITL composes with executor-level HITL across all primitives that support both.| Step-Level Gate | Executor-Level Gate | Pause Order |
|---|---|---|
requires_confirmation on Step | @tool(requires_confirmation=True) | step confirm → tool confirm |
requires_user_input on Step | @tool(requires_confirmation=True) | step input → tool confirm |
requires_output_review on Step | @tool(requires_confirmation=True) | tool confirm → output review |
requires_confirmation on Condition | @tool(requires_confirmation=True) in branch | condition confirm → tool confirm |
requires_user_input on Router | @tool(requires_confirmation=True) in branch | route select → tool confirm |
requires_confirmation on Router | @tool(requires_confirmation=True) in branch | router confirm → tool confirm |
requires_confirmation on Loop | @tool(requires_confirmation=True) in inner step | loop start confirm → tool confirm (per iteration) |
For
requires_output_review + executor HITL, the executor pause comes first (during step execution) and the output review pause comes after (once the step’s output is ready). The order matches when each gate naturally fires.Streaming
The same active-requirement pattern applies. Read the paused run from the session, not the stream.Loop Limitation
Loop with executor HITL inside its inner step pauses on the iteration where the agent calls the HITL tool. The loop’s own requires_confirmation (start gate) fires once before the first iteration. There is no per-iteration executor gate beyond what the agent’s tool already provides.
Cookbooks
Runnable examples in cookbook/04_workflows/08_human_in_the_loop/dual_level_hitl/:| File | Step-Level Gate | Executor-Level Gate |
|---|---|---|
01_step_confirmation_and_tool_confirmation.py | Step confirmation | Tool confirmation |
02_step_user_input_and_tool_confirmation.py | Step user input | Tool confirmation |
03_condition_and_tool_confirmation.py | Condition confirmation | Tool confirmation |
04_router_selection_and_tool_confirmation.py | Router route selection | Tool confirmation |
05_output_review_and_tool_confirmation.py | Step output review | Tool confirmation |
06_loop_confirmation_and_tool_confirmation.py | Loop start confirmation | Tool confirmation |
07_router_confirmation_and_tool_confirmation.py | Router confirmation | Tool confirmation |
09_multi_step_mixed_hitl.py | Multiple steps with mixed gates | Tool confirmation |