Merge pull request #260 from IanShaw027/fix/sync-openai-gpt5-models
fix: 同步 OpenAI GPT-5 模型列表并完善参数处理
This commit is contained in:
@@ -545,14 +545,12 @@ func (s *OpenAIGatewayService) Forward(ctx context.Context, c *gin.Context, acco
|
|||||||
|
|
||||||
isCodexCLI := openai.IsCodexCLIRequest(c.GetHeader("User-Agent"))
|
isCodexCLI := openai.IsCodexCLIRequest(c.GetHeader("User-Agent"))
|
||||||
|
|
||||||
// Apply model mapping (skip for Codex CLI for transparent forwarding)
|
// Apply model mapping for all requests (including Codex CLI)
|
||||||
mappedModel := reqModel
|
mappedModel := account.GetMappedModel(reqModel)
|
||||||
if !isCodexCLI {
|
if mappedModel != reqModel {
|
||||||
mappedModel = account.GetMappedModel(reqModel)
|
log.Printf("[OpenAI] Model mapping applied: %s -> %s (account: %s, isCodexCLI: %v)", reqModel, mappedModel, account.Name, isCodexCLI)
|
||||||
if mappedModel != reqModel {
|
reqBody["model"] = mappedModel
|
||||||
reqBody["model"] = mappedModel
|
bodyModified = true
|
||||||
bodyModified = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if account.Type == AccountTypeOAuth && !isCodexCLI {
|
if account.Type == AccountTypeOAuth && !isCodexCLI {
|
||||||
@@ -568,6 +566,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
|
||||||
|
|||||||
@@ -13,7 +13,17 @@ const openaiModels = [
|
|||||||
'o1', 'o1-preview', 'o1-mini', 'o1-pro',
|
'o1', 'o1-preview', 'o1-mini', 'o1-pro',
|
||||||
'o3', 'o3-mini', 'o3-pro',
|
'o3', 'o3-mini', 'o3-pro',
|
||||||
'o4-mini',
|
'o4-mini',
|
||||||
'gpt-5', 'gpt-5-mini', 'gpt-5-nano',
|
// GPT-5 系列(同步后端定价文件)
|
||||||
|
'gpt-5', 'gpt-5-2025-08-07', 'gpt-5-chat', 'gpt-5-chat-latest',
|
||||||
|
'gpt-5-codex', 'gpt-5-pro', 'gpt-5-pro-2025-10-06',
|
||||||
|
'gpt-5-mini', 'gpt-5-mini-2025-08-07',
|
||||||
|
'gpt-5-nano', 'gpt-5-nano-2025-08-07',
|
||||||
|
// GPT-5.1 系列
|
||||||
|
'gpt-5.1', 'gpt-5.1-2025-11-13', 'gpt-5.1-chat-latest',
|
||||||
|
'gpt-5.1-codex', 'gpt-5.1-codex-max', 'gpt-5.1-codex-mini',
|
||||||
|
// GPT-5.2 系列
|
||||||
|
'gpt-5.2', 'gpt-5.2-2025-12-11', 'gpt-5.2-chat-latest',
|
||||||
|
'gpt-5.2-codex', 'gpt-5.2-pro', 'gpt-5.2-pro-2025-12-11',
|
||||||
'chatgpt-4o-latest',
|
'chatgpt-4o-latest',
|
||||||
'gpt-4o-audio-preview', 'gpt-4o-realtime-preview'
|
'gpt-4o-audio-preview', 'gpt-4o-realtime-preview'
|
||||||
]
|
]
|
||||||
@@ -211,7 +221,10 @@ const openaiPresetMappings = [
|
|||||||
{ label: 'GPT-4.1', from: 'gpt-4.1', to: 'gpt-4.1', color: 'bg-indigo-100 text-indigo-700 hover:bg-indigo-200 dark:bg-indigo-900/30 dark:text-indigo-400' },
|
{ label: 'GPT-4.1', from: 'gpt-4.1', to: 'gpt-4.1', color: 'bg-indigo-100 text-indigo-700 hover:bg-indigo-200 dark:bg-indigo-900/30 dark:text-indigo-400' },
|
||||||
{ label: 'o1', from: 'o1', to: 'o1', color: 'bg-purple-100 text-purple-700 hover:bg-purple-200 dark:bg-purple-900/30 dark:text-purple-400' },
|
{ label: 'o1', from: 'o1', to: 'o1', color: 'bg-purple-100 text-purple-700 hover:bg-purple-200 dark:bg-purple-900/30 dark:text-purple-400' },
|
||||||
{ label: 'o3', from: 'o3', to: 'o3', color: 'bg-emerald-100 text-emerald-700 hover:bg-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-400' },
|
{ label: 'o3', from: 'o3', to: 'o3', color: 'bg-emerald-100 text-emerald-700 hover:bg-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-400' },
|
||||||
{ label: 'GPT-5', from: 'gpt-5', to: 'gpt-5', color: 'bg-amber-100 text-amber-700 hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-400' }
|
{ label: 'GPT-5', from: 'gpt-5', to: 'gpt-5', color: 'bg-amber-100 text-amber-700 hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-400' },
|
||||||
|
{ label: 'GPT-5.1', from: 'gpt-5.1', to: 'gpt-5.1', color: 'bg-orange-100 text-orange-700 hover:bg-orange-200 dark:bg-orange-900/30 dark:text-orange-400' },
|
||||||
|
{ label: 'GPT-5.2', from: 'gpt-5.2', to: 'gpt-5.2', color: 'bg-red-100 text-red-700 hover:bg-red-200 dark:bg-red-900/30 dark:text-red-400' },
|
||||||
|
{ label: 'GPT-5.1 Codex', from: 'gpt-5.1-codex', to: 'gpt-5.1-codex', color: 'bg-cyan-100 text-cyan-700 hover:bg-cyan-200 dark:bg-cyan-900/30 dark:text-cyan-400' }
|
||||||
]
|
]
|
||||||
|
|
||||||
const geminiPresetMappings = [
|
const geminiPresetMappings = [
|
||||||
|
|||||||
@@ -390,7 +390,7 @@ export default {
|
|||||||
opencode: {
|
opencode: {
|
||||||
title: 'OpenCode Example',
|
title: 'OpenCode Example',
|
||||||
subtitle: 'opencode.json',
|
subtitle: 'opencode.json',
|
||||||
hint: 'Config path: ~/.config/opencode/opencode.json (create if not exists). This is an example, adjust model and options as needed.',
|
hint: 'Config path: ~/.config/opencode/opencode.json (or opencode.jsonc), create if not exists. Use default providers (openai/anthropic/google) or custom provider_id. API Key can be configured directly or via /connect command. This is an example, adjust models and options as needed.',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
customKeyLabel: 'Custom Key',
|
customKeyLabel: 'Custom Key',
|
||||||
|
|||||||
@@ -387,7 +387,7 @@ export default {
|
|||||||
opencode: {
|
opencode: {
|
||||||
title: 'OpenCode 配置示例',
|
title: 'OpenCode 配置示例',
|
||||||
subtitle: 'opencode.json',
|
subtitle: 'opencode.json',
|
||||||
hint: '配置文件路径:~/.config/opencode/opencode.json,不存在需手动创建。示例仅供参考,模型与选项可按需调整。',
|
hint: '配置文件路径:~/.config/opencode/opencode.json(或 opencode.jsonc),不存在需手动创建。可使用默认 provider(openai/anthropic/google)或自定义 provider_id。API Key 支持直接配置或通过客户端 /connect 命令配置。示例仅供参考,模型与选项可按需调整。',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
customKeyLabel: '自定义密钥',
|
customKeyLabel: '自定义密钥',
|
||||||
|
|||||||
Reference in New Issue
Block a user