Built-in tool that enables an agent to transfer control to a sub-agent.
When an LLM agent has sub-agents configured, transfer_to_agent tools are
automatically generated — one per sub-agent. When the LLM calls this tool,
it produces an event with actions.transfer_to_agent set, which the runner
picks up to hand off execution to the target agent.
Differences from Python ADK
Python ADK creates a single transfer_to_agent tool with an enum constraint
on the agent_name parameter. Elixir creates one tool per target agent
(named transfer_to_agent_<name>) with the target hardcoded in the closure.
Both approaches prevent hallucinated agent names:
- Python: enum constraint restricts valid values
- Elixir: separate tools mean the LLM picks the right tool by name, no parameter to hallucinate
The per-agent approach was chosen for Elixir because:
- It eliminates a class of errors (wrong agent_name parameter)
- Tool descriptions per-agent give the LLM better context for selection
- It works naturally with Elixir's pattern matching
How it works
- The parent agent's tool list is augmented with one
transfer_to_agent_*tool per sub-agent - When the LLM invokes the tool, it returns a transfer event
- The parent agent's run loop detects the transfer and delegates to the target sub-agent
- The sub-agent runs and its events are returned
Summary
Functions
Extract the target agent name from a transfer result.
Generate transfer tools for a list of target agents.
Check if a tool result is a transfer signal.
Functions
Extract the target agent name from a transfer result.
@spec tools_for_sub_agents([ADK.Agent.t()]) :: [ADK.Tool.FunctionTool.t()]
Generate transfer tools for a list of target agents.
Returns a list of ADK.Tool.FunctionTool structs, one per target agent.
Each tool's parameters include an enum constraint on the agent_name
field listing all valid target names, preventing the LLM from hallucinating
non-existent agent names.
Check if a tool result is a transfer signal.