Skip to content

fix(anthropic): demote reordered thinking signatures on interleaved multi-thinking turns#35976

Open
fesalfayed wants to merge 1 commit into
NousResearch:mainfrom
fesalfayed:fix/anthropic-interleaved-thinking-reorder
Open

fix(anthropic): demote reordered thinking signatures on interleaved multi-thinking turns#35976
fesalfayed wants to merge 1 commit into
NousResearch:mainfrom
fesalfayed:fix/anthropic-interleaved-thinking-reorder

Conversation

@fesalfayed

Copy link
Copy Markdown

What does this PR do?

Extended-thinking Claude models interleave thinking and tool_use blocks (thinking, tool_use, thinking, tool_use, …) and sign each thinking block against its original position in that sequence. _convert_assistant_message rebuilds the assistant turn as [all thinking][text][all tool_use], so any latest turn carrying 2+ thinking blocks alongside tool_use is reordered and its signatures no longer match. Replaying them returns a non-retryable HTTP 400:

messages.N.content.M: `thinking` or `redacted_thinking` blocks in the latest
assistant message cannot be modified. These blocks must remain as they were
in the original response.

Since the turn is rebuilt from the store every iteration, the gateway loops on it with no recovery. The reported content.M lands in the tool_use region (Anthropic is validating the original interleaved layout), which is the tell that this is a reorder rather than the orphan-strip case fixed in #35859.

reasoning_details carries no positional anchor to re-interleave the blocks from, so faithful reconstruction is impossible. This extends the existing dead-signature handling in _manage_thinking_signatures: when the latest turn has 2+ thinking blocks and any tool_use, demote those thinking blocks to text (reasoning preserved) instead of replaying dead signatures. A single leading thinking block is unaffected — its position is unchanged, so its signature is still valid.

This is distinct from #35847/#35859 (orphan-stripped tool_use): there are no orphans here — every tool_use is answered — so that fix does not cover it.

Related Issue

Fixes #35975

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • agent/anthropic_adapter.py_manage_thinking_signatures: mark the latest turn's signature dead (→ demote thinking to text) when it has 2+ thinking blocks alongside tool_use.
  • tests/agent/test_anthropic_adapter.py — two tests: interleaved multi-thinking demotion, and a single-thinking + tool_use no-over-fire guard.

How to Test

pytest tests/agent/test_anthropic_adapter.py -k "thinking or signature or orphan or interleav" -q

(21 passed locally — the 2 new tests plus the existing thinking/signature/orphan suite, confirming no over-fire regression on test_signed_thinking_preserved_on_last_turn.)

Checklist

Code

  • My commit messages follow Conventional Commits
  • My PR contains only changes related to this fix
  • Tests pass
  • I've added tests for my changes
  • Tested on macOS 26.4, Python 3.11.15

Documentation & Housekeeping

  • N/A — behavior fix, no config/doc/schema changes.

…ulti-thinking turns

Extended-thinking models interleave thinking and tool_use blocks
(thinking, tool_use, thinking, ...) and sign each thinking block against
its original position. _convert_assistant_message rebuilds the turn as
[all thinking][text][all tool_use], so any latest turn with 2+ thinking
blocks alongside tool_use is reordered and its signatures are dead;
replaying them returns a non-retryable HTTP 400 (the reported content.N
lands in the tool_use region). reasoning_details carries no positional
anchor to re-interleave from, so demote those thinking blocks to text in
_manage_thinking_signatures, preserving the reasoning. A single leading
thinking block is unaffected (its position is unchanged).
@alt-glitch alt-glitch added type/bug Something isn't working P0 Critical — data loss, security, crash loop comp/agent Core agent loop, run_agent.py, prompt builder provider/anthropic Anthropic native Messages API labels May 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent loop, run_agent.py, prompt builder P0 Critical — data loss, security, crash loop provider/anthropic Anthropic native Messages API type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: extended-thinking + interleaved multi-thinking tool turn → non-retryable HTTP 400 crash-loop (reordered thinking signature)

2 participants