fix(agent): strip thinking blocks from content arrays on signature recovery - #24407
fix(agent): strip thinking blocks from content arrays on signature recovery#24407liuhao1024 wants to merge 1 commit into
Conversation
…covery The thinking-signature recovery path (FailoverReason.thinking_signature) only stripped the top-level reasoning_details field from messages. But Anthropic thinking blocks live inside assistant message content arrays. After the recovery, convert_messages_to_anthropic() on the retry kept the signed thinking blocks from the last assistant message, causing the same HTTP 400 'Invalid signature in thinking block' error on every retry. This is especially visible when switching from a provider that emits thinking blocks with its own signatures (e.g. MiniMax via Anthropic transport) to Anthropic proper — the MiniMax signatures are invalid for Anthropic and the recovery never actually removed them. Fix: also strip thinking/redacted_thinking blocks from assistant message content arrays during recovery. If all content was thinking, insert a placeholder. Add 7 regression tests covering the recovery logic. Fixes [Bug]: cross-provider switch from MiniMax to Anthropic fails with Invalid signature in thinking block NousResearch#24401
|
Thanks for identifying the content-array variant of this recovery gap. The premise still holds on current main: Problems
Suggested changes
This is an automated hermes-sweeper review. |
GottZ
left a comment
There was a problem hiding this comment.
This was generated by AI during triage.
Summary
Two PRs address the repeated HTTP 400 caused by replaying invalid signed Anthropic thinking state. #24407 filters thinking blocks from assistant content arrays but mutates canonical history, whereas #70107 removes both replay channels from API-time copies while preserving canonical messages.
Related pull requests
- #24407
related— (+145/-7) — superseded / needs rework: The diff removes thinking and redacted-thinking blocks from canonicalmessages, directly addressing the reported content-array signature failure but risking persisted-history corruption; its tests only reproduce the loop rather than exercising the actual retry and Anthropic conversion path. Despite the keep_open review on #24407, that contributor review itself identifies these blocking issues and requires moving the fix toapi_messages. - #70107
duplicate— (+48/-10) — preferred fix: The diff updates the current recovery path to clear bothreasoning_detailsand the orderedanthropic_content_blocksreplay channel from shallow-copiedapi_messages, preventing the invalid signature from being resent while leaving canonical history unchanged.
Duplicates
#24407 and #70107 target the same signature-recovery retry failure and substantially overlap in intent; #70107 implements the fix against the current API-time replay architecture.
Suggested consolidation
Merge #70107 as the narrower current-architecture fix; #24407 can be closed as superseded because its present diff mutates canonical messages and lacks a real-path retry/conversion test, notwithstanding its keep_open review.
Complex graph
flowchart LR
classDef open fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
classDef merged fill:#dcfce7,stroke:#15803d,color:#14532d
classDef closed fill:#e5e7eb,stroke:#6b7280,color:#1f2937
classDef unverified fill:#f3f4f6,stroke:#9ca3af,color:#374151
classDef best stroke-width:3px,stroke:#b45309
classDef target stroke-width:3px,stroke:#4338ca
subgraph Dup24407 ["PRs duplicating each other"]
P24407["PR #24407 (open)"]
P70107["PR #70107 (open)"]
end
class P24407 open
class P70107 open
class P24407 target
click P24407 "https://github.com/NousResearch/hermes-agent/pull/24407"
click P70107 "https://github.com/NousResearch/hermes-agent/pull/70107"
Graph: solid arrow = fixes / best fix, dashed arrow = partial or unverified (see edge label); boxed group = PRs duplicating each other; amber border = best fix; indigo border = target; gray node = closed or no verify verdict yet (state tag in the node label).
Cross-PR triage: Reviewed 2 pull requests and 0 issues in this complex. Each diff was read against this issue; Assessment working set: 15 kB of PR diffs, 5 kB of issue/PR text, 1 kB of discussion (1 comments), 1 verify verdict. verdicts reflect diff content, not PR titles. Part of an automated triage batch.
What does this PR do?
The thinking-signature recovery path only stripped the top-level
reasoning_detailsfield from messages, but Anthropic thinking blocks live inside assistant messagecontentarrays. After recovery,convert_messages_to_anthropic()on the retry kept the signed thinking blocks from the last assistant message, causing the same HTTP 400 "Invalid signature in thinking block" error on every retry attempt.Root Cause
When a user switches from a provider that emits thinking blocks with its own signatures (e.g. MiniMax via Anthropic transport) to Anthropic proper, the message history contains thinking blocks with MiniMax-specific signatures. Anthropic rejects these with HTTP 400. The recovery code at
run_agent.py(thinking_signature branch) only did:But the thinking blocks are in
_m["content"]as a list of content blocks, not inreasoning_details. After thecontinue, the retry goes throughconvert_messages_to_anthropic()which re-processes messages and keeps signed thinking blocks from the last assistant message — the same invalid signatures that caused the original error.Related Issue
N/A
Type of Change
Changes Made
How to Test
pytest tests/ -q— all tests should passChecklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture and workflows — or N/A