Factory with Input Schema

Client-controlled agent parameters validated against a Pydantic schema before the factory runs.

The client sends a factory_input JSON object in the run request. The factory declares a Pydantic model in input_schema, and AgentOS validates the input against it before exposing ctx.input as a typed instance.

"""Factory with Input Schema -- client-controlled agent parameters.

The client sends a `factory_input` JSON object in the run request. The factory
declares a Pydantic model for validation. AgentOS validates the input and
exposes it as `ctx.input` (a typed Pydantic instance).
"""

from typing import Literal

from agno.agent import Agent, AgentFactory
from agno.db.postgres import PostgresDb
from agno.factory import RequestContext
from agno.models.openai import OpenAIResponses
from agno.os import AgentOS
from pydantic import BaseModel

# ---------------------------------------------------------------------------
# Database
# ---------------------------------------------------------------------------

db = PostgresDb(
    id="factory-schema-db",
    db_url="postgresql+psycopg://ai:ai@localhost:5532/ai",
)

# ---------------------------------------------------------------------------
# Input schema
# ---------------------------------------------------------------------------

PERSONAS = {
    "analyst": "You are a data-driven research analyst. Cite sources and use numbers.",
    "advisor": "You are a strategic advisor. Focus on actionable recommendations.",
    "skeptic": "You are a critical skeptic. Challenge assumptions and highlight risks.",
}


class ResearchInput(BaseModel):
    """Schema for factory_input -- validated by AgentOS before the factory runs."""

    persona: Literal["analyst", "advisor", "skeptic"] = "analyst"
    depth: int = 3


# ---------------------------------------------------------------------------
# Factory
# ---------------------------------------------------------------------------


def build_research_agent(ctx: RequestContext) -> Agent:
    """Build a research agent with the requested persona and depth."""
    cfg: ResearchInput = ctx.input

    return Agent(
        model=OpenAIResponses(id="gpt-5.4"),
        db=db,
        instructions=(
            f"{PERSONAS[cfg.persona]}\n\n"
            f"Research depth: {cfg.depth} (higher = more thorough).\n"
            "Be concise but comprehensive."
        ),
        add_datetime_to_context=True,
        markdown=True,
    )


research_factory = AgentFactory(
    db=db,
    id="research-agent",
    name="Research Agent",
    description="Builds a research agent with configurable persona and depth",
    factory=build_research_agent,
    input_schema=ResearchInput,
)

# ---------------------------------------------------------------------------
# AgentOS
# ---------------------------------------------------------------------------

agent_os = AgentOS(
    id="factory-schema-demo",
    description="Demo: agent factory with pydantic input schema",
    agents=[research_factory],
)
app = agent_os.get_app()

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

Run the Example

Save the code above as 02_input_schema_factory.py in a new directory. This is a standalone example; the cookbook’s current input-schema lesson is a separate implementation.

uv venv
source .venv/bin/activate
uv pip install 'agno[os,openai]' 'psycopg[binary]' sqlalchemy
export OPENAI_API_KEY="your-openai-api-key"
python 02_input_schema_factory.py

Before starting, provide a local PostgreSQL database at the URL in the example, or change db_url to your local test database. Its user needs permission to create the session tables.

In another terminal, send the validated factory_input as JSON in the multipart field:

curl http://localhost:7777/agents/research-agent/runs \
  -F 'message=Compare approaches to documentation search.' \
  -F 'factory_input={"persona":"skeptic","depth":3}' \
  -F stream=false

An unsupported persona fails validation before the factory constructs an agent.