Four actionable findings from round 30. Skipped P1 #1 / #2 / #3
(huggingface-hub bump in studio.txt / single-env / colab-new) because
the live B200 Studio that successfully generated FLUX.2 klein images
runs the exact combo the reviewer flags as broken:
huggingface_hub 0.36.2 + transformers 4.57.6 + diffusers 0.37.1
Flux2KleinPipeline: True (imports cleanly)
The is_offline_mode ImportError only fires with transformers 5.x, and
the standard install path pins transformers==4.57.6 via constraints.
The round 26 fix bumped no-torch-runtime.txt + pyproject huggingfacenotorch
where the --no-deps install path can land on transformers 5.x; that
remains the correct surface.
1. core/inference/diffusion.py: preflight transformers + accelerate
via importlib.util.find_spec BEFORE any destructive GPU-owner
unload. Diffusers can expose stub pipeline classes when
transformers / accelerate are missing, so the load used to drop
chat first and fail later inside from_pretrained. find_spec
keeps existing tests that stub these modules passing because no
real module is executed (round 30 P1 #11).
2. models/export.py ExportGGUFRequest.quantization_method: extend
the embedded HF token validator to this field too. Round 23
added the control-char guard but not the token guard; the value
is forwarded into worker command lines and reflected in error /
success text (round 30 P1 #5).
3. models/data_recipe.py SeedInspectUploadRequest: add
_no_control_chars + _reject_embedded_hf_token field_validators
to filename and to each entry of file_names. Mirrors the sibling
SeedInspectRequest.dataset_name hardening (round 30 P1 #6).
4. frontend/src/features/images/images-page.tsx: defer the initial
refreshStatus() call via queueMicrotask so the synchronous
setRefreshingStatus(true) inside it does not trip the
react-hooks/set-state-in-effect lint on mount (round 30 P2 #12).
Deferred (need larger surgery / out of scope for this round):
P1 #4 native_path_lease for diffusion local-path loads
P1 #7-#10 helper/advisor + public-start window mutual lock symmetry
Tests: 98 targeted (diffusion + cached_gguf + inference_validation)
pass locally; frontend npm run typecheck passes.
Five additional P1 findings round 27 reviewer flagged on top of the
round 27 commit 6c528fb0 (Counter refcount + handoff visibility were
already covered). Three remaining studio.txt / no-torch-runtime hub
suggestions are NOT applied because they would re-break CI; the
empirical evidence (round 26 commit 65ea3a2c restored CI green) takes
precedence over the reviewer's stale-state suggestion.
1. models/training.py TrainingStartRequest: extend the embedded HF
token validator to subset, train_split, eval_split. Round 26 only
added the control-char guard to those three; the token guard was
asymmetric and would accept owner/data\\nFAKE hf_abcdef...
payloads through subset / split fields.
2. models/datasets.py CheckFormatRequest: extend both validators
(control chars + embedded HF token) to subset and train_split.
Same asymmetric-fix bug as #1.
3. models/data_recipe.py SeedInspectRequest: extend both validators
to subset and split. Same pattern.
4. utils/datasets/llm_assist.py precache_helper_gguf: register the
helper repo in the helper/advisor refcount registry around the
hf_hub_download loop, then unregister in the finally. Without
this, the FastAPI-startup background pre-cache could be racing
a concurrent DELETE /api/models/delete-cached against the same
cache directory. The runtime helper / advisor calls already
register (round 26 P1 #13/#14) but the precache was the
asymmetric gap.
5. routes/models.py _loaded_model_matches_deleted_path: match
bidirectionally (active under target OR target under active) so
deleting a child directory of a loaded local model (.../my-flux/
text_encoder while .../my-flux is loaded) trips the guard.
Mirrors the diffusion delete-guard symmetric path-overlap check.
Tests: 105 targeted (diffusion + cache + inference_validation) and
the broader backend suite pass locally.
Twelve P1 findings from round 26 reviewer aggregate, plus the CI
revert of round 25 P1 #5 to a less invasive location.
1. requirements/studio.txt + requirements/single-env/constraints.txt:
revert the round 25 huggingface-hub bump (broke Studio Update CI,
Mac Studio Update CI, Mac Studio UI CI, Studio UI CI all with
ResolutionImpossible against transformers==4.57.6 which requires
hub<1.0). Standard install path stays on the well-tested 4.57.6 +
0.36.2 + trl 0.23.1 trio.
2. requirements/no-torch-runtime.txt + pyproject.toml
[huggingfacenotorch]: bump huggingface_hub floor from >=0.34.0 to
>=1.3.0,<2.0 -- this is where the actual transformers 5.x +
hub 0.36.2 broken combo can land because the file installs
--no-deps. transformers 5.x calls hub.is_offline_mode which only
exists in hub 1.x.
3. utils/datasets/llm_assist.py: revert round 25 P1 #4 (helper/advisor
sharing the global llama backend) which introduced three
regressions: a chat-evict load race after the busy precheck, a
finally-block that could unload a user chat model, and an
identifier mismatch the delete guard could not canonicalize. Go
back to PRIVATE LlamaCppBackend instances and expose the active
helper/advisor repos through a new thread-safe registry
(helper_advisor_owns_repo / _register_helper_advisor_repo /
_unregister_helper_advisor_repo) so DELETE /api/models/delete-cached
can still block the rmtree.
4. routes/models.py delete_cached_model: check the new helper/advisor
registry up front and 409 if a helper/advisor still owns the
target repo. Closes round 26 P1 #13 and #14 (helper/advisor
identifiers were prefixed and would never equal the raw repo id).
5. routes/models.py get_lora_base_model: validate lora_path with
_validate_logged_identifier before it is reflected in 404 detail
and error logs (round 26 P1 #12).
6. routes/inference.py /unload: round 21 P1 #3 added a "or not
is_loaded" fallback that let an unload of owner/B cancel a pending
llama load of owner/A. Replace it with a narrow
llama_is_starting_without_identifier branch that only fires when
llama-server is mid-startup with neither identifier set (round 26
P1 #5).
7. routes/inference.py /unload: poll loading_model_identifier for up
to 5 s after asyncio.to_thread(unload_model) so a legitimate
pending-load cancel does not 503 because the load thread has not
yet observed _cancel_event in its finally (round 26 P2 #15).
8. models/training.py TrainingStartRequest: extend identifier
hardening to hf_dataset, subset, train_split, eval_split. Round 22
only guarded model_name (round 26 P1 #10).
9. models/data_recipe.py SeedInspectRequest: add _no_control_chars +
_reject_embedded_hf_token field_validators on dataset_name (round
26 P1 #11).
Tests: 105 targeted (diffusion + cached_gguf + llama_cpp_cache +
inference_model_validation + models_get_model_config) and 1768
broader backend tests pass locally. Pre-existing
test_desktop_auth.py, test_studio_api.py, and
test_training_worker_flash_attn.py failures reproduce on HEAD
without these changes.
P1 #1 + #2 + #6: extended the chat / diffusion / training
identifier hardening to every export-side request model.
ExportCommonOptions (parent of ExportMergedModelRequest /
ExportBaseModelRequest / ExportLoRAAdapterRequest) now applies
_no_control_chars and _reject_embedded_hf_token to repo_id and
base_model_id; ExportGGUFRequest gets the same on its repo_id
plus a control-char check on quantization_method; and
LoadCheckpointRequest validates checkpoint_path. Previously
"/api/export/*" accepted newline-smuggled identifiers and
URL-form ``hf_xxxxx`` tokens that flowed into log lines.
P1 #3 + #4: ``_run_with_helper`` and ``_run_multi_pass_advisor``
now use a shared ``_gpu_workload_busy_for_helper`` that gates on
diffusion (round 22 already), training, AND export. The round 22
guard only checked diffusion, so the dataset helper / advisor
could still load llama-server on top of an active training run
or a resident export checkpoint. Each step fails closed
(unverifiable status counts as busy) so the user's primary
workload is preserved.
P1 #5: PublishDatasetRequest in models/data_recipe.py also
applies the identifier hardening to repo_id; the publish path
previously accepted control characters and URL-form tokens.
P1 #7-10: added _validate_logged_identifier helper to
routes/models.py and applied it to the path / query parameter
endpoints that flow into logger.info(...) calls --
``/config/{model_name}``, ``/check-vision/{model_name}``,
``/check-embedding/{model_name}``, ``/gguf-variants``. Mapped
the validator's ValueError to HTTP 422 so the client sees the
same shape as a Pydantic validation failure.
P2 #11 + #12: ``Loading diffusion model %s`` and
``Diffusion load failed for %s`` log lines route ``repo_id`` /
``effective_base`` through ``_display_repo_id`` (collapses
absolute local paths to the leaf, still scrubs HF tokens)
instead of plain ``_redact_hf_tokens``. The error path was
already collapsed in the user-facing 400 / RuntimeError, but
the structured-log lines kept the full path.
All 97 diffusion + training-validation + related tests pass
locally.
* fix(recipe-studio): prevent fitView from zooming to wrong location on recipe load
* feat: add pymupdf/python-docx deps and unstructured uploads storage root
* feat: add POST /seed/upload-unstructured-file endpoint
* feat: add multi-file chunking with source_file column
* feat: update frontend types and API layer for multi-file upload
* feat: round-robin preview rows across source files
Ensures every uploaded file is represented in the preview table
by cycling through sources instead of just taking the first N rows.
* fix: disable OCR, fix auto-load timing, fix persistence on reload
- Disable pymupdf4llm OCR with write_images=False, show_progress=False
- Replace onAllUploaded callback with useEffect that detects uploading→done
transition (avoids stale closure reading empty file IDs)
- Fix importer to preserve file IDs from saved recipes instead of clearing
(clearing only happens at share time via sanitizeSeedForShare)
* fix: harden unstructured upload with input validation and state fixes
Validate block_id/file_id with alphanumeric regex to prevent path
traversal, use exact stem match for file deletion, add error handling
for metadata writes and empty files, fix React stale closures and
object mutations in upload loop, and correct validation logic for
unstructured seed resolved_paths.
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* fix: address PR review - legacy path import, share sanitizer, sync effect
Promote legacy source.path into resolved_paths for old unstructured
recipes, clear source.paths in share sanitizer to prevent leaking local
filesystem paths, and gate file sync effect to dialog open transition
so users can actually delete all uploaded files.
* fix: CSV column fix (BOM + whitespace + unnamed index re-save) for #4470
* fix: harden unstructured upload flow and polish dialog UX
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* miscallenous studio
* chore: upload dataset misc
* chore: redudancy studio cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* fix: adress the pr comments
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* fix: adress comments about recipes
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
- Added `ExecutionsView` with execution history tracking, live updates, and detailed data analysis.
- Implemented IndexedDB support via Dexie to persist execution records locally.
- Enhanced backend preview logic to return execution analysis and artifacts.
- Updated studio header with view toggling between "Editor" and "Executions."