From 604949390bba94b7a998d892d0ae314adfa8b653 Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Wed, 1 Jul 2026 09:29:51 +0000 Subject: [PATCH] Studio Images: list on-device unsloth diffusion models in the picker The Images picker's On Device tab hid every non-GGUF cached repo whenever a task filter was active, so downloaded unsloth diffusion pipelines (bnb-4bit and FP8 safetensors) never showed up there. List cached repos that pass the task gate, limited under a filter to unsloth-hosted ones so base repos (which fail the diffusion load trust gate) don't appear only to dead-end on click. Chat behavior is unchanged: the task gate still drops image repos there. --- .../assistant-ui/model-selector/pickers.tsx | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx b/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx index 5fe8c4fd6d..f44c4dc150 100644 --- a/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx +++ b/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx @@ -1790,18 +1790,21 @@ export function HubModelPicker({ ), [cachedGguf, downloadedSort, loadTimes, task], ); - // Non-GGUF (safetensors) cached repos aren't single-file diffusion GGUFs, so - // hide them entirely when a task filter is active (the Images picker). In chat, - // drop cached diffusers pipeline repos (a Z-Image / FLUX base) the same way. + // Cached non-GGUF repos. In chat, passesTaskGate drops diffusers image repos. In the + // Images picker (task set) it keeps them, but limit to repos this backend can actually + // load as diffusion: unsloth-hosted ones. Base repos (Qwen/Qwen-Image, FLUX bases) are + // cached as dependencies and fail the diffusion trust gate, so listing them would dead-end. const sortedCachedModels = useMemo( () => - task - ? [] - : sortCachedRepos( - cachedModels.filter((c) => passesTaskGate(c.task, c.repo_id, task)), - downloadedSort, - loadTimes, - ), + sortCachedRepos( + cachedModels.filter( + (c) => + passesTaskGate(c.task, c.repo_id, task) && + (!task || isUnslothRepoId(c.repo_id)), + ), + downloadedSort, + loadTimes, + ), [cachedModels, downloadedSort, loadTimes, task], ); // Each local section's search is scoped to its own models (matched by name).