Nous.Teams.Coordinator (nous v0.17.2)

Copy Markdown View Source

Team lifecycle GenServer that manages agent processes within a team.

The Coordinator is responsible for spawning, stopping, and monitoring agent processes. It registers agents in the Nous.AgentRegistry with team-scoped keys and sets up PubSub subscriptions.

Architecture

Each team has exactly one Coordinator, started as part of Nous.Teams.Supervisor. The Coordinator uses the team's DynamicSupervisor to start AgentServer processes.

Teams.Supervisor
├── Coordinator (this module)
├── SharedState
├── RateLimiter (optional)
└── DynamicSupervisor (for agents)
    ├── AgentServer ("alice")
    └── AgentServer ("bob")

Quick Start

{:ok, pid} = Coordinator.start_link(
  team_id: "team_1",
  team_name: "Research Team",
  pubsub: MyApp.PubSub,
  agent_supervisor: agent_sup_pid,
  shared_state: shared_state_pid
)

{:ok, agent_pid} = Coordinator.spawn_agent(pid, "alice", %{
  model: "openai:gpt-4",
  instructions: "You are a researcher"
})

agents = Coordinator.list_agents(pid)
Coordinator.stop_agent(pid, "alice")
Coordinator.dissolve(pid)

Summary

Functions

Returns a specification to start this module under a supervisor.

Dissolve the team by stopping all agents and cleaning up.

List all agents in the team.

Spawn a new agent within the team.

Start a Coordinator for a team.

Stop an agent by name.

Get the team's current status.

Types

agent_info()

@type agent_info() :: %{name: String.t(), pid: pid(), status: :running | :stopped}

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

dissolve(pid)

@spec dissolve(pid()) :: :ok

Dissolve the team by stopping all agents and cleaning up.

Examples

:ok = Coordinator.dissolve(coordinator)

list_agents(pid)

@spec list_agents(pid()) :: [agent_info()]

List all agents in the team.

Returns a list of maps with :name, :pid, and :status keys.

Examples

agents = Coordinator.list_agents(coordinator)
# [%{name: "alice", pid: #PID<0.123.0>, status: :running}]

spawn_agent(pid, agent_name, agent_config, opts \\ [])

@spec spawn_agent(pid(), String.t(), map(), keyword()) ::
  {:ok, pid()} | {:error, term()}

Spawn a new agent within the team.

The agent is started under the team's DynamicSupervisor, registered in Nous.AgentRegistry with a {:team, team_id, name} key, and subscribed to team PubSub topics.

Options

  • :role — a Nous.Teams.Role struct to apply
  • :plugins — list of plugin modules for the agent

Examples

{:ok, pid} = Coordinator.spawn_agent(coordinator, "alice", %{
  model: "openai:gpt-4",
  instructions: "Research specialist"
})

start_link(opts)

@spec start_link(keyword()) :: GenServer.on_start()

Start a Coordinator for a team.

Options

  • :team_id (required) — unique identifier for the team
  • :team_name — human-readable team name (default: team_id)
  • :pubsub — PubSub module for messaging
  • :agent_supervisor — pid of the team's DynamicSupervisor for agents
  • :shared_state — pid of the team's SharedState process
  • :rate_limiter — pid of the team's RateLimiter process (optional)
  • :name — optional GenServer name

stop_agent(pid, agent_name)

@spec stop_agent(pid(), String.t()) :: :ok | {:error, :not_found}

Stop an agent by name.

Examples

:ok = Coordinator.stop_agent(coordinator, "alice")

team_status(pid)

@spec team_status(pid()) :: map()

Get the team's current status.

Returns a map with :team_id, :team_name, :agent_count, and :agents keys.

Examples

status = Coordinator.team_status(coordinator)
# %{team_id: "team_1", team_name: "Research", agent_count: 2, agents: [...]}