Pure-Python core of Workflow Sweep: parse an API-format workflow, suggest bindings,
expand them into jobs (cache-friendly axis order, resume fingerprints), substitute
into the template and append the collector node. Builder state emits kind=workflow
arrays, config_utils.expand_configs dispatches model_type=workflow, and
manifest_utils.append_items adds disk-fresh manifest appends.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- run_generation_loop walks a flat job plan (config_utils.build_job_plan) instead of the
nested resolution x config loops; job_order=minimize_reloads reorders it to cut model
and LoRA reloads. as_written reproduces the old order exactly.
- Preview pass (fewer steps, smaller snapped latent, no upscales); items carry config_fp,
preview_of, full_* keys. A full run skips cells whose preview was rejected (tombstoned
in meta.rejected_preview_fps by delete_rejected); a preview run skips cells that already
have a full image.
- check_if_job_completed gets a keyword-only preview flag (positional API unchanged).
- Distributed mode is untouched apart from an 'ignored' warning.
fix: a per-config resolution no longer leaks its w/h/batch_idx into later configs of the
same pass (the old loop set them once per input job; the pre-flight scan already did this
correctly, so pre-flight and the main loop disagreed).
fix: the async look-ahead picked the next config via job_idx*len(expanded)+conf_idx, which
was wrong whenever per-config-resolution configs were skipped after the first pass; it now
reads the next plan entry.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
From #21: _expand_ltx_entry ran positive/negative through to_list, so the
Builder's [["p1","p2"]] reached the LTX encoder as a list; it now uses
parse_prompt_input_nested like expand_configs. The text-encoder dropdown
falls back to ["None"] when the list is empty. convertConfigsToConfigArrays
keeps the per-entry model type for builder-schema models[].
Refs #21
Co-authored-by: DRuggeri <DRuggeri@users.noreply.github.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Builder Run Settings already emitted add_random_seeds_to_gens through
_session_settings; this adds the missing new-state default and the
saved-config migration, tests for the emit -> sampler_node unwrap ->
expand_configs path, and a README Run Settings entry.
The extra seeds are now derived from the base seed
(config_utils.derive_extra_seeds) instead of unseeded random.randint, as the
README always promised. Besides reproducibility this makes stop/resume work:
the skip check matches on seed, so an interrupted run can now skip the
extra-seed images it already rendered.
Ported from #21 (it conflicts after the repo restructure). Closes#21.
Co-authored-by: DRuggeri <DRuggeri@users.noreply.github.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Pure helpers in config_utils (build_job_plan, order_job_plan, count_switches,
config_fingerprint, item_fingerprint, preview_dims, build_preview_index,
should_skip_for_previews, build_full_fp_set) with tests. Not wired in yet.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
MOSS-Image (Flux.2 latent: 128ch, 16 px per cell) jobs were built with the
SD-era `h // 8`, so every image sampled a latent with 4x the cells and decoded
at 2x the requested size (832x1216 -> 1664x2432): ~10x slower than the official
ComfyUI template (~120 s vs ~10 s per image on the 5060 Ti).
- model_loader: get_latent_downscale_ratio() reads latent_format.spacial_downscale_ratio
(8 for SD/SDXL/Flux.1, 16 for the Flux.2 family); make_empty_latent() builds the
job latent and warns when WxH is not a multiple of the ratio. Both orchestrator
latent sites (main loop + distributed worker) use it; hires-fix latent upscale,
tiled hires sampling and VAE tiling divisors no longer assume 8.
- CLIP type: resolve_clip_type() warns on unknown types instead of silently using
stable_diffusion, and when clip_type is left at the default it follows the
detected model family (MOSSImage -> moss_image, Flux2 -> flux2, ...). MOSS loaded
as a generic Qwen3.5 TE before (wrong chat template). The Builder's CLIP Type
list is now read from ComfyUI's CLIPLoader/DualCLIPLoader (static list = fallback,
now including moss_image); LS_CACHE_VERSION 3 refreshes cached lists.
- Skip Layer Guidance: new Extra Model & Sampling sub-group wrapping
SkipLayerGuidanceDiTSimple (double/single layers, start/end %), plumbed like Deep
Shrink (builder emission, expand_configs, orchestrator, generate_image). Defaults
match the official MOSS-Image workflow (single block 22, 0-50%).
- tests: latent geometry + clip type resolution, dynamic clip type lists, SLG
config emission/expansion (24 new; the 15 pre-existing torch-stub failures unchanged).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds a new SUB-GROUP 4 in the Builder UI's "Extra Model & Sampling
Options" section with all 7 params from ComfyUI's built-in
PatchModelAddDownscale node:
- block_number (int, default 3)
- downscale_factor (float, default 2.0)
- start_percent / end_percent (float 0-1, default 0.0 / 0.35)
- downscale_after_skip (bool, default true)
- downscale_method / upscale_method (combo: bicubic/nearest-exact/
bilinear/area/bislerp, default bicubic)
Toggle checkbox controls whether the patch is applied. State plumbs:
config_array.use_deep_shrink/* (JS) -> state_to_configs_json -> per-
config entries -> expand_configs base_combos -> generate_image -> looks
up PatchModelAddDownscale via NODE_CLASS_MAPPINGS and calls .patch() to
patch the model before sampling. Logs an "Applied
PatchModelAddDownscale" line on each gen for visibility.
Mirrors the existing model_sampling_override / use_advanced_sampling
patterns for consistency. Hidden on LTX video config arrays since the
patch targets the SDXL/SD UNet.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
User reported that changing seed in the Revise modal had no effect —
the new seed was overwritten and the orchestrator's check_if_job_completed
matched the original item's seed, skipping the gen.
Root cause: config_utils.expand_configs unconditionally wrote
"seed": <global node seed> for every config, ignoring entry["seed"]
from the configs_json. Builder UI doesn't emit entry["seed"] (it relies
on the node-level seed widget), so this regression only surfaced when
something else explicitly set per-entry seed — exactly what triggerGen
does.
Fix: use entry["seed"] when present and non-empty, otherwise fall back
to the global seed. Builder UI flow unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace flat upscale configs with pipeline/steps/repeat architecture:
- Pipelines run independently from base image
- Steps chain sequentially within a pipeline
- Steps support repeat count for iterative refinement
Add "Save Pre-Upscaled Output" option to also keep the base image.
Add "Adjust Prompt During HiRes Fix" with prepend/append/replace
behaviors. HiRes-adjusted prompts are batch pre-encoded for efficiency.
Results written to manifest metadata and exposed as label overlays.
Fix fmtVal scoping error in buildLabelOverlay (was referenced outside
the upscale block where it was defined).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Seed: expanded per-gen behavior + new full run seed behavior (random/increment/decrement before/after entire run)
- Canvas: fix flicker during simultaneous pan+zoom via requestAnimationFrame batching
- Upscaling: 3 session-level modes (HiRes fix, model upscale, model+HiRes) with tiled VAE support
- Cooldown: configurable GPU breaks between generations with optional VRAM clearing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Each config array can now have its own resolution list displayed as chips with
categorized preset dropdown (SD 1.5/SDXL/Flux × Square/Portrait/Landscape) plus
custom W×H input. Resolutions flow through configs_json, expand in the Cartesian
product, and override the sampler's global resolutions_json on a per-config basis.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>