# `Codex.Realtime.Session`
[🔗](https://github.com/nshkrdotcom/codex_sdk/blob/v0.18.0/lib/codex/realtime/session.ex#L1)

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.

# `t`

```elixir
@type t() :: %Codex.Realtime.Session{
  active_response?: boolean(),
  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()) =&gt; non_neg_integer()},
  item_transcripts: %{required(String.t()) =&gt; String.t()},
  pending_response_create?: boolean(),
  pending_tool_calls: %{optional(pid()) =&gt; map()},
  playback_tracker: Codex.Realtime.PlaybackTracker.t(),
  run_config: Codex.Realtime.Config.RunConfig.t(),
  subscribers: %{optional(pid()) =&gt; reference()},
  websocket_module: module(),
  websocket_pid: pid() | nil
}
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `close`

```elixir
@spec close(GenServer.server()) :: :ok
```

Close the session.

Closes the WebSocket connection and stops the session process.

# `current_agent`

```elixir
@spec current_agent(GenServer.server()) :: term()
```

Get the current agent.

# `history`

```elixir
@spec history(GenServer.server()) :: [Codex.Realtime.Items.item()]
```

Get the conversation history.

# `interrupt`

```elixir
@spec interrupt(GenServer.server()) :: :ok | {:error, term()}
```

Interrupt the current response.

Sends a cancel signal to stop the model from generating more output.

Returns `{:error, :not_connected}` if the websocket is unavailable.

# `send_audio`

```elixir
@spec send_audio(GenServer.server(), binary(), keyword()) :: :ok | {:error, term()}
```

Send audio data to the model.

Returns `{:error, :not_connected}` if the websocket is unavailable.

## 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)

# `send_message`

```elixir
@spec send_message(GenServer.server(), String.t() | map()) :: :ok | {:error, term()}
```

Send a text message to the model.

Returns `{:error, :not_connected}` if the websocket is unavailable.

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/..."}
      ]
    })

# `send_raw_event`

```elixir
@spec send_raw_event(GenServer.server(), map()) :: :ok | {:error, term()}
```

Send a raw event to the model.

Use this for advanced scenarios where you need to send custom events.

Returns `{:error, :not_connected}` if the websocket is unavailable.

# `start_link`

```elixir
@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 transport module
    (default: `Codex.Realtime.OpenAIWebSocket`). Custom modules must provide
    `send_frame/2` and `close/1`.

## Returns

  * `{:ok, pid}` on success
  * `{:error, reason}` on failure

# `subscribe`

```elixir
@spec subscribe(GenServer.server(), pid()) :: :ok
```

Subscribe to session events.

The subscriber process will receive `{:session_event, event}` messages
for all session events.

# `unsubscribe`

```elixir
@spec unsubscribe(GenServer.server(), pid()) :: :ok
```

Unsubscribe from session events.

# `update_session`

```elixir
@spec update_session(
  GenServer.server(),
  Codex.Realtime.Config.SessionModelSettings.t()
) ::
  :ok | {:error, term()}
```

Update session settings.

Use this to change model settings mid-session, such as voice or modalities.

Returns `{:error, :not_connected}` if the websocket is unavailable.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
