A team is a named group of agents that work together under a shared context. Teams define hierarchy, escalation paths, and agent composition for your project.
Team structure
Teams are stored in .polpo/teams.json and managed via the CLI, API, or dashboard. Each team has a name, an optional description, and agents:
{
"project": "my-saas-app",
"teams": [
{
"name": "engineering",
"description": "Builds and maintains the product",
"agents": [
{ "name": "tech-lead", "role": "Reviews code and coordinates the team" },
{ "name": "backend-dev", "role": "Server-side development", "reportsTo": "tech-lead" },
{ "name": "frontend-dev", "role": "Client-side development", "reportsTo": "tech-lead" }
]
}
]
}
| Field | Type | Description |
|---|
name | string | Unique team identifier |
description | string | What this team does |
agents | Agent[] | Array of agent configurations (see Configuration) |
Hierarchy
The reportsTo field on an agent creates a reporting relationship, forming an org chart within the team.
tech-lead
backend-dev
frontend-dev
This hierarchy serves two purposes:
Task escalation
When an agent’s task fails after exhausting retries, the task is escalated to the agent’s reportsTo target. The escalation agent receives the original task context plus the failure details.
Coordination
The orchestrator uses the hierarchy to route review requests and coordinate multi-agent work. A lead agent can delegate sub-tasks to agents that report to it.
Escalation policy
When a task fails, the escalation path is determined by the agent’s reportsTo field and the task’s retryPolicy:
| Field | Type | Description |
|---|
escalateAfter | number | Number of failed retries before escalation triggers |
fallbackAgent | string | Agent to reassign the task to (overrides reportsTo) |
escalateModel | string | Upgrade to a more capable model on the escalated attempt |
{
"name": "backend-dev",
"role": "Server-side development",
"reportsTo": "tech-lead",
"retryPolicy": {
"escalateAfter": 2,
"fallbackAgent": "senior-dev",
"escalateModel": "anthropic/claude-sonnet-4-5"
}
}
If no reportsTo is defined and no fallbackAgent is set in the retry policy, the task fails without escalation after retries are exhausted.
Volatile teams
Missions can define temporary, purpose-built teams that exist only for the duration of the mission. These are volatile teams.
How volatile teams work
Mission defines agents
The mission definition includes a team block with volatile: true and an array of agents.
Agents are created on start
When the mission starts, the volatile agents are registered and available for task assignment.
Agents are removed on completion
When the mission completes (or fails/is cancelled), the volatile agents are automatically cleaned up.
Volatile agent config
Volatile agents use the same configuration as permanent agents, with two additional fields:
| Field | Type | Description |
|---|
volatile | boolean | Must be true for mission-scoped agents |
missionGroup | string | Links the agent to its parent mission |
Cleanup behavior
Control what happens to volatile agents after the mission ends via settings.volatileCleanup:
| Value | Behavior |
|---|
on_complete (default) | Agents are automatically removed when the mission completes |
manual | Agents persist until explicitly removed via CLI or API |
You can disable volatile teams entirely with settings.enableVolatileTeams: false (enabled by default).
Example: volatile team in a mission
{
"name": "quarterly-audit",
"prompt": "Audit Q1 expenses and generate a compliance report",
"tasks": [
{
"title": "Gather financial data",
"assignTo": "data-analyst",
"dependsOn": []
},
{
"title": "Check compliance rules",
"assignTo": "compliance-checker",
"dependsOn": ["Gather financial data"]
},
{
"title": "Write audit report",
"assignTo": "report-writer",
"dependsOn": ["Check compliance rules"]
}
],
"team": {
"name": "audit-crew",
"volatile": true,
"agents": [
{
"name": "data-analyst",
"role": "Extract and normalize financial data from spreadsheets",
"model": "anthropic/claude-sonnet-4-5",
"allowedTools": ["read", "excel_*", "glob"]
},
{
"name": "compliance-checker",
"role": "Verify data against compliance rules",
"model": "anthropic/claude-sonnet-4-5",
"allowedTools": ["read", "grep"],
"reportsTo": "report-writer"
},
{
"name": "report-writer",
"role": "Produce the final audit report",
"model": "anthropic/claude-sonnet-4-5",
"allowedTools": ["read", "write", "edit"]
}
]
}
}
Volatile agents do not persist memory between mission runs. If you need agents to retain context across recurring missions, use permanent agents instead.
Complete example
A project with a permanent team of three agents with hierarchy:
{
"project": "my-saas-app",
"teams": [
{
"name": "product",
"description": "End-to-end product development",
"agents": [
{
"name": "lead",
"role": "Technical lead. Reviews work, coordinates agents, handles escalations.",
"model": "anthropic/claude-sonnet-4-5",
"allowedTools": ["read", "edit", "bash", "glob", "grep", "memory_*"],
"reasoning": "high"
},
{
"name": "developer",
"role": "Full-stack developer. Implements features and fixes bugs.",
"model": "anthropic/claude-sonnet-4-5",
"allowedTools": ["read", "write", "edit", "bash", "glob", "grep", "http_fetch"],
"allowedPaths": ["src", "tests"],
"reportsTo": "lead",
"reasoning": "medium"
},
{
"name": "writer",
"role": "Technical writer. Creates and maintains documentation.",
"model": "openai/gpt-4o",
"allowedTools": ["read", "write", "edit", "glob", "grep", "search_web"],
"allowedPaths": ["docs", "README.md"],
"reportsTo": "lead"
}
]
}
],
"settings": {
"maxRetries": 2,
"enableVolatileTeams": true,
"volatileCleanup": "on_complete"
}
}
This creates the following org chart:
product
lead
developer
writer
Team management
Teams are defined in .polpo/teams.json and synced to the cloud via polpo deploy. Edit the file locally and deploy to apply changes.
You can also manage teams programmatically via the API:
import { Orchestrator } from "@polpo/core";
const orchestrator = new Orchestrator("./polpo.json");
// Add an agent to a team
orchestrator.addAgent("product", {
name: "designer",
role: "UI/UX design",
model: "anthropic/claude-sonnet-4-5",
allowedTools: ["read", "write", "image_*"],
reportsTo: "lead",
});
// Remove an agent
orchestrator.removeAgent("product", "designer");