Stop Realtime V2 response.done delegation (#17267)

Stop parsing Realtime V2 response completion as a Codex handoff;
delegation stays tied to item completion.\n\nValidation: just fmt; git
diff --check

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Ahmed Ibrahim
2026-04-09 17:17:49 -07:00
committed by GitHub
Unverified
parent a44645129a
commit 32224878b3
3 changed files with 2 additions and 54 deletions
@@ -982,7 +982,7 @@ mod tests {
}
#[test]
fn parse_realtime_v2_response_done_handoff_event() {
fn parse_realtime_v2_response_done_event() {
let payload = json!({
"type": "response.done",
"response": {
@@ -999,12 +999,7 @@ mod tests {
assert_eq!(
parse_realtime_event(payload.as_str(), RealtimeEventParser::RealtimeV2),
Some(RealtimeEvent::HandoffRequested(RealtimeHandoffRequested {
handoff_id: "call_123".to_string(),
item_id: "item_123".to_string(),
input_transcript: "delegate from done".to_string(),
active_transcript: Vec::new(),
}))
None
);
}
@@ -48,7 +48,6 @@ pub(super) fn parse_realtime_event_v2(payload: &str) -> Option<RealtimeEvent> {
.map(RealtimeEvent::ConversationItemAdded),
"conversation.item.done" => parse_conversation_item_done_event(&parsed),
"response.created" => Some(RealtimeEvent::ConversationItemAdded(parsed)),
"response.done" => parse_response_done_event(parsed),
"response.cancelled" => Some(RealtimeEvent::ResponseCancelled(
RealtimeResponseCancelled {
response_id: parsed
@@ -116,30 +115,6 @@ fn parse_conversation_item_done_event(parsed: &Value) -> Option<RealtimeEvent> {
.map(|item_id| RealtimeEvent::ConversationItemDone { item_id })
}
fn parse_response_done_event(parsed: Value) -> Option<RealtimeEvent> {
if let Some(handoff) = parse_response_done_handoff_requested_event(&parsed) {
return Some(handoff);
}
Some(RealtimeEvent::ConversationItemAdded(parsed))
}
fn parse_response_done_handoff_requested_event(parsed: &Value) -> Option<RealtimeEvent> {
let item = parsed
.get("response")
.and_then(Value::as_object)
.and_then(|response| response.get("output"))
.and_then(Value::as_array)?
.iter()
.find(|item| {
item.get("type").and_then(Value::as_str) == Some("function_call")
&& item.get("name").and_then(Value::as_str) == Some(CODEX_TOOL_NAME)
})?
.as_object()?;
parse_handoff_requested_event(item)
}
fn parse_handoff_requested_event(item: &JsonMap<String, Value>) -> Option<RealtimeEvent> {
let item_type = item.get("type").and_then(Value::as_str);
let item_name = item.get("name").and_then(Value::as_str);
@@ -966,28 +966,6 @@ fn spawn_realtime_input_task(input: RealtimeInputTask) -> JoinHandle<()> {
{
response_in_progress = true;
}
Some("response.done")
if matches!(session_kind, RealtimeSessionKind::V2) =>
{
response_in_progress = false;
output_audio_state = None;
if pending_response_create {
if let Err(err) = writer.send_response_create().await {
let mapped_error = map_api_error(err);
warn!(
"failed to send deferred response.create: {mapped_error}"
);
let _ = events_tx
.send(RealtimeEvent::Error(
mapped_error.to_string(),
))
.await;
break;
}
pending_response_create = false;
response_in_progress = true;
}
}
_ => {}
}
}