Pause Anatomy

The objects a paused workflow exposes: WorkflowRunOutput, StepRequirement, and the executor requirements you resolve to continue.

When a workflow pauses for HITL, it exposes the pause through three nested objects. You read them to find out what is being asked, then resolve the innermost ones and call continue_run.

run_output = workflow.run("...")

if run_output.is_paused:
    for step_req in run_output.step_requirements or []:
        ...  # inspect and resolve
    run_output = workflow.continue_run(run_output)

1. WorkflowRunOutput

The top-level run object tells you that a pause happened and where.

FieldTypeDescription
is_pausedboolTrue while waiting for user action
pause_kind"step" | "executor" | NoneWhich level paused. None when not paused.
paused_step_nameOptional[str]Name of the step that paused
paused_step_indexOptional[int]Index of the paused step
step_requirementsOptional[List[StepRequirement]]All requirements accumulated across pauses. The last entry is active.

Convenience filters return subsets of step_requirements:

PropertyReturns requirements that need...
active_step_requirementsany resolution (not yet resolved)
steps_requiring_confirmationconfirm / reject
steps_requiring_user_inputuser input values
steps_requiring_output_reviewoutput review
steps_requiring_routeroute selection
steps_requiring_executor_resolutionexecutor (agent/team) tool resolution

step_requirements accumulates resolved requirements as run history. To determine the current pause, read only the last entry: (run_output.step_requirements or [])[-1:]. This matters during nested HITL, where a single run pauses more than once. The filter properties above already exclude resolved requirements, so prefer them when you can.

2. StepRequirement

Each entry in step_requirements describes one paused step. The fields that are set depend on what kind of pause it is.

FieldSet WhenDescription
step_name / step_index / step_idalwaysIdentifies the step
step_typealwaysThe primitive that created it (Step, Loop, Router, ...)
requires_confirmationstep confirmationPending confirm/reject
confirmation_messagestep confirmationMessage to show the user
requires_user_inputstep user inputPending input values
user_input_schemastep user inputList[UserInputField] to fill
requires_route_selectionrouter selectionPending route choice
available_choicesrouter selectionRoute names to pick from
requires_output_reviewoutput reviewOutput ready for review
step_outputoutput reviewThe executed StepOutput under review
requires_executor_inputexecutor pauseAn agent/team tool call paused
executor_requirementsexecutor pauseList of pending tool calls (see below)
executor_id / executor_name / executor_typeexecutor pauseThe paused agent or team

Resolution methods (step-level):

MethodFor
confirm()Confirmation
reject(feedback=...)Confirmation / output review
edit(new_output)Output review (accept with edits)
set_user_input(**values)User input
select(choice) / select_multiple([...])Route selection

Status properties: needs_confirmation, needs_user_input, needs_output_review, needs_route_selection, needs_executor_resolution, is_resolved, is_timed_out.

3. Executor Requirements

When requires_executor_input is True, the step paused because the agent or team called a HITL tool. Each entry in executor_requirements is one pending tool call: the agent's RunRequirement serialized to a dict. You resolve it by mutating the dict in place.

KeyDescription
["tool_execution"]["tool_name"]Name of the paused tool
["tool_execution"]["tool_args"]Arguments the agent chose
["tool_execution"]["requires_confirmation"]True for requires_confirmation tools
["tool_execution"]["requires_user_input"]True for requires_user_input tools
["tool_execution"]["external_execution_required"]True for external_execution tools
["tool_execution"]["user_input_schema"]Fields the user must supply (for requires_user_input tools)

Resolution mutations (executor-level):

MutationFor
["confirmation"] = True and ["tool_execution"]["confirmed"] = TrueApprove @tool(requires_confirmation=True)
["confirmation"] = False, ["tool_execution"]["confirmed"] = False, optional ["tool_execution"]["confirmation_note"]Reject a confirmation
Fill value on each field in ["user_input_schema"] and ["tool_execution"]["user_input_schema"]@tool(requires_user_input=True)
["external_execution_result"] = result and ["tool_execution"]["result"] = result@tool(external_execution=True)

See Executor HITL for full resolution examples.

Resolution Flow

run_output = workflow.run("...")

while run_output.is_paused:
    # Active requirement only (history-safe)
    for step_req in (run_output.step_requirements or [])[-1:]:
        if step_req.requires_executor_input:
            for executor_req in step_req.executor_requirements or []:
                executor_req["confirmation"] = True
                executor_req["tool_execution"]["confirmed"] = True
        elif step_req.needs_confirmation:
            step_req.confirm()
        elif step_req.needs_user_input:
            step_req.set_user_input(**collect_values(step_req))
        elif step_req.needs_route_selection:
            step_req.select(choose(step_req.available_choices))

    run_output = workflow.continue_run(run_output)

print(run_output.content)

Developer Resources