feat(models): device-fit chips — show loadable models with Easy/Fits/Tight instead of hiding them#561
feat(models): device-fit chips — show loadable models with Easy/Fits/Tight instead of hiding them#561alichherawalla wants to merge 2 commits into
Conversation
…fit) from the owned budgets
…w snug the fit is Browse used to HIDE any model whose quants all exceeded the balanced budget (fileExceedsBudget), so a model that's loadable via reclaim credit + Load Anyway just vanished. Now browse keeps every model with a quant that isn't 'wontFit' (past the aggressive ceiling) and tags it with a small device-fit chip: Easy / Fits / Tight (fitTier owner). Only genuinely-too-big models are hidden. - useTextModels: relax the browse hide-filter to noLoadableQuant (every quant 'wontFit'); attach each model's best-quant fitTier for the chip. Recommended stays filtered by deviceRecommendation (curated cap) and search/sort are untouched. - ModelCardContent: render the fit chip in the badges row (InfoBadgesRow extracted to module scope to stay under the complexity gate); emerald for easy/fits, muted for a snug 'tight'. - TextModelsTab detail 'Available Files': relax the same way so a 'tight' model opened from browse still lists a downloadable quant (isCompatible still flags snug ones for the Load-Anyway warning). Rendered tests: a tight model now shows in browse with its chip (red-verified: revert → hidden); the detail list offers loadable quants and hides only 'wontFit' (boundary pinned at 8GB×0.75 = exactly 6.0GB). Note: cosmetic chip colors/placement want an on-device eyeball. Image-tab parity + the Home picker chip are follow-ups (same owner).
|
ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing |
📝 WalkthroughWalkthroughModel file sizing now produces RAM fit tiers. Browse results retain models with at least one loadable quant and expose fit-tier metadata for compact-card chips. Detail file lists use the same loadability verdict, with integration tests covering tight models and aggressive-ceiling boundaries. ChangesFit-tier model browsing
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant HuggingFace
participant useTextModels
participant fitTier
participant ModelsScreen
participant ModelCardContent
HuggingFace->>useTextModels: model metadata and quantized file sizes
useTextModels->>fitTier: classify quant file sizes
fitTier-->>useTextModels: fit tiers
useTextModels-->>ModelsScreen: filtered models with fitTier
ModelsScreen-->>ModelCardContent: render model card
ModelCardContent-->>ModelCardContent: display fit-tier chip
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed: one or more packages not found in the registry. 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.
Actionable comments posted: 1
🤖 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 `@src/components/ModelCardContent.tsx`:
- Around line 129-134: Update the conditional rendering for model.paramCount and
model.minRamGB in ModelCardContent so numeric zero values do not render directly
as children of View. Use explicit presence checks that render each badge only
when its value is defined or otherwise valid, while preserving the existing
badge text and behavior for positive values.
🪄 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: 6e3d6e99-16db-4702-9d59-795d7965244f
📒 Files selected for processing (7)
__tests__/integration/models/browseFitChipShowsLoadableModels.rendered.test.tsx__tests__/integration/models/detailFilesFitHintUsesOwnedBudget.rendered.test.tsxsrc/components/ModelCardContent.tsxsrc/screens/ModelsScreen/TextModelsTab.tsxsrc/screens/ModelsScreen/useTextModels.tssrc/services/memoryBudget.tssrc/types/index.ts
| {model.paramCount && ( | ||
| <View style={styles.infoBadge}><Text style={styles.infoText}>{model.paramCount}B params</Text></View> | ||
| )} | ||
| {model.minRamGB && ( | ||
| <View style={styles.infoBadge}><Text style={styles.infoText}>{model.minRamGB}GB+ RAM</Text></View> | ||
| )} |
There was a problem hiding this comment.
🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win
Prevent React Native crash on falsy numeric values.
When model.paramCount or model.minRamGB evaluates to 0, React Native attempts to render the number 0 directly inside a <View>, resulting in a "Text strings must be rendered within a component" runtime crash.
🛠 Proposed fix
- {model.paramCount && (
+ {!!model.paramCount && (
<View style={styles.infoBadge}><Text style={styles.infoText}>{model.paramCount}B params</Text></View>
)}
- {model.minRamGB && (
+ {!!model.minRamGB && (
<View style={styles.infoBadge}><Text style={styles.infoText}>{model.minRamGB}GB+ RAM</Text></View>
)}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {model.paramCount && ( | |
| <View style={styles.infoBadge}><Text style={styles.infoText}>{model.paramCount}B params</Text></View> | |
| )} | |
| {model.minRamGB && ( | |
| <View style={styles.infoBadge}><Text style={styles.infoText}>{model.minRamGB}GB+ RAM</Text></View> | |
| )} | |
| {!!model.paramCount && ( | |
| <View style={styles.infoBadge}><Text style={styles.infoText}>{model.paramCount}B params</Text></View> | |
| )} | |
| {!!model.minRamGB && ( | |
| <View style={styles.infoBadge}><Text style={styles.infoText}>{model.minRamGB}GB+ RAM</Text></View> | |
| )} |
🧰 Tools
🪛 React Doctor (0.7.6)
[error] 129-129: Your users hit a crash when this value is 0 & renders a bare 0 as text.
When the number is 0, this shows a bare 0 as text, which crashes on RN. Use {value > 0 && <X />}, {Boolean(value) && <X />}, or {value ? <X /> : null}.
(rn-no-falsy-and-render)
🤖 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 `@src/components/ModelCardContent.tsx` around lines 129 - 134, Update the
conditional rendering for model.paramCount and model.minRamGB in
ModelCardContent so numeric zero values do not render directly as children of
View. Use explicit presence checks that render each badge only when its value is
defined or otherwise valid, while preserving the existing badge text and
behavior for positive values.
Source: Linters/SAST tools
|



The parked fit-chip UX, built fresh as its own feature PR.
Problem
Browse HID any model whose quants all exceeded the balanced budget (
fileExceedsBudget). But the load path can reach the aggressive ceiling (Android reclaim credit + Load Anyway), so genuinely-loadable models just vanished from browse — and if one slipped through, tapping it opened an empty file list (its quants were hidden too).Change
Browse now keeps every model with a quant that isn't
wontFit(past the aggressive ceiling) and tags it with a small device-fit chip — Easy / Fits / Tight. Only genuinely-too-big models are hidden.memoryBudget.fitTier(Easy/Fits/Tight/Won't fit) from the SAME owned budgets — soft = balanced fraction, ceil = aggressive fraction. No new magic numbers.noLoadableQuant(hide only when every quant is wontFit); attach each model's best-quant tier for the chip. Recommended stays filtered (bydeviceRecommendation— the curated param cap) and search/sort are untouched.InfoBadgesRowto module scope to stay under the complexity gate.isCompatiblestill flags snug ones for the Load-Anyway warning (the 'slight relaxation', not a free pass).Tests (rendered, red-verified)
wontFit; the boundary is pinned at 8GB × 0.75 = exactly 6.0GB (integer bytes) to kill a</<=mutant.Follow-ups (noted, not in scope)
fitTierowner).Summary by CodeRabbit