Generation profile (#50) #104

Merged
crowmaki merged 3 commits from issue-50-generation-profile into main 2026-10-08 22:38:26 +00:00
Owner

Closes #50.

What changed

  • Generation profile (studio-core/src/generation_profile.rs): diffusion model file (any quantization), text encoder file, an ordered LoRA stack with strengths, Distilled/Full speed, and draft/final short sides. The shipped default reads its two files from the h3.draft template, so it can't drift from the workflows. It is Distilled at 768 / 1120 with no LoRAs.
  • Storage: migration V22 adds project_profile (a singleton) and project_profile_lora. A Project from before V22 gets the shipped profile. A new Project copies AppDefaults.generation_profile. An older defaults.json without that field loads with the shipped profile.
  • Edit: set_generation_profile replaces the whole profile as one undoable edit ("Change generation profile"). It trims file names and refuses blank files, a non-numeric LoRA strength, a short side under 32, and a draft larger than the final.
  • Pickers: comfyui_profile_choices lists /api/models/diffusion_models, text_encoders and loras. When ComfyUI is offline, it returns the reason instead of failing.
  • Preflight: preflight(client, Option<&GenerationProfile>). comfyui_preflight passes the open Project's profile. If a profile file is missing, the three H3 workflows are Not ready with a missing_profile_file reason. The image workflows don't use the profile, so the reason doesn't apply to them. A missing file is matched across \ and /. The render worker passes None for now, because it only runs image jobs. Checking a job's own profile before submission arrives with the draft Take queue (#51).
  • Staleness: the module doc says that the profile is never an input to staleness. I'll comment on #58 with the details.
  • LoRA switch: each LoRA can be switched off. It stays in the stack, dimmed, but is not applied, and preflight doesn't look for its file. The switch is a new Switch control in the UI kit (src/lib/ui/Switch.svelte, on Bits UI).
  • UI: the Generation profile settings page replaces the placeholder. The ComfyUI Section links a missing profile file to that page.

Screenshots

The pickers list what ComfyUI has. A LoRA that ComfyUI doesn't list is marked Missing:

Generation profile page

Diffusion model picker

Each LoRA has an on/off switch. Here a LoRA that ComfyUI lacks is switched on, so it is marked Missing and the H3 workflows are Not ready:

LoRA switched on

Switched off, it stays in the list without being applied, and ComfyUI is ready again:

LoRA switched off

When ComfyUI is offline, the page shows only the saved choices and the file pickers are disabled:

Profile while ComfyUI is offline

A missing profile file makes only the H3 workflows Not ready:

ComfyUI Section with a missing profile file

The screenshots use a stand-in ComfyUI that serves the shipped nodes and some made-up model files.

Testing

  • cargo test --workspace --all-features
  • bun test src scripts
  • bun run check
  • New tests:
    • crates/studio-core/tests/generation_profile.rs covers defaults, app defaults, undo, validation, migration, preflight of missing profile files against the fake, and the pickers.
    • src-tauri/tests/smoke.rs covers the adapter.
    • src/lib/settings/profile.test.ts covers the picker items and the LoRA stack edits.
  • Checked by hand in the running app: picking a model, adding a LoRA, and a refused draft size, which shows the error and goes back to 768.

Review notes

  • The draft ≤ final rule (also a SQL CHECK) is my addition, because Promotion goes from the draft size up to the final size. Say if you'd rather allow it.
  • Rounding to ×32 and applying the speed mode to speed_modes both happen when the job is built (#51), not in this PR.
Closes #50. ## What changed - **Generation profile** (`studio-core/src/generation_profile.rs`): diffusion model file (any quantization), text encoder file, an ordered LoRA stack with strengths, Distilled/Full speed, and draft/final short sides. The shipped default reads its two files from the `h3.draft` template, so it can't drift from the workflows. It is Distilled at 768 / 1120 with no LoRAs. - **Storage**: migration V22 adds `project_profile` (a singleton) and `project_profile_lora`. A Project from before V22 gets the shipped profile. A new Project copies `AppDefaults.generation_profile`. An older `defaults.json` without that field loads with the shipped profile. - **Edit**: `set_generation_profile` replaces the whole profile as one undoable edit ("Change generation profile"). It trims file names and refuses blank files, a non-numeric LoRA strength, a short side under 32, and a draft larger than the final. - **Pickers**: `comfyui_profile_choices` lists `/api/models/diffusion_models`, `text_encoders` and `loras`. When ComfyUI is offline, it returns the reason instead of failing. - **Preflight**: `preflight(client, Option<&GenerationProfile>)`. `comfyui_preflight` passes the open Project's profile. If a profile file is missing, the three H3 workflows are Not ready with a `missing_profile_file` reason. The image workflows don't use the profile, so the reason doesn't apply to them. A missing file is matched across `\` and `/`. The render worker passes `None` for now, because it only runs image jobs. Checking a job's own profile before submission arrives with the draft Take queue (#51). - **Staleness**: the module doc says that the profile is never an input to staleness. I'll comment on #58 with the details. - **LoRA switch**: each LoRA can be switched off. It stays in the stack, dimmed, but is not applied, and preflight doesn't look for its file. The switch is a new `Switch` control in the UI kit (`src/lib/ui/Switch.svelte`, on Bits UI). - **UI**: the Generation profile settings page replaces the placeholder. The ComfyUI Section links a missing profile file to that page. ## Screenshots The pickers list what ComfyUI has. A LoRA that ComfyUI doesn't list is marked Missing: ![Generation profile page](https://git.crowmaki.me/attachments/0cf42030-0b98-41e8-a378-3b96dc425358) ![Diffusion model picker](https://git.crowmaki.me/attachments/22ab5919-8447-4350-ad75-a32b6d19ae3a) Each LoRA has an on/off switch. Here a LoRA that ComfyUI lacks is switched on, so it is marked Missing and the H3 workflows are Not ready: ![LoRA switched on](https://git.crowmaki.me/attachments/7d35ff39-feb0-4b4e-b5cf-9f293a593a77) Switched off, it stays in the list without being applied, and ComfyUI is ready again: ![LoRA switched off](https://git.crowmaki.me/attachments/23529c4b-f9f7-48b7-bc91-4e2117336bcd) When ComfyUI is offline, the page shows only the saved choices and the file pickers are disabled: ![Profile while ComfyUI is offline](https://git.crowmaki.me/attachments/9c8be37a-ab4b-48a3-bf5d-a278839b2ff4) A missing profile file makes only the H3 workflows Not ready: ![ComfyUI Section with a missing profile file](https://git.crowmaki.me/attachments/bcaefd2b-6cc4-4732-9473-b9619e92fc4d) The screenshots use a stand-in ComfyUI that serves the shipped nodes and some made-up model files. ## Testing - `cargo test --workspace --all-features` - `bun test src scripts` - `bun run check` - New tests: - `crates/studio-core/tests/generation_profile.rs` covers defaults, app defaults, undo, validation, migration, preflight of missing profile files against the fake, and the pickers. - `src-tauri/tests/smoke.rs` covers the adapter. - `src/lib/settings/profile.test.ts` covers the picker items and the LoRA stack edits. - Checked by hand in the running app: picking a model, adding a LoRA, and a refused draft size, which shows the error and goes back to 768. ## Review notes - The draft ≤ final rule (also a SQL CHECK) is my addition, because Promotion goes from the draft size up to the final size. Say if you'd rather allow it. - Rounding to ×32 and applying the speed mode to `speed_modes` both happen when the job is built (#51), not in this PR.
A Project default Generation profile: diffusion model and text encoder
files, a LoRA stack with strengths, Distilled/Full speed and draft/final
short sides (768/1120). New Projects copy it from the app defaults, and
Projects from before it get the shipped H3 files.

The settings page picks files from the user's ComfyUI via /api/models/*.
Preflight checks the open Project's profile files on the H3 workflows.
The profile is never an input to staleness.
Fix the run of spaces in the missing profile file message and pin it in
a test, note that V22's file names are frozen, and give the profile
view's refresh clearer names.
A LoRA switched off stays in the stack but is not applied, and preflight
no longer needs its file. The LoRA rows get a slider switch, a new
Switch control in the UI kit.

Also document loading the Forgejo token from .env for PR images.
crowmaki deleted branch issue-50-generation-profile 2026-10-08 22:38:27 +00:00
Sign in to join this conversation.
No description provided.