> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agno.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Dual HITL: Step User Input + Executor Tool Confirmation (Streaming)

> Two different HITL types in one step: Pause 1 (step-level): Step has requires_user_input=True -> collects city name from user Pause 2 (executor-level): Agent's tool has requires_confirmation=True -> user confirms tool call.

```python dual_level_hitl.py theme={null}
"""
Dual HITL: Step User Input + Executor Tool Confirmation (Streaming)
====================================================================

Two different HITL types in one step:
  Pause 1 (step-level): Step has requires_user_input=True -> collects city name from user
  Pause 2 (executor-level): Agent's tool has requires_confirmation=True -> user confirms tool call

The user input is injected into step_input.additional_data["user_input"] and the agent
receives it as context.

Usage:
    .venvs/demo/bin/python cookbook/04_workflows/08_human_in_the_loop/dual_level_hitl/02_step_user_input_and_tool_confirmation.py
"""

from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.os import AgentOS
from agno.tools import tool
from agno.workflow.step import Step
from agno.workflow.workflow import Workflow
from rich.console import Console
from workflow_db import db

console = Console()


@tool(requires_confirmation=True)
def book_flight(origin: str, destination: str) -> str:
    """Book a flight between two cities.

    Args:
        origin: Departure city.
        destination: Arrival city.
    """
    return f"Flight booked: {origin} -> {destination}"


travel_agent = Agent(
    name="TravelAgent",
    model=OpenAIChat(id="gpt-4o-mini"),
    tools=[book_flight],
    instructions=(
        "You are a travel agent. Use the book_flight tool to book flights. "
        "Check the user_input in the context for the destination city."
    ),
    telemetry=False,
)


workflow = Workflow(
    name="UserInputAndToolConfirm",
    db=db,
    steps=[
        Step(
            name="book_travel",
            agent=travel_agent,
            requires_user_input=True,
            user_input_message="Which city do you want to fly to?",
            user_input_schema=[
                {
                    "name": "destination",
                    "field_type": "text",
                    "description": "Destination city",
                    "required": True,
                },
            ],
        ),
    ],
    telemetry=False,
)

agent_os = AgentOS(
    id="dual-level-hitl-demo",
    description="Demo: dual-level HITL workflow",
    name="Dual Level HITL Workflow",
    agents=[travel_agent],
    teams=[],
    workflows=[workflow],
)
app = agent_os.get_app()

if __name__ == "__main__":
    agent_os.serve(app="dual_level_hitl:app", reload=True)
```

The example imports this helper module from the same directory:

```python workflow_db.py theme={null}
from agno.db.postgres import PostgresDb

db_url = "postgresql+psycopg://ai:ai@localhost:5532/ai"
db = PostgresDb(db_url=db_url)
```

## Run the Example

<Steps>
  <Snippet file="create-venv-step.mdx" />

  <Step title="Install dependencies">
    ```bash theme={null}
    uv pip install -U "agno[os]" fastmcp openai psycopg-binary starlette
    ```
  </Step>

  <Step title="Export your API keys">
    <CodeGroup>
      ```bash Mac/Linux theme={null}
      export JWT_VERIFICATION_KEY="your_jwt_verification_key_here"
      export OPENAI_API_KEY="your_openai_api_key_here"
      ```

      ```bash Windows theme={null}
      $Env:JWT_VERIFICATION_KEY="your_jwt_verification_key_here"
      $Env:OPENAI_API_KEY="your_openai_api_key_here"
      ```
    </CodeGroup>
  </Step>

  <Snippet file="run-pgvector-step.mdx" />

  <Step title="Run the example">
    Save the code blocks above as `dual_level_hitl.py` and `workflow_db.py` in the same directory, then run:

    ```bash theme={null}
    python dual_level_hitl.py
    ```
  </Step>
</Steps>

Full source: [cookbook/05\_agent\_os/human\_in\_the\_loop/workflow/dual\_level\_hitl.py](https://github.com/agno-agi/agno/blob/main/cookbook/05_agent_os/human_in_the_loop/workflow/dual_level_hitl.py)
