diff --git a/codex-rs/app-server/tests/suite/v2/realtime_conversation.rs b/codex-rs/app-server/tests/suite/v2/realtime_conversation.rs index 317155da70..d1507e1cef 100644 --- a/codex-rs/app-server/tests/suite/v2/realtime_conversation.rs +++ b/codex-rs/app-server/tests/suite/v2/realtime_conversation.rs @@ -3,6 +3,8 @@ use anyhow::Result; use app_test_support::McpProcess; use app_test_support::create_mock_responses_server_sequence_unchecked; use app_test_support::to_response; +use base64::Engine; +use base64::engine::general_purpose::STANDARD as BASE64_STANDARD; use codex_app_server_protocol::JSONRPCError; use codex_app_server_protocol::JSONRPCResponse; use codex_app_server_protocol::LoginAccountResponse; @@ -40,6 +42,10 @@ use tokio::time::timeout; const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10); const STARTUP_CONTEXT_HEADER: &str = "Startup context from Codex."; +fn realtime_pcm_silence_20ms_base64() -> String { + BASE64_STANDARD.encode([0u8; 960]) +} + #[tokio::test] async fn realtime_conversation_streams_v2_notifications() -> Result<()> { skip_if_no_network!(Ok(())); @@ -155,7 +161,7 @@ async fn realtime_conversation_streams_v2_notifications() -> Result<()> { .send_thread_realtime_append_audio_request(ThreadRealtimeAppendAudioParams { thread_id: started.thread_id.clone(), audio: ThreadRealtimeAudioChunk { - data: "BQYH".to_string(), + data: realtime_pcm_silence_20ms_base64(), sample_rate: 24_000, num_channels: 1, samples_per_channel: Some(480), diff --git a/codex-rs/core/tests/suite/realtime_conversation.rs b/codex-rs/core/tests/suite/realtime_conversation.rs index 660168aaf2..d5efb0d87c 100644 --- a/codex-rs/core/tests/suite/realtime_conversation.rs +++ b/codex-rs/core/tests/suite/realtime_conversation.rs @@ -1,5 +1,7 @@ use anyhow::Context; use anyhow::Result; +use base64::Engine; +use base64::engine::general_purpose::STANDARD as BASE64_STANDARD; use chrono::Utc; use codex_login::CodexAuth; use codex_login::OPENAI_API_KEY_ENV_VAR; @@ -41,6 +43,11 @@ const MEMORY_PROMPT_PHRASE: &str = "You have access to a memory folder with guidance from prior runs."; const REALTIME_CONVERSATION_TEST_SUBPROCESS_ENV_VAR: &str = "CODEX_REALTIME_CONVERSATION_TEST_SUBPROCESS"; + +fn realtime_pcm_silence_20ms_base64() -> String { + BASE64_STANDARD.encode([0u8; 960]) +} + fn websocket_request_text( request: &core_test_support::responses::WebSocketRequest, ) -> Option { @@ -207,7 +214,7 @@ async fn conversation_start_audio_text_close_round_trip() -> Result<()> { test.codex .submit(Op::RealtimeConversationAudio(ConversationAudioParams { frame: RealtimeAudioFrame { - data: "AQID".to_string(), + data: realtime_pcm_silence_20ms_base64(), sample_rate: 24000, num_channels: 1, samples_per_channel: Some(480), @@ -426,7 +433,7 @@ async fn conversation_audio_before_start_emits_error() -> Result<()> { test.codex .submit(Op::RealtimeConversationAudio(ConversationAudioParams { frame: RealtimeAudioFrame { - data: "AQID".to_string(), + data: realtime_pcm_silence_20ms_base64(), sample_rate: 24000, num_channels: 1, samples_per_channel: Some(480), @@ -625,7 +632,7 @@ async fn conversation_second_start_replaces_runtime() -> Result<()> { test.codex .submit(Op::RealtimeConversationAudio(ConversationAudioParams { frame: RealtimeAudioFrame { - data: "AQID".to_string(), + data: realtime_pcm_silence_20ms_base64(), sample_rate: 24000, num_channels: 1, samples_per_channel: Some(480), @@ -1585,7 +1592,7 @@ async fn inbound_handoff_request_clears_active_transcript_after_each_handoff() - test.codex .submit(Op::RealtimeConversationAudio(ConversationAudioParams { frame: RealtimeAudioFrame { - data: "AQID".to_string(), + data: realtime_pcm_silence_20ms_base64(), sample_rate: 24000, num_channels: 1, samples_per_channel: Some(480), @@ -2073,7 +2080,7 @@ async fn inbound_handoff_request_steers_active_turn() -> Result<()> { test.codex .submit(Op::RealtimeConversationAudio(ConversationAudioParams { frame: RealtimeAudioFrame { - data: "AQID".to_string(), + data: realtime_pcm_silence_20ms_base64(), sample_rate: 24000, num_channels: 1, samples_per_channel: Some(480),