From 4af845d43a63f3a37864287e9c854f8755391519 Mon Sep 17 00:00:00 2001 From: Sameer Kankute Date: Mon, 27 Apr 2026 20:58:02 +0530 Subject: [PATCH] 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 --- .../llms/gemini/realtime/transformation.py | 24 +++++++++++++++++++ .../test_gemini_realtime_transformation.py | 8 +++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/litellm/llms/gemini/realtime/transformation.py b/litellm/llms/gemini/realtime/transformation.py index 3473e323746..c3432032fc8 100644 --- a/litellm/llms/gemini/realtime/transformation.py +++ b/litellm/llms/gemini/realtime/transformation.py @@ -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 diff --git a/tests/test_litellm/llms/gemini/realtime/test_gemini_realtime_transformation.py b/tests/test_litellm/llms/gemini/realtime/test_gemini_realtime_transformation.py index a8a53fb52e5..c531f949232 100644 --- a/tests/test_litellm/llms/gemini/realtime/test_gemini_realtime_transformation.py +++ b/tests/test_litellm/llms/gemini/realtime/test_gemini_realtime_transformation.py @@ -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"