fix(gateway): 完善 max_output_tokens 参数处理逻辑

根据不同平台和账号类型处理 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
This commit is contained in:
ianshaw
2026-01-12 11:08:28 -08:00
parent fe8198c8cd
commit fe6a3f4267

View File

@@ -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 // Re-serialize body only if modified
if bodyModified { if bodyModified {
var err error var err error