feat(catalog): mode-aware pricing and litellm-model-catalog-api integration#1
Conversation
…ration Load from the catalog API with Vite proxy support, show exact pricing for chat, image, audio transcription, and TTS models, and render mode-specific quick start snippets. Co-authored-by: Cursor <cursoragent@cursor.com>
Highlight SDK/proxy code via :global CSS for {@html} snippets. Add audio
transcription and TTS proxy curl examples alongside existing mode-specific SDK samples.
Co-authored-by: Cursor <cursoragent@cursor.com>
|
bugbot run |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 5 potential issues.
Bugbot Autofix is ON, but it could not run because the branch was deleted or merged before autofix could start.
Reviewed by Cursor Bugbot for commit 3c4644b. Configure here.
| -d ${curlStr(`{ | ||
| "model": "${modelStr}", | ||
| "messages": [{"role": "user", "content": "Hello!"}] | ||
| }`)}`; |
There was a problem hiding this comment.
Double HTML escaping in curl snippet display
Medium Severity
In getLiteLLmProxyCurlSnippetHtml, model names in JSON-body curl snippets are double-escaped. This occurs because modelStr is pre-escaped, then passed to curlStr which escapes it again, leading to incorrect display for image_generation, embedding, audio_speech, and chat completion examples.
Reviewed by Cursor Bugbot for commit 3c4644b. Configure here.
| return raw; | ||
| } | ||
| return 0; | ||
| } |
There was a problem hiding this comment.
Output sort skips valid zero-cost slot values
Medium Severity
The imageModeOutputSortValue function includes an if (v > 0) check that's not present in imageModeInputSortValue. This causes models with a $0.00 output pricing slot to incorrectly use fallback pricing fields for sorting, creating a discrepancy with the displayed $0.00 price.
Reviewed by Cursor Bugbot for commit 3c4644b. Configure here.
| {:else if mode === "audio_transcription"} | ||
| Audio pricing <span class="detail-unit">per second where applicable</span> | ||
| {:else if isAudioPricingMode(mode)} | ||
| Audio pricing <span class="detail-unit">per second · per character where applicable</span> |
There was a problem hiding this comment.
Unreachable audio pricing heading branch
Low Severity
The {:else if isAudioPricingMode(mode)} branch in the pricing heading is unreachable. isAudioPricingMode only returns true for "audio_speech" and "audio_transcription", but both are already matched by the two preceding {:else if} branches. The generic "per second · per character" label can never be displayed.
Reviewed by Cursor Bugbot for commit 3c4644b. Configure here.
|
|
||
| function formatUsdPerMillion(perToken: number): string { | ||
| return formatTokenCostPerMillion(perToken).replace(/\/M$/, "/M tok"); | ||
| } |
There was a problem hiding this comment.
Unused helper functions are dead code
Low Severity
formatUsdFlat and formatUsdPerMillion are newly introduced private functions that are never called anywhere in the codebase. Grep confirms the only matches are their definitions. These appear to be leftover helpers that were written but never wired in, adding dead code.
Reviewed by Cursor Bugbot for commit 3c4644b. Configure here.
| {:else if mode === "audio_transcription"} | ||
| Audio pricing <span class="detail-unit">per second where applicable</span> | ||
| {:else if isAudioPricingMode(mode)} | ||
| Audio pricing <span class="detail-unit">per second · per character where applicable</span> |
There was a problem hiding this comment.
Unreachable audio pricing mode branch is dead code
Low Severity
The {:else if isAudioPricingMode(mode)} branch is unreachable because mode === "audio_speech" and mode === "audio_transcription" are already matched by the two preceding conditions, and isAudioPricingMode only checks for exactly those two values. This dead branch adds confusion about whether there are other audio modes that could reach it.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 3c4644b. Configure here.


Summary
litellm-model-catalog-api(optional viaVITE_USE_LOCAL_CATALOG_API+ Vite proxy)Depends on BerriAI/litellm-model-catalog-api#1 for
pricing_slotsin API responses.Fixes LIT-2904
Image Gen

Before
After

Embedding


Before
After
Transcription


Before
After
Audio Speech


Before
After
Note
Medium Risk
Large UI/pricing refactor affects how every model’s costs are shown and sorted; optional API path depends on external catalog API and env/proxy setup, but default GitHub fetch remains.
Overview
Adds optional litellm-model-catalog-api loading (
VITE_USE_LOCAL_CATALOG_API, paginatedfetchAllCatalogModels, Vite/model_catalogproxy) alongside the existing GitHub JSON path, with sharedfinishLoadfor both sources.Extracts
catalogApi.tsandmodelPresentation.tsso pricing usespricing_slotswhen present and falls back to raw catalog fields. Display drops the old<$0.01per-1M floor in favor of exact USD with unit suffixes (/M,/img,/s,/char, etc.). Image and audio modes get dedicated table/detail pricing, image tier extras, and mode-specific Python SDK + proxy curl snippets (via{@html}with escaped model names).sample_specis surfaced as a pinned schema reference row (filters/sort tweaks, field-reference detail panel, no “report incorrect data”). GitHub loads still peelsample_specout of the JSON object before building model rows.UI polish: cost column labels, cache column tooltips, Features hidden for image/audio rows, sticky header/table CSS fixes,
image_editmode label.Reviewed by Cursor Bugbot for commit 3c4644b. Bugbot is set up for automated code reviews on this repo. Configure here.