_arch_to_task mapped every arch in _VIDEO_GGUF_ARCHS to text-to-video, so a cached wan GGUF was
surfaced in the Video picker even though no Wan VideoFamily is registered in this build, and
selecting it 400s on load. Gate the video task on detect_video_family actually resolving the
arch: an unregistered video arch (wan here) falls to the unsupported bucket (hidden from chat and
the Video/Images pickers) until its family lands, so the picker never offers a GGUF that cannot
load. Correct in both stacked video PRs (ltxv resolves; wan resolves only once its family exists).
Two follow-ups to the video-tab review fixes:
- the cached-hub arch fallback only probed the active HF cache, but the cached-gguf picker
scans the active, legacy, and default cache roots; a GGUF cached in a non-active root was
offered yet 400d on load. Probe all three roots.
- on a mount/refresh with a model already resident, status.loaded made the Reapply button render
but lastLoad (set only by our own loads) was null, so clicking it silently did nothing. Track a
session reapply descriptor and hide the button when it is absent rather than offer a dead control.
Three video-tab fixes:
- delete-cached refused a loaded video repo but not one a background load is still downloading
(status().loaded is False in that window); add VideoBackend.loading_repo_ids() mirroring the
image backend and check it in the route so deleting mid-download can no longer yank blobs.
- the cached-gguf picker tags a cached HUB GGUF by its general.architecture, but the loader's
arch fallback only read a LOCAL file, so an opaquely-named cached hub LTX GGUF the picker
offered 400d on load; read the arch from the cached blob (network-free) too.
- on a mount with a model already loaded (refresh / load from another client) steps and guidance
stuck at the pre-load default, so a base checkpoint silently generated a degraded clip; seed
them from the backend-authoritative status.defaults once per newly-loaded model.
- delete_cached_model guarded chat (llama.cpp/transformers) and Images but not the
Video backend, so a loaded video GGUF (which shares the On-Device GGUF delete UI)
could be removed from under a live pipeline. Add the mirror guard on
get_video_backend().status().
- The Video picker admits a local GGUF by its general.architecture, but the loader
detected the family only from path/name tokens, so a renamed ltxv file (e.g.
model.gguf) was offered yet failed validate_load_request with a 400. _detect_load_family
now falls back to reading the arch (its string is a family alias) when name detection
misses, so the loader accepts exactly what the picker offered; an unsupported video arch
(wan) still resolves to None and 400s as before.
Ideogram 4 assembles two DiTs per-component (a conditional transformer plus a
separate unconditional_transformer), so there is no transformer-only single-file
or GGUF artifact that could supply both. Add a pipeline_only family flag and
reject the gguf/single_file kinds in validate_load_request, before a load evicts
the current model, instead of assembling a pipeline missing its second DiT.
Extend the fp8 bf16-resident size override to a LOCAL directory mirror of the
ideogram-4-fp8 base: such a path never string-matches base_repo, so detect the
fp8 layout from the transformer shard headers (a *.weight_scale marker) and
reserve the bf16 footprint, matching the remote-base behaviour. A local nf4
mirror has no fp8 scales and correctly stays planned against its compressed bytes.
A successful on-demand wheel install writes into site-packages after the
import system already cached that directory's listing, so the very next
find_spec / import in the same process can miss the freshly installed
package when the install lands within the directory mtime's resolution.
That silently falls set_attention_backend back to native on first use.
Call importlib.invalidate_caches() after a successful install so the
kernel is picked up immediately, and cover both the success and failure
paths in the attention installer tests.
Review follow-ups on the image-generation PR:
- ControlNet: resolve_controlnet accepts a bare owner/name repo without the
non-GGUF base trust gate, and _controlnet_pipe hands it straight to
from_pretrained. A malicious pickle .bin would deserialize on load, so run
the same Hugging Face malware preflight (evaluate_file_security) the chat and
export loaders use before any remote ControlNet load; local dirs are exempt.
- Dataset thumbnails: key the cache on the full filename instead of the stem so
sample.png and sample.jpg no longer collide on one .thumbs file (which could
serve or delete the wrong image); the delete cleanup globs the same key.
- Diffusion training start: mirror start_training's API-key guard so an API
client cannot start training (which frees VRAM by unloading chat) while an
inference request is streaming; it now returns 409 before any GPU is freed.
- Model picker: include the curated safetensors row keys in the recommended
roving key list so arrow-key navigation reaches those rows instead of hitting
the duplicate option-missing id.
Tests: ControlNet malware gate (remote blocked before from_pretrained, local
skipped), thumbnail same-stem cache separation, API-key diffusion-start 409
before GPU free. Full diffusion suites green.