From db8927a8e2a57891955b5fa5f8cb75a69e816f76 Mon Sep 17 00:00:00 2001 From: felixxia-oai Date: Mon, 15 Jun 2026 23:50:11 +0100 Subject: [PATCH] Deflake realtime handoff steering test (#28300) ## Summary - keep the realtime mock websocket open for the handoff steering test after scripted responses - avoid racing the mock server close before the standalone handoff append is observed, which was showing up as a Windows timeout in CI __Details__: Failures in samples seem to be caused by: 1. The mock websocket sends conversation.handoff.requested. 2. The mock immediately closes the websocket because start_websocket_server(...) defaults to close_after_requests: true. 3. On Windows, that close often surfaces as os error 10053 / 10054. 4. The realtime stream shuts down before the routed handoff finishes creating/steering the follow-up request. 5. The test waits for the expected follow-up event and times out. The PR changes only step 2: for this test, the mock websocket stays open after sending the scripted handoff event. The same handoff event is still sent, and the test still asserts the important steering behavior: 1. first Responses request has the original prompt 2. first request does not contain realtime delegation 3. second Responses request does contain the realtime delegation ## Validation - `just fmt` - `just test -p codex-core --test all suite::realtime_conversation::inbound_handoff_request_steers_active_turn` ## Recent CI failures with the same signature - https://github.com/openai/codex/actions/runs/27538033492/job/81392362858 - 2026-06-15, `[codex] update multi-agent v2 prompts` - same test failed after `conversation.handoff.requested`; websocket read failed with `os error 10053` - https://github.com/openai/codex/actions/runs/27543877820/job/81412200651 - 2026-06-15, `feat: dispatch queued user messages through core idle extensions` - same test failed; websocket read failed with `os error 10054` - https://github.com/openai/codex/actions/runs/27544342375/job/81413801641 - 2026-06-15, `[codex] Make marketplace loading capability aware` - same test failed; websocket read failed with `os error 10053` --- .../core/tests/suite/realtime_conversation.rs | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/codex-rs/core/tests/suite/realtime_conversation.rs b/codex-rs/core/tests/suite/realtime_conversation.rs index fc05e98e0..5fb303cba 100644 --- a/codex-rs/core/tests/suite/realtime_conversation.rs +++ b/codex-rs/core/tests/suite/realtime_conversation.rs @@ -3579,24 +3579,29 @@ async fn inbound_handoff_request_steers_active_turn() -> Result<()> { let (api_server, completions) = start_streaming_sse_server(vec![first_chunks, second_chunks]).await; - let realtime_server = start_websocket_server(vec![vec![ - vec![json!({ - "type": "session.updated", - "session": { "id": "sess_steer", "instructions": "backend prompt" } - })], - vec![ - json!({ - "type": "conversation.input_transcript.delta", - "delta": "steer via realtime" - }), - json!({ - "type": "conversation.handoff.requested", - "handoff_id": "handoff_steer", - "item_id": "item_steer", - "input_transcript": "steer via realtime" - }), + let realtime_server = start_websocket_server_with_headers(vec![WebSocketConnectionConfig { + requests: vec![ + vec![json!({ + "type": "session.updated", + "session": { "id": "sess_steer", "instructions": "backend prompt" } + })], + vec![ + json!({ + "type": "conversation.input_transcript.delta", + "delta": "steer via realtime" + }), + json!({ + "type": "conversation.handoff.requested", + "handoff_id": "handoff_steer", + "item_id": "item_steer", + "input_transcript": "steer via realtime" + }), + ], ], - ]]) + response_headers: Vec::new(), + accept_delay: None, + close_after_requests: false, + }]) .await; let mut builder = test_codex().with_model("gpt-5.4").with_config({