Fast-exit in the fix for parallel function calling with Gemini 3, if we can determine up-front that there's no work to do

This commit is contained in:
Paul Kompfner
2026-01-13 17:32:20 -05:00
parent 30fbcfbf71
commit be49a54856

View File

@@ -256,7 +256,7 @@ class GeminiLLMAdapter(BaseLLMAdapter[GeminiLLMInvocationParams]):
self._apply_thought_signatures_to_messages(thought_signature_dicts, messages) self._apply_thought_signatures_to_messages(thought_signature_dicts, messages)
# When thinking is enabled, merge parallel tool calls into single messages # When thinking is enabled, merge parallel tool calls into single messages
messages = self._merge_parallel_tool_calls_for_thinking(messages) messages = self._merge_parallel_tool_calls_for_thinking(thought_signature_dicts, messages)
# Check if we only have function-related messages (no regular text) # Check if we only have function-related messages (no regular text)
has_regular_messages = any( has_regular_messages = any(
@@ -436,7 +436,9 @@ class GeminiLLMAdapter(BaseLLMAdapter[GeminiLLMInvocationParams]):
tool_call_id_to_name_mapping=tool_call_id_to_name_mapping, tool_call_id_to_name_mapping=tool_call_id_to_name_mapping,
) )
def _merge_parallel_tool_calls_for_thinking(self, messages: List[Content]) -> List[Content]: def _merge_parallel_tool_calls_for_thinking(
self, thought_signature_dicts: List[dict], messages: List[Content]
) -> List[Content]:
"""Merge parallel tool calls into single Content objects when thinking is enabled. """Merge parallel tool calls into single Content objects when thinking is enabled.
Gemini expects parallel tool calls (multiple function calls made Gemini expects parallel tool calls (multiple function calls made
@@ -460,6 +462,8 @@ class GeminiLLMAdapter(BaseLLMAdapter[GeminiLLMInvocationParams]):
messages appear in between. messages appear in between.
Args: Args:
thought_signature_dicts: A list of thought signature dicts, used
to determine if the work of merging is necessary.
messages: List of Content messages to process. messages: List of Content messages to process.
Returns: Returns:
@@ -469,6 +473,16 @@ class GeminiLLMAdapter(BaseLLMAdapter[GeminiLLMInvocationParams]):
if not messages: if not messages:
return messages return messages
# Fast-exit if no function-call-related thought signatures
# This is a shortcut for determining both:
# - whether thinking is enabled, and
# - whether there are function calls in the messages
has_function_call_signatures = any(
ts.get("bookmark", {}).get("function_call") for ts in thought_signature_dicts
)
if not has_function_call_signatures:
return messages
def is_tool_call_message(msg: Content) -> bool: def is_tool_call_message(msg: Content) -> bool:
"""Check if message contains only function_call parts.""" """Check if message contains only function_call parts."""
return ( return (