Skip to content

fix(engines): show the under-provisioned-VRAM warning instead of discarding it - #1280

Merged
debpalash merged 4 commits into
mainfrom
fix/surface-vram-caveat-1226
Jul 28, 2026
Merged

fix(engines): show the under-provisioned-VRAM warning instead of discarding it#1280
debpalash merged 4 commits into
mainfrom
fix/surface-vram-caveat-1226

Conversation

@debpalash

@debpalash debpalash commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Four open low-VRAM reports share one shape:

Issue GPU
#1240 GTX 1650 Ti — 4 GB
#1246 GTX 1650 Ti — 4 GB
#1248 RTX 2050 — 4 GB
#1277 RTX 3060 Laptop — 6 GB

The user generates, waits out the entire 300 s compute budget, and is then told the job "was too heavy for the available compute".

The warning already existed

#1226 added exactly the right message in engine_routing._caveat:

NVIDIA GeForce GTX 1650 Ti has 4.0 GB VRAM; this engine wants about 6 GB. It will run, but expect slow generations that may time out. Unload other models before generating, keep the text short, or pick a lighter engine.

/engines/select echoes it in routing_reason. But notifyEngineSelected surfaced a reason only when routing_status === 'cpu_fallback' — and the VRAM caveat rides on an accelerated verdict. So it fell through to the plain green "switched" success toast and was discarded. The user was told everything was fine, then waited five minutes to learn it wasn't.

Change

Any caveat on the echo now raises a warn-tone toast naming it (longer duration, since it lists the ways around the limit). Also covers the kernel-risk caveat, which took the same path.

Still advisory, not blocking — matching the routing layer's documented contract: the driver can page to system RAM, and short inputs fit where long ones don't. The engine is still selected. This is the first-run path too, since the wizard's library step shares notifyEngineSelected.

Verification

  • Fail-before: both new tests fail against the previous version.
  • engines.selectWithCaveat added to all 21 locales; locale-parity + CJK suites green.
  • Frontend 1592 passing, lint 0 errors, typecheck clean.

Known remaining gap

A user whose engine is already selected sees this only when they re-pick. A generate-time preflight would close that, but it needs a "once per session, not once per generate" design — flagging rather than guessing at it here.

Refs #1226, #1240, #1246, #1248, #1277

Updated engine-selection toasts so accelerated routing caveats (including VRAM limits and kernel-risk) surface as longer, advisory warning toasts using the new engines.selectWithCaveat/selectCpuFallback i18n strings, and the selection remains unchanged. This extends the first-run wizard flow and adds/adjusts engine_switched copy across all 21 locales, along with frontend tests and stricter locale-parity checks to prevent placeholder-only translations. Main risk to review: users with an already-selected engine may only see the warning upon reselecting it, since generate-time preflight is deferred.

…arding it

Four of the open low-VRAM reports (#1240, #1246, #1248 on 4 GB cards; #1277
on 6 GB) share one shape: the user generates, waits out the entire 300s
compute budget, and is then told the job "was too heavy for the available
compute".

The warning existed the whole time. Routing computes it (#1226's `_caveat`:
"…has 4.0 GB VRAM; this engine wants about 6 GB. It will run, but expect slow
generations that may time out"), and `/engines/select` echoes it in
`routing_reason` — but notifyEngineSelected only surfaced a reason when
`routing_status === 'cpu_fallback'`. The VRAM caveat rides on an ACCELERATED
verdict, so it fell through to the green "switched" success toast and was
thrown away. The user was told everything was fine, then waited five minutes
to find out it wasn't.

Now any caveat on the echo raises a warn-tone toast naming it, with a longer
duration since it lists the ways around the limit. This covers the kernel-risk
caveat on the same path.

Deliberately still ADVISORY, not blocking — matching the routing layer's
documented contract (the driver can page to system RAM, and short inputs fit
where long ones don't). The engine is still selected; the user just finds out
now instead of after the timeout. This is the first-run path too: the wizard's
library step shares notifyEngineSelected.

Fail-before verified: both new tests fail against the previous version.

Known remaining gap: a user whose engine is already selected sees this only
when they re-pick. A generate-time preflight would close that, but it needs a
"once per session, not per generate" design — filed as follow-up rather than
guessed at here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR surfaces actionable engine-routing caveats without changing engine selection behavior.

  • Accelerated selections with VRAM or kernel-risk caveats now display a longer warning toast.
  • CPU fallback remains warning-toned, while benign CPU-only and unavailable routing explanations retain the normal success notification.
  • All supported locales receive translated notification text, with parity tests guarding against placeholder-only translations.

Important Files Changed

Filename Overview
frontend/src/utils/engineSelectToast.js The notification predicate matches the backend routing-notice contract and preserves benign status handling.
frontend/src/test/engineSelectToast.test.js Regression coverage exercises VRAM and kernel caveats plus the previously reported CPU-only and unavailable false-positive cases.
tests/test_locale_parity.py The new check prevents placeholder-only values while retaining an explicit exception mechanism for legitimate cases.
frontend/src/i18n/locales/en.json Adds the user-facing caveat message and replaces the placeholder-only engine-switch notification with prose.

Reviews (4): Last reviewed commit: "style: oxfmt the new toast test cases" | Re-trigger Greptile

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 400a244d-7e4f-4b79-9bd0-324b558cb019

📥 Commits

Reviewing files that changed from the base of the PR and between dcbcad8 and 2fa4d52.

📒 Files selected for processing (1)
  • frontend/src/test/engineSelectToast.test.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/test/engineSelectToast.test.js

📝 Walkthrough

Walkthrough

The frontend adds localized engine-selection messages across locales, shows warning toasts for accelerated routing caveats, tests guarded routing outcomes, and strengthens locale parity validation.

Changes

Engine caveat feedback

Layer / File(s) Summary
Localized engine-selection messages
frontend/src/i18n/locales/*.json
Replaces arrow-style switch messages and adds CPU-fallback and caveated-selection translations using engine and reason placeholders.
Caveated selection warning behavior
frontend/src/utils/engineSelectToast.js, frontend/src/test/engineSelectToast.test.js
Shows warning toasts for accelerated results with routing reasons, suppresses the success toast, and covers VRAM, kernel-risk, and guard cases.
Locale parity validation
tests/test_locale_parity.py
Adds placeholder-only value validation and tightens missing-key baselines.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 8 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (8 passed)
Check name Status Explanation
Title check ✅ Passed Conventional-commit style with scope and a body issue reference; it matches the warning-toast change.
Description check ✅ Passed It includes the summary, change rationale, verification, and remaining gap, so the PR description is mostly complete.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cross-Platform Default Parity ✅ Passed PASS: notifyEngineSelected has no OS-specific branches; the same routing predicate drives toast behavior on all hosts, and tests cover cpu_fallback, accelerated+reason, cpu_only, and unavailable un...
I18n Completeness (21 Locales) ✅ Passed All 21 locale files define engines.selectCpuFallback, engines.selectWithCaveat, and settings.engine_switched; the touched frontend code uses translated toast text only.
Local-First Guarantee ✅ Passed PR only changes locale strings, tests, and a toast wrapper; no new cloud/telemetry/key requirement was added, and selectEngine still targets local /engines/select via apiPost.
Backward Compatibility ✅ Passed Only frontend toast/i18n/test changes; no backend schema, migration, or engine-asset changes, so existing data and installed models stay compatible.

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

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 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 `@frontend/src/i18n/locales/ar.json`:
- Around line 581-582: Replace the bare selectWithCaveat value with a natural,
locale-specific warning phrase in frontend/src/i18n/locales/ar.json:581-582,
de.json:581-582, es.json:581-582, fr.json:581-582, hi.json:581-582,
id.json:581-582, it.json:581-582, ja.json:581-582, ko.json:581-582, and
nl.json:581-582. Preserve both {{engine}} and {{reason}} placeholders in every
translation; routingCaveatTitle requires no direct change.

In `@frontend/src/i18n/locales/pl.json`:
- Around line 581-582: Replace the untranslated selectWithCaveat value with
natural localized wording around the {{engine}} and {{reason}} placeholders,
preserving both placeholders and the warning meaning. Apply the corresponding
translations in frontend/src/i18n/locales/pl.json#L581-L582, pt.json#L581-L582,
ru.json#L581-L582, sv.json#L581-L582, th.json#L581-L582, tr.json#L581-L582,
uk.json#L581-L582, vi.json#L581-L582, zh-CN.json#L540-L541, and
zh-TW.json#L581-L582.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 6be911b3-d036-4d2b-b5da-edb79705abef

📥 Commits

Reviewing files that changed from the base of the PR and between b01c635 and d4ba4fd.

📒 Files selected for processing (23)
  • frontend/src/i18n/locales/ar.json
  • frontend/src/i18n/locales/de.json
  • frontend/src/i18n/locales/en.json
  • frontend/src/i18n/locales/es.json
  • frontend/src/i18n/locales/fr.json
  • frontend/src/i18n/locales/hi.json
  • frontend/src/i18n/locales/id.json
  • frontend/src/i18n/locales/it.json
  • frontend/src/i18n/locales/ja.json
  • frontend/src/i18n/locales/ko.json
  • frontend/src/i18n/locales/nl.json
  • frontend/src/i18n/locales/pl.json
  • frontend/src/i18n/locales/pt.json
  • frontend/src/i18n/locales/ru.json
  • frontend/src/i18n/locales/sv.json
  • frontend/src/i18n/locales/th.json
  • frontend/src/i18n/locales/tr.json
  • frontend/src/i18n/locales/uk.json
  • frontend/src/i18n/locales/vi.json
  • frontend/src/i18n/locales/zh-CN.json
  • frontend/src/i18n/locales/zh-TW.json
  • frontend/src/test/engineSelectToast.test.js
  • frontend/src/utils/engineSelectToast.js

Comment thread frontend/src/i18n/locales/ar.json Outdated
Comment thread frontend/src/i18n/locales/pl.json Outdated
…eholder

CodeRabbit flagged engines.selectWithCaveat as untranslated in 20 locales.
It was worse than that: en.json said "{{engine}}: {{reason}}" too, so the
English string had never been written and every "translation" was a faithful
copy of a non-sentence. All 21 languages would have shown a bare
"omnivoice: <English backend text>".

Writes the en sentence, translates it into all 20, and translates
engines.selectCpuFallback alongside it — same function, same toast, and it
was English-only in every locale (missing-key ratchet tightened 518 -> 517,
zh-CN 511 -> 510).

Adds test_no_placeholder_only_values to pin the class. Parity tests cannot
catch this: the key is present everywhere and the placeholders match exactly.
Only the absence of prose gives it away, so the guard checks en.json too —
that is where this one started. A bot catching a mechanical rule twice means
the rule belongs in CI (CLAUDE.md, Token economy).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 `@tests/test_locale_parity.py`:
- Around line 42-50: Remove settings.engine_switched from
_PLACEHOLDER_ONLY_ALLOWLIST, then update that key in all 21 locale JSON files
with localized user-facing prose while preserving the placeholder values and
intended engine-switch success meaning.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8a4670b8-54b8-41fd-837e-36a4232d5a50

📥 Commits

Reviewing files that changed from the base of the PR and between d4ba4fd and 61ec1e8.

📒 Files selected for processing (22)
  • frontend/src/i18n/locales/ar.json
  • frontend/src/i18n/locales/de.json
  • frontend/src/i18n/locales/en.json
  • frontend/src/i18n/locales/es.json
  • frontend/src/i18n/locales/fr.json
  • frontend/src/i18n/locales/hi.json
  • frontend/src/i18n/locales/id.json
  • frontend/src/i18n/locales/it.json
  • frontend/src/i18n/locales/ja.json
  • frontend/src/i18n/locales/ko.json
  • frontend/src/i18n/locales/nl.json
  • frontend/src/i18n/locales/pl.json
  • frontend/src/i18n/locales/pt.json
  • frontend/src/i18n/locales/ru.json
  • frontend/src/i18n/locales/sv.json
  • frontend/src/i18n/locales/th.json
  • frontend/src/i18n/locales/tr.json
  • frontend/src/i18n/locales/uk.json
  • frontend/src/i18n/locales/vi.json
  • frontend/src/i18n/locales/zh-CN.json
  • frontend/src/i18n/locales/zh-TW.json
  • tests/test_locale_parity.py
🚧 Files skipped from review as they are similar to previous changes (18)
  • frontend/src/i18n/locales/hi.json
  • frontend/src/i18n/locales/vi.json
  • frontend/src/i18n/locales/uk.json
  • frontend/src/i18n/locales/id.json
  • frontend/src/i18n/locales/es.json
  • frontend/src/i18n/locales/tr.json
  • frontend/src/i18n/locales/zh-CN.json
  • frontend/src/i18n/locales/ru.json
  • frontend/src/i18n/locales/ja.json
  • frontend/src/i18n/locales/zh-TW.json
  • frontend/src/i18n/locales/it.json
  • frontend/src/i18n/locales/nl.json
  • frontend/src/i18n/locales/de.json
  • frontend/src/i18n/locales/en.json
  • frontend/src/i18n/locales/sv.json
  • frontend/src/i18n/locales/fr.json
  • frontend/src/i18n/locales/pt.json
  • frontend/src/i18n/locales/ko.json

Comment thread tests/test_locale_parity.py
debpalash and others added 2 commits July 28, 2026 15:49
…ce()

Greptile P1: testing a bare `routing_reason` also fires on benign verdicts.
Routing rule 5 gives a Windows DirectML host cpu_only + an explanatory reason
on a perfectly normal pick, and rule 6 attaches one to `unavailable` — neither
is a hardware warning, but both drew a 10s amber toast. routing_notice() in
engine_routing.py is the canonical predicate (cpu_fallback always, accelerated
only with a reason); the frontend now matches it. Two tests, both failing
before.

Also translates settings.engine_switched, which shipped as the identical
"{{family}} → {{engine}}" in all 21 files — an untranslated success toast
everywhere (CodeRabbit). That was the sole _PLACEHOLDER_ONLY_ALLOWLIST entry,
so the allowlist is now empty and the guard has no exceptions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@debpalash
debpalash merged commit 574b283 into main Jul 28, 2026
16 checks passed
@debpalash
debpalash deleted the fix/surface-vram-caveat-1226 branch July 28, 2026 11:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant