fix(gemini): set both camelCase and snake_case thought_signature in tool call request body
The Gemini HTTP API provider only set thoughtSignature (camelCase) when building tool call request bodies. Gemini 2.5 models accept camelCase, but Gemini 3.5 Flash Agentic reasoning requires thought_signature (snake_case) — matching the format it returns in API responses. When only the camelCase variant was sent, Gemini 3.5 Flash rejected the request with a 400 Bad Request for missing thought_signature. The fix sets both ThoughtSignature and ThoughtSignatureSnake in the geminiPart struct, matching the pattern already used in antigravity_provider.go. This ensures compatibility with both Gemini 2.x (camelCase) and Gemini 3.x Agentic (snake_case) models. Closes #3111
This commit is contained in:
parent
083e68b49a
commit
5b41f18c3d
2 changed files with 4 additions and 3 deletions
|
|
@ -285,6 +285,7 @@ func (p *GeminiProvider) buildRequestBody(
|
||||||
}
|
}
|
||||||
if thoughtSignature != "" {
|
if thoughtSignature != "" {
|
||||||
part.ThoughtSignature = thoughtSignature
|
part.ThoughtSignature = thoughtSignature
|
||||||
|
part.ThoughtSignatureSnake = thoughtSignature
|
||||||
}
|
}
|
||||||
content.Parts = append(content.Parts, part)
|
content.Parts = append(content.Parts, part)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -453,7 +453,7 @@ func TestGeminiProvider_ChatStreamReturnsErrorOnInvalidDataFrame(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGeminiProvider_BuildRequestBody_UsesCamelCaseThoughtSignatureOnly(t *testing.T) {
|
func TestGeminiProvider_BuildRequestBody_SetsBothThoughtSignatureFormats(t *testing.T) {
|
||||||
provider := NewGeminiProvider("test-key", "https://example.com/v1beta", "", "", 0, nil, nil)
|
provider := NewGeminiProvider("test-key", "https://example.com/v1beta", "", "", 0, nil, nil)
|
||||||
|
|
||||||
body := provider.buildRequestBody(
|
body := provider.buildRequestBody(
|
||||||
|
|
@ -484,8 +484,8 @@ func TestGeminiProvider_BuildRequestBody_UsesCamelCaseThoughtSignatureOnly(t *te
|
||||||
if !strings.Contains(jsonBody, `"thoughtSignature":"sig-1"`) {
|
if !strings.Contains(jsonBody, `"thoughtSignature":"sig-1"`) {
|
||||||
t.Fatalf("request body = %s, expected camelCase thoughtSignature", jsonBody)
|
t.Fatalf("request body = %s, expected camelCase thoughtSignature", jsonBody)
|
||||||
}
|
}
|
||||||
if strings.Contains(jsonBody, `"thought_signature"`) {
|
if !strings.Contains(jsonBody, `"thought_signature":"sig-1"`) {
|
||||||
t.Fatalf("request body = %s, unexpected snake_case thought_signature", jsonBody)
|
t.Fatalf("request body = %s, expected snake_case thought_signature for Gemini 3.5 Flash Agentic compatibility", jsonBody)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue