diff --git a/python/semantic_kernel/connectors/ai/google/google_ai/services/google_ai_chat_completion.py b/python/semantic_kernel/connectors/ai/google/google_ai/services/google_ai_chat_completion.py index 22422c331d2b..576058625023 100644 --- a/python/semantic_kernel/connectors/ai/google/google_ai/services/google_ai_chat_completion.py +++ b/python/semantic_kernel/connectors/ai/google/google_ai/services/google_ai_chat_completion.py @@ -302,6 +302,8 @@ def _create_chat_message_content( items: list[CMC_ITEM_TYPES] = [] if candidate.content and candidate.content.parts: for idx, part in enumerate(candidate.content.parts): + if getattr(part, "thought", False) is True: + continue if part.text: items.append(TextContent(text=part.text, inner_content=response, metadata=response_metadata)) elif part.function_call: @@ -357,6 +359,8 @@ def _create_streaming_chat_message_content( items: list[STREAMING_ITEM_TYPES] = [] if candidate.content and candidate.content.parts: for idx, part in enumerate(candidate.content.parts): + if getattr(part, "thought", False) is True: + continue if part.text: items.append( StreamingTextContent( diff --git a/python/tests/unit/connectors/ai/google/google_ai/services/test_google_ai_chat_completion.py b/python/tests/unit/connectors/ai/google/google_ai/services/test_google_ai_chat_completion.py index a0dc2e786195..cc87b0364e13 100644 --- a/python/tests/unit/connectors/ai/google/google_ai/services/test_google_ai_chat_completion.py +++ b/python/tests/unit/connectors/ai/google/google_ai/services/test_google_ai_chat_completion.py @@ -5,7 +5,15 @@ import pytest from google.genai import Client from google.genai.models import AsyncModels -from google.genai.types import Content, GenerateContentConfigDict +from google.genai.types import ( + Candidate, + Content, + FinishReason as GoogleFinishReason, + GenerateContentConfigDict, + GenerateContentResponse, + GenerateContentResponseUsageMetadata, + Part, +) from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehavior from semantic_kernel.connectors.ai.google.google_ai.google_ai_prompt_execution_settings import ( @@ -259,6 +267,63 @@ async def test_google_ai_chat_completion_with_function_choice_behavior_no_tool_c # endregion chat completion +def test_google_ai_chat_completion_filters_thought_text_parts(google_ai_unit_test_env) -> None: + google_ai_chat_completion = GoogleAIChatCompletion() + + candidate = Candidate() + candidate.index = 0 + candidate.content = Content(role="model", parts=[]) + candidate.finish_reason = GoogleFinishReason.STOP + + thinking_part = Part.from_text(text="internal reasoning") + thinking_part.thought = True # type: ignore[attr-defined] + answer_part = Part.from_text(text="final answer") + + candidate.content.parts.extend([thinking_part, answer_part]) + + response = GenerateContentResponse() + response.candidates = [candidate] + response.usage_metadata = GenerateContentResponseUsageMetadata( + prompt_token_count=0, + cached_content_token_count=0, + candidates_token_count=0, + total_token_count=0, + ) + + message = google_ai_chat_completion._create_chat_message_content(response, candidate) + + assert message.content == "final answer" + assert len(message.items) == 1 + + +def test_google_ai_streaming_chat_completion_filters_thought_text_parts(google_ai_unit_test_env) -> None: + google_ai_chat_completion = GoogleAIChatCompletion() + + candidate = Candidate() + candidate.index = 0 + candidate.content = Content(role="model", parts=[]) + candidate.finish_reason = GoogleFinishReason.STOP + + thinking_part = Part.from_text(text="internal reasoning") + thinking_part.thought = True # type: ignore[attr-defined] + answer_part = Part.from_text(text="streamed answer") + candidate.content.parts.extend([thinking_part, answer_part]) + + response = GenerateContentResponse() + response.candidates = [candidate] + response.usage_metadata = GenerateContentResponseUsageMetadata( + prompt_token_count=0, + cached_content_token_count=0, + candidates_token_count=0, + total_token_count=0, + ) + + message = google_ai_chat_completion._create_streaming_chat_message_content(response, candidate) + + assert message.content == "streamed answer" + assert len(message.items) == 1 + + # region streaming chat completion