A realtime agent optimized for voice interactions.
Realtime agents are specialized agents meant to be used within a Codex.Realtime.Session
to build voice agents. Due to the nature of this agent, some configuration options differ
from regular Codex.Agent instances:
modelchoice is constrained to realtime-capable models- Output types and structured outputs are not supported
- Voice can be configured at the agent level
Features
- Voice-to-voice communication
- Tool execution during conversations
- Handoffs to other agents
- Dynamic instructions (string or function)
- Output guardrails
Examples
# Simple agent
agent = %Codex.Realtime.Agent{
name: "Assistant",
instructions: "You are a helpful voice assistant."
}
# Agent with dynamic instructions
agent = %Codex.Realtime.Agent{
name: "Greeter",
instructions: fn ctx -> "Welcome #{ctx.user_name}!" end
}
# Agent with handoffs
support_agent = %Codex.Realtime.Agent{name: "Support"}
main_agent = %Codex.Realtime.Agent{
name: "Main",
handoffs: [support_agent]
}
Summary
Functions
Create a copy of the agent with the given fields changed.
Find handoff target by tool name.
Get all tools including handoff tools.
Create a new realtime agent from keyword options.
Resolve instructions, calling function if needed.
Types
@type t() :: %Codex.Realtime.Agent{ handoff_description: String.t() | nil, handoffs: [t() | Codex.Handoff.t()], hooks: term(), instructions: String.t() | instruction_fn() | nil, model: String.t(), name: String.t(), output_guardrails: [term()], tools: [module()] }
Functions
Create a copy of the agent with the given fields changed.
Examples
new_agent = Codex.Realtime.Agent.clone(agent, name: "NewName")
@spec find_handoff_target(t(), String.t()) :: {:ok, t() | Codex.Agent.t()} | {:error, :not_found}
Find handoff target by tool name.
Given a tool name like "transfer_to_support", finds the corresponding agent or handoff target in the handoffs list.
Examples
support = %Agent{name: "Support"}
agent = %Agent{handoffs: [support]}
{:ok, target} = Agent.find_handoff_target(agent, "transfer_to_support")
target.name #=> "Support"
@spec get_tools(t()) :: [module() | Codex.Handoff.t()]
Get all tools including handoff tools.
Returns the agent's tools combined with auto-generated handoff tools for each configured handoff.
Examples
support = %Agent{name: "Support"}
agent = %Agent{tools: [MyTool], handoffs: [support]}
Agent.get_tools(agent)
#=> [MyTool, %Handoff{tool_name: "transfer_to_support", ...}]
Create a new realtime agent from keyword options.
Examples
agent = Codex.Realtime.Agent.new(
name: "VoiceBot",
instructions: "Be helpful and concise."
)
Resolve instructions, calling function if needed.
Supports both arity-1 functions (receiving context) and arity-2 functions (receiving context and agent).
Examples
# String instructions
agent = %Agent{instructions: "Be helpful"}
Agent.resolve_instructions(agent, %{}) #=> "Be helpful"
# Function instructions (arity 1)
agent = %Agent{instructions: fn ctx -> "Hello #{ctx.user}" end}
Agent.resolve_instructions(agent, %{user: "Alice"}) #=> "Hello Alice"
# Function instructions (arity 2)
agent = %Agent{
name: "Bot",
instructions: fn ctx, agent -> "Hello #{ctx.user}, I'm #{agent.name}" end
}
Agent.resolve_instructions(agent, %{user: "Bob"}) #=> "Hello Bob, I'm Bot"