Skip to content

fix(core): preserve structured thoughts during session resume#24106

Open
X9VoiD wants to merge 1 commit intogoogle-gemini:mainfrom
X9VoiD:fix/issue-23046-thought-rendering
Open

fix(core): preserve structured thoughts during session resume#24106
X9VoiD wants to merge 1 commit intogoogle-gemini:mainfrom
X9VoiD:fix/issue-23046-thought-rendering

Conversation

@X9VoiD
Copy link
Copy Markdown

@X9VoiD X9VoiD commented Mar 28, 2026

Summary

Fix [Thought: true] leaking as literal text after session resume (#23046). The toPart() converter in converter.ts (from #6859) was unconditionally stringifying {thought: true} parts for all API calls, not just CountToken. I verified the CountToken API accepts the same thought: true schema as GenerateContent, so the workaround is removed entirely (Gemini CLI still works after resume even without the workaround for CountToken API).

This is a simpler approach than #23048 (filter thoughts out) and #23526 (flag-based conditional), as it trusts both APIs with structured thought data.

Details

  • converter.ts: Removed toPart() logic that appended \n[Thought: true] to text parts
  • partUtils.ts: Fixed partToString verbose output to render [Thought] cleanly
  • sessionUtils.test.ts: Added integration test covering the full resume pipeline (ConversationRecordconvertSessionToClientHistory()toContents()) to prevent regression

Partial revert of commit fef89f5 (#6859).

Related Issues

Fixes #23046 | Related: #23048, #23526

How to Validate

npm run test -w @google/gemini-cli-core -- src/utils/sessionUtils.test.ts

The new integration test catches the regression precisely. When the fix is reverted, it fails with:

AssertionError: expected [...] to deeply equal [...]

- Expected  (clean structured thought)
+ Received  (string-contaminated)

        {
-         "text": "**Thinking** I need to process this",
-         "thought": true,
+         "text": "**Thinking** I need to process this\n [Thought: true]",
        },

Manual: Resume a Code Assist (OAuth) session that had thinking blocks. Before: [Thought: true] appears in responses and worsens each turn. After: clean output. Validated on real models.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
    • Windows
      • npm run
    • Linux

@X9VoiD X9VoiD requested a review from a team as a code owner March 28, 2026 11:43
@X9VoiD X9VoiD force-pushed the fix/issue-23046-thought-rendering branch from b1185a2 to ccbb8b8 Compare March 28, 2026 11:46
This change ensures that AI thinking blocks are correctly handled during session serialization and deserialization, preventing string contamination like '[Thought: true]'. By removing unnecessary transformations in the API conversion layer, we maintain the structured 'thought: true' property, which is supported by the CountToken and other generation APIs.

Verified by running Gemini CLI with real models and added a new integration test to prevent regressions.

Fixes google-gemini#23046
Partial revert of fef89f5 (google-gemini#6859)
@X9VoiD X9VoiD force-pushed the fix/issue-23046-thought-rendering branch from ccbb8b8 to 6567975 Compare March 28, 2026 11:48
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses an issue where structured thought data was being leaked as literal text during session resumption. By removing an outdated conversion workaround and updating how thoughts are rendered, the system now correctly handles structured thought data, ensuring clean output and preventing data contamination in API requests.

Highlights

  • API Compatibility: Removed the workaround in converter.ts that was incorrectly stringifying structured thought data into literal text, as the API now natively supports the {thought: true} schema.
  • UI Rendering: Updated partUtils.ts to ensure that structured thoughts are rendered cleanly in the UI instead of displaying raw metadata.
  • Regression Testing: Added a new integration test in sessionUtils.test.ts to verify the full conversion pipeline and ensure that thoughts are preserved correctly during session resumption.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request removes the logic that previously converted thought parts into text parts for API compatibility in converter.ts and its associated tests. It also updates partToString in partUtils.ts to handle cases where part.thought is a boolean, ensuring that thoughts are correctly identified and formatted without being mutated into string text during session resume or rewind operations. A new integration test has been added to verify this behavior. One issue was identified where a boolean check was too broad and could incorrectly handle false values.

I am having trouble creating individual review comments. Click here to see my feedback.

packages/core/src/utils/partUtils.ts (46)

high

The condition typeof part.thought === 'boolean' is too broad. It will incorrectly handle the case where part.thought is false, causing a non-thought part to be displayed as [Thought]. This is misleading and inconsistent with other logic (e.g., getResponseText) which would treat such a part as regular text.

The check should be more specific to only identify parts that are explicitly marked as thoughts.

      if (part.thought === true) {

@gemini-cli gemini-cli bot added the area/agent Issues related to Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality label Mar 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/agent Issues related to Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: Code Assist session resume leaks [Thought: true] as literal text in model responses

1 participant