| 50 | } |
| 51 | |
| 52 | function mergeCost(base: ModelV2Info["cost"], override: ModelsDev.Model["cost"] | undefined) { |
| 53 | if (!override) return base |
| 54 | const next = cost(override) |
| 55 | const [baseDefault, ...baseTiers] = base |
| 56 | const [nextDefault, ...nextTiers] = next |
| 57 | const tierKey = (item: ModelV2Info["cost"][number]) => `${item.tier?.type ?? "base"}:${item.tier?.size ?? 0}` |
| 58 | const merge = (left: ModelV2Info["cost"][number], right: ModelV2Info["cost"][number]) => ({ |
| 59 | ...left, |
| 60 | ...right, |
| 61 | tier: right.tier ?? left.tier, |
| 62 | cache: { ...left.cache, ...right.cache }, |
| 63 | }) |
| 64 | const tiers = new Map(baseTiers.map((item) => [tierKey(item), item])) |
| 65 | for (const item of nextTiers) { |
| 66 | const current = tiers.get(tierKey(item)) |
| 67 | tiers.set(tierKey(item), current ? merge(current, item) : item) |
| 68 | } |
| 69 | return [merge(baseDefault ?? { input: 0, output: 0, cache: { read: 0, write: 0 } }, nextDefault), ...tiers.values()] |
| 70 | } |
| 71 | |
| 72 | function modeName(model: ModelsDev.Model, mode: string) { |
| 73 | return `${model.name} ${mode.charAt(0).toUpperCase()}${mode.slice(1)}` |