feat(replay-vision): restore gemini-3-flash-preview as 5-credit default#73026
Conversation
Brings back Gemini 3 Flash (gemini-3-flash-preview) as a selectable model and the default for new scanners, at 5 credits per observation. PR #72713 had retired it in favor of the 15-credit gemini-3.6-flash default. The selectable lineup is now three models across two Google tiers: - gemini-3.5-flash-lite: 2 credits (budget) - gemini-3-flash-preview: 5 credits (default, flash preview) - gemini-3.6-flash: 15 credits (stable flash) 5 credits is exactly the margin-formula output for its token prices (0.50 in / 3.00 out per 1M tokens at the 3.75x target margin), so pricing stays internally consistent with the rest of the lineup. Existing scanners are unaffected. Migration 0052 already remapped anything on gemini-3-flash-preview to gemini-3.6-flash, so this only adds the model back for new scanners. gemini-3-flash-preview is a preview id, so watch for Google retiring it and remap like 0052 if that happens. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
😎 This pull request was merged. |
🤖 CI report✅ Bundle size — no changeUncompressed size of every built Total: 64.67 MiB · no change No file changed by more than 1000 B. Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report ✅ Eager graph — within budgetHow much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy
🟢 Largest files eagerly shipped from
|
| Size | File |
|---|---|
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 24.6 KiB | ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js |
| 6.3 KiB | ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js |
| 4.5 KiB | ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js |
| 3.9 KiB | ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js |
| 1.4 KiB | ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js |
| 1.3 KiB | src/RootErrorBoundary.tsx |
| 912 B | ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js |
| 789 B | src/scenes/ChunkLoadErrorBoundary.tsx |
| 762 B | src/index.tsx |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
| Size | File |
|---|---|
| 281.5 KiB | ../node_modules/.pnpm/posthog-js@1.407.1/node_modules/posthog-js/dist/rrweb.js |
| 267.7 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 236.0 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 226.1 KiB | ../node_modules/.pnpm/posthog-js@1.407.1/node_modules/posthog-js/dist/module.js |
| 167.1 KiB | src/queries/validators.js |
| 154.3 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 105.8 KiB | src/lib/api.ts |
| 94.0 KiB | ../packages/quill/packages/quill/dist/index.js |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479
✅ Toolbar bundle — eager 2.18 MiB within budget
What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.
| Metric | Size | Δ vs base | Budget |
|---|---|---|---|
| Eager (shipped) entry + static imports |
2.18 MiB · 17 files | no change | ████░░░░░░ 38.1% of 5.72 MiB |
| Deferred (lazy) | 2.07 MiB · 33 files | no change | n/a — loads on demand |
Loader dist/toolbar.js |
1.1 KiB | no change | █░░░░░░░░░ 5.8% of 19.5 KiB |
Largest eagerly-shipped chunks
| Size | File |
|---|---|
| 713.8 KiB | dist/toolbar/toolbar-app-HY7HJI4V.css |
| 545.0 KiB | dist/toolbar/chunk-chunk-RQ4FN27S.js |
| 484.2 KiB | dist/toolbar/chunk-chunk-QS5AHYGW.js |
| 133.6 KiB | dist/toolbar/chunk-chunk-SYFILNLU.js |
| 131.8 KiB | dist/toolbar/chunk-chunk-T5KY5WYR.js |
| 71.0 KiB | dist/toolbar/toolbar-app-IWQPCR2K.js |
| 69.0 KiB | dist/toolbar/chunk-chunk-27JL52RE.js |
| 35.6 KiB | dist/toolbar/chunk-chunk-ZOYUTNIC.js |
| 20.9 KiB | dist/toolbar/chunk-chunk-IIQH4XLX.js |
| 12.2 KiB | dist/toolbar/chunk-chunk-PIK3PADE.js |
Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile
✅ Dist folder size — 🔺 +1.2 KiB (+0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 1357.65 MiB · 🔺 +1.2 KiB (+0.0%)
⚠️ Django migration SQL — 1 new migration to review
We've detected new migrations on this PR. Review the SQL output for each migration:
products/replay_vision/backend/migrations/0053_alter_replayscanner_model.py
BEGIN;
--
-- Alter field model on replayscanner
--
-- (no-op)
COMMIT;Last updated: 2026-07-23 09:59 UTC (234d1bd)
✅ Django migration risk — migration analysis complete
We've analyzed your migrations for potential risks.
Summary: 0 Safe | 1 Needs Review | 0 Blocked
⚠️ Needs Review
May have performance impact
replay_vision.0053_alter_replayscanner_model
└─ #1 ⚠️ AlterField
Field alteration may cause table locks or data loss (check if changing type or constraints)
model: replayscanner, field: model, field_type: CharField
Last updated: 2026-07-23 09:59 UTC (234d1bd)
🦔 Hogbox preview · ✅ ready▶ Open the preview
commit |
|
Note 🤖 stamphog reviewed Gates denied this PR for touching billing logic and a migration, which is risky territory; the only review present is COMMENTED (not approved), with an unresolved style nit — not independent assurance on the pricing/migration change itself.
Gate mechanics and policy version
Updated in place — this replaces 1 earlier stamphog review(s) on this PR. |
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
products/replay_vision/backend/tests/test_billing.py:89
**Use standard test parameterization**
This synchronous test uses `pytest.mark.parametrize` even though it needs no pytest-only fixture or async support. Using the repository-standard `parameterized.expand` avoids introducing a second parameterization convention and an otherwise unnecessary pytest import.
Reviews (1): Last reviewed commit: "Merge branch 'master' into ahillen/repla..." | Re-trigger Greptile |
Problem
Yesterday's #72713 retired Gemini 3 Flash (
gemini-3-flash-preview) and switched the default scanner model togemini-3.6-flash, which bills at 15 credits per observation instead of 5. We want the cheaper 5-credit model back as the default so new scanners start at the familiar lower price point.Changes
Restores
gemini-3-flash-previewas a selectable model and the default for new scanners, at 5 credits per observation. The lineup is now three models across two Google tiers:GEMINI_3_FLASH_PREVIEWback to theScannerModelenum with display name "Gemini 3 Flash (preview)" so it reads distinctly from the stable "Gemini 3.6 Flash".billing.GEMINI_MODELSat 5 credits. That is exactly what the margin formula produces from its token prices (0.50 in / 3.00 out per 1M tokens at the 3.75x target), so pricing stays consistent with the rest of the lineup.DEFAULT_MODELto the preview, and regenerates OpenAPI/MCP types.AlterField, no DB schema change).Note
Existing scanners are unaffected. Migration 0052 already remapped anything on
gemini-3-flash-previewtogemini-3.6-flash, so this only changes what new scanners default to.gemini-3-flash-previewis a preview id, so if Google retires it we remap like 0052 did.How did you test this code?
Automated tests I (Claude) ran locally, all passing:
test_billing.py, including the mirror test (enum ↔GEMINI_MODELS) and the flash margin test, which I parameterized to also assertgemini-3-flash-preview's 5 credits equals the formula output. That guards against a future token-price change silently leaving the credit price stale, which no existing test caught (the mirror test only checks membership).test_api.pyestimate tests. I updatedtest_estimate_counts_only_in_window_sessionsto expect 5 credits / 15 per month now that the default model changed.I regenerated types with
hogli build:openapiand ranhogli ci:preflight(0 failures). I did not get the full frontend typecheck to green in my worktree because the quill workspace packages are not built there (an environment quirk unrelated to this change). replay_vision itself reports zero type errors.Automatic notifications
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Arnaud asked me to double-check whether the flash model costs 5 or 15 credits after yesterday's PRs, then to bring back the 5-credit model as the default with a version-explicit name. I (Claude) traced the pricing history and confirmed the 5-credit model was
gemini-3-flash-preview(not the "3.1" flash-lite preview, which was 2 credits and never the default), verified 5 credits sits exactly on the margin formula, and made the change.Skills invoked:
/improving-drf-endpoints(serializer default),/django-migrations(choices migration),/writing-tests(test changes).Decisions: kept the change additive (added the preview alongside the existing 2- and 15-credit models rather than reverting the whole #72713 lineup) since existing scanners already migrated to
gemini-3.6-flash. Considered adding a pro tier but left it out per Arnaud's call to keep the three-model lineup. Named it "Gemini 3 Flash (preview)" to make the version explicit next to "Gemini 3.6 Flash".