> ## 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.

# StudioTools + human-in-the-loop served through AgentOS

> Same HITL studio agent as studio_hitl_agent.py, but running behind AgentOS: the run pauses surface through the AgentOS API and chat UI instead of the console.

Same HITL studio agent as studio\_hitl\_agent.py, but running behind AgentOS: the run pauses surface through the AgentOS API and chat UI instead of the console. When the studio agent is missing details it pauses with a structured multi-select question (ask\_user) or a free-text input request (get\_user\_input), and create\_agent always pauses for explicit confirmation before anything is persisted. The AgentOS UI renders each pause and continues the run with the user's response.

```python studio_hitl_agent_os.py theme={null}
"""StudioTools + human-in-the-loop served through AgentOS.

Same HITL studio agent as studio_hitl_agent.py, but running behind AgentOS:
the run pauses surface through the AgentOS API and chat UI instead of the
console. When the studio agent is missing details it pauses with a structured
multi-select question (ask_user) or a free-text input request
(get_user_input), and create_agent always pauses for explicit confirmation
before anything is persisted. The AgentOS UI renders each pause and continues
the run with the user's response.

Try in the chat UI:
    - "Create an agent called 'research-buddy'."  (the agent must ask for
      tools and instructions, then ask you to confirm the create call)
    - "What models and tools do we have available?"

Usage:
    # Start the AgentOS server
    .venvs/demo/bin/python cookbook/05_agent_os/studio_tool/studio_hitl_agent_os.py
"""

from pathlib import Path

from agno.agent import Agent
from agno.db.sqlite import SqliteDb
from agno.models.anthropic import Claude
from agno.models.openai import OpenAIResponses
from agno.os import AgentOS
from agno.registry import Registry
from agno.tools.calculator import CalculatorTools
from agno.tools.duckduckgo import DuckDuckGoTools
from agno.tools.hackernews import HackerNewsTools
from agno.tools.studio import StudioTools
from agno.tools.user_control_flow import UserControlFlowTools
from agno.tools.user_feedback import UserFeedbackTools

DB_DIR = Path(__file__).parent / "tmp"
DB_DIR.mkdir(exist_ok=True)

db = SqliteDb(id="studio-hitl-os-db", db_file=str(DB_DIR / "studio_hitl_os.db"))

registry = Registry(
    name="Studio HITL Registry",
    tools=[DuckDuckGoTools(), HackerNewsTools(), CalculatorTools()],
    models=[
        OpenAIResponses(id="gpt-5.5"),
        Claude(id="claude-sonnet-4-6"),
    ],
    dbs=[db],
)

studio_agent = Agent(
    id="studio-hitl-agent",
    name="Studio HITL",
    model=OpenAIResponses(id="gpt-5.5"),
    tools=[
        StudioTools(
            registry=registry,
            db=db,
            default_model_id="gpt-5.5",
            # Pause the run for explicit user approval before persisting.
            requires_confirmation_tools=["create_agent"],
        ),
        # Lets the agent ask structured multiple-choice questions.
        UserFeedbackTools(),
        # Lets the agent pause the run and ask for free-text details.
        UserControlFlowTools(),
    ],
    instructions=[
        "You help the user compose new agents from registry primitives.",
        "Call list_tools and list_models first so you know what is available.",
        "NEVER guess or invent missing details.",
        "If the user did not say which tools the new agent needs, use ask_user with one "
        "multi_select question whose options are ONLY the exact tool names returned by "
        "list_tools -- never include your own toolkits as options.",
        "If the user did not provide instructions for the new agent, use get_user_input "
        "to ask for them as free text.",
        "Only call create_agent once the user has supplied tools and instructions, and "
        "pass the exact tool names the user chose.",
        "After creating a component, report its id, name, model and tools.",
    ],
    db=db,
    markdown=True,
)

agent_os = AgentOS(
    id="studio-hitl-agent-os",
    description="Studio agent with human-in-the-loop composition",
    agents=[studio_agent],
    registry=registry,
    db=db,
)
app = agent_os.get_app()


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

## Run the Example

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

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

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

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

  <Step title="Run the example">
    Save the code above as `studio_hitl_agent_os.py`, then run:

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

Full source: [cookbook/05\_agent\_os/studio\_tool/studio\_hitl\_agent\_os.py](https://github.com/agno-agi/agno/blob/main/cookbook/05_agent_os/studio_tool/studio_hitl_agent_os.py)
