docs: address PR #43 review findings on ai models table#44
Conversation
- Generator now sets an explicit limit and errors on suspected truncation instead of silently returning a partial snapshot. - formatPrice falls back to exponential notation below $0.001 so very cheap models no longer render as the broken string "$". - Footer denominator uses live models.length, not the snapshot-time count. - Drops the Supabase project URL from the snapshot — it is not consumed by the component and there is no reason to embed it in committed JSON. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Mogplex PR Review
Status: Attention needed
This follow-up PR cleanly addresses all four findings from #43. The logic is correct and the code is well-structured. One minor correctness issue remains in formatPrice: the perMtok === 0 strict-equality guard does not catch -0 or very small IEEE-754 sub-epsilon values that could still produce a broken string, though in practice this is extremely unlikely with real pricing data. There is also a small observation about the count field in the snapshot now being redundant.
2 findings were added inline.
| const snapshot = { | ||
| source: `${SUPABASE_URL}/rest/v1/ai_models`, | ||
| fetched_at: new Date().toISOString(), | ||
| count: rows.length, |
There was a problem hiding this comment.
Warning: count field in snapshot is now redundant and can drift again
The snapshot object still includes count: rows.length. Now that the component uses DATA.models.length (the fix in ai-models-table.tsx L139), count is dead data and the original drift problem can silently recur if someone regenerates the snapshot and count ends up out of sync with reality again (e.g. via manual JSON edits). Since the Snapshot type still declares count: number, downstream code could conceivably use it. Either remove count from both the type and the generated JSON (the field serves no purpose now that the component doesn't read it), or add a lint/CI check that they agree. The simpler fix is to drop it entirely.
| function formatPrice(value: number | null): string { | ||
| if (value == null) return '—'; | ||
| const perMtok = value * 1_000_000; | ||
| if (perMtok === 0) return '$0'; |
There was a problem hiding this comment.
Suggestion: perMtok === 0 strict-equality guard misses -0
The guard if (perMtok === 0) return '$0' is technically correct for +0 but Object.is(-0, 0) is false, so a value of 0 stored as -0 in the JSON would fall through. In practice, pricing data is never negative, but for robustness consider if (perMtok === 0 || Object.is(perMtok, -0)) return '$0', or more idiomatically if (!perMtok) return '$0' (which covers both 0 and -0 while being harmless here since null is already handled above). Low priority — just worth noting.
The component reads DATA.models.length now, so count was dead data that could silently drift out of sync on manual JSON edits. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Mogplex PR Review
Status: Attention needed
This is a clean, well-scoped follow-up PR that correctly addresses all four findings from the prior review. All four changes are accurate and the code reads well. One minor correctness edge case in formatPrice is worth noting, and there are two small suggestions.
Warnings
- formatPrice: strict equality on floating-point zero may not catch all zero-price values (src/components/ai-models-table.tsx:L40)
The guardif (perMtok === 0) return '$0'uses strict equality on a float derived from multiplication (value * 1_000_000). If a database row holds a denormalized very small positive float (e.g.5e-328— the smallest normal double) the multiplication can round to+0in IEEE 754, which will be caught correctly. However, ifvalueitself is-0(negative zero is a valid IEEE 754 value), the check still passes but the rendered string$0hides the sign — more importantly,-0 * 1_000_000 === -0and-0 >= 1is false,-0 >= 0.001is false, so execution would fall through totoExponential(1), which renders$-0.0e+0.
In practice this is a theoretical edge case unless the DB stores negative prices, but it's worth a defensive fix: replace if (perMtok === 0) with if (perMtok === 0 || Object.is(perMtok, -0)) or simply if (Math.abs(perMtok) < Number.EPSILON * 1_000_000) to catch both. Alternatively, clamp negatives to zero before formatting if they're considered invalid.
Suggestions
- gen-models-table.ts: empty-rows guard fires on legitimate empty catalog (scripts/gen-models-table.ts:L81)
Therows.length === 0throw is a useful safety net, but it also fires if every model is intentionally hidden or unavailable (e.g. during a planned maintenance window). Consider logging aconsole.warnand letting the script continue rather than hard-failing, or at minimum document in the error message that temporarily hiding all models will break this script so future operators know what to check first. This is a minor DX note, not a blocker. - Snapshot type still includes unused fields from Row that the component never renders (src/components/ai-models-table.tsx:L6)
Modelin the component type includesis_available,is_hidden, andis_recommended/recommendation_bucket, but none of these are rendered or used in the filter logic. This is pre-existing rather than introduced by this PR, so not a blocker — just worth tidying in a future cleanup to keep the imported JSON payload smaller and the type surface minimal.
Follow-up to #43, addressing the four findings from the mogplex bot review.
Summary
scripts/gen-models-table.ts): set an explicitlimit=10000on the Supabase REST call and throw if the response is empty or at/above the page size, so a growing catalog can't silently produce a truncated snapshot.formatPricelow-value bug (src/components/ai-models-table.tsx): values that round to$0.000after stripping trailing zeros previously produced the broken string"$". Now falls back to exponential notation below$0.001(e.g.$1.0e-4).src/components/ai-models-table.tsx): useDATA.models.lengthinstead of the snapshot-timeDATA.count, so the two can never disagree.sourceURL from snapshot (scripts/gen-models-table.ts,src/data/ai-models.json,Snapshottype): the field is not read by the component and there is no reason to keep the Supabase project URL embedded in committed JSON.Test plan
pnpm types:checkcleanpnpm lintcleanpnpm buildclean/web/modelson the preview deploy and confirm table renders + filters work + "Showing N of N" matches🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmithwith what you need.