unsloth/studio/frontend/src/features
Daniel Han feadfd5c1b
studio/frontend: compare composer blocks send when no model picked (#5574)
* studio/frontend: compare composer blocks send when no model picked

Closes the racing-handle half of #5569. In Compare mode (GeneralCompare
shell with model1/model2 props), if the user sends a prompt before
picking models in either pane, the SharedComposer used to fall through
to the per-handle append branch. Both panes then raced
createOpenAIStreamAdapter -> autoLoadSmallestModel, one won, the other
dispatched into an unloaded slot and produced an empty bubble with a
1000000.0 tok/s readout. The per-pane picker state never observed the
global checkpoint change either, so both pickers stayed at
"Select model".

Add a guard before the content build: when handlesRef has model1/model2
keys but both selections are empty, surface a toast asking the user to
pick models first, leave the text in the composer for retry, and never
enter the racing dispatch path. Keeps the per-pane picker state as the
source of truth for which model is on each side.

The unphysical tok/s readout that the same path produced is separately
covered by PR #5570 (display guard).

* studio/frontend: tighten compare-mode guard to require both panes

Review feedback on #5574:

  - Gemini: the redundant `model1 !== undefined && model2 !== undefined`
    checks let the racing-handle dispatch slip through whenever the
    Compare props arrive as undefined, which is the exact case the
    guard is trying to block.
  - Codex: with `isGeneralizedCompare` keyed on `model1?.id || model2?.id`,
    a half-selected Compare (one model picked, one empty) still falls
    into the generalized branch. The composer clears, the empty pane
    gets the user message appended, and `startRun` only fires for the
    side with an id, leaving the empty pane with a dangling prompt
    and no response.

Switch `isGeneralizedCompare` to require BOTH panes (`&&`), drop the
undefined gate, and surface the "Pick a model in each pane" toast for
either the fully-empty or half-selected case. `hasCompareHandles` is
true only inside GeneralCompareContent, so LoraCompare and the
single-pane path stay unchanged.

* studio/frontend: shorten compare-mode no-model-guard comment

* studio/frontend: clarify compare-pane toast wording

---------

Co-authored-by: danielhanchen <michaelhan2050@gmail.com>
2026-05-19 06:56:30 -07:00
..
auth studio/web: differentiate offline from backend-down in fetch error (#5591) 2026-05-19 06:56:10 -07:00
chat studio/frontend: compare composer blocks send when no model picked (#5574) 2026-05-19 06:56:30 -07:00
data-recipes Fix Studio desktop tray installer and titlebar and bux fixes (#5179) 2026-04-30 08:40:39 -07:00
export studio/frontend: wire logout, singleflight refresh, shared 422 helper, current-password input (#5490) 2026-05-18 00:03:03 -07:00
native-intents studio/frontend: make toast and inline error text selectable and copyable (#5506) 2026-05-18 03:47:21 -07:00
onboarding feat(studio): add Continued Pretraining (CPT) as a training method (#4677) 2026-05-06 13:38:35 +04:00
profile Studio: Polish spacing and profile input radius (#5222) 2026-05-04 00:38:19 +04:00
recipe-studio studio/frontend: make toast and inline error text selectable and copyable (#5506) 2026-05-18 03:47:21 -07:00
settings studio/frontend: keep theme classes mutually exclusive on <html> (#5580) 2026-05-19 06:56:15 -07:00
studio studio/frontend: make toast and inline error text selectable and copyable (#5506) 2026-05-18 03:47:21 -07:00
tour fix(studio): open tour ReadMore links in new tab (#4694) 2026-03-30 23:41:14 -07:00
training studio/frontend: make toast and inline error text selectable and copyable (#5506) 2026-05-18 03:47:21 -07:00