Nous.AgentDynamicSupervisor (nous v0.17.1)

Copy Markdown View Source

DynamicSupervisor that owns the lifecycle of every Nous.AgentServer.

Started by Nous.Application alongside Nous.AgentRegistry: this process supervises the agents, the registry names them. Each child is an AgentServer for one session, started with Nous.AgentRegistry.via_tuple(session_id) as its :name, so the two are always in step — start an agent here and it becomes resolvable there; when it exits, the registry entry disappears with it.

Restart intensity is deliberately loosened to max_restarts: 100 in max_seconds: 10. The :one_for_one default of 3-in-5 means one user's crash-looping agent would collapse the supervisor and take every other tenant's agent with it; the wider budget still trips if the whole layer is broken, but not for a single bad session.

Children are transient in practice, not pre-declared: nothing is started at boot, and you add agents at runtime with start_agent/3.

Examples

# `agent_config` is a plain map (see `t:Nous.AgentServer.agent_config/0`),
# not a built `%Nous.Agent{}` — the server constructs the agent itself.
config = %{
  model: "openai:gpt-4o-mini",
  instructions: "You are a helpful assistant.",
  tools: [&Nous.Tools.DateTimeTools.current_date/2]
}

{:ok, pid} = Nous.AgentDynamicSupervisor.start_agent("session-42", config)

# The session ID is the handle from here on
{:ok, ^pid} = Nous.AgentDynamicSupervisor.find_agent("session-42")
Nous.AgentServer.send_message(pid, "What day is it?")

# Session IDs are unique; a second start returns the running process
Nous.AgentDynamicSupervisor.start_agent("session-42", config)
#=> {:error, {:already_started, pid}}

:ok = Nous.AgentDynamicSupervisor.stop_agent("session-42")
Nous.AgentDynamicSupervisor.find_agent("session-42")
#=> {:error, :not_found}

Summary

Functions

Returns a specification to start this module under a supervisor.

Find an agent process by session ID.

Start an AgentServer under this supervisor, registered in AgentRegistry.

Start the supervisor. Called by Nous.Application; you do not need this.

Stop an agent by session ID.

Functions

child_spec(arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

find_agent(session_id)

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

Find an agent process by session ID.

A thin alias for Nous.AgentRegistry.lookup/1.

start_agent(session_id, agent_config, opts \\ [])

Start an AgentServer under this supervisor, registered in AgentRegistry.

agent_config is the map described by Nous.AgentServer.agent_config/0. Returns {:error, {:already_started, pid}} if session_id already has a live agent.

Options

Accepts all options supported by Nous.AgentServer.start_link/1.

start_link(opts)

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

Start the supervisor. Called by Nous.Application; you do not need this.

stop_agent(session_id)

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

Stop an agent by session ID.

Returns {:error, :not_found} when no agent is registered for that session.