|
| 1 | +import type { Model } from "~/services/copilot/get-models" |
| 2 | + |
| 3 | +import { state } from "~/lib/state" |
| 4 | + |
| 5 | +export const findEndpointModel = (sdkModelId: string): Model | undefined => { |
| 6 | + const models = state.models?.data ?? [] |
| 7 | + const exactMatch = models.find((m) => m.id === sdkModelId) |
| 8 | + if (exactMatch) { |
| 9 | + return exactMatch |
| 10 | + } |
| 11 | + |
| 12 | + const normalized = _normalizeSdkModelId(sdkModelId) |
| 13 | + if (!normalized) { |
| 14 | + return undefined |
| 15 | + } |
| 16 | + |
| 17 | + const modelName = `claude-${normalized.family}-${normalized.version}` |
| 18 | + const model = models.find((m) => m.id === modelName) |
| 19 | + if (model) { |
| 20 | + return model |
| 21 | + } |
| 22 | + |
| 23 | + return undefined |
| 24 | +} |
| 25 | + |
| 26 | +/** |
| 27 | + * Normalizes an SDK model ID to extract the model family and version. |
| 28 | + * this method from github copilot extension |
| 29 | + * Examples: |
| 30 | + * - "claude-opus-4-5-20251101" -> { family: "opus", version: "4.5" } |
| 31 | + * - "claude-3-5-sonnet-20241022" -> { family: "sonnet", version: "3.5" } |
| 32 | + * - "claude-sonnet-4-20250514" -> { family: "sonnet", version: "4" } |
| 33 | + * - "claude-haiku-3-5-20250514" -> { family: "haiku", version: "3.5" } |
| 34 | + * - "claude-haiku-4.5" -> { family: "haiku", version: "4.5" } |
| 35 | + */ |
| 36 | +const _normalizeSdkModelId = ( |
| 37 | + sdkModelId: string, |
| 38 | +): { family: string; version: string } | undefined => { |
| 39 | + const lower = sdkModelId.toLowerCase() |
| 40 | + |
| 41 | + // Strip date suffix (8 digits at the end) |
| 42 | + const withoutDate = lower.replace(/-\d{8}$/, "") |
| 43 | + |
| 44 | + // Pattern 1: claude-{family}-{major}-{minor} (e.g., claude-opus-4-5, claude-haiku-3-5) |
| 45 | + const pattern1 = withoutDate.match(/^claude-(\w+)-(\d+)-(\d+)$/) |
| 46 | + if (pattern1) { |
| 47 | + return { family: pattern1[1], version: `${pattern1[2]}.${pattern1[3]}` } |
| 48 | + } |
| 49 | + |
| 50 | + // Pattern 2: claude-{major}-{minor}-{family} (e.g., claude-3-5-sonnet) |
| 51 | + const pattern2 = withoutDate.match(/^claude-(\d+)-(\d+)-(\w+)$/) |
| 52 | + if (pattern2) { |
| 53 | + return { family: pattern2[3], version: `${pattern2[1]}.${pattern2[2]}` } |
| 54 | + } |
| 55 | + |
| 56 | + // Pattern 3: claude-{family}-{major}.{minor} (e.g., claude-haiku-4.5) |
| 57 | + const pattern3 = withoutDate.match(/^claude-(\w+)-(\d+)\.(\d+)$/) |
| 58 | + if (pattern3) { |
| 59 | + return { family: pattern3[1], version: `${pattern3[2]}.${pattern3[3]}` } |
| 60 | + } |
| 61 | + |
| 62 | + // Pattern 4: claude-{family}-{major} (e.g., claude-sonnet-4) |
| 63 | + const pattern4 = withoutDate.match(/^claude-(\w+)-(\d+)$/) |
| 64 | + if (pattern4) { |
| 65 | + return { family: pattern4[1], version: pattern4[2] } |
| 66 | + } |
| 67 | + |
| 68 | + // Pattern 5: claude-{major}-{family} (e.g., claude-3-opus) |
| 69 | + const pattern5 = withoutDate.match(/^claude-(\d+)-(\w+)$/) |
| 70 | + if (pattern5) { |
| 71 | + return { family: pattern5[2], version: pattern5[1] } |
| 72 | + } |
| 73 | + |
| 74 | + return undefined |
| 75 | +} |
0 commit comments