Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/realtime/twilio_sip/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ This example shows how to handle OpenAI Realtime SIP calls with the Agents SDK.

1. Install dependencies:
```bash
uv pip install -r examples/realtime/twilio-sip/requirements.txt
uv pip install -r examples/realtime/twilio_sip/requirements.txt
```
2. Export required environment variables:
```bash
Expand Down
24 changes: 16 additions & 8 deletions src/agents/realtime/openai_realtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ def __init__(self) -> None:
self._playback_tracker: RealtimePlaybackTracker | None = None
self._created_session: OpenAISessionCreateRequest | None = None
self._server_event_type_adapter = get_server_event_type_adapter()
self._call_id: str | None = None

async def connect(self, options: RealtimeModelConfig) -> None:
"""Establish a connection to the model and keep it alive."""
Expand All @@ -220,6 +221,7 @@ async def connect(self, options: RealtimeModelConfig) -> None:
if model_name:
self.model = model_name

self._call_id = call_id
api_key = await get_api_key(options.get("api_key"))

if "tracing" in model_settings:
Expand Down Expand Up @@ -833,10 +835,13 @@ def _get_session_config(
speed = model_settings.get("speed")
modalities = model_settings.get("modalities", DEFAULT_MODEL_SETTINGS.get("modalities"))

input_audio_format = model_settings.get(
"input_audio_format",
DEFAULT_MODEL_SETTINGS.get("input_audio_format"),
)
if self._call_id:
input_audio_format = model_settings.get("input_audio_format")
else:
input_audio_format = model_settings.get(
"input_audio_format",
DEFAULT_MODEL_SETTINGS.get("input_audio_format"),
)
input_audio_transcription = model_settings.get(
"input_audio_transcription",
DEFAULT_MODEL_SETTINGS.get("input_audio_transcription"),
Expand All @@ -845,10 +850,13 @@ def _get_session_config(
"turn_detection",
DEFAULT_MODEL_SETTINGS.get("turn_detection"),
)
output_audio_format = model_settings.get(
"output_audio_format",
DEFAULT_MODEL_SETTINGS.get("output_audio_format"),
)
if self._call_id:
output_audio_format = model_settings.get("output_audio_format")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a developer does not explicitly pass format settings, OpenAIRealtimeSIPModel relies on the default one.

else:
output_audio_format = model_settings.get(
"output_audio_format",
DEFAULT_MODEL_SETTINGS.get("output_audio_format"),
)
input_audio_noise_reduction = model_settings.get(
"input_audio_noise_reduction",
DEFAULT_MODEL_SETTINGS.get("input_audio_noise_reduction"),
Expand Down
23 changes: 23 additions & 0 deletions tests/realtime/test_openai_realtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,29 @@ def test_get_and_update_session_config(self, model):
assert cfg.audio is not None and cfg.audio.output is not None
assert cfg.audio.output.voice == "verse"

def test_session_config_defaults_audio_formats_when_not_call(self, model):
settings: dict[str, Any] = {}
cfg = model._get_session_config(settings)
assert cfg.audio is not None
assert cfg.audio.input is not None
assert cfg.audio.input.format is not None
assert cfg.audio.input.format.type == "audio/pcm"
assert cfg.audio.output is not None
assert cfg.audio.output.format is not None
assert cfg.audio.output.format.type == "audio/pcm"

def test_session_config_preserves_sip_audio_formats(self, model):
model._call_id = "call-123"
settings = {
"turn_detection": {"type": "semantic_vad", "interrupt_response": True},
}
cfg = model._get_session_config(settings)
assert cfg.audio is not None
assert cfg.audio.input is not None
assert cfg.audio.input.format is None
assert cfg.audio.output is not None
assert cfg.audio.output.format is None

@pytest.mark.asyncio
async def test_handle_error_event_success(self, model):
"""Test successful handling of error events."""
Expand Down