Manages a realtime session with WebSocket connection.
A RealtimeSession is a GenServer that manages the connection to OpenAI's
Realtime API, handles event dispatch, tool execution, and conversation history.
Usage
# Define an agent
agent = %Codex.Realtime.Agent{
name: "Assistant",
model: "gpt-4o-realtime-preview",
instructions: "Be helpful and concise."
}
# Start the session
{:ok, session} = Session.start_link(agent: agent)
# Subscribe to events
:ok = Session.subscribe(session, self())
# Send a message
:ok = Session.send_message(session, "Hello!")
# Receive events
receive do
{:session_event, %Events.AgentStartEvent{}} ->
IO.puts("Agent started!")
{:session_event, %Events.AudioEvent{audio: audio}} ->
# Handle audio data
end
# Close when done
Session.close(session)Events
Subscribers receive events as {:session_event, event} messages. See
Codex.Realtime.Events for the full list of event types.
Tool Execution
When the model calls a tool, the session automatically executes it and sends the result back to the model. Tool events are emitted to subscribers.
Summary
Functions
Returns a specification to start this module under a supervisor.
Close the session.
Get the current agent.
Get the conversation history.
Interrupt the current response.
Send audio data to the model.
Send a text message to the model.
Send a raw event to the model.
Start a realtime session.
Subscribe to session events.
Unsubscribe from session events.
Update session settings.
Types
@type t() :: %Codex.Realtime.Session{ agent: term(), config: Codex.Realtime.Config.ModelConfig.t(), context: map(), history: [Codex.Realtime.Items.item()], interrupted_response_ids: MapSet.t(String.t()), item_guardrail_run_counts: %{required(String.t()) => non_neg_integer()}, item_transcripts: %{required(String.t()) => String.t()}, pending_tool_calls: %{optional(pid()) => map()}, playback_tracker: Codex.Realtime.PlaybackTracker.t(), run_config: Codex.Realtime.Config.RunConfig.t(), subscribers: %{optional(pid()) => reference()}, websocket_module: module() | nil, websocket_pid: pid() | nil }
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec close(GenServer.server()) :: :ok
Close the session.
Closes the WebSocket connection and stops the session process.
@spec current_agent(GenServer.server()) :: term()
Get the current agent.
@spec history(GenServer.server()) :: [Codex.Realtime.Items.item()]
Get the conversation history.
@spec interrupt(GenServer.server()) :: :ok
Interrupt the current response.
Sends a cancel signal to stop the model from generating more output.
@spec send_audio(GenServer.server(), binary(), keyword()) :: :ok
Send audio data to the model.
Options
:commit- Whether to commit the audio buffer (default: false)
Examples
Session.send_audio(session, audio_bytes)
Session.send_audio(session, audio_bytes, commit: true)
@spec send_message(GenServer.server(), String.t() | map()) :: :ok
Send a text message to the model.
Can be a simple string or a structured message map.
Examples
Session.send_message(session, "Hello!")
Session.send_message(session, %{
"type" => "message",
"role" => "user",
"content" => [
%{"type" => "input_text", "text" => "Hello!"},
%{"type" => "input_image", "image_url" => "data:image/..."}
]
})
@spec send_raw_event(GenServer.server(), map()) :: :ok
Send a raw event to the model.
Use this for advanced scenarios where you need to send custom events.
@spec start_link(keyword()) :: GenServer.on_start()
Start a realtime session.
Options
:agent- Required. The realtime agent configuration.:config- Optional model configuration (API key, URL, etc.).:run_config- Optional runtime configuration.:context- Optional context map passed to tools and events.:websocket_pid- Optional. For testing with a mock WebSocket.:websocket_module- Optional. Override the WebSocket module (default: WebSockex).
Returns
{:ok, pid}on success{:error, reason}on failure
@spec subscribe(GenServer.server(), pid()) :: :ok
Subscribe to session events.
The subscriber process will receive {:session_event, event} messages
for all session events.
@spec unsubscribe(GenServer.server(), pid()) :: :ok
Unsubscribe from session events.
@spec update_session( GenServer.server(), Codex.Realtime.Config.SessionModelSettings.t() ) :: :ok
Update session settings.
Use this to change model settings mid-session, such as voice or modalities.