Skip to content
  1. OPERATORS
  2. CONTROLLERS

Agent Swarm

v1.0.1new

Agent Swarm runs one task across several Agents. A lead Agent decides what to hand out, worker Agents do the parts, and the lead finishes with a summary. It replaces the older Agent Orchestrator. The swarm has no model of its own: every model call is made by the Agents you point it at.

One Swarm Run
Run Swarmcall_agentcomplete_swarm
● data
Task
String field or DAT
◆ agent
Lead Agent
Decides, then finishes
● data
Swarm Outputs
Status, workers, summary
◆ agent
Worker Agents
Each runs its own call

The lead is the Agent you set in Lead Agent on the Swarm page. It reads the task, sends work out, reads what comes back, and decides when the job is done. For the length of a run it gets three tools from the swarm:

  • call_agent sends a prompt to one worker. Workers do not see the lead’s conversation, so the prompt has to carry everything the worker needs.
  • check_swarm reads the worker list, running calls, finished runs, errors, and a short trace of a worker’s conversation.
  • complete_swarm ends the run with a status (success, partial, or failed) and a summary. That summary is your result.

You don’t have to write a system message for the lead. On Run Swarm the swarm builds one for that run, in this order: the lead’s own system message, the Extra System Prompt DAT, a generated block listing the workers and the rules of the Protocol Preset, then the Protocol DAT. Your DATs are not edited.

Run Swarm also changes a few things on the lead:

  • It clears the lead’s conversation. Don’t use an Agent you are chatting with as the lead.
  • It sets Session Mode to Persistent so each round builds on the last.
  • It sets Tool Follow-up Response to match the preset.
  • With Auto-Inject Tools on, it adds the swarm to the lead’s Tools sequence. If you turn this off, add the swarm to that sequence yourself.

When a run closes, Session Mode and Tool Follow-up Response go back to what they were and the swarm’s slot in the Tools sequence is turned off. The slot stays there and the next run reuses it.

The lead needs Use Tools on, which is the default, and a model that can call tools.

Workers are Agents in the Workers sequence on the Workers page. You start with two slots and can add more with the sequence’s + button. Each slot has Worker Agent, Enabled, and Prompt Prefix, which goes in front of every prompt that worker receives.

A worker runs each call with its own model, system message, and tools. The swarm doesn’t change any of them, so a worker can use search, MCP tools, or anything else you would wire into an Agent.

  • One call at a time. If the lead calls a worker that is busy, it gets busy back. To run two jobs at once, use two Agents. Don’t use the lead as a worker.
  • Memory. A worker keeps its conversation according to its own Session Mode. The Agent default is Persistent, so a worker remembers earlier calls, including calls from earlier runs. Neither Run Swarm nor Reset Session clears it. Set Session Mode to Auto (new each call) if every call should start clean.
  • Results. Each result goes back to the lead with the worker’s status and final response. If a worker comes back empty or with an error, the lead also gets what could be recovered from that worker’s tool results, plus a hint to look closer with check_swarm.

The lead picks workers by agent_id, which is the worker’s operator name. Capability Source decides what else the lead is told about each one:

Capability SourceWhat the lead sees
Auto (GetTool then fallback)If the worker has Expose This Agent as a Tool on, its Tool Name becomes the agent_id and its Tool Description is used. Otherwise, the start of its system message. Otherwise, a generic line.
Worker GetTool onlyTool Name and Tool Description, or the generic line.
Worker name onlyThe operator name and the generic line.

The easiest way to get good routing is a clear first sentence in each worker’s system message. Run Swarm rescans the workers every time. Refresh Capability Cache only updates the worker count and Output 2 while the swarm is idle.

One lead, two workers, one task. You need three Agents with a working model. ChatTD defaults are fine as long as the lead’s model can call tools.

  1. Place three Agents and name them lead, concepts, and network.
  2. On the Model page of concepts, use System Message DAT or Edit System Message to set the system message to: You suggest visual concepts for live audio-reactive sets. Answer in five sentences or fewer.
  3. On the Model page of network, set the system message to: You list TouchDesigner operators and how to wire them for a given visual idea. Use short bullet points.
  4. Place an Agent Swarm. On the Swarm page set Lead Agent to lead.
  5. On the Workers page set the first Worker Agent to concepts and the second to network.
  6. Leave Protocol Preset on Background Parallel and Worker Aggregation on Parallel Batch.
  7. Back on the Swarm page, set Task to: Plan a three minute audio-reactive set. Get a visual concept and a list of TouchDesigner operators that could build it, then give me one short plan.
  8. Pulse Run Swarm.

Here is what Status and Current Round on the Swarm page do:

StatusRoundWhat is happening
running1The lead reads the task and calls call_agent for both workers.
waiting1The lead’s turn is over and both workers are running.
waiting1The first worker finishes. Its result is held until the other one is done.
running2The second worker finishes. The lead is called again with both results in one message.
complete2The lead calls complete_swarm. Active turns off.

The node viewer shows SETUP until a lead and a worker are set, ACTIVE during the run, and a dot for each worker.

Some models call one tool per turn. In that case you see an extra round, because the lead sends the second worker after reading the first result. Turning on Parallel Tool Calls on the lead’s Model page asks the model to send both at once.

The swarm has three outputs, all DATs. After the run above they look like this, with your text and timings in place of these.

Output 1 is a status table:

metric value
status complete
active False
session_id swarm-3f9a1c07de
round 2
max_rounds 10
rounds_remaining 8
worker_count 2
pending_count 0
completed_runs 2
error_runs 0
session_cost 0.0
session_tokens 0
final_status success
final_summary Open on slow ink-in-water visuals driven by...
last_event swarm_complete | lead_tool | success: Open on...

Output 2 has one row per worker. Here it is without the display_name, agent_id, agent_path, worker_run_id, and error columns, to fit the page:

worker_name state pending last_status elapsed_s preview
concepts ready False success 6.2 Slow ink-in...
network ready False success 8.7 - Audio De...

Output 3 is a JSON text with everything in Output 1, the worker rows, and the last eight activity events. For this run the events are swarm_start, lead_dispatch_initial_task, lead_response, worker_response twice, lead_dispatch_worker_result, and swarm_complete.

Your result is final_summary. preview is cut at 240 characters, so read a worker’s full answer from that worker’s own outputs. The lead’s whole exchange, including both worker results, is on the lead’s conversation output.

Protocol Preset decides how the lead is told to work. A preset is instructions to the lead plus the Tool Follow-up Response setting. Nothing forces the model to follow it, so use the Protocol DAT to add your own rules.

PresetThe lead is told toTool Follow-up Response
Background Parallel (default)Call workers in the background. Results arrive later as user messages. Good when workers can run independently.Off
Foreground DeferredCall one worker and wait. The result comes back as the tool result, and the lead reads it before deciding what’s next.On
Audit RecoveryCall workers in the background. If a result is empty, partial, or an error, inspect the trace with check_swarm, and prefer evidence from sources over model confidence.Off
Strict PipelineRun defined steps one at a time, check each result against what was expected, and stop early with partial if a required step fails.On

Worker Aggregation applies to background calls. Parallel Batch waits for every pending worker and calls the lead once with all the results. Serial calls the lead after each worker, and the lead is told to wait for each response before starting the next worker. Each of those lead calls is one round.

In the foreground presets the back and forth can all happen inside one lead call, so Current Round can stay at 1. There, the lead’s own Tool Turn Budget on its Tools page is what limits it.

Stop marks the run as stopped. It does not cancel calls that are already in flight: an Agent that is working finishes its call, and the swarm ignores the result. After Stop, Status reads error and final_status reads stopped.

If the lead is in the middle of a turn, the run closes when that turn ends and the lead’s settings go back. If only workers were running, Active stays on after they finish, and you need Reset Session before the next run.

Reset Session clears the swarm’s own state and nothing else. It clears:

  • Session ID, Current Round, Rounds Remaining, Session Cost ($), and Session Tokens. Status goes back to idle and Active turns off.
  • The list of workers being waited on, the record of finished worker runs, and any results held for the next lead call.
  • The cached worker list, final_status, and final_summary.
  • The activity and callback_trace tables inside the operator. The three outputs are rewritten to match.

It leaves alone:

  • Lead Agent, the Workers sequence, the task, and every other parameter.
  • Everything on the Agents themselves: conversations, tools, Session Mode, and Tool Follow-up Response.

Reset also drops the lead settings the swarm was holding to put back. After a normal run that doesn’t matter, because they were already restored. After a stuck run, check the lead yourself: see Troubleshooting.

Reset is refused while Status is running or waiting. It logs a warning and does nothing, so pulse Stop first. You don’t need Reset between normal runs: Run Swarm starts a new session and clears activity and the lead’s conversation on its own.

Max Rounds (default 10) counts calls to the lead. Worker calls don’t add rounds.

On Exhaust sets what happens at the limit. One Final Summary Call asks the lead for one last answer with its tools off, using Summary Prompt as the message. final_status becomes partial, and the answer is in the lead’s own outputs rather than in final_summary. Stop Immediately ends the run with no extra call.

Turn on Expose This Swarm as a Tool on the Expose page and add the swarm to another Agent’s Tools sequence. That Agent gets one tool, named by Tool Name (run_swarm by default), that takes a task. The Agent waits, and the tool result comes back when the swarm closes, with status, summary, session_id, rounds, session_cost, and session_tokens.

Each call writes its text into Task and sets Task Source to String Field. If the swarm is already running, the caller gets busy. Leave Auto-Inject Tools on when you expose a swarm, because that is how its own lead gets the control tools instead of the exposed tool.

Pulse Create Callbacks DAT on the Callbacks page, or use the DAT the operator docks when you place it. Turn on the events you want. Each callback gets one info dictionary with ownerComp plus these keys:

  • onSwarmStart: session_id, task, workers
  • onDelegate: worker_name, display_name, worker_op, prompt, expected, worker_run_id
  • onWorkerResponse: worker_name, display_name, response, elapsed, callback_info
  • onLeadResponse: response, tools_used, callback_info
  • onBudget: reason, rounds, session_cost
  • onSwarmComplete: session_id, status, summary, rounds, session_cost, session_tokens

onLeadResponse does not fire for the lead turn that calls complete_swarm. Use onSwarmComplete to pick up the result.

Record Debug Trace writes callback and tool events to the callback_trace table inside the operator. It is off by default. Clear Debug Trace on Run empties that table at the start of each run.

Agent Swarm replaces Agent Orchestrator. There is no in-place upgrade: place an Agent Swarm and point it at your Agents. Your validation agent becomes the lead, and your action agents become workers. If your validation agent’s system message mentions the old tools, take that out, because the swarm now writes those instructions itself.

Agent OrchestratorAgent Swarm
Validation AgentLead Agent
Agents sequence (action agents)Workers sequence
Task DATTask Source set to DAT, then Task DAT, or the Task string field
Start Orchestration, Stop OrchestrationRun Swarm, Stop
Max RoundsMax Rounds on the Limits page
assign_task_to_agentcall_agent
complete_orchestrationcomplete_swarm
acknowledge_waiting and the Waiting pageGone. A worker finishing is what calls the lead again.
Session storage basesGone. The lead’s own conversation and the three outputs replace them.
  • Status is error right after Run Swarm. Read final_summary on Output 1. It says Leadagent must reference a valid Agent operator., No active workers configured. Add at least one Worker., Task is empty., or that the lead is busy.
  • The run ends at once with partial and Lead produced output without calling any tool. The lead answered in text. Check Use Tools on the lead and that its model can call tools.
  • A run is stuck, Run Swarm does nothing, or Reset Session says to stop first. Pulse Stop on the swarm, pulse Cancel Current on any Agent still working, then pulse Reset Session. Then check the lead’s Use Tools, Tool Follow-up Response, and Session Mode, because Reset does not put them back.
  • A worker never shows up. It has to be an Agent with Enabled on. If two workers end up with the same agent_id, the second one is skipped and the operator logs a warning.
  • last_status is empty or error on Output 2. Open that worker and read its outputs and log. The error column and preview show the short version.
  • A worker keeps talking about an earlier job. Its Session Mode is Persistent. Pulse Clear Session on it, or switch it to Auto (new each call).
Swarmstatus (Swarmstatus) op('agent_swarm').par.Swarmstatus Str
Default:
"" (Empty String)
Active (Active) op('agent_swarm').par.Active Toggle
Default:
False
Status (Status) op('agent_swarm').par.Status Str

idle | running | waiting | complete | error

Default:
"" (Empty String)
Session ID (Sessionid) op('agent_swarm').par.Sessionid Str
Default:
"" (Empty String)
Current Round (Currentround) op('agent_swarm').par.Currentround Int
Default:
0
Range:
0 to 50
Slider Range:
0 to 50
Lead Agent Header
Lead Agent (Leadagent) op('agent_swarm').par.Leadagent OP

Agent operator that decides when to delegate and when to finish. Must have AgentEXT.

Default:
"" (Empty String)
Extra System Prompt DAT (Leadsystemextra) op('agent_swarm').par.Leadsystemextra DAT

Optional DAT whose text is appended to the lead's system prompt during the swarm. Restored on Stop.

Default:
"" (Empty String)
Protocol Preset (Protocolpreset) op('agent_swarm').par.Protocolpreset Menu

Lead coordination protocol. Advanced users can extend agent_swarm_protocols.py for project-specific behavior.

Default:
background_parallel
Options:
background_parallel, foreground_deferred, audit_recovery, strict_pipeline
Protocol DAT (Protocoldat) op('agent_swarm').par.Protocoldat DAT

Optional DAT appended after the selected protocol. Use for project-specific user-authored protocol text.

Default:
"" (Empty String)
Task Header
Task Source (Tasksource) op('agent_swarm').par.Tasksource Menu
Default:
string
Options:
string, dat
Task (Task) op('agent_swarm').par.Task Str

Initial task description sent to the lead.

Default:
"" (Empty String)
Task DAT (Taskdat) op('agent_swarm').par.Taskdat DAT
Default:
"" (Empty String)
Controls Header
Run Swarm (Run) op('agent_swarm').par.Run Pulse
Default:
False
Stop (Stop) op('agent_swarm').par.Stop Pulse
Default:
False
Reset Session (Reset) op('agent_swarm').par.Reset Pulse
Default:
False
Workers Header
Workercount (Workercount) op('agent_swarm').par.Workercount Str
Default:
"" (Empty String)
Refresh Capability Cache (Refreshcapabilities) op('agent_swarm').par.Refreshcapabilities Pulse
Default:
False
Capability Source (Capabilitysource) op('agent_swarm').par.Capabilitysource Menu

How to describe each worker to the lead. Auto prefers worker.GetTool() metadata when Enablegettool is set.

Default:
auto
Options:
auto, gettool, name_only
Auto-Inject Tools (Autoinject) op('agent_swarm').par.Autoinject Toggle

On Run, append this swarm to the lead's Tool sequence. On Stop, remove it.

Default:
True
Worker Aggregation (Aggregation) op('agent_swarm').par.Aggregation Menu

When the lead delegates to multiple workers in one turn, decide whether to re-call the lead after each worker or after all complete.

Default:
parallel_batch
Options:
serial, parallel_batch
Workers (Worker) op('agent_swarm').par.Worker Sequence
Default:
0
Worker Agent (Worker0op) op('agent_swarm').par.Worker0op OP
Default:
"" (Empty String)
Enabled (Worker0enable) op('agent_swarm').par.Worker0enable Toggle
Default:
True
Prompt Prefix (Worker0prefix) op('agent_swarm').par.Worker0prefix Str
Default:
"" (Empty String)
Worker Agent (Worker1op) op('agent_swarm').par.Worker1op OP
Default:
"" (Empty String)
Enabled (Worker1enable) op('agent_swarm').par.Worker1enable Toggle
Default:
True
Prompt Prefix (Worker1prefix) op('agent_swarm').par.Worker1prefix Str
Default:
"" (Empty String)
Rounds Header
Max Rounds (Maxrounds) op('agent_swarm').par.Maxrounds Int

Maximum number of lead-agent turns. A "round" is one lead Call.

Default:
10
Range:
1 to 100
Slider Range:
1 to 100
Rounds Remaining (Roundsremaining) op('agent_swarm').par.Roundsremaining Int
Default:
0
Range:
0 to 1
Slider Range:
0 to 1
Cost / Tokens Header
Max Total Cost ($) (Maxcost) op('agent_swarm').par.Maxcost Float

Hard stop when sum of lead+worker session cost exceeds this. 0 = unlimited.

Default:
0.0
Range:
0 to 10
Slider Range:
0 to 10
Session Cost ($) (Sessioncost) op('agent_swarm').par.Sessioncost Float
Default:
0.0
Range:
0 to 1
Slider Range:
0 to 1
Session Tokens (Sessiontokens) op('agent_swarm').par.Sessiontokens Int
Default:
0
Range:
0 to 1000000
Slider Range:
0 to 1000000
On Budget Exhausted Header
On Exhaust (Onbudgetexhausted) op('agent_swarm').par.Onbudgetexhausted Menu

When budget is hit, stop or give the lead one tool-less call to summarize.

Default:
final_summary
Options:
stop_immediately, final_summary
Summary Prompt (Summaryprompt) op('agent_swarm').par.Summaryprompt Str
Default:
Budget reached. Summarize what the swarm accomplished and any open questions.
Expose Swarm as Tool Header
Expose This Swarm as a Tool (Enablegettool) op('agent_swarm').par.Enablegettool Toggle

When True, GetTool() returns a run_swarm tool definition so a higher-level agent can invoke this swarm.

Default:
False
Tool Name (Toolname) op('agent_swarm').par.Toolname Str
Default:
run_swarm
Tool Description (Tooldescription) op('agent_swarm').par.Tooldescription Str
Default:
Run this swarm as a callable multi-agent tool. The swarm coordinates the lead and worker agents, then returns the completed result through the Agent tool-result bridge.
Callbacks Header
Callback DAT (Callbackdat) op('agent_swarm').par.Callbackdat DAT
Default:
agent_swarm_callbacks
Create Callbacks DAT (Createcallbacks) op('agent_swarm').par.Createcallbacks Pulse
Default:
False
Record Debug Trace (Tracecallbacks) op('agent_swarm').par.Tracecallbacks Toggle

Append swarm callback and tool-chain events to callback_trace for debugging.

Default:
False
Clear Debug Trace on Run (Clearcallbacktraceonrun) op('agent_swarm').par.Clearcallbacktraceonrun Toggle

Clear callback_trace at the beginning of each swarm run.

Default:
True
Clear Debug Trace (Clearcallbacktrace) op('agent_swarm').par.Clearcallbacktrace Pulse
Default:
False
Event Toggles Header
On Swarm Start (Onswarmstart) op('agent_swarm').par.Onswarmstart Toggle
Default:
True
On Swarm Complete (Onswarmcomplete) op('agent_swarm').par.Onswarmcomplete Toggle
Default:
True
On Delegate (Ondelegate) op('agent_swarm').par.Ondelegate Toggle

Lead has called a delegate tool. callbackInfo includes worker_name, prompt.

Default:
True
On Worker Response (Onworkerresponse) op('agent_swarm').par.Onworkerresponse Toggle

A worker has finished. callbackInfo includes worker_name, response.

Default:
True
On Lead Response (Onleadresponse) op('agent_swarm').par.Onleadresponse Toggle

Lead has finished one round. callbackInfo includes response, tools_used.

Default:
True
On Budget Exhausted (Onbudget) op('agent_swarm').par.Onbudget Toggle
Default:
True
v1.0.12026-05-02
  • added process_id to lead, worker, and final_summary dispatch calls - expanded tags with role_lead, role_worker, and agent name identifiers
  • Silence panelkit debug prints in baked panel_exec DATs
v1.0.02026-05-02
  • enabled worker slots by default on fresh placement - renamed callback trace controls to debug trace with tracing off by default - fixed manifest BOM encoding
  • Initial agent_swarm structure
v0.1.02026-05-01
  • Initial production package for the Agent Swarm coordinator.
  • Provides a lead/worker multi-agent coordination surface built around the shipping Agent lifecycle.