fix(llm): report zero cost for OpenRouter free-tier models - #613
Conversation
OpenRouter models with the `:free` suffix (e.g. `stepfun/step-3.5-flash:free`)
and the `openrouter/free` router were falling through to `default_cost()`,
which reports GPT-4o pricing (~$2.50/$10.00 per 1M tokens) instead of $0.
Root cause: `model_cost()` strips the provider prefix via `rsplit_once('/')`,
leaving identifiers like `step-3.5-flash:free` or `free` that don't match any
known model or the `is_local_model()` heuristic.
Fix: add an early return before prefix stripping that checks for the `:free`
suffix and the bare `free` / `openrouter/free` identifiers, returning zero cost.
Tests: 4 new test cases covering the `:free` suffix with various providers,
the `openrouter/free` router, and the bare `free` edge case.
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request resolves an issue where OpenRouter free-tier models were incorrectly reporting non-zero costs in the UI. By introducing an early cost calculation check for specific free model identifiers, the system now accurately reflects zero cost for these models, improving the precision of cost reporting for users utilizing free-tier services. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request addresses an issue where OpenRouter free-tier models were incorrectly assigned a cost. The change adds a check at the beginning of the model_cost function to identify free models by their ID and return a zero cost. This check handles models with a :free suffix, as well as the openrouter/free and free identifiers. The change is accompanied by a comprehensive set of unit tests that validate the new logic for various scenarios. The implementation is correct and aligns with the pull request's goal. No issues were found during the review.
… (nearai#613) OpenRouter models with the `:free` suffix (e.g. `stepfun/step-3.5-flash:free`) and the `openrouter/free` router were falling through to `default_cost()`, which reports GPT-4o pricing (~$2.50/$10.00 per 1M tokens) instead of $0. Root cause: `model_cost()` strips the provider prefix via `rsplit_once('/')`, leaving identifiers like `step-3.5-flash:free` or `free` that don't match any known model or the `is_local_model()` heuristic. Fix: add an early return before prefix stripping that checks for the `:free` suffix and the bare `free` / `openrouter/free` identifiers, returning zero cost. Tests: 4 new test cases covering the `:free` suffix with various providers, the `openrouter/free` router, and the bare `free` edge case.
… (nearai#613) OpenRouter models with the `:free` suffix (e.g. `stepfun/step-3.5-flash:free`) and the `openrouter/free` router were falling through to `default_cost()`, which reports GPT-4o pricing (~$2.50/$10.00 per 1M tokens) instead of $0. Root cause: `model_cost()` strips the provider prefix via `rsplit_once('/')`, leaving identifiers like `step-3.5-flash:free` or `free` that don't match any known model or the `is_local_model()` heuristic. Fix: add an early return before prefix stripping that checks for the `:free` suffix and the bare `free` / `openrouter/free` identifiers, returning zero cost. Tests: 4 new test cases covering the `:free` suffix with various providers, the `openrouter/free` router, and the bare `free` edge case.
Problem
OpenRouter free-tier models report GPT-4o default pricing (~$2.50/$10.00 per 1M tokens) instead of $0 in the IronClaw UI.
Fixes #463.
Root Cause
model_cost()insrc/llm/costs.rsnormalizes model identifiers by stripping the provider prefix viarsplit_once("/"). For OpenRouter free-tier models this produces identifiers that don't match any entry in the cost table:stepfun/step-3.5-flash:freestep-3.5-flash:freeopenrouter/freefreeNeither matches any known model name nor the
is_local_model()heuristic, so they fall through todefault_cost()— which returns GPT-4o pricing.Fix
Add an early return before the prefix-stripping normalization that checks for:
:freesuffix (covers allprovider/model:freepatterns)openrouter/freeand barefreeidentifiersAll matching models return
(Decimal::ZERO, Decimal::ZERO).The check is placed before prefix stripping intentionally — the
:freesuffix is part of the OpenRouter routing convention and would be lost or misinterpreted if we stripped first and matched later.Tests
4 new test cases added:
test_openrouter_free_suffix_zero_cost—:freesuffix modeltest_openrouter_free_router_zero_cost—openrouter/freeroutertest_bare_free_zero_cost— edge case: barefreetest_free_suffix_various_providers— parametric test across 4 different provider-prefixed free modelsChanges
src/llm/costs.rs: 6-line early return + 40 lines of tests