Skip to content

fix(messages): omit empty thinking signature instead of signature: "" (strict clients reject it)#228

Merged
dwgx merged 1 commit into
dwgx:masterfrom
warelik:fix/signature-omit
Jul 25, 2026
Merged

fix(messages): omit empty thinking signature instead of signature: "" (strict clients reject it)#228
dwgx merged 1 commit into
dwgx:masterfrom
warelik:fix/signature-omit

Conversation

@warelik

@warelik warelik commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

中文 TL;DR

上游从不产出 Anthropic thinking signature,代理原来发 signature:"",严格客户端
(如 Grok Build 的 messages 后端)会判为非法。改为无真实签名时省略该字段;上游给了
真实签名则原样转发。

Summary

signature: "" on an Anthropic thinking block is a proxy-synthesized placeholder,
not a real Anthropic signature (our upstream never emits one). Some strict clients
reject the empty string as invalid. Omit the field when there's no real signature;
forward a real one verbatim when upstream provides it (forward-compat).

Fix

  • src/handlers/messages.js:
    • non-stream openAIToAnthropic: build the thinking block without signature
      unless reasoning_signature is present.
    • AnthropicStreamTranslator: emit signature_delta only when a real
      delta.reasoning_signature arrived (drop the empty-string fallback).

Test plan

  • test/messages.test.js: signature/delta absent without a real signature
    (non-stream + streamed); real-signature round-trip preserved
  • test/anthropic-input-validation.test.js: no regressions
  • Full suite: npm test2761 pass / 0 fail

Branch is on current master (v3.5.0), applies cleanly.

…ature: ""

Our upstream never emits an Anthropic thinking signature, so the proxy sent
signature: "" (and an empty signature_delta). Strict clients (e.g. Grok Build's
messages backend) reject an empty-string signature as invalid. Omit the field
when there's no real signature; forward it verbatim when upstream provides one.

- src/handlers/messages.js: non-stream openAIToAnthropic omits signature unless
  reasoning_signature is present; AnthropicStreamTranslator only emits
  signature_delta when a real delta.reasoning_signature arrived
- test/messages.test.js: assert the field/delta is absent without a real signature;
  real-signature round-trip preserved
@dwgx
dwgx merged commit f433c85 into dwgx:master Jul 25, 2026
5 checks passed
dwgx added a commit that referenced this pull request Jul 25, 2026
- contributors.json: 新增 6 条(#224 S / #225 A+ / #226 S / #227 A / #228 B+ / #229 A)
- README 中英: warelik 段落补本轮六个 PR 的技术叙述
@dwgx

dwgx commented Jul 25, 2026

Copy link
Copy Markdown
Owner

已合并,谢谢 🙏 这条改得对,而且原来的注释其实自己就埋了线索 —— 它写着空串是 "Foxfishc-verified safe fallback",但那个验证只覆盖了当时那个客户端。signature: "" 在 Anthropic spec 里本来就不是一个合法值,严格客户端按 spec 校验就会拒,所以"缺失时省略字段"比"填一个占位符"更符合协议本意。

流式那半修得尤其对:原来是无条件发 signature_delta,现在改成只在真有 reasoning_signature 时才发。测试也跟着从"必有一个空串 signature_delta"改成"无真实签名时不发",同时保留了 thinking_delta 与 content_block_stop 的顺序断言 —— 该松的松、该守的守,没有顺手把顺序保证一起删掉,这个分寸是对的。

上游将来真给 signature 仍原样透传,前向兼容没丢。

已加入致谢名单,评级 B+。

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.

2 participants