feat(pricing): add is_usable_rate, one definition of a billable rate

A rate is usable only when it is finite and non-negative. Zero is usable —
"free" is a real price — but NaN, ±inf and negatives are not prices at all.

Python's truthiness cannot answer this question: inf and NaN are both truthy,
and NaN > 0, NaN < 0 and NaN == 0 are all False, so a malformed rate passes
every `if rate:` and every comparison-based guard. Stating the test once means
every caller answers it identically.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Jeroen Ubbink
2026-08-25 15:42:15 +02:00
co-authored by Claude Opus 5
parent f4645bde59
commit 8a0547a8a0
+24
View File
@@ -1,5 +1,6 @@
import asyncio
import json
import math
import random
import httpx
@@ -58,6 +59,29 @@ class Pricing(BaseModel):
max_cost: float = 0.0 # in sats not msats
def is_usable_rate(rate: float) -> bool:
"""True if a single billable rate is a number a request could be billed on.
The one definition of a usable rate, so every guard that asks the question
answers it identically. A rate qualifies only when it is finite and
non-negative; zero is usable (it means "free", which is a real price) but
``NaN``, ``±inf`` and negatives are not prices at all.
Non-finite: ``inf > 0`` is True, so an infinite rate reads as chargeable and
would be served, routed and billed as ``inf``; ``NaN`` poisons every total it
enters and defeats ordinary comparisons, since ``NaN > 0``, ``NaN < 0`` and
``NaN == 0`` are all False. Negative: a negative rate produces a negative
cost, which the settlement path subtracts from the balance — it pays the
caller to make requests.
Both reach a stored row from upstream catalogs as well as the admin edge
(``json.loads`` accepts the bare ``NaN``/``Infinity`` literals and overflows
``1e999`` to ``inf``), so the check belongs in one shared place rather than
at each writer.
"""
return math.isfinite(rate) and rate >= 0.0
class TopProvider(BaseModel):
context_length: int | None = None
max_completion_tokens: int | None = None