Python: surface Gemini thought summaries as reasoning content - #7488
Open
giles17 wants to merge 1 commit into
Open
Python: surface Gemini thought summaries as reasoning content#7488giles17 wants to merge 1 commit into
giles17 wants to merge 1 commit into
Conversation
Gemini thought-summary parts (part.thought=True) were dropped in _parse_parts, so reasoning never reached ChatResponse.contents. Emit them as text_reasoning content instead, matching OpenAIResponsesClient. Round-trip is safe: _convert_message_contents never re-emits reasoning text as a Part. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b8aa906e-1408-40c1-9a45-6deb40dc36f8
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the Python Gemini provider to surface Gemini “thought summary” response parts (when thinking_config.include_thoughts is enabled) as text_reasoning content in ChatResponse.contents, aligning the behavior with other providers that already expose reasoning content.
Changes:
- Update
GeminiChatClient._parse_partsto emitContent.from_text_reasoning(...)forpart.thought == Trueparts that include text. - Update
ThinkingConfig.include_thoughtsdocumentation to reflect that thought summaries are surfaced astext_reasoning. - Replace the prior “thought parts are skipped” test with new coverage asserting (a) thought parts become reasoning content and (b) empty thought parts produce no content.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| python/packages/gemini/agent_framework_gemini/_chat_client.py | Emit Gemini thought-summary parts as text_reasoning content and update docstrings accordingly. |
| python/packages/gemini/tests/test_gemini_client.py | Update/add tests to validate reasoning surfacing and empty-thought behavior. |
Contributor
Python Test Coverage Report •
Python Unit Test Overview
|
||||||||||||||||||||||||||||||
giles17
marked this pull request as ready for review
August 3, 2026 16:44
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.
Motivation & Context
GeminiChatClientnever surfaced a Gemini model's reasoning. Whenthinking_config.include_thoughtsis set, Gemini returns thought summaries(condensed traces of its internal reasoning) as response parts with
part.thought = True, but_parse_partsskipped every thought part. As aresult the reasoning never reached
ChatResponse.contents, and downstreamconsumers (AG-UI/CopilotKit, "thinking" UIs) showed nothing even when the caller
opted in via
include_thoughts.This also made behaviour inconsistent across providers:
OpenAIResponsesClientalready surfaces reasoning as
Content.from_text_reasoning(...).Description & Review Guide
What are the major changes?
_parse_partsnow emits thought-summary parts astext_reasoningcontent(
Content.from_text_reasoning(text=..., raw_representation=part)) instead ofdropping them. A thought part with no text still produces no content.
ThinkingConfig.include_thoughtsdocstring to reflect thatsummaries are surfaced as
text_reasoning.test_thinking_parts_are_silently_skippedwithtest_thinking_parts_are_surfaced_as_reasoning, and addedtest_empty_thinking_part_produces_no_reasoning_content.What is the impact of these changes?
OpenAIResponsesClient. The change is round-trip safe:_convert_message_contentsnever re-emits reasoning text as a Part, so nothing is sent back to Gemini on
replay. Thought parts are only returned when the caller sets
include_thoughts, so default behaviour is unchanged.What do you want reviewers to focus on?
thought_signature-as-reasoning path (on function-call parts) is unaffected.Related Issue
Fixes #7225
Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.