GenServer managing a Live API WebSocket session.
Provides a high-level interface for real-time bidirectional communication with Gemini models for voice, video, and text interactions.
Usage
# Start a session
{:ok, pid} = Session.start_link(
model: "gemini-2.5-flash-native-audio-preview-12-2025",
auth: :gemini,
on_message: fn msg -> IO.inspect(msg) end,
on_error: fn err -> Logger.error(inspect(err)) end
)
# Connect to the Live API
:ok = Session.connect(pid)
# Send text content
:ok = Session.send_client_content(pid, "Hello!")
# Send realtime audio
:ok = Session.send_realtime_input(pid, audio: audio_blob)
# Close when done
:ok = Session.close(pid)Callbacks
on_message- Called for each server messageon_error- Called on errorson_close- Called when session closeson_tool_call- Called when model requests tool execution (may return tool responses)on_transcription- Called for audio transcriptionson_voice_activity- Called for voice activity signals
Session State
The session tracks:
- Connection status
- Setup completion
- Active tool calls
- Session resumption handle
- Usage metadata
Audio Format
- Input: 16-bit PCM, 16kHz, mono
- Output: 16-bit PCM, 24kHz, mono
Summary
Functions
Returns a specification to start this module under a supervisor.
Closes the session gracefully.
Connects to the Live API and sends setup configuration.
Returns the session resumption handle (if available).
Sends client content (text turns) to the model.
Sends realtime input (audio, video, text) to the model.
Sends tool/function responses to the model.
Starts a new Live session process.
Returns the current session status.
Types
@type session_status() ::
:disconnected | :connecting | :setup_pending | :ready | :closing
@type state() :: %{ websocket: Gemini.Client.WebSocket.t() | term() | nil, websocket_module: module(), websocket_opts: keyword(), status: session_status(), config: map(), callbacks: map(), pending_setup: Gemini.Types.Live.Setup.t() | nil, session_handle: String.t() | nil, usage_metadata: map() | nil, owner: pid() }
@type tool_call_callback() :: (Gemini.Types.Live.ToolCall.t() -> tool_call_callback_result())
@type tool_call_callback_result() :: :ok | {:tool_response, tool_responses()} | {:send_tool_response, tool_responses()} | tool_responses()
@type tool_response() :: map()
@type tool_responses() :: [tool_response()]
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec close(GenServer.server()) :: :ok
Closes the session gracefully.
Returns
:ok- Session closed
@spec connect(GenServer.server()) :: :ok | {:error, term()}
Connects to the Live API and sends setup configuration.
Must be called after start_link/1 to establish the WebSocket connection.
Waits for the setup_complete response before returning.
Returns
:ok- Connected and setup complete{:error, reason}- Connection failed
@spec get_session_handle(GenServer.server()) :: String.t() | nil
Returns the session resumption handle (if available).
The handle can be used to resume a session after disconnection. Only available if session_resumption was enabled and the server has provided a handle.
@spec send_client_content(GenServer.server(), String.t() | list(), keyword()) :: :ok | {:error, term()}
Sends client content (text turns) to the model.
Parameters
session- Session PIDcontent- String or list of turn mapsopts- Options::turn_complete- Whether this completes the turn (default: true)
Returns
:ok- Content sent{:error, reason}- Send failed
Examples
# Simple text
Session.send_client_content(pid, "What is 2+2?")
# With turn control
Session.send_client_content(pid, "Part 1", turn_complete: false)
Session.send_client_content(pid, "Part 2", turn_complete: true)
# Multi-turn context
Session.send_client_content(pid, [
%{role: "user", parts: [%{text: "Hello"}]},
%{role: "model", parts: [%{text: "Hi!"}]},
%{role: "user", parts: [%{text: "How are you?"}]}
])
@spec send_realtime_input( GenServer.server(), keyword() ) :: :ok | {:error, term()}
Sends realtime input (audio, video, text) to the model.
Parameters
session- Session PIDopts- Input options::audio- Audio blob (16-bit PCM, 16kHz mono):video- Video blob:text- Text string:activity_start- Signal start of user activity:activity_end- Signal end of user activity:audio_stream_end- Signal audio stream ended
Returns
:ok- Input sent{:error, reason}- Send failed
Examples
# Send audio chunk
Session.send_realtime_input(pid, audio: %{data: pcm_data, mime_type: "audio/pcm;rate=16000"})
# Signal manual activity
Session.send_realtime_input(pid, activity_start: true)
Session.send_realtime_input(pid, audio: audio_chunk)
Session.send_realtime_input(pid, activity_end: true)
@spec send_tool_response(GenServer.server(), list()) :: :ok | {:error, term()}
Sends tool/function responses to the model.
Parameters
session- Session PIDresponses- List of function response maps with:id,:name, and:responsekeys
Returns
:ok- Response sent{:error, reason}- Send failed
Example
Session.send_tool_response(pid, [
%{id: "call_123", name: "get_weather", response: %{temp: 72}}
])
@spec start_link(keyword()) :: GenServer.on_start()
Starts a new Live session process.
Options
:model- Required. Model name (e.g., "gemini-2.5-flash-native-audio-preview-12-2025"):auth- Auth strategy (:geminior:vertex_ai, default: auto-detect):project_id- Required for Vertex AI:location- Vertex AI location (default: "us-central1"):api_version- Live API version (default: "v1beta"):generation_config- Generation configuration:system_instruction- System instruction content:tools- Tool declarations:proactivity- Proactivity configuration (v1alpha):enable_affective_dialog- Enable affective dialog (v1alpha):realtime_input_config- Realtime input configuration:on_message- Callback for server messages:on_error- Callback for errors:on_close- Callback for session close:on_tool_call- Callback for tool call requests (may return tool responses)- Return
{:tool_response, responses}or a list of responses to send automatically
- Return
:on_tool_call_cancellation- Callback for tool call cancellation:on_transcription- Callback for transcriptions:on_voice_activity- Callback for voice activity signals:on_session_resumption- Callback for session resumption updates:on_go_away- Callback for GoAway notices (impending disconnection):session_resumption- Enable session resumption:resume_handle- Handle from previous session to resume:context_window_compression- Enable context compression:websocket_module- Advanced: override WebSocket client module (useful for testing):websocket_opts- Advanced: extra options passed to WebSocket.connect/2
Returns
{:ok, pid}- Session started{:error, reason}- Start failed
Examples
{:ok, session} = Session.start_link(
model: "gemini-2.5-flash-native-audio-preview-12-2025",
auth: :gemini,
generation_config: %{response_modalities: ["TEXT"]},
on_message: fn msg -> IO.inspect(msg) end
)
@spec status(GenServer.server()) :: session_status()
Returns the current session status.
Status Values
:disconnected- Not connected:connecting- Connection in progress:setup_pending- Connected, waiting for setup_complete:ready- Connected and ready for messages:closing- Received GoAway, closing soon