How the `provision.ts` Module Creates Sub-Agents with Coordinator Rosters

The provision.ts module creates sub-agents by first instantiating specialist agents, then constructing a coordinator agent with a multiagent field containing an agents array that references the specialist IDs, effectively establishing a hierarchical roster that enables parallel workflow dispatch.

In the anthropics/cwc-workshops repository, the research desk implementation demonstrates how to build scalable multi-agent systems using the Anthropic API. The provision.ts module serves as the core provisioning logic that establishes a filing analyst coordinator capable of orchestrating specialist sub-agents. Understanding how this module constructs coordinator rosters is essential for implementing agent dispatch patterns that leverage parallel processing capabilities.

The Coordinator Architecture in provision.ts

The provision.ts file implements a hierarchical agent pattern where a coordinator agent manages a roster of sub-agents. This architecture appears in both the reference implementation at research-desk/src/lib/provision.ts and the completed solution at research-desk/solutions/src/lib/provision.ts.

A coordinator differs from standard agents through its multiagent configuration field. When this field is set to type "coordinator", the agent gains the ability to route requests to other agents listed in its roster. The roster itself is defined at creation time through the agents array, which contains references to previously created specialist agents plus an optional self-reference.

Step-by-Step Agent Creation Process

The provisioning logic follows a specific sequence to establish the coordinator-sub-agent relationship. Each step builds upon the previous to ensure the coordinator can reference valid agent IDs.

Step 1: Provisioning Specialist Agents First

Before creating the coordinator, the module instantiates the specialist agents that will serve as sub-agents. In research-desk/src/lib/provision.ts (lines 78-96), the code creates financials and risk agents with dedicated system prompts and the standard AGENT_TOOLSET toolset.

These agents are provisioned as independent entities first:

// Specialist agents created before coordinator
const financials = await client.beta.agents.create({
  name: `${agentPrefix}-financials`,
  model: MODEL,
  system: loadPrompt("financials_system.md"),
  tools: [AGENT_TOOLSET],
});

const risk = await client.beta.agents.create({
  name: `${agentPrefix}-risk`,
  model: MODEL,
  system: loadPrompt("risk_system.md"),
  tools: [AGENT_TOOLSET],
});

The system stores these agent IDs in the configuration object (financials.id and risk.id) for reference during coordinator creation.

Step 2: Configuring the Coordinator Agent

After establishing the specialists, the module creates the coordinator agent at lines 198-215. The key distinction is the multiagent field, which transforms this from a standard agent into a coordinator:

const analyst = await client.beta.agents.create({
  name: `${agentPrefix}-filing-analyst`,
  model: MODEL,
  system: loadPrompt("analyst_system.md", { edgar_identity: cfg.edgar_identity }),
  tools: [AGENT_TOOLSET],
  // Coordinator configuration
  multiagent: {
    type: "coordinator",
    agents: [ /* roster entries */ ],
  },
} as never);

The type: "coordinator" declaration signals to the Anthropic platform that this agent should manage sub-agent dispatch rather than handling all requests directly.

Step 3: Populating the Sub-Agent Roster

The agents array within the multiagent object defines the coordinator's roster. This array accepts two entry types that determine how the orchestrator routes requests:

  • type: "agent" – References an existing agent by its ID, allowing the coordinator to dispatch work to that specialist.
  • type: "self" – Includes the coordinator itself in the roster, enabling fallback routing when no specialist matches the request criteria.

The complete roster configuration appears as follows:

multiagent: {
  type: "coordinator",
  agents: [
    { type: "agent", id: financials.id }, // Financial specialist
    { type: "agent", id: risk.id },       // Risk analyst
    { type: "self" },                     // Coordinator fallback
  ],
},

When the head-of-research agent invokes the custom dispatch_analysts tool, the orchestrator (defined in research-desk/src/lib/orchestrator.ts) references this roster to spawn separate sessions for each sub-agent, enabling parallel processing of ticker requests.

Key Files in the Coordinator Implementation

Several modules work together to enable the coordinator roster pattern:

Summary

  • Specialist agents must be created before the coordinator, as the roster requires valid agent IDs that exist in the Anthropic platform.
  • The multiagent field with type: "coordinator" designates an agent as capable of managing sub-agents through its roster configuration.
  • The roster agents array mixes type: "agent" entries (referencing specialists by ID) with type: "self" entries (enabling coordinator fallback).
  • The orchestrator.ts module leverages this roster to dispatch parallel sessions when the head-of-research triggers analyst workflows.
  • Agent IDs are persisted in desk.json via the config module, maintaining the coordinator-sub-agent relationships between provisioning runs.

Frequently Asked Questions

What is the purpose of type: "self" in the coordinator roster?

The type: "self" entry includes the coordinator agent itself in its own roster, allowing the orchestrator to route requests back to the coordinator when no specialist sub-agent matches the specific task requirements. This creates a fallback mechanism that prevents dispatch failures when request parameters fall outside specialist domains.

Where does provision.ts store the sub-agent IDs before creating the coordinator?

The module stores sub-agent IDs in the configuration object returned by the agent creation calls—specifically financials.id and risk.id—which are passed as variables to the coordinator's multiagent.agents array. These IDs are subsequently persisted to research-desk/desk.json through the config.ts module to maintain state across application restarts.

How does the orchestrator know which sub-agents to dispatch?

The orchestrator.ts module reads the coordinator's roster definition from the agent configuration stored in desk.json. When the head-of-research agent calls the custom dispatch_analysts tool, the orchestrator iterates through the multiagent.agents array and spawns a separate session for each type: "agent" entry, passing the appropriate context to each specialist sub-agent.

Can I add more than two sub-agents to a coordinator roster?

Yes, the agents array in the multiagent field accepts any number of entries. You can extend the roster by creating additional specialist agents (such as compliance or ESG analysts) and adding corresponding { type: "agent", id: newAgent.id } entries to the array before coordinator creation, enabling more granular specialization in your multi-agent workflow.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →