fix(antigravity): discard thinking blocks with non-Claude-format signatures

Proxy-generated thinking blocks may carry hex hashes or other non-Claude
signatures (e.g. "d5cb9cd0823142109f451861") from Gemini responses. These
are now discarded alongside empty-signature blocks during the strip phase,
before validation runs. Valid Claude signatures always start with 'E' or 'R'
(after stripping any cache prefix).
This commit is contained in:
sususu98
2026-04-13 17:38:43 +08:00
parent 278a89824c
commit 41ae2c81e7

View File

@@ -73,9 +73,10 @@ type claudeSignatureTree struct {
HasField7 bool HasField7 bool
} }
// StripEmptySignatureThinkingBlocks removes thinking blocks with empty signatures // StripInvalidSignatureThinkingBlocks removes thinking blocks whose signatures
// from messages[].content[]. These come from proxy-generated responses (Antigravity/Gemini) // are empty or not valid Claude format (must start with 'E' or 'R' after
// where no real Claude signature exists. // stripping any cache prefix). These come from proxy-generated responses
// (Antigravity/Gemini) where no real Claude signature exists.
func StripEmptySignatureThinkingBlocks(payload []byte) []byte { func StripEmptySignatureThinkingBlocks(payload []byte) []byte {
messages := gjson.GetBytes(payload, "messages") messages := gjson.GetBytes(payload, "messages")
if !messages.IsArray() { if !messages.IsArray() {
@@ -90,7 +91,7 @@ func StripEmptySignatureThinkingBlocks(payload []byte) []byte {
var kept []string var kept []string
stripped := false stripped := false
for _, part := range content.Array() { for _, part := range content.Array() {
if part.Get("type").String() == "thinking" && strings.TrimSpace(part.Get("signature").String()) == "" { if part.Get("type").String() == "thinking" && !hasValidClaudeSignature(part.Get("signature").String()) {
stripped = true stripped = true
continue continue
} }
@@ -111,6 +112,23 @@ func StripEmptySignatureThinkingBlocks(payload []byte) []byte {
return payload return payload
} }
// hasValidClaudeSignature returns true if sig looks like a real Claude thinking
// signature: non-empty and starts with 'E' or 'R' (after stripping optional
// cache prefix like "modelGroup#").
func hasValidClaudeSignature(sig string) bool {
sig = strings.TrimSpace(sig)
if sig == "" {
return false
}
if idx := strings.IndexByte(sig, '#'); idx >= 0 {
sig = strings.TrimSpace(sig[idx+1:])
}
if sig == "" {
return false
}
return sig[0] == 'E' || sig[0] == 'R'
}
func ValidateClaudeBypassSignatures(inputRawJSON []byte) error { func ValidateClaudeBypassSignatures(inputRawJSON []byte) error {
messages := gjson.GetBytes(inputRawJSON, "messages") messages := gjson.GetBytes(inputRawJSON, "messages")
if !messages.IsArray() { if !messages.IsArray() {