From e27b0adbc80a2c0f47320449bd7145de6eb2dd0c Mon Sep 17 00:00:00 2001 From: erio Date: Sat, 4 Apr 2026 14:07:19 +0800 Subject: [PATCH] refactor: remove resolveOpenAIUpstreamModel, use normalizeCodexModel directly Eliminates unnecessary indirection layer. The wrapper function only called normalizeCodexModel with a special case for "gpt 5.3 codex spark" (space-separated variant) that is no longer needed. All call sites now use normalizeCodexModel directly. --- .../service/openai_compat_prompt_cache_key.go | 8 +++--- .../openai_gateway_chat_completions.go | 2 +- .../service/openai_gateway_messages.go | 2 +- .../service/openai_gateway_service.go | 2 +- .../internal/service/openai_model_mapping.go | 28 ++----------------- .../service/openai_model_mapping_test.go | 18 ++++++------ .../internal/service/openai_ws_forwarder.go | 4 +-- 7 files changed, 20 insertions(+), 44 deletions(-) diff --git a/backend/internal/service/openai_compat_prompt_cache_key.go b/backend/internal/service/openai_compat_prompt_cache_key.go index 46381838..88e16a4d 100644 --- a/backend/internal/service/openai_compat_prompt_cache_key.go +++ b/backend/internal/service/openai_compat_prompt_cache_key.go @@ -10,8 +10,8 @@ import ( const compatPromptCacheKeyPrefix = "compat_cc_" func shouldAutoInjectPromptCacheKeyForCompat(model string) bool { - switch resolveOpenAIUpstreamModel(strings.TrimSpace(model)) { - case "gpt-5.4", "gpt-5.3-codex", "gpt-5.3-codex-spark": + switch normalizeCodexModel(strings.TrimSpace(model)) { + case "gpt-5.4", "gpt-5.3-codex": return true default: return false @@ -23,9 +23,9 @@ func deriveCompatPromptCacheKey(req *apicompat.ChatCompletionsRequest, mappedMod return "" } - normalizedModel := resolveOpenAIUpstreamModel(strings.TrimSpace(mappedModel)) + normalizedModel := normalizeCodexModel(strings.TrimSpace(mappedModel)) if normalizedModel == "" { - normalizedModel = resolveOpenAIUpstreamModel(strings.TrimSpace(req.Model)) + normalizedModel = normalizeCodexModel(strings.TrimSpace(req.Model)) } if normalizedModel == "" { normalizedModel = strings.TrimSpace(req.Model) diff --git a/backend/internal/service/openai_gateway_chat_completions.go b/backend/internal/service/openai_gateway_chat_completions.go index 1d5bf0d0..be076cc0 100644 --- a/backend/internal/service/openai_gateway_chat_completions.go +++ b/backend/internal/service/openai_gateway_chat_completions.go @@ -46,7 +46,7 @@ func (s *OpenAIGatewayService) ForwardAsChatCompletions( // 2. Resolve model mapping early so compat prompt_cache_key injection can // derive a stable seed from the final upstream model family. billingModel := resolveOpenAIForwardModel(account, originalModel, defaultMappedModel) - upstreamModel := resolveOpenAIUpstreamModel(billingModel) + upstreamModel := normalizeCodexModel(billingModel) promptCacheKey = strings.TrimSpace(promptCacheKey) compatPromptCacheInjected := false diff --git a/backend/internal/service/openai_gateway_messages.go b/backend/internal/service/openai_gateway_messages.go index 8c389556..dd416269 100644 --- a/backend/internal/service/openai_gateway_messages.go +++ b/backend/internal/service/openai_gateway_messages.go @@ -62,7 +62,7 @@ func (s *OpenAIGatewayService) ForwardAsAnthropic( // 3. Model mapping billingModel := resolveOpenAIForwardModel(account, normalizedModel, defaultMappedModel) - upstreamModel := resolveOpenAIUpstreamModel(billingModel) + upstreamModel := normalizeCodexModel(billingModel) responsesReq.Model = upstreamModel logger.L().Debug("openai messages: model mapping applied", diff --git a/backend/internal/service/openai_gateway_service.go b/backend/internal/service/openai_gateway_service.go index f12177f3..28c4b1f4 100644 --- a/backend/internal/service/openai_gateway_service.go +++ b/backend/internal/service/openai_gateway_service.go @@ -1939,7 +1939,7 @@ func (s *OpenAIGatewayService) Forward(ctx context.Context, c *gin.Context, acco // 针对所有 OpenAI 账号执行 Codex 模型名规范化,确保上游识别一致。 if model, ok := reqBody["model"].(string); ok { - upstreamModel = resolveOpenAIUpstreamModel(model) + upstreamModel = normalizeCodexModel(model) if upstreamModel != "" && upstreamModel != model { logger.LegacyPrintf("service.openai_gateway", "[OpenAI] Upstream model resolved: %s -> %s (account: %s, type: %s, isCodexCLI: %v)", model, upstreamModel, account.Name, account.Type, isCodexCLI) diff --git a/backend/internal/service/openai_model_mapping.go b/backend/internal/service/openai_model_mapping.go index 4f8c094b..9bf3fba3 100644 --- a/backend/internal/service/openai_model_mapping.go +++ b/backend/internal/service/openai_model_mapping.go @@ -1,10 +1,8 @@ package service -import "strings" - -// resolveOpenAIForwardModel resolves the account/group mapping result for -// OpenAI-compatible forwarding. Group-level default mapping only applies when -// the account itself did not match any explicit model_mapping rule. +// resolveOpenAIForwardModel determines the upstream model for OpenAI-compatible +// forwarding. Group-level default mapping only applies when the account itself +// did not match any explicit model_mapping rule. func resolveOpenAIForwardModel(account *Account, requestedModel, defaultMappedModel string) string { if account == nil { if defaultMappedModel != "" { @@ -19,23 +17,3 @@ func resolveOpenAIForwardModel(account *Account, requestedModel, defaultMappedMo } return mappedModel } - -func resolveOpenAIUpstreamModel(model string) string { - if isBareGPT53CodexSparkModel(model) { - return "gpt-5.3-codex-spark" - } - return normalizeCodexModel(strings.TrimSpace(model)) -} - -func isBareGPT53CodexSparkModel(model string) bool { - modelID := strings.TrimSpace(model) - if modelID == "" { - return false - } - if strings.Contains(modelID, "/") { - parts := strings.Split(modelID, "/") - modelID = parts[len(parts)-1] - } - normalized := strings.ToLower(strings.TrimSpace(modelID)) - return normalized == "gpt-5.3-codex-spark" || normalized == "gpt 5.3 codex spark" -} diff --git a/backend/internal/service/openai_model_mapping_test.go b/backend/internal/service/openai_model_mapping_test.go index 42f58b37..a88c5825 100644 --- a/backend/internal/service/openai_model_mapping_test.go +++ b/backend/internal/service/openai_model_mapping_test.go @@ -74,30 +74,28 @@ func TestResolveOpenAIForwardModel_PreventsClaudeModelFromFallingBackToGpt51(t * Credentials: map[string]any{}, } - withoutDefault := resolveOpenAIUpstreamModel(resolveOpenAIForwardModel(account, "claude-opus-4-6", "")) + withoutDefault := normalizeCodexModel(resolveOpenAIForwardModel(account, "claude-opus-4-6", "")) if withoutDefault != "gpt-5.1" { - t.Fatalf("resolveOpenAIUpstreamModel(...) = %q, want %q", withoutDefault, "gpt-5.1") + t.Fatalf("normalizeCodexModel(...) = %q, want %q", withoutDefault, "gpt-5.1") } - withDefault := resolveOpenAIUpstreamModel(resolveOpenAIForwardModel(account, "claude-opus-4-6", "gpt-5.4")) + withDefault := normalizeCodexModel(resolveOpenAIForwardModel(account, "claude-opus-4-6", "gpt-5.4")) if withDefault != "gpt-5.4" { - t.Fatalf("resolveOpenAIUpstreamModel(...) = %q, want %q", withDefault, "gpt-5.4") + t.Fatalf("normalizeCodexModel(...) = %q, want %q", withDefault, "gpt-5.4") } } -func TestResolveOpenAIUpstreamModel(t *testing.T) { +func TestNormalizeCodexModel(t *testing.T) { cases := map[string]string{ - "gpt-5.3-codex-spark": "gpt-5.3-codex-spark", - "gpt 5.3 codex spark": "gpt-5.3-codex-spark", - " openai/gpt-5.3-codex-spark ": "gpt-5.3-codex-spark", + "gpt-5.3-codex-spark": "gpt-5.3-codex", "gpt-5.3-codex-spark-high": "gpt-5.3-codex", "gpt-5.3-codex-spark-xhigh": "gpt-5.3-codex", "gpt-5.3": "gpt-5.3-codex", } for input, expected := range cases { - if got := resolveOpenAIUpstreamModel(input); got != expected { - t.Fatalf("resolveOpenAIUpstreamModel(%q) = %q, want %q", input, got, expected) + if got := normalizeCodexModel(input); got != expected { + t.Fatalf("normalizeCodexModel(%q) = %q, want %q", input, got, expected) } } } diff --git a/backend/internal/service/openai_ws_forwarder.go b/backend/internal/service/openai_ws_forwarder.go index 1ebe5542..6d45baab 100644 --- a/backend/internal/service/openai_ws_forwarder.go +++ b/backend/internal/service/openai_ws_forwarder.go @@ -2515,7 +2515,7 @@ func (s *OpenAIGatewayService) ProxyResponsesWebSocketFromClient( } normalized = next } - upstreamModel := resolveOpenAIUpstreamModel(account.GetMappedModel(originalModel)) + upstreamModel := normalizeCodexModel(account.GetMappedModel(originalModel)) if upstreamModel != originalModel { next, setErr := applyPayloadMutation(normalized, "model", upstreamModel) if setErr != nil { @@ -2773,7 +2773,7 @@ func (s *OpenAIGatewayService) ProxyResponsesWebSocketFromClient( mappedModel := "" var mappedModelBytes []byte if originalModel != "" { - mappedModel = resolveOpenAIUpstreamModel(account.GetMappedModel(originalModel)) + mappedModel = normalizeCodexModel(account.GetMappedModel(originalModel)) needModelReplace = mappedModel != "" && mappedModel != originalModel if needModelReplace { mappedModelBytes = []byte(mappedModel)