Repository navigation
fix(translator): drop unsigned reasoning on Claude output - #12917
diegosouzapw merged 6 commits into
Conversation
|
Clean, well-reasoned fix — dropping unsigned reasoning instead of laundering it into visible |
|
Re-homed to |
Rescope per owner decision: the response-side translators keep the tip's deliberate policy (relay reasoning as thinking unless the client opted out), so the response-side edits of this branch are dropped in favor of the tip's versions. The signature-replay fix moves to the request path toward Anthropic. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Assistant thinking/redacted_thinking blocks with no signature/data (reasoning relayed from a non-Anthropic leg) can only be rejected by api.anthropic.com with "Invalid signature in thinking block". Drop them on the Claude passthrough request path (provider claude); signed blocks are forwarded verbatim. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
…ough helper Keeps chatCore.ts within its frozen file-size ceiling. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Open tool-use cycles can still reach Anthropic without the required thinking precursor, and the PR description does not match the current diff.
Review effort: Balanced
Findings: 1
Open (2)
What changed in this PR
Adds Claude passthrough sanitization to prevent unsigned thinking blocks from being replayed to Anthropic.
Changes:
- Removes unsigned thinking history while preserving signed blocks.
- Adds unit and passthrough regression coverage.
- Adds a changelog fragment.
Validation: Commands run: none. Changed test: tests/unit/claude-passthrough-unsigned-thinking-12917.test.ts. Coverage: not provided.
| File | Description |
|---|---|
open-sse/handlers/chatCore/passthroughHelpers.ts |
Filters unsigned thinking blocks. |
tests/unit/claude-passthrough-unsigned-thinking-12917.test.ts |
Tests helper and passthrough behavior. |
changelog.d/fixes/12917-drop-unsigned-reasoning-claude-output.md |
Documents the fix. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| changed = true; | ||
| const content = message.content.filter((block) => !isUnsignedThinkingBlock(block)); | ||
| if (content.length > 0) kept.push({ ...message, content }); |
| @@ -0,0 +1 @@ | |||
| - **fix(claude):** drop assistant `thinking` / `redacted_thinking` blocks that carry no signature from the history before it is replayed to the genuine Anthropic upstream (Claude passthrough), so reasoning relayed from an OpenAI-compatible leg no longer triggers `Invalid signature in thinking block` on the next turn — signed blocks are forwarded untouched ([#12917](https://github.com/diegosouzapw/OmniRoute/pull/12917)) — thanks @atescivitci-cmd | |||
|
Thanks @atescivitci-cmd — merged into |


Summary
reasoning_contentinto ClaudethinkingblocksWhy
thinkingblocks sent back to Anthropic must carry Anthropic-valid signatures. Reasoning fields from OpenAI-compatible providers do not have those signatures, so translating them into Claudethinkingcreates replay history that Anthropic rejects withInvalid signature in thinking block.Validation
node --import tsx/esm --test tests/unit/translator-resp-openai-to-claude.test.tsnode --import tsx/esm --test tests/unit/translator-openai-to-claude.test.tsnpx eslint open-sse/handlers/responseTranslator.ts open-sse/translator/response/openai-to-claude.ts tests/unit/translator-resp-openai-to-claude.test.ts --cache --cache-location .eslintcache --suppressions-location config/quality/eslint-suppressions.jsonnpm run typecheck:core -- --pretty false