Teams
Team management with SQLite-backed store for agent teams, membership, task tracking, and lifecycle management.
The teams module provides types and a SQLite-backed store for managing teams of agents. It handles team creation, membership, per-team task tracking, lifecycle management, and plan approval workflows.
A team is leader-led. On a team's first message the leader plans before any member acts — strategic planning known as Team Strata. That plan is welded into every member's prompt, so members work from a shared strategy rather than improvising in isolation. Members then execute assigned Coord Tasks under a status flow with an explicit review gate, and the leader accepts or rejects each deliverable via the task_review tool.
Design Philosophy
- Persistence-first — All team state is stored in SQLite for durability
- Lifecycle-aware — Teams have explicit states (active, disbanded, archived)
- Task integration — Teams can have shared tasks with per-member assignments
- Leader-led strategy — The leader plans first (Team Strata); the plan welds into member prompts, and the leader reviews deliverables before they count as done
Core Types
Team
pub struct Team {
pub id: TeamId,
pub name: String,
pub description: String,
pub status: TeamStatus,
pub members: Vec<TeamMember>,
pub created_at: DateTime<Utc>,
}TeamStatus
pub enum TeamStatus {
Active,
Disbanded,
Archived,
}TeamMember
pub struct TeamMember {
pub id: MemberId,
pub name: String,
pub role: TeamRole,
pub status: MemberStatus,
}
pub enum TeamRole {
Leader,
Member,
Observer,
}TeamTask
pub struct TeamTask {
pub id: TaskId,
pub title: String,
pub assignee: Option<MemberId>,
pub status: TeamTaskStatus,
}
pub enum TeamTaskStatus {
Pending,
InProgress,
WaitingReview,
Completed,
}Coord Tasks move through Pending → InProgress → WaitingReview → Completed. A member does not mark its own task done — when it submits, the task lands in WaitingReview and a synthetic re-dispatch routes the deliverable back to the leader. The leader then accepts or rejects it:
task_review { task_id, verdict: approve | reject, feedback? }- approve → the task advances to
Completed. - reject (with optional
feedback) → the task returns to the member for revision.
This keeps the leader as the single gate on what counts as finished work.
TeamStore
SQLite-backed persistence:
pub trait TeamStore: Send + Sync {
async fn create_team(
&self,
team: &NewTeam,
) -> Result<TeamId>;
async fn add_member(
&self,
team_id: TeamId,
member: &NewTeamMember,
) -> Result<()>;
async fn get_team(
&self,
team_id: TeamId,
) -> Result<Option<Team>>;
async fn list_teams(
&self,
) -> Result<Vec<TeamSummary>>;
async fn create_task(
&self,
team_id: TeamId,
task: &NewTeamTask,
) -> Result<TaskId>;
}SqliteTeamStore
pub struct SqliteTeamStore {
pool: SqlitePool,
}Safety:
- All queries use parameterized
params![] TeamStatusandTeamTaskStatusimplementFromSqlfor proper error propagation (nounwrap_or_default)- Uses
tokio::sync::Mutex(no poisoning)
Lifecycle
Created → Active → [Disbanded | Archived]Transitions:
Created → Active— Team is ready for useActive → Disbanded— Team is disbanded (members removed)Active → Archived— Team is archived (read-only)
Validation: Operations check team status before proceeding. Adding members to a disbanded team returns an error.
Team Strata (Strategic Coordination)
On a team's first message, the leader plans before any member runs:
First message → leader plans (Team Strata)
→ plan welded into every member's prompt
→ members execute assigned Coord Tasks
→ submit → WaitingReview → leader task_review (approve/reject)
→ CompletedThe leader's strategic plan is injected into each member's prompt for that team, so every member shares the same picture of the goal, the breakdown, and their assignment. Members work under Coord Tasks and submit deliverables for review; the leader gates completion with task_review. A blank-named team is auto-named by the LLM on its first message.
In the desktop panel, a team is chosen from a ModelPicker-style pill + popover at the top of the sidebar — switching the active team is one click, alongside the team's Group Chat window.
Events
pub enum TeamEvent {
TeamCreated { team_id: TeamId },
MemberJoined { team_id: TeamId, member_id: MemberId },
MemberLeft { team_id: TeamId, member_id: MemberId },
TaskCreated { team_id: TeamId, task_id: TaskId },
TaskCompleted { team_id: TeamId, task_id: TaskId },
}Artifacts
Teams can produce shared artifacts:
pub struct TeamArtifact {
pub id: ArtifactId,
pub name: String,
pub content_type: String,
pub content: Vec<u8>,
}Safety Properties
- No SQL injection — Parameterized queries throughout
- No lock poisoning — Uses
tokio::sync::Mutex - Type-safe status —
FromSqlimplementations prevent silent parsing failures - No unwrap in production — All database operations return
Result
Code Location
src/teams/mod.rs— Module entry pointsrc/teams/store.rs—TeamStoretrait and SQLite implementationsrc/teams/types.rs— Core typessrc/teams/lifecycle.rs— Lifecycle managementsrc/teams/events.rs— Event definitionssrc/teams/artifacts.rs— Artifact managementsrc/teams/plans.rs— Plan approval workflowsrc/teams/context.rs— Team context for agentssrc/teams/sessions/— Session managementsrc/teams/messages/— Team messaging
See Also
- Agent Runtime — How agents spawn and manage tasks
- Group Chat — Three-panel team chat with attribution bubbles
- Arena — Multi-agent collaboration workspace