Skip to content

Commit 69d8e3a

Browse files
committed
fix(antigravity): preserve thought signature on tool call parts
1 parent d5b29c8 commit 69d8e3a

File tree

1 file changed

+40
-8
lines changed

1 file changed

+40
-8
lines changed

pkg/providers/antigravity_provider.go

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,11 @@ type antigravityContent struct {
159159
}
160160

161161
type antigravityPart struct {
162-
Text string `json:"text,omitempty"`
163-
FunctionCall *antigravityFunctionCall `json:"functionCall,omitempty"`
164-
FunctionResponse *antigravityFunctionResponse `json:"functionResponse,omitempty"`
162+
Text string `json:"text,omitempty"`
163+
ThoughtSignature string `json:"thoughtSignature,omitempty"`
164+
ThoughtSignatureSnake string `json:"thought_signature,omitempty"`
165+
FunctionCall *antigravityFunctionCall `json:"functionCall,omitempty"`
166+
FunctionResponse *antigravityFunctionResponse `json:"functionResponse,omitempty"`
165167
}
166168

167169
type antigravityFunctionCall struct {
@@ -233,7 +235,7 @@ func (p *AntigravityProvider) buildRequest(messages []Message, tools []ToolDefin
233235
content.Parts = append(content.Parts, antigravityPart{Text: msg.Content})
234236
}
235237
for _, tc := range msg.ToolCalls {
236-
toolName, toolArgs := normalizeStoredToolCall(tc)
238+
toolName, toolArgs, thoughtSignature := normalizeStoredToolCall(tc)
237239
if toolName == "" {
238240
logger.WarnCF("provider.antigravity", "Skipping tool call with empty name in history", map[string]interface{}{
239241
"tool_call_id": tc.ID,
@@ -244,6 +246,8 @@ func (p *AntigravityProvider) buildRequest(messages []Message, tools []ToolDefin
244246
toolCallNames[tc.ID] = toolName
245247
}
246248
content.Parts = append(content.Parts, antigravityPart{
249+
ThoughtSignature: thoughtSignature,
250+
ThoughtSignatureSnake: thoughtSignature,
247251
FunctionCall: &antigravityFunctionCall{
248252
Name: toolName,
249253
Args: toolArgs,
@@ -307,12 +311,16 @@ func (p *AntigravityProvider) buildRequest(messages []Message, tools []ToolDefin
307311
return req
308312
}
309313

310-
func normalizeStoredToolCall(tc ToolCall) (string, map[string]interface{}) {
314+
func normalizeStoredToolCall(tc ToolCall) (string, map[string]interface{}, string) {
311315
name := tc.Name
312316
args := tc.Arguments
317+
thoughtSignature := ""
313318

314319
if name == "" && tc.Function != nil {
315320
name = tc.Function.Name
321+
thoughtSignature = tc.Function.ThoughtSignature
322+
} else if tc.Function != nil {
323+
thoughtSignature = tc.Function.ThoughtSignature
316324
}
317325

318326
if args == nil {
@@ -326,7 +334,7 @@ func normalizeStoredToolCall(tc ToolCall) (string, map[string]interface{}) {
326334
}
327335
}
328336

329-
return name, args
337+
return name, args, thoughtSignature
330338
}
331339

332340
func resolveToolResponseName(toolCallID string, toolCallNames map[string]string) string {
@@ -363,8 +371,10 @@ type antigravityJSONResponse struct {
363371
Candidates []struct {
364372
Content struct {
365373
Parts []struct {
366-
Text string `json:"text,omitempty"`
367-
FunctionCall *antigravityFunctionCall `json:"functionCall,omitempty"`
374+
Text string `json:"text,omitempty"`
375+
ThoughtSignature string `json:"thoughtSignature,omitempty"`
376+
ThoughtSignatureSnake string `json:"thought_signature,omitempty"`
377+
FunctionCall *antigravityFunctionCall `json:"functionCall,omitempty"`
368378
} `json:"parts"`
369379
Role string `json:"role"`
370380
} `json:"content"`
@@ -396,10 +406,16 @@ func (p *AntigravityProvider) parseJSONResponse(body []byte) (*LLMResponse, erro
396406
contentParts = append(contentParts, part.Text)
397407
}
398408
if part.FunctionCall != nil {
409+
argumentsJSON, _ := json.Marshal(part.FunctionCall.Args)
399410
toolCalls = append(toolCalls, ToolCall{
400411
ID: fmt.Sprintf("call_%s_%d", part.FunctionCall.Name, time.Now().UnixNano()),
401412
Name: part.FunctionCall.Name,
402413
Arguments: part.FunctionCall.Args,
414+
Function: &FunctionCall{
415+
Name: part.FunctionCall.Name,
416+
Arguments: string(argumentsJSON),
417+
ThoughtSignature: extractPartThoughtSignature(part.ThoughtSignature, part.ThoughtSignatureSnake),
418+
},
403419
})
404420
}
405421
}
@@ -461,10 +477,16 @@ func (p *AntigravityProvider) parseSSEResponse(body string) (*LLMResponse, error
461477
contentParts = append(contentParts, part.Text)
462478
}
463479
if part.FunctionCall != nil {
480+
argumentsJSON, _ := json.Marshal(part.FunctionCall.Args)
464481
toolCalls = append(toolCalls, ToolCall{
465482
ID: fmt.Sprintf("call_%s_%d", part.FunctionCall.Name, time.Now().UnixNano()),
466483
Name: part.FunctionCall.Name,
467484
Arguments: part.FunctionCall.Args,
485+
Function: &FunctionCall{
486+
Name: part.FunctionCall.Name,
487+
Arguments: string(argumentsJSON),
488+
ThoughtSignature: extractPartThoughtSignature(part.ThoughtSignature, part.ThoughtSignatureSnake),
489+
},
468490
})
469491
}
470492
}
@@ -498,6 +520,16 @@ func (p *AntigravityProvider) parseSSEResponse(body string) (*LLMResponse, error
498520
}, nil
499521
}
500522

523+
func extractPartThoughtSignature(thoughtSignature string, thoughtSignatureSnake string) string {
524+
if thoughtSignature != "" {
525+
return thoughtSignature
526+
}
527+
if thoughtSignatureSnake != "" {
528+
return thoughtSignatureSnake
529+
}
530+
return ""
531+
}
532+
501533
// --- Schema sanitization ---
502534

503535
// Google/Gemini doesn't support many JSON Schema keywords that other providers accept.

0 commit comments

Comments
 (0)