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.7 "opus-4.7": "claude-opus-4-7-high", "opus-4.7-thinking": "claude-opus-4-7-thinking-high", "opus-4.7-low": "claude-opus-4-7-low", "opus-4.7-medium": "claude-opus-4-7-medium", "opus-4.7-high": "claude-opus-4-7-high", "opus-4.7-xhigh": "claude-opus-4-7-xhigh", "opus-4.7-max": "claude-opus-4-7-max", // 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 → Cursor IDs // Claude 4.7 "claude-opus-4-7": "claude-opus-4-7-high", "claude-opus-4.7": "claude-opus-4-7-high", "claude-opus-4-7-thinking": "claude-opus-4-7-thinking-high", "claude-opus-4.7-thinking": "claude-opus-4-7-thinking-high", // Claude 4.6 "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-6-thinking": "claude-4.6-opus-high-thinking", "claude-sonnet-4-6-thinking": "claude-4.6-sonnet-medium-thinking", // Claude 4.5 "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-opus-4-5-thinking": "claude-4.5-opus-high-thinking", "claude-sonnet-4-5-thinking": "claude-4.5-sonnet-thinking", // Claude 4 "claude-sonnet-4": "claude-4-sonnet", "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.7 — Cursor uses "claude-opus-4-7-*" natively, add friendly aliases {"claude-opus-4-7-low", "claude-opus-4.7-low", "Claude Opus 4.7 (Low)"}, {"claude-opus-4-7-medium", "claude-opus-4.7-medium", "Claude Opus 4.7 (Medium)"}, {"claude-opus-4-7-high", "claude-opus-4.7-high", "Claude Opus 4.7"}, {"claude-opus-4-7-xhigh", "claude-opus-4.7-xhigh", "Claude Opus 4.7 (XHigh)"}, {"claude-opus-4-7-max", "claude-opus-4.7-max", "Claude Opus 4.7 (Max)"}, {"claude-opus-4-7-thinking-low", "claude-opus-4.7-thinking-low", "Claude Opus 4.7 Thinking (Low)"}, {"claude-opus-4-7-thinking-medium", "claude-opus-4.7-thinking-medium", "Claude Opus 4.7 Thinking (Medium)"}, {"claude-opus-4-7-thinking-high", "claude-opus-4.7-thinking-high", "Claude Opus 4.7 Thinking"}, {"claude-opus-4-7-thinking-xhigh", "claude-opus-4.7-thinking-xhigh", "Claude Opus 4.7 Thinking (XHigh)"}, {"claude-opus-4-7-thinking-max", "claude-opus-4.7-thinking-max", "Claude Opus 4.7 Thinking (Max)"}, // Claude 4.6 {"claude-4.6-opus-high", "claude-opus-4-6", "Claude Opus 4.6"}, {"claude-4.6-opus-high-thinking", "claude-opus-4-6-thinking", "Claude Opus 4.6 (Thinking)"}, {"claude-4.6-opus-max", "claude-opus-4-6-max", "Claude Opus 4.6 (Max)"}, {"claude-4.6-opus-max-thinking", "claude-opus-4-6-max-thinking", "Claude Opus 4.6 Max (Thinking)"}, {"claude-4.6-sonnet-medium", "claude-sonnet-4-6", "Claude Sonnet 4.6"}, {"claude-4.6-sonnet-medium-thinking", "claude-sonnet-4-6-thinking", "Claude Sonnet 4.6 (Thinking)"}, // Claude 4.5 {"claude-4.5-opus-high", "claude-opus-4-5", "Claude Opus 4.5"}, {"claude-4.5-opus-high-thinking", "claude-opus-4-5-thinking", "Claude Opus 4.5 (Thinking)"}, {"claude-4.5-sonnet", "claude-sonnet-4-5", "Claude Sonnet 4.5"}, {"claude-4.5-sonnet-thinking", "claude-sonnet-4-5-thinking", "Claude Sonnet 4.5 (Thinking)"}, // Claude 4 {"claude-4-sonnet", "claude-sonnet-4", "Claude Sonnet 4"}, {"claude-4-sonnet-thinking", "claude-sonnet-4-thinking", "Claude Sonnet 4 (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 }