fix(gemini realtime): keep call_id→name mapping across function_call_output retries

A client SDK that retries function_call_output (or sends the same result
twice) would previously hit a missing-name lookup on the second send
because _handle_function_call_output popped the call_id → name entry.
Without name, Gemini may silently reject the response. Use dict.get so
the mapping persists for the lifetime of the session.
This commit is contained in:
mateo-berri 2026-05-22 21:50:22 +00:00
parent b60cc950f3
commit c59260fc70
No known key found for this signature in database
2 changed files with 19 additions and 3 deletions

View file

@ -417,9 +417,11 @@ class GeminiRealtimeConfig(BaseRealtimeConfig):
else {"result": parsed_output}
)
# Look up the function name from stored mapping and remove the
# entry to prevent unbounded growth in long-running sessions.
function_name = self._tool_call_id_to_name.pop(call_id, None)
# Look up the function name from stored mapping. Keep the entry so a
# client SDK that retries function_call_output (or sends it twice for
# the same tool call) still produces a Gemini toolResponse with the
# required ``name`` field.
function_name = self._tool_call_id_to_name.get(call_id)
if not function_name:
verbose_logger.warning(
f"Gemini Realtime: Function name not found for call_id={call_id}. "

View file

@ -534,6 +534,20 @@ def test_gemini_realtime_function_call_output_transformation():
assert func_response["response"]["temperature"] == 72
assert func_response["response"]["conditions"] == "sunny"
# A retry of the same function_call_output (e.g. a client SDK that
# re-sends the result) must still produce a functionResponses payload
# carrying ``name`` — the call_id → name mapping must not be evicted
# after the first lookup.
retry_messages = config.transform_realtime_request(
json.dumps(function_output),
"gemini-2.5-flash",
session_configuration_request="existing",
)
retry_response = json.loads(retry_messages[0])["toolResponse"]["functionResponses"][
0
]
assert retry_response["name"] == "get_weather"
def test_gemini_realtime_user_text_transformation():
"""Test transformation of OpenAI user message to Gemini clientContent format."""