package converter import "strings" // Short-name aliases → actual Cursor model IDs. // Allows users to configure friendly names in OpenCode instead of memorising // exact Cursor IDs like "claude-4.6-sonnet-medium". var shortAlias = map[string]string{ // Claude 4.6 "sonnet-4.6": "claude-4.6-sonnet-medium", "sonnet-4.6-thinking": "claude-4.6-sonnet-medium-thinking", "opus-4.6": "claude-4.6-opus-high", "opus-4.6-thinking": "claude-4.6-opus-high-thinking", "opus-4.6-max": "claude-4.6-opus-max", // Claude 4.5 "sonnet-4.5": "claude-4.5-sonnet", "sonnet-4.5-thinking": "claude-4.5-sonnet-thinking", "opus-4.5": "claude-4.5-opus-high", "opus-4.5-thinking": "claude-4.5-opus-high-thinking", // Claude 4 "sonnet-4": "claude-4-sonnet", "sonnet-4-thinking": "claude-4-sonnet-thinking", // Anthropic API-style names "claude-opus-4-6": "claude-4.6-opus-high", "claude-opus-4.6": "claude-4.6-opus-high", "claude-sonnet-4-6": "claude-4.6-sonnet-medium", "claude-sonnet-4.6": "claude-4.6-sonnet-medium", "claude-opus-4-5": "claude-4.5-opus-high", "claude-opus-4.5": "claude-4.5-opus-high", "claude-sonnet-4-5": "claude-4.5-sonnet", "claude-sonnet-4.5": "claude-4.5-sonnet", "claude-sonnet-4": "claude-4-sonnet", "claude-opus-4-6-thinking": "claude-4.6-opus-high-thinking", "claude-sonnet-4-6-thinking": "claude-4.6-sonnet-medium-thinking", "claude-opus-4-5-thinking": "claude-4.5-opus-high-thinking", "claude-sonnet-4-5-thinking": "claude-4.5-sonnet-thinking", "claude-sonnet-4-thinking": "claude-4-sonnet-thinking", // Old Anthropic date-based names "claude-sonnet-4-20250514": "claude-4-sonnet", "claude-opus-4-20250514": "claude-4.5-opus-high", // GPT shortcuts "gpt-5.4": "gpt-5.4-medium", "gpt-5.4-fast": "gpt-5.4-medium-fast", // Gemini "gemini-3.1": "gemini-3.1-pro", } // ResolveToCursorModel maps a user-supplied model name to its Cursor model ID. // If the name is already a valid Cursor ID, it passes through unchanged. func ResolveToCursorModel(requested string) string { if requested == "" { return "" } key := strings.ToLower(strings.TrimSpace(requested)) if mapped, ok := shortAlias[key]; ok { return mapped } return requested } type aliasEntry struct { CursorID string AliasID string Name string } var reverseAliases = []aliasEntry{ {"claude-4.6-opus-high", "claude-opus-4-6", "Claude 4.6 Opus"}, {"claude-4.6-opus-high-thinking", "claude-opus-4-6-thinking", "Claude 4.6 Opus (Thinking)"}, {"claude-4.6-sonnet-medium", "claude-sonnet-4-6", "Claude 4.6 Sonnet"}, {"claude-4.6-sonnet-medium-thinking", "claude-sonnet-4-6-thinking", "Claude 4.6 Sonnet (Thinking)"}, {"claude-4.5-opus-high", "claude-opus-4-5", "Claude 4.5 Opus"}, {"claude-4.5-opus-high-thinking", "claude-opus-4-5-thinking", "Claude 4.5 Opus (Thinking)"}, {"claude-4.5-sonnet", "claude-sonnet-4-5", "Claude 4.5 Sonnet"}, {"claude-4.5-sonnet-thinking", "claude-sonnet-4-5-thinking", "Claude 4.5 Sonnet (Thinking)"}, {"claude-4-sonnet", "claude-sonnet-4", "Claude 4 Sonnet"}, {"claude-4-sonnet-thinking", "claude-sonnet-4-thinking", "Claude 4 Sonnet (Thinking)"}, } // GetAnthropicModelAliases returns alias entries for models available in Cursor, // so that /v1/models shows both Cursor IDs and friendly Anthropic-style names. func GetAnthropicModelAliases(availableCursorIDs []string) []struct { ID string Name string } { set := make(map[string]bool, len(availableCursorIDs)) for _, id := range availableCursorIDs { set[id] = true } var result []struct { ID string Name string } for _, a := range reverseAliases { if set[a.CursorID] { result = append(result, struct { ID string Name string }{ID: a.AliasID, Name: a.Name}) } } return result }