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

Orchestrates realtime agent sessions.

A `Runner` is the equivalent of `Codex.AgentRunner` for realtime agents. It
automatically handles multiple turns by maintaining a persistent connection
with the underlying model layer.

The session manages the local history copy, executes tools, runs guardrails
and facilitates handoffs between agents.

Since this code runs on your server, it uses WebSockets by default. You can
optionally create your own custom model layer by implementing the
`Codex.Realtime.Model` behaviour.

## Example

    # Create an agent
    agent = Codex.Realtime.Agent.new(
      name: "VoiceAssistant",
      instructions: "You are a helpful voice assistant."
    )

    # Create a runner
    runner = Codex.Realtime.Runner.new(agent,
      config: %Codex.Realtime.Config.RunConfig{
        tracing_disabled: false
      }
    )

    # Start a session
    {:ok, session} = Codex.Realtime.Runner.run(runner)

    # Use the session
    Codex.Realtime.Session.send_message(session, "Hello!")

    # Subscribe to events
    Codex.Realtime.Session.subscribe(session, self())
    receive do
      {:session_event, event} -> handle_event(event)
    end

## Options

When creating a runner with `new/2`:

  * `:config` - A `%Codex.Realtime.Config.RunConfig{}` for runtime settings
  * `:model` - Optional custom model module implementing the Model behaviour

When starting a session with `run/2`:

  * `:context` - Context map passed to the session
  * `:model_config` - A `%Codex.Realtime.Config.ModelConfig{}` for API settings
  * `:websocket_pid` - For testing with a mock WebSocket
  * `:websocket_module` - Override the WebSocket module (default: WebSockex)

# `t`

```elixir
@type t() :: %Codex.Realtime.Runner{
  config: Codex.Realtime.Config.RunConfig.t() | nil,
  model: module() | nil,
  starting_agent: Codex.Realtime.Agent.t() | nil
}
```

# `new`

```elixir
@spec new(
  Codex.Realtime.Agent.t(),
  keyword()
) :: t()
```

Create a new realtime runner.

## Arguments

  * `starting_agent` - The agent to start the session with.

## Options

  * `:config` - Override parameters to use for the entire run.
  * `:model` - The model to use. If not provided, will use the default
    OpenAI realtime model.

## Example

    agent = Codex.Realtime.Agent.new(name: "Assistant")
    runner = Codex.Realtime.Runner.new(agent,
      config: %Codex.Realtime.Config.RunConfig{tracing_disabled: true}
    )

# `run`

```elixir
@spec run(
  t(),
  keyword()
) :: {:ok, pid()} | {:error, term()}
```

Start a realtime session.

Returns a session that can be used for bidirectional communication.

## Options

  * `:context` - Context to pass to the session (default: `%{}`)
  * `:model_config` - Model connection configuration (`%ModelConfig{}`)
  * `:websocket_pid` - For testing with a mock WebSocket
  * `:websocket_module` - Override the WebSocket module

## Returns

  * `{:ok, pid}` - Session started successfully
  * `{:error, reason}` - Failed to start session

## Example

    runner = Runner.new(agent)
    {:ok, session} = Runner.run(runner)

    # Send messages
    Session.send_message(session, "Hello!")

    # Stream events
    Session.subscribe(session, self())
    receive do
      {:session_event, event} -> handle_event(event)
    end

    # Close when done
    Session.close(session)

---

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