Skip to main content

Controller Setup Guide

This guide walks you through customizing your Supervaizer controller step by step.

Overview​

info

This step-by-step guide uses the Hello World Agent as a reference example.

See the Quickstart guide for installation instructions.

After running supervaizer scaffold, you'll have a template file to customize. This guide shows you how to:

Define agent parameters: ParameterSetup()

Define agent methods: AgentMethod()

Define the fields of the AgentMethods: AgentMethodField()

Declare the agent: Agent()

Define the account: Account()

Setup the server: Server()

(Optional) Custom Routes: APIRouter()

note

Open supervaizer_control_example.py and adapt the content to your agent.

1. Define agent parameters​

Use Parameter / ParametersSetup to declare what the agent needs. These show up in Supervaize UI and can be marked as env or secret.

Map Parameters
loading...

📖 See the model references

Parameter Documentation

ParameterSetup Documentation

Prompt: Define agent parameters
In my supervaizer_control.py, define the agent parameters using ParametersSetup and Parameter from the supervaizer package.

My agent needs the following configuration:
- [Describe each parameter: name, description, whether it's an environment variable, whether it's a secret]

Use ParametersSetup.from_list([...]) with Parameter objects.
Set is_environment=True for env variables and is_secret=True for secrets.

2. Define agent methods​

Point Supervaizer to your agent's functions.

tip

It usually saves time to create a wrapper module where your agent's methods are called with the expected parameters.

Methods: wire your agent's functions
from supervaizer import AgentMethod

job_start = AgentMethod(
name="start", # This is required
method="agent_simple.job_start", # Path to the main function in dotted notation
params={}, # Default parameters to pass to the function
is_async=False, # Only use sync methods for the moment
fields=[] # Defined below
)

See below for definition of fields

Additional required methods
job_stop = AgentMethod(
name="stop", # Must be present
method="agent_simple.job_stop",
is_async=False,
)

job_status = AgentMethod(
name="status", # Must be present
method="agent_simple.job_status",
is_async=False,
)
Optional: poll method for manual update checking
job_poll = AgentMethod(
name="poll", # Optional
method="agent_simple.job_poll",
description="Check external services for updates",
is_async=False,
)
tip

The job_poll method is optional. Define it when your agent depends on external events (webhooks, email replies, etc.) and you want a manual "Check for updates" button in the workbench. See Manual Polling for details.

📖 See the model reference

ParameterModel Documentation

Prompt: Define agent methods
In my supervaizer_control.py, define the AgentMethod entries that wire Supervaizer to my agent's functions.

My agent module is called [my_agent_module] and exposes these functions:
- [function_name] for starting jobs
- [function_name] for stopping jobs
- [function_name] for checking status

Create three AgentMethod objects:
1. job_start with name="start", method="[my_agent_module].[start_function]", is_async=False, params and fields (fields will be defined next)
2. job_stop with name="stop", method="[my_agent_module].[stop_function]", is_async=False
3. job_status with name="status", method="[my_agent_module].[status_function]", is_async=False

The "start" and "stop" and "status" method names are required by Supervaizer.

3. Define the fields of the AgentMethods​

The fields parameter defines the user input form that will be displayed in the Supervaize UI. Each field specifies what data users need to provide when calling your agent method.

Field setup for the "Start" method​

Fields of Start AgentMethod
loading...

📖 See the model reference

AgentMethodField Documentation

Prompt: Define AgentMethod fields
In my supervaizer_control.py, define the AgentMethodField entries for the "start" method's fields parameter.

These fields define the user input form displayed in the Supervaize UI when a job is launched.

My start method needs the following user inputs:
- [Field name, type (str/int/float/bool), field_type (CharField/IntegerField/TextField/BooleanField), required or optional]

Create AgentMethodField objects and assign them to the fields=[] list of the job_start AgentMethod.
Each field needs: name, type, field_type, and required.

Dynamic choices​

For fields whose options are determined at runtime (e.g., a list of projects fetched from a database), use dynamic_choices instead of static choices:

AgentMethodField(
name="List of projects",
type=str,
field_type="ChoiceField",
dynamic_choices="projects", # key name — resolved at runtime
required=True,
)

Then define a callback function and pass it to your Agent:

def get_dynamic_choices(method_name: str, context: dict) -> dict[str, list[tuple[str, str]]]:
if method_name == "start":
# Fetch from database, API, or any source
# context contains workspace_id and mission_id
return {
"projects": [("P1", "Project 1"), ("P2", "Project 2"), ("P3", "Project 3")],
}
return {}

agent = Agent(
name="my_agent",
# ... other fields ...
dynamic_choices_callback=get_dynamic_choices,
)
info

choices and dynamic_choices are mutually exclusive on a field. Use choices for fixed options known at definition time, and dynamic_choices for options that change at runtime.

See the full Dynamic Choices guide for details.

4. Declare the agent​

The Agent class defines your agent's metadata and capabilities. This is where you specify what your agent does, who maintains it, and how it can be discovered.

Agent definition
loading...

📖 See the model reference

Agent Documentation

Prompt: Declare the agent
In my supervaizer_control.py, declare the Agent instance that registers my agent with Supervaizer.

Use the following metadata:
- name: [My Agent Name]
- author: [Author Name <email>]
- version: [version string, e.g. "1.0"]
- description: [What the agent does]
- tags: [list of tags for discovery, e.g. "automation", "data processing"]

Generate a deterministic ID using shortuuid.uuid(name).
Wire the previously defined methods using AgentMethods(job_start=..., job_stop=..., job_status=..., job_poll=... (optional)).
Attach the parameters_setup defined in step 1.
tip

If your agent uses dynamic choice fields, pass the dynamic_choices_callback parameter to the Agent constructor. See Dynamic Choices.

5.Setup the Supervaize Account and configure your Environment variables​

info

This step is not needed to run the supervaizer as an A2A server only. See Protocol support

Create your developer account on the Supervaize platform.

Create your API Key and collect your environment variables.

See the Quickstart guide to setup the environment variables

Account definition
loading...

📖 See the model reference

Account Documentation

Prompt: Setup the account
In my supervaizer_control.py, define the Supervaize Account using environment variables.

Create an Account instance with:
- workspace_id from SUPERVAIZE_WORKSPACE_ID env var (default to a dummy value)
- api_key from SUPERVAIZE_API_KEY env var (default to a dummy value)
- api_url from SUPERVAIZE_API_URL env var (default to "https://app.supervaize.com")

Use os.getenv() with fallback defaults to prevent errors when env vars are missing.

6. Setup the Server​

Config​

The Server class wraps all the defined components together.

At the minimum, the server requires at least one agent to be defined and the supervisor account (we are using Supervaize as the supervisor).

Server definition
loading...

:::warning Important Note that if supervisor_account is provided, the A2A protocol is automatically activated :::

📖 See the model reference

Server Documentation

Server launch​

Server launch
loading...

See Server Start 🚀 for CLI instructions

Prompt: Setup the server
In my supervaizer_control.py, define the Server instance and the launch entry point.

Create a Server with:
- agents: list of my Agent instances defined in step 4
- a2a_endpoints: True to enable A2A protocol discovery
- supervisor_account: the Account instance defined in step 5

Expose the FastAPI app for deployment:
app = sv_server.app

Add the main entry point:
if __name__ == "__main__":
sv_server.launch(log_level="DEBUG")

7. Custom Routes (optional)​

Agents can mount their own FastAPI routers to expose custom HTTP endpoints alongside the workbench. This is useful for tool endpoints, webhooks, or any agent-specific API.

Define custom routes
from fastapi import APIRouter

agent_api = APIRouter()

@agent_api.post("/webhook")
async def handle_webhook(payload: dict):
"""Receive webhooks from an external service."""
# Process the webhook payload
return {"status": "received"}

@agent_api.get("/status")
async def custom_status():
"""Custom status endpoint for this agent."""
return {"healthy": True, "pending_tasks": 0}

Then pass the router to your Agent definition:

Attach custom routes to the agent
agent = Agent(
# ... other config from step 4 ...
custom_routes=agent_api,
)

Supervaizer mounts the router at /agents/{agent_slug}/api/, so the endpoints above become:

  • POST /agents/my-agent/api/webhook
  • GET /agents/my-agent/api/status
tip

Custom routes are mounted without any additional authentication by Supervaizer. If your endpoints need auth, handle it within the router itself.

What's next?​