multiagent object with type: "coordinator" and an agents roster. The coordinator owns the top-level task and coordinates its roster the two ways a team can. It is an ordinary agent in every other respect: it has a model, a budget, a system prompt, and it runs inside a session you drive directly.
Making one
The roster lives on the coordinator’s own config, so a team is made in two steps — create an agent, then give it a roster. There are no roster flags onvetta agent create.
id, version, created_at, and updated_at. Adding, removing, or repinning members produces a new coordinator version — the roster is part of the agent’s config.
Any published harness can be the coordinator’s.
send_to_agent and board_write reach the
coordinator’s model either in the toolset Vetta assembles for the turn, or — on claude_code and
hermes, which run a CLI inside a micro-VM on that CLI’s own toolset — over a session-scoped tool
endpoint the machine is given. One caveat on those two: wait_for_agents does not pause the turn,
so the coordinator parks once the turn goes idle instead of mid-call. It costs a few extra model
calls, not a wrong answer. See
Harness capabilities.On the wire a roster member is an
agt_ id. web-researcher@3 is a CLI spelling: vetta team resolves the name against your org’s agents and writes the id. The API rejects anything that is not an agt_ id.The coordinator’s half of the board
Withboard: true the coordinator owns the team’s one company board, and every agent on its current roster is seated on it. The coordinator’s job on that board is to put the work on cards and hand them out — not to do the work, and not to work a teammate’s card for them.
- A card is the hand-over; a message is a nudge. A card carries a title, what “done” looks like in the notes, and
blocked_byfor anything that must finish first. It is durable, it is readable by every teammate and by you, and it is what starts a teammate:board_write({ op: "assign", card_id, assignee: "writer" })on atodocard with no open blocker, and a session ofwriteris started on it on the next tick of the board’s clock. Asend_to_agentmessage is private, is not on the record, and is the right tool for a question — not for the work. - Never move a teammate’s card. Claiming (
doing) is the assignee’s move, and closing (done, with a note) is the assignee’s too. The coordinator reads the card, comments on it, reassigns it or unblocks it — and moves only its own. The board refuses the rest anyway (already_claimed), but a coordinator that respects the rule leaves a board a person can read: whoever holds a card is whoever moved it. - The board tells the coordinator what changed. When a card reaches
doneorblocked, the coordinator gets one session per board with the digest of the cards that changed. That is its cue to read them, reassign or unblock what is stuck, and assign what comes next. A woken teammate that stopped without finishing does not vanish: its card is parked asblockedwith a system comment for the coordinator to act on.
Crew, not member
A card starts a top-level session of the rostered agent — a member of the crew, on that agent’s own budget and its own concurrency, answerable to the board. Asend_to_agent({ wait: true }) starts a member thread of the coordinator’s session — on the coordinator’s budget, parking the coordinator until it answers. They are different tools for different work:
Both are seated on the board — a member thread reads and comments on the cards like anyone else on the roster — and neither delegates: a rostered agent carries no roster of its own, so
wait: true is the coordinator’s alone. See Delegation for the other side of this.
Roster entry types
Each entry inagents is discriminated by a type field. A bare "agt_…" string is also accepted and normalises to the agent form at parse, so exactly one shape reaches storage.
agent — reference another agent
Referenced members are fully independent agents with their own model, harness, tools, skills, and system prompt. Session-level configuration overrides applied to the coordinator’s session do not reach id-referenced members — they run exactly as their pinned version defines.
self — spawn copies of the coordinator
self copies (and to the coordinator itself), because they share the coordinator’s configuration.
advisor — parses, but is not served
model instead of an id.
Roster entry types at a glance
Configuration reference
The multiagent field
It accepts an object, a boolean, or null, and all three arms mean something:
object | boolean | null
An object declares the team.
false and null mean the agent is not a coordinator — null is how an existing roster is cleared on a PATCH, which false cannot say because false is also the create-time default. true is read as a coordinator with an empty roster and no board, which has nobody to delegate to; it is a degenerate case, not a shortcut.agent entry
string
required
The
agt_ id of another agent in your organization to delegate to.integer
The version of the referenced agent to pin. Omit the version and Vetta pins the member’s current version at the moment the coordinator is saved — the stored roster always carries an explicit pin, and it does not drift. See Rosters & versioning.
Next: delegation
How the coordinator invokes members, and the isolated sessions they run in.