From 9100f981d73aa51dfe8b75cf7dd29ddbf7926981 Mon Sep 17 00:00:00 2001 From: badgerbees <93577481+badgerbees@users.noreply.github.com> Date: Fri, 20 Mar 2026 00:14:33 +0700 Subject: [PATCH] fix(providers): robust Gemini thought_signature detection and history mapping Improves supportsThoughtSignature with providerType and model normalization. Strengthens collapseToolCallsWithoutSig with TrimSpace and camelCase support to handle 'Thinking=OFF' whitespace signatures and proxy key translations. --- internal/providers/openai.go | 5 +++-- internal/providers/openai_gemini.go | 12 +++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/internal/providers/openai.go b/internal/providers/openai.go index 5cbb8bf1..49692143 100644 --- a/internal/providers/openai.go +++ b/internal/providers/openai.go @@ -259,8 +259,9 @@ func (p *OpenAIProvider) buildRequestBody(model string, req ChatRequest, stream inputMessages := req.Messages // Compute provider capability once: does this endpoint support Google's thought_signature? - // We check name, apiBase, and the model string (which covers OpenRouter/LiteLLM routing to Gemini). - supportsThoughtSignature := strings.Contains(strings.ToLower(p.name), "gemini") || + // We check providerType, name, apiBase, and the model string (robust detection for proxies/OpenRouter). + supportsThoughtSignature := strings.Contains(strings.ToLower(p.providerType), "gemini") || + strings.Contains(strings.ToLower(p.name), "gemini") || strings.Contains(strings.ToLower(p.apiBase), "generativelanguage") || strings.Contains(strings.ToLower(model), "gemini") diff --git a/internal/providers/openai_gemini.go b/internal/providers/openai_gemini.go index 55678187..3b2916ec 100644 --- a/internal/providers/openai_gemini.go +++ b/internal/providers/openai_gemini.go @@ -17,7 +17,17 @@ func collapseToolCallsWithoutSig(msgs []Message) []Message { continue } for _, tc := range m.ToolCalls { - if tc.Metadata["thought_signature"] == "" { + // If meta is nil or signature is empty/whitespace, collapse the whole message's tool cycle. + // Checks both snake_case and camelCase for cross-proxy reliability. + sig := "" + if tc.Metadata != nil { + sig = tc.Metadata["thought_signature"] + if sig == "" { + sig = tc.Metadata["thoughtSignature"] + } + } + + if strings.TrimSpace(sig) == "" { for _, tc2 := range m.ToolCalls { collapseIDs[tc2.ID] = true }