fix(antigravity): preserve thought signature on tool call parts

This commit is contained in:
mrbeandev 2026-02-17 11:41:08 +05:30
parent 7f1fd88bf9
commit 833d1e988c

View file

@ -159,9 +159,11 @@ type antigravityContent struct {
} }
type antigravityPart struct { type antigravityPart struct {
Text string `json:"text,omitempty"` Text string `json:"text,omitempty"`
FunctionCall *antigravityFunctionCall `json:"functionCall,omitempty"` ThoughtSignature string `json:"thoughtSignature,omitempty"`
FunctionResponse *antigravityFunctionResponse `json:"functionResponse,omitempty"` ThoughtSignatureSnake string `json:"thought_signature,omitempty"`
FunctionCall *antigravityFunctionCall `json:"functionCall,omitempty"`
FunctionResponse *antigravityFunctionResponse `json:"functionResponse,omitempty"`
} }
type antigravityFunctionCall struct { type antigravityFunctionCall struct {
@ -233,7 +235,7 @@ func (p *AntigravityProvider) buildRequest(messages []Message, tools []ToolDefin
content.Parts = append(content.Parts, antigravityPart{Text: msg.Content}) content.Parts = append(content.Parts, antigravityPart{Text: msg.Content})
} }
for _, tc := range msg.ToolCalls { for _, tc := range msg.ToolCalls {
toolName, toolArgs := normalizeStoredToolCall(tc) toolName, toolArgs, thoughtSignature := normalizeStoredToolCall(tc)
if toolName == "" { if toolName == "" {
logger.WarnCF("provider.antigravity", "Skipping tool call with empty name in history", map[string]interface{}{ logger.WarnCF("provider.antigravity", "Skipping tool call with empty name in history", map[string]interface{}{
"tool_call_id": tc.ID, "tool_call_id": tc.ID,
@ -244,6 +246,8 @@ func (p *AntigravityProvider) buildRequest(messages []Message, tools []ToolDefin
toolCallNames[tc.ID] = toolName toolCallNames[tc.ID] = toolName
} }
content.Parts = append(content.Parts, antigravityPart{ content.Parts = append(content.Parts, antigravityPart{
ThoughtSignature: thoughtSignature,
ThoughtSignatureSnake: thoughtSignature,
FunctionCall: &antigravityFunctionCall{ FunctionCall: &antigravityFunctionCall{
Name: toolName, Name: toolName,
Args: toolArgs, Args: toolArgs,
@ -307,12 +311,16 @@ func (p *AntigravityProvider) buildRequest(messages []Message, tools []ToolDefin
return req return req
} }
func normalizeStoredToolCall(tc ToolCall) (string, map[string]interface{}) { func normalizeStoredToolCall(tc ToolCall) (string, map[string]interface{}, string) {
name := tc.Name name := tc.Name
args := tc.Arguments args := tc.Arguments
thoughtSignature := ""
if name == "" && tc.Function != nil { if name == "" && tc.Function != nil {
name = tc.Function.Name name = tc.Function.Name
thoughtSignature = tc.Function.ThoughtSignature
} else if tc.Function != nil {
thoughtSignature = tc.Function.ThoughtSignature
} }
if args == nil { if args == nil {
@ -326,7 +334,7 @@ func normalizeStoredToolCall(tc ToolCall) (string, map[string]interface{}) {
} }
} }
return name, args return name, args, thoughtSignature
} }
func resolveToolResponseName(toolCallID string, toolCallNames map[string]string) string { func resolveToolResponseName(toolCallID string, toolCallNames map[string]string) string {
@ -363,8 +371,10 @@ type antigravityJSONResponse struct {
Candidates []struct { Candidates []struct {
Content struct { Content struct {
Parts []struct { Parts []struct {
Text string `json:"text,omitempty"` Text string `json:"text,omitempty"`
FunctionCall *antigravityFunctionCall `json:"functionCall,omitempty"` ThoughtSignature string `json:"thoughtSignature,omitempty"`
ThoughtSignatureSnake string `json:"thought_signature,omitempty"`
FunctionCall *antigravityFunctionCall `json:"functionCall,omitempty"`
} `json:"parts"` } `json:"parts"`
Role string `json:"role"` Role string `json:"role"`
} `json:"content"` } `json:"content"`
@ -396,10 +406,16 @@ func (p *AntigravityProvider) parseJSONResponse(body []byte) (*LLMResponse, erro
contentParts = append(contentParts, part.Text) contentParts = append(contentParts, part.Text)
} }
if part.FunctionCall != nil { if part.FunctionCall != nil {
argumentsJSON, _ := json.Marshal(part.FunctionCall.Args)
toolCalls = append(toolCalls, ToolCall{ toolCalls = append(toolCalls, ToolCall{
ID: fmt.Sprintf("call_%s_%d", part.FunctionCall.Name, time.Now().UnixNano()), ID: fmt.Sprintf("call_%s_%d", part.FunctionCall.Name, time.Now().UnixNano()),
Name: part.FunctionCall.Name, Name: part.FunctionCall.Name,
Arguments: part.FunctionCall.Args, Arguments: part.FunctionCall.Args,
Function: &FunctionCall{
Name: part.FunctionCall.Name,
Arguments: string(argumentsJSON),
ThoughtSignature: extractPartThoughtSignature(part.ThoughtSignature, part.ThoughtSignatureSnake),
},
}) })
} }
} }
@ -461,10 +477,16 @@ func (p *AntigravityProvider) parseSSEResponse(body string) (*LLMResponse, error
contentParts = append(contentParts, part.Text) contentParts = append(contentParts, part.Text)
} }
if part.FunctionCall != nil { if part.FunctionCall != nil {
argumentsJSON, _ := json.Marshal(part.FunctionCall.Args)
toolCalls = append(toolCalls, ToolCall{ toolCalls = append(toolCalls, ToolCall{
ID: fmt.Sprintf("call_%s_%d", part.FunctionCall.Name, time.Now().UnixNano()), ID: fmt.Sprintf("call_%s_%d", part.FunctionCall.Name, time.Now().UnixNano()),
Name: part.FunctionCall.Name, Name: part.FunctionCall.Name,
Arguments: part.FunctionCall.Args, Arguments: part.FunctionCall.Args,
Function: &FunctionCall{
Name: part.FunctionCall.Name,
Arguments: string(argumentsJSON),
ThoughtSignature: extractPartThoughtSignature(part.ThoughtSignature, part.ThoughtSignatureSnake),
},
}) })
} }
} }
@ -498,6 +520,16 @@ func (p *AntigravityProvider) parseSSEResponse(body string) (*LLMResponse, error
}, nil }, nil
} }
func extractPartThoughtSignature(thoughtSignature string, thoughtSignatureSnake string) string {
if thoughtSignature != "" {
return thoughtSignature
}
if thoughtSignatureSnake != "" {
return thoughtSignatureSnake
}
return ""
}
// --- Schema sanitization --- // --- Schema sanitization ---
// Google/Gemini doesn't support many JSON Schema keywords that other providers accept. // Google/Gemini doesn't support many JSON Schema keywords that other providers accept.