Adds SeedVR2 as a new upscale mode alongside HiRes Fix, Model Upscale,
and Model+HiRes. Requires ComfyUI-SeedVR2_VideoUpscaler to be installed
as a dependency — the plugin calls its nodes programmatically.
Data Model:
- New seedvr2 options object on each upscale step with all SeedVR2
parameters: dit_model, resolution, max_resolution, seed,
color_correction, batch_size, noise scales, blocks_to_swap,
attention_mode, offload_device, cache_model, VAE tiling options
- _defaultSeedVR2Options() / createDefaultSeedVR2Options() helpers
- Migration: ensureStepFields adds seedvr2 defaults to existing configs
Builder UI (conf-builder-config-management.js):
- "SeedVR2 Upscale" added to mode dropdown
- When selected, shows full SeedVR2 settings: DiT model selection
(10 variants: 3B/7B x fp16/fp8/GGUF/sharp), resolution, seed,
color correction, noise scales, batch size, VRAM optimization
(blocks_to_swap, attention_mode, offload), VAE tiling with
conditional encode/decode tile size and overlap fields
Dashboard (logic_upscale_modal.js):
- Same SeedVR2 mode and fields in renderPipelineEditor via _renderStep
- All fields use existing _makeSelect/_makeNumber/_makeCheckbox helpers
Python Execution (image_generation.py):
- New seedvr2_upscale(pil_image, seedvr2_config) function
- Imports SeedVR2 nodes from NODE_CLASS_MAPPINGS at runtime
- Calls SeedVR2LoadDiTModel → SeedVR2LoadVAEModel → SeedVR2VideoUpscaler
- Converts PIL→tensor→SeedVR2→tensor→PIL
- Clear error if SeedVR2 not installed
Pipeline Integration (generation_orchestrator.py):
- Inline upscale path: mode=="seedvr2" branch decodes current latent
to PIL, calls seedvr2_upscale, saves result, updates manifest
- Supports chained steps: non-final SeedVR2 steps re-encode to latent
for the next step in the pipeline
Preset compatible: seedvr2 config serializes naturally as JSON, saved
and loaded with upscale presets without any special handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The master's wait-for-workers loop could block forever if a worker
crashed without cleanup, leaving a job in "Claimed" state. The
_release_timed_out_jobs() was only called during claim_job, never
during the wait loop.
Fixes:
- Call release_timed_out_jobs() every 5s during the wait loop to
reclaim jobs from dead workers (no heartbeat)
- Add configurable wait_timeout (default 600s/10min) from distribution
config — after timeout, force-reclaim all remaining claimed jobs and
proceed to finalization instead of looping forever
- Add public release_timed_out_jobs() method to DistributionManager
- Remaining jobs after timeout are marked completed and abandoned with
a warning, unblocking the ComfyUI queue
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Workers now generate base images only, and the master runs all upscale
pipelines after distributed generation completes. Uses the existing
run_deferred_upscales() function. The warning message now says upscales
will run on master after collection instead of "not supported."
Builds deferred queue from all generated items in existing_data, runs
after remote VAE cleanup but before final manifest save.
Also adds model count endpoint for fast change detection.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add _expand_lora_weight_arrays() that expands bracket notation in LoRA
strength fields into Cartesian product of configs:
lora1:[0.5, 1.0]:1.0 + lora2:0.8:[0.7, 1.0] → 4 configs
Distinguishes weight arrays (brackets in strength after :) from folder
random syntax (brackets in name before :). Runs before folder expansion
so both features work together correctly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The delayed manager cleanup used a flat 30s timer, which could expire
before a slow worker finished submitting its last result. Now polls
every 10s (up to 5 minutes) checking if any registered workers still
have recent heartbeats before cleaning up the manager.
Also added clarifying comment on submit_result route — it intentionally
does NOT check is_active, only manager existence, to accept late
submissions from workers that were mid-generation when master finished.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New 'Run Settings' section in Builder UI with a job number input.
When set > 0, the generation loop skips all jobs before that number.
Useful for resuming at a specific point without relying on
auto-detection. Flows through session settings to the orchestrator.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When run_upscales_at_end is enabled, inline upscale is skipped and
jobs are queued. After generation completes (before cleanup), the
deferred phase loads base images from disk, VAE-encodes them, and
runs full pipeline chains. Includes resume support, interrupt handling,
and progress reporting with phase="upscaling".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace set() with ordered list dedup for batch encoding so prompts
generate in the order they're written in the config array
- Track cumulative upscale duration so the time metric includes both
generation and all upscale steps instead of just the last upscale
Co-Authored-By: Claude Opus 4.6 (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>
Three bugs fixed:
1. Upscaled images used bare 'filename=...' instead of full '/view?filename=...&type=output&subfolder=...' URL format, causing 404s in dashboard
2. Upscaled manifest entries missing 'id' and 'rejected' fields, causing holes in dashboard grid
3. Base (non-upscaled) images were still saved to pending_batch when upscaling was enabled — now only upscaled final versions appear in output
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Skip upscale combos that require a model when none is selected.
Use effective_size=2.0 for model_only mode instead of 1.0 which
would resize the model output back to original resolution.
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>
Previously, check_if_job_completed() with optional inputs would only
match on sampler/scheduler/steps/cfg/denoise/seed — skipping model,
prompt, and lora checks. This caused false positive matches, skipping
jobs even when the user changed models via optional input nodes.
Now returns -1 (no match) immediately when has_optional_inputs=True,
forcing all jobs to re-generate since upstream changes can't be detected.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The conditioning serialization was only preserving pooled_output, dropping
critical keys like attention_mask that Wan/T5 models need for proper
sampling. This caused KSampler to produce NaN latents on distributed workers.
Includes backwards compatibility with old serialization format.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ComfyUI v16.3's Dynamic VRAM uses ModelPatcherDynamic which asserts
force_patch_weights=False. Removed the flag from both CLIP GPU loading
calls to match ComfyUI's own CLIP.load_model() pattern. Backwards
compatible with older ComfyUI versions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix Python 3.10 SyntaxError: extract backslash replace() out of f-string
expression in config_builder_node.py (issue #12)
- Fix dashboard iframe stealing focus from ComfyUI on every live update
by removing viewport.focus() from render/update paths in logic_virtual.js
- Intercept Ctrl+S in dashboard iframe and forward to ComfyUI parent
window so workflow save works instead of triggering browser Save As dialog
- Config Builder VAE settings now override sampler node's remote_vae_endpoint
via config_overrides_vae flag in generation_orchestrator.py flush logic
- Fix Shift+1-9 column hotkeys: use e.code instead of e.key since Shift
produces symbols (!@#$) not digits for e.key on standard keyboards
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The DistributionManager, config builder, and UI all already used 600 as
the default, but the orchestrator's fallback was still 300. This caused
premature job reclaim when workers loaded models for the first time.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Worker downloads missing models from master via HTTP before processing.
Background pre-fetch thread downloads upcoming models during job execution.
Distribution manager scans pending queue for unique model references.
Job claim responses include upcoming_models list when sync enabled.
Master passes sync_models_to_workers flag to workers via start_worker.
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>