diff --git a/src/cli.js b/src/cli.js index ec93e39..9aeb724 100755 --- a/src/cli.js +++ b/src/cli.js @@ -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 ). diff --git a/src/openrouter-api.js b/src/openrouter-api.js index f3e2862..42d82fa 100644 --- a/src/openrouter-api.js +++ b/src/openrouter-api.js @@ -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 +} +