Merge pull request #2252 from sususu98/fix/antigravity-empty-thought-text

fix(antigravity): always include text field in thought parts to prevent Google 500
This commit is contained in:
Luis Pater
2026-03-23 21:41:25 +08:00
committed by GitHub
@@ -104,59 +104,59 @@ func ConvertClaudeRequestToAntigravity(modelName string, inputRawJSON []byte, _
// Always try cached signature first (more reliable than client-provided) // Always try cached signature first (more reliable than client-provided)
// Client may send stale or invalid signatures from different sessions // Client may send stale or invalid signatures from different sessions
signature := "" signature := ""
if thinkingText != "" { if thinkingText != "" {
if cachedSig := cache.GetCachedSignature(modelName, thinkingText); cachedSig != "" { if cachedSig := cache.GetCachedSignature(modelName, thinkingText); cachedSig != "" {
signature = cachedSig signature = cachedSig
// log.Debugf("Using cached signature for thinking block") // log.Debugf("Using cached signature for thinking block")
}
} }
}
// Fallback to client signature only if cache miss and client signature is valid // Fallback to client signature only if cache miss and client signature is valid
if signature == "" { if signature == "" {
signatureResult := contentResult.Get("signature") signatureResult := contentResult.Get("signature")
clientSignature := "" clientSignature := ""
if signatureResult.Exists() && signatureResult.String() != "" { if signatureResult.Exists() && signatureResult.String() != "" {
arrayClientSignatures := strings.SplitN(signatureResult.String(), "#", 2) arrayClientSignatures := strings.SplitN(signatureResult.String(), "#", 2)
if len(arrayClientSignatures) == 2 { if len(arrayClientSignatures) == 2 {
if cache.GetModelGroup(modelName) == arrayClientSignatures[0] { if cache.GetModelGroup(modelName) == arrayClientSignatures[0] {
clientSignature = arrayClientSignatures[1] clientSignature = arrayClientSignatures[1]
}
} }
} }
if cache.HasValidSignature(modelName, clientSignature) {
signature = clientSignature
}
// log.Debugf("Using client-provided signature for thinking block")
} }
if cache.HasValidSignature(modelName, clientSignature) {
signature = clientSignature
}
// log.Debugf("Using client-provided signature for thinking block")
}
// Store for subsequent tool_use in the same message // Store for subsequent tool_use in the same message
if cache.HasValidSignature(modelName, signature) { if cache.HasValidSignature(modelName, signature) {
currentMessageThinkingSignature = signature currentMessageThinkingSignature = signature
} }
// Skip trailing unsigned thinking blocks on last assistant message // Skip trailing unsigned thinking blocks on last assistant message
isUnsigned := !cache.HasValidSignature(modelName, signature) isUnsigned := !cache.HasValidSignature(modelName, signature)
// If unsigned, skip entirely (don't convert to text) // If unsigned, skip entirely (don't convert to text)
// Claude requires assistant messages to start with thinking blocks when thinking is enabled // Claude requires assistant messages to start with thinking blocks when thinking is enabled
// Converting to text would break this requirement // Converting to text would break this requirement
if isUnsigned { if isUnsigned {
// log.Debugf("Dropping unsigned thinking block (no valid signature)") // log.Debugf("Dropping unsigned thinking block (no valid signature)")
enableThoughtTranslate = false enableThoughtTranslate = false
continue continue
} }
// Valid signature, send as thought block // Valid signature, send as thought block
partJSON := []byte(`{}`) // Always include "text" field — Google Antigravity API requires it
partJSON, _ = sjson.SetBytes(partJSON, "thought", true) // even for redacted thinking where the text is empty.
if thinkingText != "" { partJSON := []byte(`{}`)
partJSON, _ = sjson.SetBytes(partJSON, "text", thinkingText) partJSON, _ = sjson.SetBytes(partJSON, "thought", true)
} partJSON, _ = sjson.SetBytes(partJSON, "text", thinkingText)
if signature != "" { if signature != "" {
partJSON, _ = sjson.SetBytes(partJSON, "thoughtSignature", signature) partJSON, _ = sjson.SetBytes(partJSON, "thoughtSignature", signature)
} }
clientContentJSON, _ = sjson.SetRawBytes(clientContentJSON, "parts.-1", partJSON) clientContentJSON, _ = sjson.SetRawBytes(clientContentJSON, "parts.-1", partJSON)
} else if contentTypeResult.Type == gjson.String && contentTypeResult.String() == "text" { } else if contentTypeResult.Type == gjson.String && contentTypeResult.String() == "text" {
prompt := contentResult.Get("text").String() prompt := contentResult.Get("text").String()
// Skip empty text parts to avoid Gemini API error: // Skip empty text parts to avoid Gemini API error: