Improve models page pricing summaries and hover cards#474
Conversation
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
|
Warning Rate limit exceeded
To continue reviewing without waiting, purchase usage credits in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR extends the models display system to track and render pricing detail rows as structured ChangesPricing Detail Rows Data Flow
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 54608722ad
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
apps/web/src/components/(data)/models/Models/ModelCard.tsx (1)
994-1078: 💤 Low valueHardcoded label strings create fragile coupling across files.
The specialized rendering branches at lines 994 (
group.baseLabel === "Image Output") and 1011 (group.baseLabel === "Video Output") rely on exact string matches against labels produced ingetMonitorModels.ts(lines 184 and 190). If those label strings are ever renamed or localized in the server-side fetcher, the specialized rendering silently falls through to the generic renderer with no type or test signal.Consider attaching a
kind: "image_output" | "video_output"discriminator to each pricing row when it is built ingetMonitorModels.ts, or export the label strings from a shared constants module that both files import.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/`(data)/models/Models/ModelCard.tsx around lines 994 - 1078, The rendering logic in ModelCard.tsx branches on fragile baseLabel string checks (group.baseLabel === "Image Output" / "Video Output"); update the data shape in getMonitorModels.ts to include a stable discriminator (e.g., add kind: "image_output" | "video_output" on each pricing row) or export canonical label constants from a shared module and use those constants here; then replace the string comparisons in ModelCard.tsx (the checks around group.baseLabel and the audio grouping logic using getVideoAudioGroup) to check the new kind property or imported constants so rendering no longer depends on literal label text.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/web/src/components/`(data)/models/Models/ModelCard.tsx:
- Around line 636-654: The input fallback row uses formatFromPrice (producing
"$X per Y") while the output and other rows use the "$X / Y" style; update the
fallbackPricingRows creation so the "input" row uses the same formatter as the
"output" row (replace formatFromPrice with formatPriceWithUnit for the
model.lowest_input_price value, preserving any relevant options like allowZero
behavior) so both input and output rows render with a consistent "$X / Y"
format; keep the existing .filter(Boolean) logic unchanged.
In `@apps/web/src/lib/fetchers/models/table-view/getMonitorModels.ts`:
- Around line 219-226: The decimal cutoff logic in formatPriceAmount is
inconsistent with the client-side formatter used in ModelCard.tsx (formatPrice),
causing differing precision for the same price; update formatPriceAmount to use
the same threshold values as formatPrice in ModelCard.tsx (adjust the 3-decimal
cutoff from <0.1 to <0.01 and ensure the surrounding branches match the same
boundaries), then run the UI where formatDetailValue and ModelCard use these
formatters to verify identical output.
---
Nitpick comments:
In `@apps/web/src/components/`(data)/models/Models/ModelCard.tsx:
- Around line 994-1078: The rendering logic in ModelCard.tsx branches on fragile
baseLabel string checks (group.baseLabel === "Image Output" / "Video Output");
update the data shape in getMonitorModels.ts to include a stable discriminator
(e.g., add kind: "image_output" | "video_output" on each pricing row) or export
canonical label constants from a shared module and use those constants here;
then replace the string comparisons in ModelCard.tsx (the checks around
group.baseLabel and the audio grouping logic using getVideoAudioGroup) to check
the new kind property or imported constants so rendering no longer depends on
literal label text.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 4d3d0cfc-f27a-4112-a345-8e2bb0eae46c
📒 Files selected for processing (6)
apps/web/src/app/(dashboard)/models/page.tsxapps/web/src/components/(data)/models/Models/ModelCard.tsxapps/web/src/components/(data)/models/Models/modelsDisplay.types.tsapps/web/src/lib/fetchers/models/getAllModels.tsapps/web/src/lib/fetchers/models/table-view/getMonitorModels.tsapps/web/src/lib/fetchers/models/table-view/types.ts
Summary
This PR improves pricing presentation on the main
/modelscatalogue so the model cards and pricing hover cards are descriptive for non-trivial pricing structures instead of being misleading or incomplete.Problem
The list view was reasonably fine for simple text-token pricing, but it broke down for media and tiered models.
Users were seeing several concrete issues:
/modelsindex could silently miss pricing detail rows that were available in the underlying pricing rulesx-ai/grok-4.3surfaced duplicate input/output prices with no explanation of the context threshold behind themRoot Cause
There were two broad causes:
What changed
Monitor feed and aggregation
get_monitor_model_rowsRPC fetch so the/modelsindex no longer truncates at 1000 rowsdata_api_pricing_rulesPricing detail labelling
Up to 200K context,Over 200K context)Card and hover-card UX
Video Outputover and overResult
The
/modelscards now behave much more like a lightweight version of the individual model pricing pages:Validation
pnpm --filter @ai-stats/web typecheckScope
This PR is intentionally limited to the web models catalogue pricing/feed path:
apps/web/src/lib/fetchers/models/table-view/getMonitorModels.tsapps/web/src/app/(dashboard)/models/page.tsxapps/web/src/components/(data)/models/Models/ModelCard.tsxSummary by CodeRabbit