Repository navigation
fix(google-genai): report thought parts as reasoning - #930
Merged
lmolkova merged 2 commits intoOct 21, 2026
Merged
Conversation
Assisted-by: Claude Opus 5.5
Pull request dashboard statusMerged · refreshed 2026-10-21 04:42 UTC Status above doesn't look right?
|
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The focused conversion addresses the reported issue with regression coverage across all four response paths and no identified blocking issues.
No open issues 🎉
What changed in this PR
Fixes #927 by distinguishing Google GenAI thought summaries from answer text using the shared ReasoningPart model.
Changes:
- Maps text parts with
thought=Trueto reasoning content. - Adds conversion and sync/async regression coverage for streaming and non-streaming responses.
- Records the fix in the changelog; Interactions API support remains unchanged.
| File | Description |
|---|---|
| instrumentation/opentelemetry-instrumentation-google-genai/tests/generate_content/test_message.py | Tests thought conversion and system-instruction handling. |
| instrumentation/opentelemetry-instrumentation-google-genai/tests/generate_content/streaming_base.py | Tests merged streamed reasoning and answer text. |
| instrumentation/opentelemetry-instrumentation-google-genai/tests/generate_content/nonstreaming_base.py | Tests non-streamed reasoning and answer text. |
| instrumentation/opentelemetry-instrumentation-google-genai/src/opentelemetry/instrumentation/google_genai/message.py | Converts thought text to ReasoningPart. |
| instrumentation/opentelemetry-instrumentation-google-genai/.changelog/930.fixed | Documents the correction. |
Review effort: Balanced
lmolkova
approved these changes
Oct 21, 2026
Comment on lines
+52
to
+57
| def test_to_system_instructions_thought_part(self): | ||
| content = genai_types.Content( | ||
| parts=[genai_types.Part(text="Let me think.", thought=True)] | ||
| ) | ||
| instructions = to_system_instructions(content=content) | ||
| self.assertEqual(instructions, [GenericPart(type="reasoning")]) |
Member
There was a problem hiding this comment.
GenericPart is deprecated and on its way out, so this test pins behavior we're about to remove. Could reasoning parts be dropped from system instructions instead?
Suggested change
| def test_to_system_instructions_thought_part(self): | |
| content = genai_types.Content( | |
| parts=[genai_types.Part(text="Let me think.", thought=True)] | |
| ) | |
| instructions = to_system_instructions(content=content) | |
| self.assertEqual(instructions, [GenericPart(type="reasoning")]) | |
| def test_to_system_instructions_thought_part(self): | |
| content = genai_types.Content( | |
| parts=[genai_types.Part(text="Let me think.", thought=True)] | |
| ) | |
| instructions = to_system_instructions(content=content) | |
| self.assertEqual(instructions, []) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #927 by mapping text parts with
thought=TruetoReasoningPartin_to_part, so thought summaries appear as{"type": "reasoning"}ingen_ai.output.messagesinstead of looking like answer text. Streamed responses take the same path, since the merge from #908 already keeps thought and answer text in separate parts._to_partalso converts input messages and system instructions. A thought part in the request history now becomes aReasoningPart, and one in system instructions becomes a type-onlyGenericPart(type="reasoning")without its text, the same way blob and URI parts are handled there. Anthropic and Bedrock also share reasoning conversion between input and output content blocks. I'll keep the shared path unless you'd rather limit this to output messages.Known gaps: the Interactions API path still doesn't capture thought summaries in streamed or non-streamed responses.
Type of change
How has this been tested?
nonstreaming_base.pyandstreaming_base.pycover a thought part followed by answer text in sync, async, streamed and non-streamed calls, andtest_message.pycovers_to_partand system instructions; all 8 fail without the changetox -e py314-test-instrumentation-google-genai-latest,py310-test-instrumentation-google-genai-oldestChecklist