After: You can run agents in a supervision tree and manage parent/child hierarchies.

Agents run inside an AgentServer GenServer process. This guide covers starting agents, sending signals, and managing parent-child hierarchies.

For complete API details, see Jido.AgentServer and Jido.Await moduledocs.

Starting Agents

Use your instance module's start_agent/2 to start agents (recommended):

{:ok, pid} = MyApp.Jido.start_agent(MyAgent)
{:ok, pid} = MyApp.Jido.start_agent(MyAgent,
  id: "custom-id",
  initial_state: %{counter: 10}
)

Or start directly via AgentServer:

{:ok, pid} = Jido.AgentServer.start_link(agent: MyAgent)
{:ok, pid} = Jido.AgentServer.start(agent: MyAgent, jido: MyApp.Jido)

call/3 vs cast/2

Synchronous - blocks until signal is processed, returns updated agent:

{:ok, agent} = Jido.AgentServer.call(pid, signal)
{:ok, agent} = Jido.AgentServer.call(pid, signal, 10_000)  # custom timeout

Asynchronous - returns immediately:

:ok = Jido.AgentServer.cast(pid, signal)

Signal Processing Flow

Signal  AgentServer.call/cast
        route_signal_to_action (via strategy.signal_routes or default)
        Agent.cmd/2
        {agent, directives}
        Directives queued  drain loop via DirectiveExec

The AgentServer routes incoming signals to actions based on your strategy's signal_routes/0, executes the action via cmd/2, and processes any returned directives.

Parent-Child Hierarchy

Spawning Children

Emit a SpawnAgent directive to create a child agent:

%Directive.SpawnAgent{agent: ChildAgent, tag: :worker_1}

The parent:

  • Monitors the child process
  • Tracks children in state.children map by tag
  • Receives jido.agent.child.exit signals when children exit

Child Communication

Children can emit signals back to their parent:

Directive.emit_to_parent(agent, signal)

Stopping Children

%Directive.StopChild{tag: :worker_1}

Completion Detection

Agents signal completion via state, not process death. This allows retrieving results and keeps the agent available for inspection.

# In your agent/strategy - set terminal status
agent = put_in(agent.state.status, :completed)
agent = put_in(agent.state.last_answer, result)

Check state externally:

{:ok, state} = Jido.AgentServer.state(pid)

case state.agent.state.status do
  :completed -> state.agent.state.last_answer
  :failed -> {:error, state.agent.state.error}
  _ -> :still_running
end

Await Helpers

The Jido.Await module provides conveniences for waiting on agent completion.

# Wait for single agent
{:ok, result} = Jido.await(pid, 10_000)

# Wait for child by tag
{:ok, result} = Jido.await_child(parent, :worker_1, 30_000)

# Wait for all agents
{:ok, results} = Jido.await_all([pid1, pid2], 30_000)

# Wait for first completion
{:ok, {winner, result}} = Jido.await_any([pid1, pid2], 10_000)

Utilities

Jido.alive?(pid)                    # Check if agent is running
{:ok, children} = Jido.get_children(parent)  # List child agents
Jido.cancel(pid)                    # Cancel a running agent

For detailed await patterns, fan-out coordination, and testing without Process.sleep, see the Await & Coordination guide.