Model pricing catalog, write path and backfill

FeatureAIService
Shipped
July 19, 2026 at 3:54 AM UTC
Author
Kamo
Commit
84a3cf0

Cost accounting could never work: AiModel has price columns, AiModelController reads them and ChatOrchestrationService reads them to compute costEstimate - but NOTHING wrote them anywhere. Models are only created by provider discovery, and no provider API returns pricing. 140 models, 0 priced, no path by which that could change. The columns were structurally unreachable. Three parts: - ModelPricingCatalog seeds vendor LIST prices at discovery, matched on a normalized identifier with a hyphen-boundary prefix rule so gpt-4 can never claim gpt-4o. Non-chat models (TTS, embeddings, realtime) are rejected by reusing the existing modality check - they bill off a different sheet. - PATCH endpoint + UI so an org can correct or clear a price. Org-scoped exactly like the existing DELETE. - Backfill fills only NULL columns, per column independently, and never overwrites what an org has set - otherwise making prices editable would be a lie. Idempotent, and wrapped so cost accounting can never block boot. **A model we are not confident about gets NO price rather than a guessed one.** GPT-5, o3, most Mistral, DeepSeek, xAI, Cohere and Meta are deliberately blank; OpenRouter and HuggingFace never match by design, since they bill their own rates and inheriting upstream pricing would be a guess. A wrong price produces an invoice-shaped figure that is confidently wrong - the same reason cost is still not computed on the streaming path, where token counts are fabricated. Conversion to the per-1k column uses RoundingMode.UNNECESSARY on purpose: a price needing more than 6 decimals throws at class-init rather than silently storing a reason and is left blank. Suite is 145 tests, green.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing