Extends the shared web/js/multi_loader.js to a third kind ("video") for
AI2GoMultiVideoLoader / AI2GoMultiVideoLoaderAdvanced: NODES map entries,
video/* MIME acceptance, drop-zone wording, a video-row preview (mm:ss +
WxH probed via a hidden <video>), and a serializeValue guard on force_rate
mirroring the existing max_size guard so a '' value can't fail validation.
README and the design spec's amendments section are extended to match.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Follows the pack's simple/Advanced batch-loader pattern (multi_image_loader,
multi_audio_loader): drop up to 8 video files onto the node, each gets its
own video_N/audio_N output (plus filename_N on Advanced). video_N is a lazy
VideoFromFile by default (decodes nothing); force_rate > 0 decodes and
retimes frames via resample_frame_indices while keeping real duration.
audio_N is decoded independently with PyAV so it stays available on the
cheap path, and is None (not an error) for clips with no audio track.
Disabled rows hold their socket position, matching the other loaders.
Registered in __init__.py; integration tests follow
tests/test_multi_audio_loader.py's shape (skipped outside a ComfyUI env).
Adds a comfy-free helper that retimes a source frame sequence to a
target fps while preserving real duration (VideoHelperSuite-style
force_rate) — 0 means off, dropping/duplicating frames otherwise.
Needed by the upcoming Multi Video Loader nodes.
Multi Loader nodes previously sized their output sockets to the loaded
file count, so deleting one file shrank the sockets and destroyed any
wire on a later socket. Add an output_slots combo (auto/1-8, front-end
only — Python already returns a fully padded output list) so a fixed
socket count can be pinned and wires survive file-list edits; the
status line now flags file/socket-count mismatches.
Also drop the separate + Add button: the drop zone itself is now
clickable and opens the same file picker, so there is one field for
both drag-and-drop and click-to-browse.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Batch already means one-item-per-queued-run in this pack (AI2GoPromptBatch);
these loaders emit everything in a single run, so Batch was misleading.
Renamed the four loader nodes/files/classes to Multi (AI2GoMultiImageLoader,
AI2GoMultiImageLoaderAdvanced, AI2GoMultiAudioLoader, AI2GoMultiAudioLoaderAdvanced),
and reworded DOWNSCALE_MODES from fit/crop/stretch to the plain-word
"keep aspect ratio"/"crop to square"/"stretch to square" (behavior unchanged).
Nothing published yet, so no back-compat aliases were added.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Six findings from the whole-branch review, fixed together:
1. addFiles() re-checks the row count before each push inside the upload loop, closing a
race where two overlapping drops could push a node past MAX_FILES.
2. removeAt() now warns whenever a wired socket is disturbed, including when the removed
row was the last one (previously required a promoted row too).
3. onConfigure no longer overwrites a files_json that failed to parse with "[]"; it shows
the parse error in the status line and leaves the original widget value in place.
4. parseFiles' mirror comment documents both of its intentional deviations from Python's
parse_files (empty input OK, entries beyond MAX_FILES ignored rather than rejected).
5. The image/audio MIME filter (and file-picker accept attr) now allows empty-MIME files
and, for audio, video/* containers like .ogg that the backend decodes fine.
6. Missing-file and decode errors in the image/audio loaders now include the file's
1-based position alongside its name.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Save Metadata (Civitai) graph trace only recognized ComfyUI's stock
LoraLoader/LoraLoaderModelOnly, so LoRAs loaded via rgthree's multi-LoRA
nodes were silently missing from the written metadata and the preview.
- tracer.py: harvest LoRAs from "Power Lora Loader (rgthree)" (lora_N dicts)
and "Lora Loader Stack (rgthree)" (flat lora_0N/strength_0N pairs), several
per node, in load order. Skip disabled, empty ("None") and zero-strength
slots to match what actually loads. Stock loaders still work.
- save_civitai_metadata.js: mirror the same detection in the live-graph
Test-detection preview (kept in sync with the Python tracer).
- Preview warning now distinguishes positive/negative (may be resolved at run
time by the AI2Go Prompt Batch node) from genuinely-unresolved fields.
- Tests for both rgthree loaders (multiple loras, ordering, skipped slots).
- README: document the supported LoRA loaders.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>