Caller-routed strategy: N named sub-agents; every tell/ask
specifies its target agent via opts[:agent].
No decomposition, no coordination across agents, no default
target -- if the caller doesn't say which agent, the call fails
loud with {:error, :no_agent_specified}. Pick this strategy
when you want an explicit routed fleet ("the code review team")
rather than an implicit pool or a decomposing coordinator.
Options
:agents(required) -- list of{name, module, opts}specs, one per sub-agent. Names must be unique within this ensemble.
Addressing
iex> E.ask!("reviewers", "review this API", agent: "alice")
iex> E.tell("reviewers", "review this PR", agent: "bob")State
%{
agents: MapSet.of(names),
pending: %{agent_name => :queue.queue(token)}
}Tokens queue per-agent in FIFO order. When an agent completes a turn, the oldest queued token for that agent is replied to.
Failure modes
opts[:agent]missing --{:error, :no_agent_specified}opts[:agent]not in the fleet --{:error, {:unknown_agent, name}}- An agent's turn errors -- that token fails; the agent stays available for subsequent turns.
- An agent dies -- its pending tokens all fail with
{:agent_down, reason}; remaining agents keep serving. - All agents die -- the session halts.