Nous.Teams.Coordinator (nous v0.16.1)

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: [...]}