const priorityProfiles = {
fastAndCheap: {
speed: 0.55,
cost: 0.35,
quality: 0.1,
},
qualityAndCost: {
speed: 0.15,
cost: 0.3,
quality: 0.55,
},
balanced: {
speed: 0.33,
cost: 0.33,
quality: 0.34,
},
};
const resolutionRanks = new Map([
["480p", 1],
["720p", 2],
["1080p", 3],
["4K", 4],
]);
function getResolutionRank(model) {
return Math.max(
0,
...(model.supported_resolutions ?? []).map((resolution) => {
return resolutionRanks.get(resolution) ?? 0;
}),
);
}
function getSpeedScore(model) {
const id = model.id.toLowerCase();
if (id.includes("fast")) return 1;
if (id.includes("lite") || id.includes("std")) return 0.8;
if (id.includes("pro") || id.includes("o1")) return 0.35;
return 0.55;
}
function normalize(value, min, max, invert = false) {
if (!Number.isFinite(value) || max === min) {
return 0.5;
}
const score = (value - min) / (max - min);
return invert ? 1 - score : score;
}
function scoreVideoModels(models, weights) {
const prices = models.map(getLowestAdvertisedPrice).filter(Number.isFinite);
const minPrice = prices.length > 0 ? Math.min(...prices) : 0;
const maxPrice = prices.length > 0 ? Math.max(...prices) : 0;
const maxResolutionRank = Math.max(0, ...models.map(getResolutionRank));
return models
.map((model) => {
const price = getLowestAdvertisedPrice(model);
const speedScore = getSpeedScore(model);
const costScore = Number.isFinite(price)
? normalize(price, minPrice, maxPrice, true)
: 0;
const qualityScore =
maxResolutionRank === 0 ? 0.5 : getResolutionRank(model) / maxResolutionRank;
const score =
weights.speed * speedScore +
weights.cost * costScore +
weights.quality * qualityScore;
return {
model,
id: model.id,
score: Number(score.toFixed(3)),
lowest_advertised_price: price,
speed_score: Number(speedScore.toFixed(3)),
cost_score: Number(costScore.toFixed(3)),
quality_score: Number(qualityScore.toFixed(3)),
};
})
.sort((first, second) => second.score - first.score);
}
function summarizeScores(rankedModels) {
return rankedModels.slice(0, 4).map(({ model: _model, ...summary }) => {
return summary;
});
}
const fastAndCheapModels = scoreVideoModels(
matchingModels,
priorityProfiles.fastAndCheap,
);
const qualityAndCostModels = scoreVideoModels(
matchingModels,
priorityProfiles.qualityAndCost,
);
const model = fastAndCheapModels[0]?.model;
if (!model) {
throw new Error("No scored video model found.");
}
console.log(
JSON.stringify(
{
fast_and_cheap: summarizeScores(fastAndCheapModels),
quality_and_cost: summarizeScores(qualityAndCostModels),
},
null,
2,
),
);
console.log(`Use ${model.id}`);