CUGA LogoCUGA AGENT
SDK

CugaSupervisor

Orchestrate multiple agents with a single supervisor; delegate to sub-agents and mix local with A2A.

CugaSupervisor

The CugaSupervisor class coordinates multiple agents: it receives a user task, delegates work to specialized sub-agents, and returns a final answer. You can mix local CugaAgent instances with remote agents via the A2A protocol.

Try the Demo

The bundled CRM + email multi-agent demo can be launched with:

cuga start demo_supervisor

This brings up the same demo surface as demo_crm but with the supervisor wired to a CRM sub-agent and an email sub-agent. Use it to see delegation and variable-passing end to end before building your own configuration.

Quick Start

Define tools and create sub-agents

Create one or more CugaAgent instances with their own tools and descriptions.

from cuga import CugaAgent, CugaSupervisor
from langchain_core.tools import tool
import asyncio

@tool
def get_customers(limit: int = 10) -> str:
    """Fetch top customers from CRM with name, email, and revenue. Returns a formatted string."""
    customers = [
        "Alice (alice@example.com, $250,000)",
        "Bob (bob@example.com, $180,000)",
        "Carol (carol@example.com, $120,000)",
        "Dave (dave@example.com, $95,000)",
        "Eve (eve@example.com, $88,000)",
    ]
    top = customers[: min(limit, len(customers))]
    return "Top customers by revenue: " + "; ".join(f"{i+1}. {c}" for i, c in enumerate(top))

@tool
def send_email(to: str, body: str) -> str:
    """Send an email. Returns confirmation."""
    return f"Email sent successfully to {to}"

crm_agent = CugaAgent(tools=[get_customers])
crm_agent.description = "CRM and customer data"

email_agent = CugaAgent(tools=[send_email])
email_agent.description = "Sending emails and notifications"

Create supervisor and invoke

Pass the agents as a dict and call invoke with the user task.

supervisor = CugaSupervisor(agents={
    "crm": crm_agent,
    "email": email_agent,
})

result = await supervisor.invoke(
    "Get our top 5 customers by revenue, then send the top customer a thank-you email"
)
print(result.answer)

Initialization

Prop

Type

Core Methods

invoke

Run the supervisor with a user message and get back a final answer.

result = await supervisor.invoke("Get top 5 customers and email the top one a thank-you")
print(result.answer)
print(result.thread_id)

from_yaml

Load supervisor and agents from a YAML configuration file. The model is taken from system settings (not from YAML).

supervisor = await CugaSupervisor.from_yaml("supervisor_config.yaml")
result = await supervisor.invoke("Your task here")

External Agents (A2A)

To add a remote agent that speaks the A2A protocol, pass an external config in agents:

remote_config = {
    "name": "analytics",
    "type": "external",
    "description": "Remote analytics service",
    "config": {
        "a2a_protocol": {
            "endpoint": "http://localhost:9999",
            "transport": "http",
        },
    },
}

supervisor = CugaSupervisor(agents={
    "crm": crm_agent,
    "email": email_agent,
    "analytics": remote_config,
})

Set pass_variables_a2a = true under [supervisor] in settings.toml if you want to pass variables to A2A agents.

Configuration

When using the CUGA server, enable the supervisor in settings.toml:

[supervisor]
enabled = true
config_path = "path/to/supervisor_config.yaml"  # optional; used when loading from YAML via server
pass_variables_a2a = false  # set true to pass variables to A2A agents in metadata

For SDK-only usage, building the supervisor in code (as in Quick Start) does not require any settings.toml changes.

Policies

CugaSupervisor uses the same policy API as CugaAgent via supervisor.policies. Intent guards block unsafe requests before delegation; playbooks inject multi-agent workflows into the supervisor prompt.

await supervisor.policies.add_intent_guard(
    name="Block Deletes",
    keywords=["delete", "remove"],
    response="Deletion is not permitted.",
)

await supervisor.policies.add_playbook(
    name="Onboarding",
    keywords=["onboard"],
    content="# Onboarding\n1. Delegate to crm to fetch the customer\n2. Delegate to email to send welcome mail",
)

result = await supervisor.invoke("Onboard the new customer Acme Corp")

Full details, support matrix, and a step-by-step example: Supervisor Policies.