Skip to content

Documentation navigation

Swarm

Swarm orchestration API for coordinating multi-agent systems.

#Swarm

Swarm coordinates a roster of Agent instances while exposing the same local tool, event, batch, scheduling, and follow-up builders as an agent.

#Construction

Python
from maivn import Agent, Swarm

researcher = Agent(name='researcher', api_key='your-api-key')
writer = Agent(name='writer', api_key='your-api-key', use_as_final_output=True)

swarm = Swarm(
    name='research-team',
    agents=[researcher, writer],
    description='Researches and writes a final brief.',
    system_prompt='Coordinate the specialists.',
)

name is required. The roster defaults to empty. A swarm accepts an optional shared Client, model directive, hooks, system/orchestration config, private-data system-tool flag, local tools, skills/resources, tags, skill sets, attached skill IDs, and MCP servers.

The roster defines the available members; an invocation does not necessarily run every member. For resource-backed tasks, routing can narrow it to the smallest authorized relevant subset before planning. Member descriptions, the request, and resources visible in each member's authenticated scope guide selection. Describe each member's specialty clearly and name the documents or comparison you need in the request. Ambiguous resource references may require clarification. Selection cannot grant access to additional members or resources.

A member's system_tools_config travels with its inline definition. For example, Agent(..., system_tools_config={'allowed_tools': []}) disables configurable system tools for that member, including fire_trigger. Tools enabled through separate features, such as human follow-up and skill retrieval, retain their own controls. An omitted member policy inherits the swarm invocation policy. When both policies are explicit, their tool allowlists and compose-target approvals are intersected, so a member cannot re-enable a tool denied by its parent. Member function tools are configured separately.

It also accepts api_key, env_file, and api_key_file. Without an explicit client or credential source, it inherits the first member's client. An empty swarm resolves environment credentials when first used. See Authentication. Trigger builders inherit its agent_id (defaulting to name) and version (default 1).

#Invocation

Python
def invoke(
    messages: SdkMessagesInput,
    *,
    force_final_tool: bool = False,
    thread_id: str | None = None,
    verbose: bool = False,
    reasoning: Literal['minimal', 'low', 'medium', 'high'] | None = None,
    metadata: Mapping[str, object] | None = None,
    memory_config: MemoryConfig | Mapping[str, object] | None = None,
    allow_private_in_system_tools: bool | None = None,
    model: RuntimeModelChoice | None = None,
    system_tools_config: SystemToolsConfig | Mapping[str, object] | None = None,
    orchestration_config: SessionOrchestrationConfig | Mapping[str, object] | None = None,
    stream_response: bool = False,
    options: RunOptions | None = None,
    origin: str | None = None,
) -> InvokeResponse:
    ...

Invocation metadata and per-call allow_private_in_system_tools are accepted but ignored. Use system_tools_config for per-call private-data policy.

ainvoke has the same keyword surface. stream and astream yield StreamEvent. Unlike Agent.invoke, swarm invocation does not expose targeted_tools or direct structured_output parameters.

Python
response = swarm.invoke('Prepare the launch brief.', thread_id='thread-42')
print(response.response)

#Thread handles

swarm.thread(thread_id=None, *, options=None) returns a local conversation handle. send / asend and stream / astream use the normal swarm execution path, preserving its roster, tools, hooks, and full message lists. The handle fixes the ID across calls. Ordinary invoke(..., thread_id=...) remains available.

Python
conversation = swarm.thread()
response = conversation.send('Prepare the launch brief.')
response = conversation.send('Revise it for the sales team.')

Use state / astate for state and events / aevents for current-turn replay. See Sessions and Streaming for replay cursors and cleanup.

#Roster and dependencies

add_agent(agent) and list_agents() manage the roster. There is no public get_agent method; look up members in the returned list. The swarm.member builder registers an agent and can attach dependency metadata; see Multi-Agent.

An agent with use_as_final_output=True can supply the swarm's final result. included_nested_synthesis on agents controls whether nested responses participate in synthesis.

#Follow-ups, events, and tools

allow_followup_questions(...) behaves like the agent builder: it handles typed runtime questions inline and preserves invoke, ainvoke, stream, and astream.

events(...), batch(...), abatch(...), toolify(...), add_tool(...), add_toolset(...), list_tools(), compile_tools(), and validate_tool_configuration() are available on the swarm. verbose=True uses the same plain/Rich terminal tier selection described in the Agent reference.

#Scheduling and cleanup

Use cron(...), interval(...), or at(...) to bind a scheduled swarm invocation. Swarm.close() is currently a compatibility no-op. The application that owns a shared client must close it after all users finish; close registered MCP servers explicitly as well.

See Agent, Multi-Agent, and Interrupts.

Live Available Models

Active, tool-capable model IDs accepted by ModelConfig.

Loading models

The current table controls remain available while records load.