| 1 | package provider |
| 2 | |
| 3 | import ( |
| 4 | "slices" |
| 5 | "strings" |
| 6 | ) |
| 7 | |
| 8 | // OfficialDeepSeekVisionModel is the pinned vision SKU DeepSeek still routes to |
| 9 | // V4.1 Flash. It stays exported for pricing, effort and backfill keying. |
| 10 | const OfficialDeepSeekVisionModel = "deepseek-v4-flash-vision-exp" |
| 11 | |
| 12 | // officialDeepSeekImageModels lists official DeepSeek IDs that accept image |
| 13 | // input natively. This is the single authority for image capability on the |
| 14 | // official endpoint: the capability resolver, the runtime vision gate and the |
| 15 | // local model catalog all consult it, so a new SKU is added in one place. |
| 16 | // |
| 17 | // deepseek-v4-flash and the beta alias are routed to V4.1 Flash for now; drop |
| 18 | // the alias once the vendor closes that transition window. |
| 19 | var officialDeepSeekImageModels = []string{ |
| 20 | "deepseek-flash", |
| 21 | "deepseek-v4.1-flash-expires-on-0910", |
| 22 | "deepseek-v4-flash", |
| 23 | OfficialDeepSeekVisionModel, |
| 24 | } |
| 25 | |
| 26 | // IsOfficialDeepSeekImageModel reports whether model is an official DeepSeek SKU |
| 27 | // with native image input. Matching is case-insensitive and trims space. |
| 28 | func IsOfficialDeepSeekImageModel(model string) bool { |
| 29 | model = strings.TrimSpace(model) |
| 30 | return slices.ContainsFunc(officialDeepSeekImageModels, func(candidate string) bool { |
| 31 | return strings.EqualFold(candidate, model) |
| 32 | }) |
| 33 | } |
| 34 | |
| 35 | // IsOfficialDeepSeekTextModel identifies known text-only models, not future |
| 36 | // SKUs. It gates the official endpoint's hard image block, so a model must stay |
| 37 | // listed until the vendor confirms it accepts images. |
| 38 | func IsOfficialDeepSeekTextModel(model string) bool { |
| 39 | switch strings.ToLower(strings.TrimSpace(model)) { |
| 40 | case "deepseek-v4-pro": |
| 41 | return true |
| 42 | } |
| 43 | return false |
| 44 | } |
| 45 |