unsloth/studio
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
..
backend Studio: tools, thinking blocks, code execution and web search for safetensors (#5520) 2026-05-19 06:30:17 -07:00
frontend studio/frontend: compare composer blocks send when no model picked (#5574) 2026-05-19 06:56:30 -07:00
src-tauri studio: regenerate desktop launcher on unsloth studio update (macOS + Linux + Windows) (#5577) 2026-05-19 05:49:10 -07:00
__init__.py Final cleanup 2026-03-12 18:28:04 +00:00
install_llama_prebuilt.py tests/studio: lock in Windows GPU detection fix (#5106) with a synthetic CI test (#5376) 2026-05-18 00:06:01 -07:00
install_python_stack.py studio: skip flash-attn install on Blackwell GPUs (sm_100+) (#5420) 2026-05-14 18:13:50 +04:00
LICENSE.AGPL-3.0 Add AGPL-3.0 license to studio folder 2026-03-09 19:36:25 +00:00
package-lock.json ci: advisory lockfile supply-chain audit (no install-script changes) (#5604) 2026-05-19 05:56:56 -07:00
package.json ci: advisory lockfile supply-chain audit (no install-script changes) (#5604) 2026-05-19 05:56:56 -07:00
setup.bat Final cleanup 2026-03-12 18:28:04 +00:00
setup.ps1 studio: regenerate desktop launcher on unsloth studio update (macOS + Linux + Windows) (#5577) 2026-05-19 05:49:10 -07:00
setup.sh Route CPU-only Linux x86_64 to ggml-org/llama.cpp prebuilts (#5302) 2026-05-05 23:22:22 -07:00
Unsloth_Studio_Colab.ipynb studio: add --local to setup.sh + overlay unsloth-zoo from git main (#5252) 2026-05-02 08:51:56 +04:00