Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -559,10 +559,16 @@ def _convert_google_genai_response_to_chatmessage(response: types.GenerateConten

usage.update(_convert_usage_metadata_to_serializable(usage_metadata))

# Remap finish_reason to "tool_calls" when tool calls are present, since Google GenAI returns
# "STOP" for both normal completions and tool calls (no dedicated FUNCTION_CALL finish reason).
mapped_finish_reason = FINISH_REASON_MAPPING.get(finish_reason or "")
if mapped_finish_reason == "stop" and tool_calls:
mapped_finish_reason = "tool_calls"

# Create meta with reasoning content and thought signatures if available
meta: dict[str, Any] = {
"model": model,
"finish_reason": FINISH_REASON_MAPPING.get(finish_reason or ""),
"finish_reason": mapped_finish_reason,
"usage": usage,
}

Expand Down Expand Up @@ -675,13 +681,19 @@ def _convert_google_chunk_to_streaming_chunk(
# Determine the effective content: tool_calls and reasoning take priority.
effective_content = "" if tool_calls or reasoning else content

# Remap finish_reason to "tool_calls" when tool calls are present, since Google GenAI returns
# "STOP" for both normal completions and tool calls (no dedicated FUNCTION_CALL finish reason).
mapped_finish_reason = FINISH_REASON_MAPPING.get(finish_reason or "")
if mapped_finish_reason == "stop" and tool_calls:
mapped_finish_reason = "tool_calls"

return StreamingChunk(
content=effective_content,
tool_calls=tool_calls,
component_info=component_info,
index=index,
start=start,
finish_reason=FINISH_REASON_MAPPING.get(finish_reason or ""),
finish_reason=mapped_finish_reason,
meta=meta,
reasoning=reasoning,
)
Expand Down
4 changes: 2 additions & 2 deletions integrations/google_genai/tests/test_chat_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ def test_live_run_with_tools_streaming(self, tools):

assert isinstance(tool_message, ChatMessage), "Tool message is not a ChatMessage instance"
assert ChatMessage.is_from(tool_message, ChatRole.ASSISTANT), "Tool message is not from the assistant"
assert tool_message.meta["finish_reason"] == "stop"
assert tool_message.meta["finish_reason"] == "tool_calls"

tool_call = tool_message.tool_calls[0]
assert tool_call.tool_name == "weather"
Expand Down Expand Up @@ -952,7 +952,7 @@ async def test_live_run_async_with_tools(self, tools):
assert len(tool_message.tool_calls) == 1, "Tool message has multiple tool calls"
assert tool_message.tool_calls[0].tool_name == "weather"
assert tool_message.tool_calls[0].arguments == {"city": "Paris"}
assert tool_message.meta["finish_reason"] == "stop"
assert tool_message.meta["finish_reason"] == "tool_calls"

async def test_live_run_async_with_thinking(self):
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ def test_convert_google_chunk_to_streaming_chunk_tool_call(self, monkeypatch):
assert chunk.tool_calls[0].tool_name == "weather"
assert chunk.tool_calls[0].arguments == '{"city": "Paris"}'
assert chunk.tool_calls[0].id == "call_123"
assert chunk.finish_reason == "stop"
assert chunk.finish_reason == "tool_calls"
assert chunk.index == 0
assert "received_at" in chunk.meta
assert chunk.component_info == component_info
Expand Down Expand Up @@ -337,7 +337,7 @@ def test_convert_google_chunk_to_streaming_chunk_mixed_content(self, monkeypatch
assert len(chunk.tool_calls) == 1
assert chunk.tool_calls[0].tool_name == "weather"
assert chunk.tool_calls[0].arguments == '{"city": "London"}'
assert chunk.finish_reason == "stop"
assert chunk.finish_reason == "tool_calls"
assert chunk.component_info == component_info

def test_convert_google_chunk_to_streaming_chunk_empty_parts(self, monkeypatch):
Expand Down Expand Up @@ -513,7 +513,7 @@ def test_convert_google_chunk_to_streaming_chunk_real_example(self, monkeypatch)
assert streaming_chunk.content == ""
assert streaming_chunk.tool_calls is not None
assert len(streaming_chunk.tool_calls) == 6
assert streaming_chunk.finish_reason == "stop"
assert streaming_chunk.finish_reason == "tool_calls"
assert streaming_chunk.index == 2
assert "received_at" in streaming_chunk.meta
assert streaming_chunk.meta["model"] == "gemini-2.5-flash"
Expand Down
Loading