diff --git a/internal/config/model_alias_test.go b/internal/config/model_alias_test.go index 459edcc..573c6e3 100644 --- a/internal/config/model_alias_test.go +++ b/internal/config/model_alias_test.go @@ -75,20 +75,6 @@ func TestResolveExpandedHistoricalAliases(t *testing.T) { } } -func TestResolveModelHeuristicReasoner(t *testing.T) { - got, ok := ResolveModel(nil, "o3-super") - if !ok || got != "deepseek-v4-pro" { - t.Fatalf("expected heuristic reasoner, got ok=%v model=%q", ok, got) - } -} - -func TestResolveModelHeuristicReasonerNoThinking(t *testing.T) { - got, ok := ResolveModel(nil, "o3-super-nothinking") - if !ok || got != "deepseek-v4-pro-nothinking" { - t.Fatalf("expected heuristic reasoner nothinking, got ok=%v model=%q", ok, got) - } -} - func TestResolveModelUnknown(t *testing.T) { _, ok := ResolveModel(nil, "totally-custom-model") if ok { @@ -96,6 +82,13 @@ func TestResolveModelUnknown(t *testing.T) { } } +func TestResolveModelUnknownKnownFamilyName(t *testing.T) { + _, ok := ResolveModel(nil, "gpt-5.5-pro-search") + if ok { + t.Fatal("expected unknown known-family model to fail resolve without alias") + } +} + func TestResolveModelRejectsLegacyDeepSeekIDs(t *testing.T) { legacyModels := []string{ "deepseek-chat", @@ -151,13 +144,6 @@ func TestResolveModelCustomAliasToVision(t *testing.T) { } } -func TestResolveModelHeuristicVisionIgnoresSearchSuffix(t *testing.T) { - got, ok := ResolveModel(nil, "gemini-vision-search") - if !ok || got != "deepseek-v4-vision" { - t.Fatalf("expected heuristic vision alias to resolve without search variant, got ok=%v model=%q", ok, got) - } -} - func TestClaudeModelsResponsePaginationFields(t *testing.T) { resp := ClaudeModelsResponse() if _, ok := resp["first_id"]; !ok { diff --git a/internal/config/models.go b/internal/config/models.go index 555fad2..f583749 100644 --- a/internal/config/models.go +++ b/internal/config/models.go @@ -214,26 +214,10 @@ func ResolveModel(store ModelAliasReader, requested string) (string, bool) { return mapped, true } baseModel, noThinking := splitNoThinkingModel(model) - resolvedModel, ok := resolveCanonicalModel(aliases, baseModel) - if !ok { - return "", false - } - return withNoThinkingVariant(resolvedModel, noThinking), true -} - -func isRetiredHistoricalModel(model string) bool { - switch { - case strings.HasPrefix(model, "claude-1."): - return true - case strings.HasPrefix(model, "claude-2."): - return true - case strings.HasPrefix(model, "claude-instant-"): - return true - case strings.HasPrefix(model, "gpt-3.5"): - return true - default: - return false + if mapped, ok := aliases[baseModel]; ok && IsSupportedDeepSeekModel(mapped) { + return withNoThinkingVariant(mapped, noThinking), true } + return "", false } func lower(s string) string { @@ -315,58 +299,3 @@ func loadModelAliases(store ModelAliasReader) map[string]string { } return aliases } - -func resolveCanonicalModel(aliases map[string]string, model string) (string, bool) { - model = lower(strings.TrimSpace(model)) - if model == "" { - return "", false - } - if isRetiredHistoricalModel(model) { - return "", false - } - if IsSupportedDeepSeekModel(model) { - return model, true - } - if mapped, ok := aliases[model]; ok && IsSupportedDeepSeekModel(mapped) { - return mapped, true - } - if strings.HasPrefix(model, "deepseek-") { - return "", false - } - - knownFamily := false - for _, prefix := range []string{ - "gpt-", "o1", "o3", "claude-", "gemini-", "llama-", "qwen-", "mistral-", "command-", - } { - if strings.HasPrefix(model, prefix) { - knownFamily = true - break - } - } - if !knownFamily { - return "", false - } - - useVision := strings.Contains(model, "vision") - useReasoner := strings.Contains(model, "reason") || - strings.Contains(model, "reasoner") || - strings.HasPrefix(model, "o1") || - strings.HasPrefix(model, "o3") || - strings.Contains(model, "opus") || - strings.Contains(model, "slow") || - strings.Contains(model, "r1") - useSearch := strings.Contains(model, "search") - - switch { - case useVision: - return "deepseek-v4-vision", true - case useReasoner && useSearch: - return "deepseek-v4-pro-search", true - case useReasoner: - return "deepseek-v4-pro", true - case useSearch: - return "deepseek-v4-flash-search", true - default: - return "deepseek-v4-flash", true - } -}