| 40 | * normalizes CLI input to a family name. |
| 41 | */ |
| 42 | export function resolveModel(input: string): Model | null { |
| 43 | const s = input.trim(); |
| 44 | if (!s) return null; |
| 45 | |
| 46 | // Exact match first |
| 47 | if ((ALL_MODEL_NAMES as readonly string[]).includes(s)) { |
| 48 | return s as Model; |
| 49 | } |
| 50 | |
| 51 | // Family heuristics |
| 52 | if (/^gpt-5\.4(-|$)/.test(s)) return 'gpt-5.4'; |
| 53 | if (/^gpt(-|$)/.test(s)) return 'gpt'; |
| 54 | if (/^o[0-9]+(-|$)/.test(s)) return 'o-series'; |
| 55 | if (/^claude-opus-4-7(-|$)/.test(s)) return 'opus-4-7'; |
| 56 | if (/^claude(-|$)/.test(s)) return 'claude'; |
| 57 | if (/^gemini(-|$)/.test(s)) return 'gemini'; |
| 58 | |
| 59 | return null; |
| 60 | } |
| 61 | |
| 62 | /** |
| 63 | * Validate a string against ALL_MODEL_NAMES. Used by host-config validators |