pydantic/genai-prices that covers all three modalities. VoiceGateway no
longer keeps any local rate catalogs: rates, source URLs, and verification
dates all live in voice-prices.
The pricing wrappers that call into it are:
src/voicegateway/inference/pricing/llm.pysrc/voicegateway/inference/pricing/stt.pysrc/voicegateway/inference/pricing/tts.py
provider/model id against voice-prices and returns the
computed cost. The per-request attribution string is voice-prices@<version>
for priced models and voicegateway-local for self-hosted (local/*,
ollama/*) models.
When a refresh is required
A rate is refreshed when a provider publishes a price change, or when a model VoiceGateway supports is missing fromvoice-prices (a pricing call returns
None). Freshness is owned by voice-prices: every model entry there carries
a prices_checked date and a pricing_source_url, so the verification trail
lives upstream rather than in this repo.
How to refresh a rate
1
Confirm the current behaviour from VoiceGateway
Use the pricing catalog directly to see what the current rate resolves to:
2
Update the rate in voice-prices
Edit the model’s entry in the relevant provider file under
prices/providers/, bump its prices_checked date, and confirm pricing_source_url still points at the provider’s price page. Run the voice-prices test suite.3
Publish a new voice-prices version
Publish a new
voice-prices version to PyPI.4
Bump the pin and run pricing tests
Update the lower bound in VoiceGateway’s
pyproject.toml dependency spec (currently voice-prices>=0.1.0,<0.2) to the new version, and re-run the pricing tests:Adding a missing model
If a pricing call returnsNone for a model VoiceGateway should support, the
model is not yet in voice-prices. Add it upstream (model id, match pattern,
and prices block) following the existing entries for that provider, publish a
new voice-prices version, and bump the pin. The coverage tests in
src/voicegateway/tests/pricing/test_stt.py and test_tts.py assert that
every supported cloud model resolves, so a missing model fails CI until it is
added.
Why pricing lives in voice-prices
voice-prices gives LLM, STT, and TTS pricing a single versioned source with a
release cadence VoiceGateway can pin against, instead of a hand-maintained
catalog that drifts. Refreshing a rate is a voice-prices release plus a pin
bump, and the attribution string records exactly which voice-prices version
priced each request.