fix(realtime): emit response.done after tool-call sequence (P0 CRITICAL)

- Add response.done event after tool-call loop to signal response completion
- Required by OpenAI SDK clients to submit tool results
- Without this, clients stall indefinitely waiting for response completion
- Update test to verify complete 6-event sequence including response.done

Made-with: Cursor
This commit is contained in:
Sameer Kankute 2026-04-27 20:58:02 +05:30
parent 4fb0833670
commit 4af845d43a
No known key found for this signature in database
2 changed files with 30 additions and 2 deletions

View file

@ -1152,6 +1152,30 @@ class GeminiRealtimeConfig(BaseRealtimeConfig):
"arguments": tool_call["arguments"],
},
})
# response.done - close the response so clients can submit tool results
returned_message.append({
"type": "response.done",
"event_id": f"event_{uuid.uuid4()}",
"response": {
"id": current_response_id,
"object": "realtime.response",
"status": "completed",
"output": [
{
"id": te["item_id"],
"object": "realtime.item",
"type": "function_call",
"status": "completed",
"call_id": te["call_id"],
"name": te["name"],
"arguments": te["arguments"],
}
for te in tool_call_events
],
"usage": None,
},
})
elif openai_event == OpenAIRealtimeEventTypes.RESPONSE_DONE:
transformed_response_done_event = self.transform_response_done_event(
message=BidiGenerateContentServerMessage(**json_message), # type: ignore

View file

@ -655,8 +655,8 @@ def test_gemini_tool_call_emits_response_created_preamble():
)
responses = result["response"]
# Should have: response.created, output_item.added, function_call_arguments.done, output_item.done, conversation.item.created
assert len(responses) >= 5
# Should have: response.created, output_item.added, function_call_arguments.done, output_item.done, conversation.item.created, response.done
assert len(responses) >= 6
assert responses[0]["type"] == "response.created"
assert "response" in responses[0]
assert responses[0]["response"]["status"] == "in_progress"
@ -670,3 +670,7 @@ def test_gemini_tool_call_emits_response_created_preamble():
assert responses[4]["type"] == "conversation.item.created"
assert responses[4]["item"]["type"] == "function_call"
assert responses[4]["item"]["status"] == "completed"
assert responses[5]["type"] == "response.done"
assert responses[5]["response"]["status"] == "completed"
assert len(responses[5]["response"]["output"]) == 1
assert responses[5]["response"]["output"][0]["type"] == "function_call"