From f5b2961270ce2b74c1944fba4f5ddf615f1129cf Mon Sep 17 00:00:00 2001 From: phoenix Date: Wed, 1 Jul 2026 18:08:25 +0800 Subject: [PATCH] fix: Handle invalid arguments correctly for Gemini reasoning models --- .../internal/pkg/antigravity/claude_types.go | 26 ++++++++++--- .../pkg/antigravity/request_transformer.go | 37 ++++++++++++------- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/backend/internal/pkg/antigravity/claude_types.go b/backend/internal/pkg/antigravity/claude_types.go index cd68c02788..7a32221408 100644 --- a/backend/internal/pkg/antigravity/claude_types.go +++ b/backend/internal/pkg/antigravity/claude_types.go @@ -1,6 +1,9 @@ package antigravity -import "encoding/json" +import ( + "encoding/json" + "strings" +) // Claude 请求/响应类型定义 @@ -145,6 +148,7 @@ type modelDef struct { ID string DisplayName string CreatedAt string // 仅 Claude API 格式使用 + IsReasoning bool } // Antigravity 支持的 Claude 模型 @@ -166,15 +170,15 @@ var geminiModels = []modelDef{ {ID: "gemini-2.5-flash-image", DisplayName: "Gemini 2.5 Flash Image", CreatedAt: "2025-01-01T00:00:00Z"}, {ID: "gemini-2.5-flash-image-preview", DisplayName: "Gemini 2.5 Flash Image Preview", CreatedAt: "2025-01-01T00:00:00Z"}, {ID: "gemini-2.5-flash-lite", DisplayName: "Gemini 2.5 Flash Lite", CreatedAt: "2025-01-01T00:00:00Z"}, - {ID: "gemini-2.5-flash-thinking", DisplayName: "Gemini 2.5 Flash Thinking", CreatedAt: "2025-01-01T00:00:00Z"}, + {ID: "gemini-2.5-flash-thinking", DisplayName: "Gemini 2.5 Flash Thinking", CreatedAt: "2025-01-01T00:00:00Z", IsReasoning: true}, {ID: "gemini-3-flash", DisplayName: "Gemini 3 Flash", CreatedAt: "2025-06-01T00:00:00Z"}, {ID: "gemini-3-pro-low", DisplayName: "Gemini 3 Pro Low", CreatedAt: "2025-06-01T00:00:00Z"}, - {ID: "gemini-3-pro-high", DisplayName: "Gemini 3 Pro High", CreatedAt: "2025-06-01T00:00:00Z"}, + {ID: "gemini-3-pro-high", DisplayName: "Gemini 3 Pro High", CreatedAt: "2025-06-01T00:00:00Z", IsReasoning: true}, {ID: "gemini-3.1-pro-low", DisplayName: "Gemini 3.1 Pro Low", CreatedAt: "2026-02-19T00:00:00Z"}, - {ID: "gemini-3.1-pro-high", DisplayName: "Gemini 3.1 Pro High", CreatedAt: "2026-02-19T00:00:00Z"}, + {ID: "gemini-3.1-pro-high", DisplayName: "Gemini 3.1 Pro High", CreatedAt: "2026-02-19T00:00:00Z", IsReasoning: true}, {ID: "gemini-3.1-flash-image", DisplayName: "Gemini 3.1 Flash Image", CreatedAt: "2026-02-19T00:00:00Z"}, {ID: "gemini-3.1-flash-image-preview", DisplayName: "Gemini 3.1 Flash Image Preview", CreatedAt: "2026-02-19T00:00:00Z"}, - {ID: "gemini-3-pro-preview", DisplayName: "Gemini 3 Pro Preview", CreatedAt: "2025-06-01T00:00:00Z"}, + {ID: "gemini-3-pro-preview", DisplayName: "Gemini 3 Pro Preview", CreatedAt: "2025-06-01T00:00:00Z", IsReasoning: true}, {ID: "gemini-3-pro-image", DisplayName: "Gemini 3 Pro Image", CreatedAt: "2025-06-01T00:00:00Z"}, } @@ -239,3 +243,15 @@ func FallbackGeminiModel(model string) GeminiModel { } return GeminiModel{Name: name, SupportedGenerationMethods: defaultGeminiMethods} } + +// IsGeminiReasoningModel 判断是否为不支持参数和强制 ToolConfig 的 Gemini 推理模型 +func IsGeminiReasoningModel(modelID string) bool { + lowerID := strings.ToLower(modelID) + for _, m := range geminiModels { + if strings.Contains(lowerID, m.ID) && m.IsReasoning { + return true + } + } + return false +} + diff --git a/backend/internal/pkg/antigravity/request_transformer.go b/backend/internal/pkg/antigravity/request_transformer.go index 5fe2de8406..7d0a707959 100644 --- a/backend/internal/pkg/antigravity/request_transformer.go +++ b/backend/internal/pkg/antigravity/request_transformer.go @@ -143,14 +143,19 @@ func TransformClaudeToGeminiWithOptions(claudeReq *ClaudeRequest, projectID, map // 5. 构建内部请求 innerRequest := GeminiRequest{ Contents: contents, + // 总是生成 sessionId,基于用户消息内容 + SessionID: generateStableSessionID(contents), + } + + // 针对 Gemini Reasoning 模型(如 gemini-3.1-pro-high等)过滤强制空 ToolConfig + isReasoning := IsGeminiReasoningModel(targetModel) + if !isReasoning || len(tools) > 0 { // 总是设置 toolConfig,与官方客户端一致 - ToolConfig: &GeminiToolConfig{ + innerRequest.ToolConfig = &GeminiToolConfig{ FunctionCallingConfig: &GeminiFunctionCallingConfig{ Mode: "VALIDATED", }, - }, - // 总是生成 sessionId,基于用户消息内容 - SessionID: generateStableSessionID(contents), + } } if systemInstruction != nil { @@ -610,7 +615,11 @@ func buildGenerationConfig(req *ClaudeRequest) *GeminiGenerationConfig { maxLimit := maxOutputTokensLimit(req.Model) config := &GeminiGenerationConfig{ MaxOutputTokens: defaultMaxOutputTokens, // 默认最大输出 - StopSequences: DefaultStopSequences, + } + + isReasoning := IsGeminiReasoningModel(req.Model) + if !isReasoning { + config.StopSequences = DefaultStopSequences } // 如果请求中指定了 MaxTokens,使用请求值 @@ -656,14 +665,16 @@ func buildGenerationConfig(req *ClaudeRequest) *GeminiGenerationConfig { } // 其他参数 - if req.Temperature != nil { - config.Temperature = req.Temperature - } - if req.TopP != nil { - config.TopP = req.TopP - } - if req.TopK != nil { - config.TopK = req.TopK + if !isReasoning { + if req.Temperature != nil { + config.Temperature = req.Temperature + } + if req.TopP != nil { + config.TopP = req.TopP + } + if req.TopK != nil { + config.TopK = req.TopK + } } return config