Skip to content

feat: modelCost — because the same paid fallback was found in three apps - #3

Merged
catomean merged 1 commit into
mainfrom
feat/model-cost
Aug 16, 2026
Merged

feat: modelCost — because the same paid fallback was found in three apps#3
catomean merged 1 commit into
mainfrom
feat/model-cost

Conversation

@catomean

Copy link
Copy Markdown
Collaborator

One mistake, three codebases, one day. Each was a fallback that began spending the moment the free tier ran dry — the path nobody watches, because it only runs when something else has already broken.

Repo The id that was billing
botsmann anthropic/claude-sonnet-5 — a premium model as the OpenRouter fallback
kivvi chain ended at Anthropic; OpenRouter default google/gemini-2.0-flash-001, the paid twin of a :free id
evig meta-llama/llama-3.3-70b-instruct — reads free, bills at 1e-7/token, and its :free sibling has been retired from the catalogue

A fallback is a reliability mechanism; paying is a business decision. Wiring the second to the first lets an outage make the decision, at the worst moment, without anyone choosing it.

The rule is narrow, and says so

A routed id (vendor/model) is free only with :free and paid without it — that suffix is the entire difference between free routing and a per-call charge for identical weights.

A bare id (llama-3.1-8b-instant) returns "unknown": whether it costs depends on the account tier at that vendor, which no string can answer. Guessing free there is the direction that let all three through review, so it is not the default.

paidModelsIn() applies it to a whole chain and returns offenders rather than throwing — the caller knows whether a paid link is a bug or a deliberate opted-in upgrade, and a library that throws on the second case gets routed around.

35 tests green, including the one that keeps this package honest: its own shipped free chain must contain no paid model.

🤖 Generated with Claude Code

One mistake, three codebases, one day. Each was a FALLBACK that began spending
the moment the free tier ran dry — the path nobody watches, because it only runs
when something else has already broken:

  botsmann   OPENROUTER_DEFAULT_MODEL = anthropic/claude-sonnet-5 (premium)
  kivvi      chain ended at Anthropic; OpenRouter default was
             google/gemini-2.0-flash-001, the paid twin of a :free id
  evig       meta-llama/llama-3.3-70b-instruct — reads free, bills at 1e-7/token,
             and its :free sibling has been retired from the catalogue

A fallback is a reliability mechanism; paying is a business decision. Wiring the
second to the first lets an outage make the decision, at the worst moment,
without anyone choosing it.

The rule is deliberately narrow and says so. A ROUTED id (vendor/model) is free
only with the :free suffix and paid without it — that suffix is the entire
difference between free routing and a per-call charge for identical weights. A
bare id (llama-3.1-8b-instant) returns "unknown": whether it costs depends on
the account tier at that vendor, which no string can answer. Guessing "free"
there is the direction that let all three through review, so it is not the
default.

paidModelsIn() applies it to a whole chain, returning offenders rather than
throwing — the caller knows whether a paid link is a bug or a deliberate,
opted-in upgrade, and a library that throws on the second case gets routed
around.

35 tests green, including the case that keeps this package honest: its own
shipped free chain must contain no paid model.
@catomean
catomean merged commit 14a41b0 into main Aug 16, 2026
1 check passed
@catomean
catomean deleted the feat/model-cost branch August 16, 2026 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant