From b9c53195a8017d1026ff2982f9a8224709083180 Mon Sep 17 00:00:00 2001 From: 1bcMax Date: Mon, 19 Oct 2026 23:37:54 -0500 Subject: [PATCH 1/2] fix(estimate): chat is free by MCP's FREE_CHAT_MODELS, not by an nvidia/ prefix Mirror @blockrun/mcp FREE_CHAT_MODELS (32 ids, incl. cohere/north-mini-code, poolside/laguna-xs-2.1, nvidia/muse-glimmer-30b and the account-sheet $0 NVIDIA ids). Bare spellings count, except bare deepseek-v4-pro, which is the paid DeepSeek model. An explicit model wins over mode, as in the MCP. --- lib/estimate.js | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/lib/estimate.js b/lib/estimate.js index 14de8b9..68cea13 100644 --- a/lib/estimate.js +++ b/lib/estimate.js @@ -90,6 +90,35 @@ const SPEECH_RATE = { const SPEECH_DEFAULT_RATE = 0.05; // elevenlabs/flash-v2.5 (the MCP default) const SOUND_EFFECT_COST = 0.0525; +// Chat models billed $0 — mirrors @blockrun/mcp FREE_CHAT_MODELS +// (src/utils/constants.ts), refreshed 2026-10-20. Membership by id, not +// vendor: cohere/ and poolside/ have $0 models, and not every nvidia/ id is +// guaranteed free. Sources: GET /v1/models billing_mode "free" and the account +// price sheet (blockrun.ai/api/pricing) at $0. +const FREE_CHAT_MODELS = new Set([ + "nvidia/gpt-oss-20b", "nvidia/nemotron-3-super-120b", "nvidia/llama-3.2-11b-vision", + "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning", "cohere/north-mini-code", "poolside/laguna-xs-2.1", + "nvidia/gpt-oss-120b", "nvidia/nemotron-3-ultra-550b", "nvidia/step-3.7-flash", "nvidia/mistral-nemotron", + "nvidia/nemotron-nano-12b-v2-vl", "nvidia/nemotron-nano-9b-v2", "nvidia/nemotron-3.5-lightning", + "nvidia/muse-glimmer-30b", "nvidia/gemma-4-31b", "nvidia/nemotron-3-super-120b-a12b-free", + "nvidia/qwen3.5-397b-a17b", "nvidia/nemotron-ultra-253b", "nvidia/nemotron-super-49b", "nvidia/deepseek-v3.2", + "nvidia/deepseek-v4-pro", "nvidia/deepseek-v4-flash", "nvidia/nemotron-3-nano-omni-nim", + "nvidia/mistral-large-3-675b", "nvidia/qwen3-coder-480b", "nvidia/devstral-2-123b", "nvidia/glm-4.7", + "nvidia/llama-4-maverick", "nvidia/qwen3-next-80b-a3b-instruct", "nvidia/qwen3.5-122b-a10b", + "nvidia/seed-oss-36b", "nvidia/mistral-small-4-119b", +]); +// Bare spellings the gateway also accepts. A free id whose bare name belongs +// to a PAID model is excluded: bare "deepseek-v4-pro" is deepseek/deepseek-v4-pro +// ($1.32/$3.96), not the $0 NVIDIA mirror (MCP FREE_SHADOWED_BY_PAID). +const FREE_SHADOWED_BY_PAID = new Set(["nvidia/deepseek-v4-pro"]); +const FREE_CHAT_BARE = new Set( + [...FREE_CHAT_MODELS].filter((id) => !FREE_SHADOWED_BY_PAID.has(id)).map((id) => id.slice(id.indexOf("/") + 1)), +); +function isFreeChatModel(model) { + const id = String(model || "").trim(); + return FREE_CHAT_MODELS.has(id) || (!id.includes("/") && FREE_CHAT_BARE.has(id)); +} + // Whether `size` is in `model`'s large tier (see IMAGE_LARGE_THRESHOLD / // IMAGE_LARGE_MIN_DIM). Unparseable sizes price at the base. function isLargerThanBase(model, size) { @@ -147,7 +176,9 @@ function estimate(toolName, input = {}) { return { usd: paid ? 0.001 : 0, label: `price · ${cat || "crypto"}${paid ? "" : " (free)"}` }; } case "chat": { - const free = input.mode === "free" || /^nvidia\//.test(input.model || ""); + // An explicit model wins over mode, as in the MCP: mode is ignored when + // model is set. + const free = input.model ? isFreeChatModel(input.model) : input.mode === "free"; return { usd: free ? 0 : 0.005, label: `chat${free ? " (free tier)" : ""}` }; } // Wallet + models are always free; data tools (if a fuller profile is used) From 714a0bd17b28fa5b5c2627cee8df8bd7a478ef28 Mon Sep 17 00:00:00 2001 From: 1bcMax Date: Mon, 19 Oct 2026 23:43:19 -0500 Subject: [PATCH 2/2] fix(estimate): drop nvidia/deepseek-v4-pro and -flash from the free list The gateways retired both (unknown-model 400), mirroring blockrun-mcp#181. Bare deepseek-v4-pro still estimates as the paid DeepSeek model. --- lib/estimate.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/estimate.js b/lib/estimate.js index 68cea13..3559d40 100644 --- a/lib/estimate.js +++ b/lib/estimate.js @@ -102,15 +102,20 @@ const FREE_CHAT_MODELS = new Set([ "nvidia/nemotron-nano-12b-v2-vl", "nvidia/nemotron-nano-9b-v2", "nvidia/nemotron-3.5-lightning", "nvidia/muse-glimmer-30b", "nvidia/gemma-4-31b", "nvidia/nemotron-3-super-120b-a12b-free", "nvidia/qwen3.5-397b-a17b", "nvidia/nemotron-ultra-253b", "nvidia/nemotron-super-49b", "nvidia/deepseek-v3.2", - "nvidia/deepseek-v4-pro", "nvidia/deepseek-v4-flash", "nvidia/nemotron-3-nano-omni-nim", + "nvidia/nemotron-3-nano-omni-nim", "nvidia/mistral-large-3-675b", "nvidia/qwen3-coder-480b", "nvidia/devstral-2-123b", "nvidia/glm-4.7", "nvidia/llama-4-maverick", "nvidia/qwen3-next-80b-a3b-instruct", "nvidia/qwen3.5-122b-a10b", "nvidia/seed-oss-36b", "nvidia/mistral-small-4-119b", ]); +// nvidia/deepseek-v4-pro and nvidia/deepseek-v4-flash are NOT here: the +// gateways retired both (unknown-model 400; blockrun#848 and its follow-up). +// // Bare spellings the gateway also accepts. A free id whose bare name belongs -// to a PAID model is excluded: bare "deepseek-v4-pro" is deepseek/deepseek-v4-pro -// ($1.32/$3.96), not the $0 NVIDIA mirror (MCP FREE_SHADOWED_BY_PAID). -const FREE_SHADOWED_BY_PAID = new Set(["nvidia/deepseek-v4-pro"]); +// to a PAID model must be listed here and excluded, so the paid model wins +// the spelling (MCP FREE_SHADOWED_BY_PAID). Empty since the nvidia DeepSeek +// mirror was retired; bare "deepseek-v4-pro" is the paid +// deepseek/deepseek-v4-pro ($1.32/$3.96) and is not in the free set at all. +const FREE_SHADOWED_BY_PAID = new Set([]); const FREE_CHAT_BARE = new Set( [...FREE_CHAT_MODELS].filter((id) => !FREE_SHADOWED_BY_PAID.has(id)).map((id) => id.slice(id.indexOf("/") + 1)), );