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:
徐闻涵0668001344 2026-06-16 20:51:59 +08:00
parent 083e68b49a
commit 5b41f18c3d
2 changed files with 4 additions and 3 deletions

View file

@ -285,6 +285,7 @@ func (p *GeminiProvider) buildRequestBody(
}
if thoughtSignature != "" {
part.ThoughtSignature = thoughtSignature
part.ThoughtSignatureSnake = thoughtSignature
}
content.Parts = append(content.Parts, part)
}

View file

@ -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)
body := provider.buildRequestBody(
@ -484,8 +484,8 @@ func TestGeminiProvider_BuildRequestBody_UsesCamelCaseThoughtSignatureOnly(t *te
if !strings.Contains(jsonBody, `"thoughtSignature":"sig-1"`) {
t.Fatalf("request body = %s, expected camelCase thoughtSignature", jsonBody)
}
if strings.Contains(jsonBody, `"thought_signature"`) {
t.Fatalf("request body = %s, unexpected snake_case thought_signature", jsonBody)
if !strings.Contains(jsonBody, `"thought_signature":"sig-1"`) {
t.Fatalf("request body = %s, expected snake_case thought_signature for Gemini 3.5 Flash Agentic compatibility", jsonBody)
}
}