Files
sub2api/backend/internal/pkg/apicompat/thinking_signature_wire_test.go
T
风起andClaude Opus 5.5 412718edf5 fix(apicompat): always include signature on Anthropic thinking blocks
AnthropicContentBlock / antigravity ClaudeContentItem serialized `signature`
with omitempty, so thinking blocks without an upstream signature (Chat
Completions reasoning_content, Responses reasoning without encrypted_content,
every streamed thinking content_block_start) went out with no `signature` key.

Anthropic always sends the key (`""` on content_block_start). Strict clients
such as Grok Build deserialize it as a required field and abort the response
or SSE stream with "missing field `signature`".

- apicompat: thinking MarshalJSON always emits `thinking` and `signature`
- antigravity: ClaudeContentItem MarshalJSON does the same; streamed thinking
  content_block_start carries `signature: ""`
- tests: wire-shape regression tests; update TestStreamingReasoning expectation

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 08:41:15 +00:00

25 lines
896 B
Go

package apicompat
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
)
// Thinking blocks must always carry the `signature` key (Anthropic wire shape);
// strict clients such as Grok Build fail with "missing field `signature`".
func TestAnthropicContentBlock_ThinkingAlwaysHasSignature(t *testing.T) {
data, err := json.Marshal(AnthropicContentBlock{Type: "thinking", Thinking: "plan"})
require.NoError(t, err)
require.JSONEq(t, `{"type":"thinking","thinking":"plan","signature":""}`, string(data))
data, err = json.Marshal(AnthropicContentBlock{Type: "thinking", Signature: "sig"})
require.NoError(t, err)
require.JSONEq(t, `{"type":"thinking","thinking":"","signature":"sig"}`, string(data))
data, err = json.Marshal(AnthropicContentBlock{Type: "text", Text: "hi"})
require.NoError(t, err)
require.JSONEq(t, `{"type":"text","text":"hi"}`, string(data))
}