[PR #11882] fix: strip incompatible thinking blocks when switching to Claude (improved) #13969

Open
opened 2026-02-16 18:18:47 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/11882

State: open
Merged: No


Summary

Fixes #6418 - Improves upon #8958 with additional bug fixes and edge case handling.

Problem

When switching from models like GLM 4.7 or MiniMax to Claude with extended thinking enabled, users get API errors:

messages.X.content.0: Invalid 'signature' in 'thinking' block

This happens because other models produce thinking blocks with signatures that are incompatible with Claude's signature validation.

Solution

In normalizeMessages(), when the target model is Claude:

  1. Add isValidClaudeSignature() helper - Validates if a signature is a valid Claude/Anthropic signature (starts with 'ErUB')
  2. Extract normalizeClaudeThinkingBlocks() - Dedicated function for better code organization and maintainability
  3. Convert ONLY invalid signatures - Valid Claude thinking blocks are preserved, only incompatible ones from GLM/MiniMax/etc are converted
  4. Use distinct tags - <assistant_thinking> for thinking blocks, <assistant_reasoning> for reasoning blocks
  5. Handle empty content - Filter out messages with empty content after processing
  6. Preserve devstral support - Maintains the devstral check in Mistral normalization

Improvements over PR #8958

Issue PR #8958 This PR
Devstral support Removed Preserved
Valid Claude signatures Converted Preserved
Tag consistency Uses same tag for both Distinct tags
Empty content handling Not handled Filtered out
Type safety Many any casts Better types
Code organization Inline Extracted helper

Changes

  • packages/opencode/src/provider/transform.ts:

    • Added isValidClaudeSignature() helper function with JSDoc
    • Added normalizeClaudeThinkingBlocks() with detailed documentation
    • Updated normalizeMessages() to use new helper for Claude
    • Preserved devstral support in Mistral check
  • packages/opencode/test/provider/thinking-blocks.test.ts:

    • Comprehensive test coverage including:
      • Valid Claude signature preservation
      • Invalid signature conversion
      • Empty thinking block handling
      • Multiple thinking blocks
      • Tool pairing preservation
      • Tool call ID normalization

Testing

  1. Start a session with GLM 4.7 or MiniMax (models that generate thinking/reasoning)
  2. Send a few messages, including one that triggers tool use
  3. Switch to Claude with extended thinking enabled
  4. Send a message - should no longer get signature errors
  5. Tool results should still work correctly
  6. Try with devstral model - should still work

Related

  • Supersedes #8958 (addresses review feedback)
  • Related to #7779 (GLM 4.7 thinking format issues)
**Original Pull Request:** https://github.com/anomalyco/opencode/pull/11882 **State:** open **Merged:** No --- ## Summary Fixes #6418 - Improves upon #8958 with additional bug fixes and edge case handling. ## Problem When switching from models like GLM 4.7 or MiniMax to Claude with extended thinking enabled, users get API errors: ``` messages.X.content.0: Invalid 'signature' in 'thinking' block ``` This happens because other models produce `thinking` blocks with signatures that are **incompatible** with Claude's signature validation. ## Solution In `normalizeMessages()`, when the target model is Claude: 1. **Add `isValidClaudeSignature()` helper** - Validates if a signature is a valid Claude/Anthropic signature (starts with 'ErUB') 2. **Extract `normalizeClaudeThinkingBlocks()`** - Dedicated function for better code organization and maintainability 3. **Convert ONLY invalid signatures** - Valid Claude thinking blocks are preserved, only incompatible ones from GLM/MiniMax/etc are converted 4. **Use distinct tags** - `<assistant_thinking>` for thinking blocks, `<assistant_reasoning>` for reasoning blocks 5. **Handle empty content** - Filter out messages with empty content after processing 6. **Preserve devstral support** - Maintains the devstral check in Mistral normalization ## Improvements over PR #8958 | Issue | PR #8958 | This PR | |-------|----------|---------| | Devstral support | ❌ Removed | ✅ Preserved | | Valid Claude signatures | ❌ Converted | ✅ Preserved | | Tag consistency | ❌ Uses same tag for both | ✅ Distinct tags | | Empty content handling | ❌ Not handled | ✅ Filtered out | | Type safety | ❌ Many `any` casts | ✅ Better types | | Code organization | ❌ Inline | ✅ Extracted helper | ## Changes - `packages/opencode/src/provider/transform.ts`: - Added `isValidClaudeSignature()` helper function with JSDoc - Added `normalizeClaudeThinkingBlocks()` with detailed documentation - Updated `normalizeMessages()` to use new helper for Claude - Preserved devstral support in Mistral check - `packages/opencode/test/provider/thinking-blocks.test.ts`: - Comprehensive test coverage including: - Valid Claude signature preservation - Invalid signature conversion - Empty thinking block handling - Multiple thinking blocks - Tool pairing preservation - Tool call ID normalization ## Testing 1. Start a session with GLM 4.7 or MiniMax (models that generate thinking/reasoning) 2. Send a few messages, including one that triggers tool use 3. Switch to Claude with extended thinking enabled 4. Send a message - should no longer get signature errors 5. Tool results should still work correctly 6. Try with devstral model - should still work ## Related - Supersedes #8958 (addresses review feedback) - Related to #7779 (GLM 4.7 thinking format issues)
yindo added the pull-request label 2026-02-16 18:18:47 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#13969