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:
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user