Skip to content

fix: preserve reasoning.text type in consolidateReasoningDetails for Gemini models#11650

Open
roomote-v0[bot] wants to merge 1 commit intomainfrom
fix/gemini-reasoning-type-mislabel-11629
Open

fix: preserve reasoning.text type in consolidateReasoningDetails for Gemini models#11650
roomote-v0[bot] wants to merge 1 commit intomainfrom
fix/gemini-reasoning-type-mislabel-11629

Conversation

@roomote-v0
Copy link
Contributor

@roomote-v0 roomote-v0 bot commented Feb 20, 2026

Related GitHub Issue

Closes: #11629

Description

This PR attempts to address Issue #11629. Feedback and guidance are welcome.

Two bugs in consolidateReasoningDetails() in src/api/transform/openai-format.ts cause assistant content[] to be stripped on Turn 2 for google/gemini-3.1-pro-preview via OpenRouter:

Bug 1 (secondary, root cause): Shared type variable mislabels reasoning.text as reasoning.encrypted

When a group contains both a reasoning.text entry and a reasoning.encrypted entry at the same index, the consolidation loop used a single shared type variable. The last entry's type overwrote earlier ones, so the text entry was emitted with type: "reasoning.encrypted" instead of type: "reasoning.text".

Fix: Track textType separately from encrypted entry types. When emitting the consolidated text entry, use the type derived from text-bearing entries only, and correct any mislabeled reasoning.encrypted back to reasoning.text.

Bug 2 (primary, cascading): Corrupted block filter drops mislabeled text entries

The filter at line 53 dropped any entry with type === "reasoning.encrypted" && !detail.data. This caught the mislabeled text entries from Bug 1, which had a text field but no data field. With all reasoning_details dropped, sanitizeGeminiMessages() saw hasReasoningDetails=false and dropped all tool_calls, producing the empty content[] that triggers the "no assistant messages" error.

Fix: Only drop entries that have neither data nor text -- truly corrupted blocks with no usable content.

Test Procedure

  • Added 3 new tests to consolidateReasoningDetails covering:
    • Mixed reasoning.text + reasoning.encrypted at same index preserves correct types
    • Mislabeled text entries (type=encrypted, has text, no data) are preserved, not dropped
    • Truly corrupted blocks (no data AND no text) are still dropped
  • Added 1 new regression test to sanitizeGeminiMessages reproducing the exact issue scenario
  • All 48 tests pass: cd src && pnpm vitest run api/transform/__tests__/openai-format.spec.ts

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and/or updated tests have been added to cover my changes.
  • Documentation Impact: No documentation updates are required.
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Documentation Updates

  • No documentation updates are required.

Additional Notes

Files modified:

  • src/api/transform/openai-format.ts -- fix consolidateReasoningDetails() type tracking and corrupted block filter
  • src/api/transform/__tests__/openai-format.spec.ts -- 4 new regression tests

Interactively review PR in Roo Code Cloud

…Gemini models

Fixes two bugs causing assistant content[] to be stripped on Turn 2 for
google/gemini-3.1-pro-preview via OpenRouter:

1. consolidateReasoningDetails() used a shared type variable across all
   entries in a group. When reasoning.text and reasoning.encrypted entries
   shared the same index, the text entry type was overwritten to
   "reasoning.encrypted". Now tracks types separately for text vs
   encrypted entries.

2. The corrupted block filter dropped any reasoning.encrypted entry without
   a data field, including mislabeled text entries that had a text field.
   Now only drops entries that have neither data nor text.

Closes #11629
@sewasti
Copy link

sewasti commented Feb 26, 2026

please review this fix to enable gemini 3.1 pro via openrouter

@jongleeat
Copy link

@roomote
This PR is now on "Review required". Please assign a reviewer to merge this pull request.

@roomote-v0
Copy link
Contributor Author

roomote-v0 bot commented Mar 4, 2026

Fixaroo Clock   See task

Marked this PR as ready for review. All 48 tests pass locally (cd src && pnpm vitest run api/transform/__tests__/openai-format.spec.ts).

@roomote-v0 roomote-v0 bot marked this pull request as ready for review March 4, 2026 01:41
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. bug Something isn't working labels Mar 4, 2026
@jongleeat
Copy link

Hello @cte, I know you must be busy, but I would really appreciate it if you could take a look at this PR when you have some free time. I'm happy to address any feedback or provide more context. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] google/gemini-3.1-pro-preview via OpenRouter: assistant content[] stripped on Turn 2 → "no assistant messages" on every follow-up

3 participants