fix: Handle invalid arguments correctly for Gemini reasoning models

This commit is contained in:
phoenix
2026-07-01 18:08:25 +08:00
parent 8c2d9b9a12
commit f5b2961270
2 changed files with 45 additions and 18 deletions
@@ -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
}
@@ -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