Skip to content

fix(google-genai): report thought parts as reasoning - #930

Merged
lmolkova merged 2 commits into
open-telemetry:mainfrom
sangkyoonnam:fix/927-google-genai-reasoning
Oct 21, 2026
Merged

lmolkova merged 2 commits into
open-telemetry:mainfrom
sangkyoonnam:fix/927-google-genai-reasoning

Conversation

@sangkyoonnam

@sangkyoonnam sangkyoonnam commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Description

Fixes #927 by mapping text parts with thought=True to ReasoningPart in _to_part, so thought summaries appear as {"type": "reasoning"} in gen_ai.output.messages instead 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_part also converts input messages and system instructions. A thought part in the request history now becomes a ReasoningPart, and one in system instructions becomes a type-only GenericPart(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

  • Bug fix (non-breaking change which fixes an issue)

How has this been tested?

  • Tests in nonstreaming_base.py and streaming_base.py cover a thought part followed by answer text in sync, async, streamed and non-streamed calls, and test_message.py covers _to_part and system instructions; all 8 fail without the change
  • tox -e py314-test-instrumentation-google-genai-latest,py310-test-instrumentation-google-genai-oldest

Checklist

  • Followed the style guidelines of this project
  • Changelog updated if the change requires an entry
  • Unit tests added
  • Documentation updated

@sangkyoonnam
sangkyoonnam requested a review from a team as a code owner October 20, 2026 08:34
Copilot AI balanced review requested due to automatic review settings October 20, 2026 08:34
@opentelemetry-pr-dashboard

opentelemetry-pr-dashboard Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Pull request dashboard status

Merged · refreshed 2026-10-21 04:42 UTC

Status above doesn't look right?
  • Anything look wrong? Report it with what you expected; it helps us improve the dashboard.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 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=True to 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

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")])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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, [])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will address in #936

@lmolkova
lmolkova added this pull request to the merge queue Oct 21, 2026
Merged via the queue into open-telemetry:main with commit 33b35dc Oct 21, 2026
82 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

google-genai: report thought parts as ReasoningPart in generate_content output messages

3 participants