From fe6a3f4267f60c5aaedf57a00f751a3a62ae0b10 Mon Sep 17 00:00:00 2001 From: ianshaw Date: Mon, 12 Jan 2026 11:08:28 -0800 Subject: [PATCH] =?UTF-8?q?fix(gateway):=20=E5=AE=8C=E5=96=84=20max=5Foutp?= =?UTF-8?q?ut=5Ftokens=20=E5=8F=82=E6=95=B0=E5=A4=84=E7=90=86=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根据不同平台和账号类型处理 max_output_tokens 参数: - OpenAI OAuth (Responses API): 保留 max_output_tokens(支持) - OpenAI API Key: 删除 max_output_tokens(不支持) - Anthropic (Claude): 转换 max_output_tokens 为 max_tokens - Gemini: 删除 max_output_tokens(由 Gemini 专用转换处理) - 其他平台: 删除(安全起见) 同时处理 max_completion_tokens 参数,仅在 OpenAI OAuth 时保留。 修复客户端(如 OpenCode)发送不支持参数导致上游返回 400 错误的问题。 Related-to: #231 --- .../service/openai_gateway_service.go | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/backend/internal/service/openai_gateway_service.go b/backend/internal/service/openai_gateway_service.go index f9078959..214da20a 100644 --- a/backend/internal/service/openai_gateway_service.go +++ b/backend/internal/service/openai_gateway_service.go @@ -568,6 +568,44 @@ func (s *OpenAIGatewayService) Forward(ctx context.Context, c *gin.Context, acco } } + // Handle max_output_tokens based on platform and account type + if !isCodexCLI { + if maxOutputTokens, hasMaxOutputTokens := reqBody["max_output_tokens"]; hasMaxOutputTokens { + switch account.Platform { + case PlatformOpenAI: + // For OpenAI API Key, remove max_output_tokens (not supported) + // For OpenAI OAuth (Responses API), keep it (supported) + if account.Type == AccountTypeAPIKey { + delete(reqBody, "max_output_tokens") + bodyModified = true + } + case PlatformAnthropic: + // For Anthropic (Claude), convert to max_tokens + delete(reqBody, "max_output_tokens") + if _, hasMaxTokens := reqBody["max_tokens"]; !hasMaxTokens { + reqBody["max_tokens"] = maxOutputTokens + } + bodyModified = true + case PlatformGemini: + // For Gemini, remove (will be handled by Gemini-specific transform) + delete(reqBody, "max_output_tokens") + bodyModified = true + default: + // For unknown platforms, remove to be safe + delete(reqBody, "max_output_tokens") + bodyModified = true + } + } + + // Also handle max_completion_tokens (similar logic) + if _, hasMaxCompletionTokens := reqBody["max_completion_tokens"]; hasMaxCompletionTokens { + if account.Type == AccountTypeAPIKey || account.Platform != PlatformOpenAI { + delete(reqBody, "max_completion_tokens") + bodyModified = true + } + } + } + // Re-serialize body only if modified if bodyModified { var err error