Skip to content

Commit f0df572

Browse files
authored
fix: default realtime websocket model to gpt-realtime-1.5 (#2737)
1 parent 72ad8e3 commit f0df572

File tree

7 files changed

+58
-14
lines changed

7 files changed

+58
-14
lines changed

examples/realtime/twilio_sip/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ async def accept_call(call_id: str) -> None:
6969
f"/realtime/calls/{call_id}/accept",
7070
body={
7171
"type": "realtime",
72-
"model": "gpt-realtime",
72+
"model": "gpt-realtime-1.5",
7373
"instructions": instructions_payload,
7474
},
7575
cast_to=dict,

src/agents/realtime/openai_realtime.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@
158158

159159

160160
_USER_AGENT = f"Agents/Python {__version__}"
161+
DEFAULT_REALTIME_MODEL = "gpt-realtime-1.5"
161162

162163
DEFAULT_MODEL_SETTINGS: RealtimeSessionModelSettings = {
163164
"voice": "ash",
@@ -271,7 +272,7 @@ class OpenAIRealtimeWebSocketModel(RealtimeModel):
271272
"""A model that uses OpenAI's WebSocket API."""
272273

273274
def __init__(self, *, transport_config: TransportConfig | None = None) -> None:
274-
self.model = "gpt-realtime" # Default model
275+
self.model = DEFAULT_REALTIME_MODEL
275276
self._websocket: ClientConnection | None = None
276277
self._websocket_task: asyncio.Task[None] | None = None
277278
self._listeners: list[RealtimeModelListener] = []
@@ -1105,7 +1106,7 @@ def _get_session_config(
11051106
# Construct full session object. `type` will be excluded at serialization time for updates.
11061107
session_create_request = OpenAISessionCreateRequest(
11071108
type="realtime",
1108-
model=(model_settings.get("model_name") or self.model) or "gpt-realtime",
1109+
model=(model_settings.get("model_name") or self.model) or DEFAULT_REALTIME_MODEL,
11091110
output_modalities=output_modalities,
11101111
audio=OpenAIRealtimeAudioConfig(
11111112
input=OpenAIRealtimeAudioInput(**audio_input_args),

tests/realtime/test_conversion_helpers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def test_try_convert_raw_message_valid_session_update(self):
3333
"type": "session.update",
3434
"other_data": {
3535
"session": {
36-
"model": "gpt-realtime",
36+
"model": "gpt-realtime-1.5",
3737
"type": "realtime",
3838
"modalities": ["text", "audio"],
3939
"voice": "ash",

tests/realtime/test_openai_realtime.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,36 @@ def mock_create_task_func(coro):
113113
assert model._websocket_task is not None
114114
assert model.model == "gpt-4o-realtime-preview"
115115

116+
@pytest.mark.asyncio
117+
async def test_connect_defaults_to_gpt_realtime_1_5(self, model, mock_websocket):
118+
"""Test that connect() uses gpt-realtime-1.5 when no model is provided."""
119+
config = {
120+
"api_key": "test-api-key-123",
121+
"initial_model_settings": {},
122+
}
123+
124+
async def async_websocket(*args, **kwargs):
125+
return mock_websocket
126+
127+
with patch("websockets.connect", side_effect=async_websocket) as mock_connect:
128+
with patch("asyncio.create_task") as mock_create_task:
129+
mock_task = AsyncMock()
130+
131+
def mock_create_task_func(coro):
132+
coro.close()
133+
return mock_task
134+
135+
mock_create_task.side_effect = mock_create_task_func
136+
137+
await model.connect(config)
138+
139+
mock_connect.assert_called_once()
140+
call_args = mock_connect.call_args
141+
assert call_args[0][0] == "wss://api.openai.com/v1/realtime?model=gpt-realtime-1.5"
142+
assert model.model == "gpt-realtime-1.5"
143+
144+
assert model._websocket_task is not None
145+
116146
@pytest.mark.asyncio
117147
async def test_session_update_includes_noise_reduction(self, model, mock_websocket):
118148
"""Session.update should pass through input_audio_noise_reduction config."""
@@ -788,6 +818,7 @@ def test_get_and_update_session_config(self, model):
788818
def test_session_config_defaults_audio_formats_when_not_call(self, model):
789819
settings: dict[str, Any] = {}
790820
cfg = model._get_session_config(settings)
821+
assert cfg.model == "gpt-realtime-1.5"
791822
assert cfg.audio is not None
792823
assert cfg.audio.input is not None
793824
assert cfg.audio.input.format is not None

tests/realtime/test_realtime_model_settings.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def helper() -> str:
5151

5252
monkeypatch.setattr(agent, "get_all_tools", AsyncMock(return_value=[helper]))
5353
agent.handoffs = [RealtimeAgent(name="handoff-child")]
54-
base_settings: RealtimeSessionModelSettings = {"model_name": "gpt-realtime"}
54+
base_settings: RealtimeSessionModelSettings = {"model_name": "gpt-realtime-1.5"}
5555
starting_settings: RealtimeSessionModelSettings = {"voice": "verse"}
5656
run_config: RealtimeRunConfig = {"tracing_disabled": True}
5757

@@ -68,9 +68,9 @@ def helper() -> str:
6868
assert merged["tools"][0].name == helper.name
6969
assert merged["handoffs"][0].agent_name == "handoff-child"
7070
assert merged["voice"] == "verse"
71-
assert merged["model_name"] == "gpt-realtime"
71+
assert merged["model_name"] == "gpt-realtime-1.5"
7272
assert merged["tracing"] is None
73-
assert base_settings == {"model_name": "gpt-realtime"}
73+
assert base_settings == {"model_name": "gpt-realtime-1.5"}
7474

7575

7676
@pytest.mark.asyncio

tests/realtime/test_session_payload_and_formats.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ class _DummyModel(pydantic.BaseModel):
2626

2727
def _session_with_output(fmt: Any | None) -> RealtimeSessionCreateRequest:
2828
if fmt is None:
29-
return RealtimeSessionCreateRequest(type="realtime", model="gpt-realtime")
29+
return RealtimeSessionCreateRequest(type="realtime", model="gpt-realtime-1.5")
3030
return RealtimeSessionCreateRequest(
3131
type="realtime",
32-
model="gpt-realtime",
32+
model="gpt-realtime-1.5",
3333
# Use dict for output to avoid importing non-exported symbols in tests
3434
audio=RealtimeAudioConfig(output=cast(Any, {"format": fmt})),
3535
)
@@ -49,7 +49,7 @@ def test_normalize_session_payload_variants() -> None:
4949
assert Model._normalize_session_payload(transcription_mapping) is None
5050

5151
# Valid realtime mapping should be converted to model
52-
realtime_mapping: Mapping[str, object] = {"type": "realtime", "model": "gpt-realtime"}
52+
realtime_mapping: Mapping[str, object] = {"type": "realtime", "model": "gpt-realtime-1.5"}
5353
as_model = Model._normalize_session_payload(realtime_mapping)
5454
assert isinstance(as_model, RealtimeSessionCreateRequest)
5555
assert as_model.type == "realtime"

tests/realtime/test_tracing.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,11 @@ async def async_websocket(*args, **kwargs):
100100
session_created_event = {
101101
"type": "session.created",
102102
"event_id": "event_123",
103-
"session": {"id": "session_456", "type": "realtime", "model": "gpt-realtime"},
103+
"session": {
104+
"id": "session_456",
105+
"type": "realtime",
106+
"model": "gpt-realtime-1.5",
107+
},
104108
}
105109

106110
with patch.object(model, "_send_raw_message") as mock_send_raw_message:
@@ -141,7 +145,11 @@ async def async_websocket(*args, **kwargs):
141145
session_created_event = {
142146
"type": "session.created",
143147
"event_id": "event_123",
144-
"session": {"id": "session_456", "type": "realtime", "model": "gpt-realtime"},
148+
"session": {
149+
"id": "session_456",
150+
"type": "realtime",
151+
"model": "gpt-realtime-1.5",
152+
},
145153
}
146154

147155
with patch.object(model, "_send_raw_message") as mock_send_raw_message:
@@ -166,7 +174,7 @@ async def test_tracing_config_none_skips_session_update(self, model, mock_websoc
166174
session_created_event = {
167175
"type": "session.created",
168176
"event_id": "event_123",
169-
"session": {"id": "session_456", "type": "realtime", "model": "gpt-realtime"},
177+
"session": {"id": "session_456", "type": "realtime", "model": "gpt-realtime-1.5"},
170178
}
171179

172180
with patch.object(model, "send_event") as mock_send_event:
@@ -205,7 +213,11 @@ async def async_websocket(*args, **kwargs):
205213
session_created_event = {
206214
"type": "session.created",
207215
"event_id": "event_123",
208-
"session": {"id": "session_456", "type": "realtime", "model": "gpt-realtime"},
216+
"session": {
217+
"id": "session_456",
218+
"type": "realtime",
219+
"model": "gpt-realtime-1.5",
220+
},
209221
}
210222

211223
with patch.object(model, "_send_raw_message") as mock_send_raw_message:

0 commit comments

Comments
 (0)