From a5420779c4464a128b27e6b5c6942405fdc86ab5 Mon Sep 17 00:00:00 2001 From: Ahmed Ibrahim Date: Wed, 4 Mar 2026 17:14:23 -0800 Subject: [PATCH] realtime: disable output interruption from turn detection --- .../src/endpoint/realtime_websocket/methods.rs | 18 ++++++++++++++++++ .../endpoint/realtime_websocket/protocol.rs | 9 +++++++++ .../codex-api/tests/realtime_websocket_e2e.rs | 12 ++++++++++++ 3 files changed, 39 insertions(+) diff --git a/codex-rs/codex-api/src/endpoint/realtime_websocket/methods.rs b/codex-rs/codex-api/src/endpoint/realtime_websocket/methods.rs index 7d4f760a7a..82a1770c92 100644 --- a/codex-rs/codex-api/src/endpoint/realtime_websocket/methods.rs +++ b/codex-rs/codex-api/src/endpoint/realtime_websocket/methods.rs @@ -9,6 +9,7 @@ use crate::endpoint::realtime_websocket::protocol::SessionAudioFormat; use crate::endpoint::realtime_websocket::protocol::SessionAudioInput; use crate::endpoint::realtime_websocket::protocol::SessionAudioOutput; use crate::endpoint::realtime_websocket::protocol::SessionAudioOutputFormat; +use crate::endpoint::realtime_websocket::protocol::SessionTurnDetection; use crate::endpoint::realtime_websocket::protocol::SessionTool; use crate::endpoint::realtime_websocket::protocol::SessionToolParameters; use crate::endpoint::realtime_websocket::protocol::SessionToolProperties; @@ -343,6 +344,11 @@ impl RealtimeWebsocketWriter { kind: "audio/pcm".to_string(), rate: 24_000, }, + turn_detection: SessionTurnDetection { + kind: "semantic_vad".to_string(), + interrupt_response: false, + create_response: true, + }, }, output: SessionAudioOutput { format: SessionAudioOutputFormat { @@ -899,6 +905,18 @@ mod tests { first_json["session"]["audio"]["input"]["format"]["rate"], Value::from(24_000) ); + assert_eq!( + first_json["session"]["audio"]["input"]["turn_detection"]["type"], + Value::String("semantic_vad".to_string()) + ); + assert_eq!( + first_json["session"]["audio"]["input"]["turn_detection"]["interrupt_response"], + Value::Bool(false) + ); + assert_eq!( + first_json["session"]["audio"]["input"]["turn_detection"]["create_response"], + Value::Bool(true) + ); assert_eq!( first_json["session"]["audio"]["output"]["format"]["type"], Value::String("audio/pcm".to_string()) diff --git a/codex-rs/codex-api/src/endpoint/realtime_websocket/protocol.rs b/codex-rs/codex-api/src/endpoint/realtime_websocket/protocol.rs index ca88c5d91f..467d9dca95 100644 --- a/codex-rs/codex-api/src/endpoint/realtime_websocket/protocol.rs +++ b/codex-rs/codex-api/src/endpoint/realtime_websocket/protocol.rs @@ -48,6 +48,7 @@ pub(super) struct SessionAudio { #[derive(Debug, Clone, Serialize)] pub(super) struct SessionAudioInput { pub(super) format: SessionAudioFormat, + pub(super) turn_detection: SessionTurnDetection, } #[derive(Debug, Clone, Serialize)] @@ -57,6 +58,14 @@ pub(super) struct SessionAudioFormat { pub(super) rate: u32, } +#[derive(Debug, Clone, Serialize)] +pub(super) struct SessionTurnDetection { + #[serde(rename = "type")] + pub(super) kind: String, + pub(super) interrupt_response: bool, + pub(super) create_response: bool, +} + #[derive(Debug, Clone, Serialize)] pub(super) struct SessionAudioOutput { pub(super) format: SessionAudioOutputFormat, diff --git a/codex-rs/codex-api/tests/realtime_websocket_e2e.rs b/codex-rs/codex-api/tests/realtime_websocket_e2e.rs index 66b99e286c..e8e90702c4 100644 --- a/codex-rs/codex-api/tests/realtime_websocket_e2e.rs +++ b/codex-rs/codex-api/tests/realtime_websocket_e2e.rs @@ -95,6 +95,18 @@ async fn realtime_ws_e2e_session_create_and_event_flow() { first_json["session"]["audio"]["input"]["format"]["rate"], Value::from(24_000) ); + assert_eq!( + first_json["session"]["audio"]["input"]["turn_detection"]["type"], + Value::String("semantic_vad".to_string()) + ); + assert_eq!( + first_json["session"]["audio"]["input"]["turn_detection"]["interrupt_response"], + Value::Bool(false) + ); + assert_eq!( + first_json["session"]["audio"]["input"]["turn_detection"]["create_response"], + Value::Bool(true) + ); assert_eq!( first_json["session"]["tool_choice"], Value::String("auto".to_string())