Skip to content

Comments

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

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

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

Conversation

@roomote
Copy link
Contributor

@roomote roomote 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

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

1 participant