Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,32 @@ async function models(args) {
}
}

if (args.includes("--discounts") || args.includes("--discounted")) {
const { fetchDiscountedModels } = await import("./openrouter-api.js")
console.log("Fetching live OpenRouter provider discounts and pricing comparisons...\n")
const discounted = await fetchDiscountedModels()
if (!discounted || !discounted.length) {
console.log("No live discount data available right now.")
return 0
}
console.log("OpenRouter Provider Pricing & Discount Comparison:")
console.log("==================================================")
for (const item of discounted) {
console.log(`\nModel: ${item.slug}`)
for (const e of item.endpoints.slice(0, 4)) {
const isCheapest = e.providerName === item.cheapest.providerName
const tag = isCheapest ? ` (★ ${item.savingsRatio}x CHEAPER)` : ""
console.log(` - ${e.providerName.padEnd(16)} $${e.promptCostPerM.toFixed(2)}/M prompt, $${e.completionCostPerM.toFixed(2)}/M completion${tag}`)
}
}
console.log("\nTo use a discounted provider in Armada:")
console.log(" armada init --openrouter-provider Novita")
console.log("Or add to armada.yaml:")
console.log(" project:")
console.log(" openrouter_providers: [\"Novita\", \"StreamLake\"]")
return 0
}

const refresh = args.includes("--refresh")
// Find the first non-flag arg as a budget candidate.
// Exclude values of flags that take a value (e.g. --cache <path>).
Expand Down
20 changes: 20 additions & 0 deletions src/openrouter-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,23 @@ export async function fetchModelEndpoints(modelSlug) {
return null
}
}

export async function fetchDiscountedModels(modelSlugs = ["z-ai/glm-5.2", "deepseek/deepseek-v4-pro", "minimax/minimax-m3", "xiaomi/mimo-v2.5"]) {
const results = []
for (const slug of modelSlugs) {
const endpoints = await fetchModelEndpoints(slug)
if (!endpoints || endpoints.length < 2) continue
const cheapest = endpoints[0]
const expensive = endpoints[endpoints.length - 1]
const savingsRatio = (expensive.totalCostPerM / (cheapest.totalCostPerM || 0.000001)).toFixed(1)
results.push({
slug,
endpoints,
cheapest,
expensive,
savingsRatio: parseFloat(savingsRatio),
})
}
return results
}