From 8f23c95546cb37742e937dee803d7df02bcbddb7 Mon Sep 17 00:00:00 2001 From: danrh <213368916+exportAnything@users.noreply.github.com> Date: Sun, 23 Aug 2026 08:03:39 -0500 Subject: [PATCH] Add synchronized music-video production planning Add measured-audio, timed-lyrics, H3 lane planning, identity relay, upload-song routing, model-specific camera contracts, LTX long-horizon planning, workflow migrations, the validated V6 example, regression coverage, and an Unreleased changelog. --- .comfyignore | 3 + .gitignore | 1 + CHANGELOG.md | 55 + GITHUB_RELEASE_CHECKLIST.md | 22 +- README.md | 69 +- __init__.py | 30 +- audio_production_nodes.py | 2900 ++++ benchmarks/ltx25_long_horizon_v1/README.md | 40 + .../ltx25_long_horizon_v1/manifest.json | 263 + examples/13_ltx25_i2v_director.json | 2 +- ...5_i2v_vs_minimax_h3_ref2va_comparison.json | 2 +- .../15_minimax_h3_ref2va_music_video_v6.json | 14021 ++++++++++++++++ examples/README.md | 16 + ltx25_contract.py | 912 +- nodes.py | 1697 +- production_planning_nodes.py | 2910 ++++ pyproject.toml | 2 +- scripts/smoke_prompt_builder.py | 32 +- tests/test_audio_production_nodes.py | 1729 ++ tests/test_grounding_guard_integration.py | 8 +- tests/test_grounding_guard_workflows.py | 169 + tests/test_ltx25_camera_capability.py | 410 + tests/test_ltx25_camera_motion_contract.py | 53 + tests/test_ltx25_contracts.py | 98 +- tests/test_ltx25_long_horizon.py | 396 + tests/test_measured_audio_director.py | 108 + .../test_minimax_h3_camera_contract_repair.py | 245 + tests/test_minimax_h3_dialogue.py | 12 + tests/test_minimax_h3_fast_test_workflow.py | 549 + ...test_minimax_h3_identity_relay_workflow.py | 380 + ...t_minimax_h3_identity_v4_smoke_artifact.py | 110 + ...h3_ref2va_deterministic_contract_repair.py | 890 + tests/test_minimax_h3_shot_count.py | 99 + ...est_minimax_h3_timed_lyrics_v5_workflow.py | 345 + ...test_minimax_h3_upload_song_v6_workflow.py | 426 + ..._minimax_music_video_expansion_workflow.py | 674 + tests/test_model_target_profile_nodes.py | 34 +- tests/test_music_video_production_workflow.py | 841 + tests/test_production_planning_nodes.py | 1875 +++ tests/test_splatstage_planner.py | 535 +- tests/test_timed_lyrics_nodes.py | 507 + timed_lyrics_nodes.py | 1191 ++ tools/create_minimax_h3_identity_v4_smoke.py | 287 + tools/migrate_minimax_h3_fast_test.py | 1205 ++ tools/migrate_minimax_h3_identity_relay.py | 1288 ++ tools/migrate_minimax_h3_timed_lyrics_v5.py | 989 ++ tools/migrate_minimax_h3_upload_song_v6.py | 969 ++ .../migrate_minimax_music_video_expansion.py | 2689 +++ tools/migrate_music_video_production.py | 2389 +++ 49 files changed, 44289 insertions(+), 188 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 audio_production_nodes.py create mode 100644 benchmarks/ltx25_long_horizon_v1/README.md create mode 100644 benchmarks/ltx25_long_horizon_v1/manifest.json create mode 100644 examples/15_minimax_h3_ref2va_music_video_v6.json create mode 100644 production_planning_nodes.py create mode 100644 tests/test_audio_production_nodes.py create mode 100644 tests/test_ltx25_camera_capability.py create mode 100644 tests/test_ltx25_long_horizon.py create mode 100644 tests/test_measured_audio_director.py create mode 100644 tests/test_minimax_h3_camera_contract_repair.py create mode 100644 tests/test_minimax_h3_fast_test_workflow.py create mode 100644 tests/test_minimax_h3_identity_relay_workflow.py create mode 100644 tests/test_minimax_h3_identity_v4_smoke_artifact.py create mode 100644 tests/test_minimax_h3_ref2va_deterministic_contract_repair.py create mode 100644 tests/test_minimax_h3_timed_lyrics_v5_workflow.py create mode 100644 tests/test_minimax_h3_upload_song_v6_workflow.py create mode 100644 tests/test_minimax_music_video_expansion_workflow.py create mode 100644 tests/test_music_video_production_workflow.py create mode 100644 tests/test_production_planning_nodes.py create mode 100644 tests/test_timed_lyrics_nodes.py create mode 100644 timed_lyrics_nodes.py create mode 100644 tools/create_minimax_h3_identity_v4_smoke.py create mode 100644 tools/migrate_minimax_h3_fast_test.py create mode 100644 tools/migrate_minimax_h3_identity_relay.py create mode 100644 tools/migrate_minimax_h3_timed_lyrics_v5.py create mode 100644 tools/migrate_minimax_h3_upload_song_v6.py create mode 100644 tools/migrate_minimax_music_video_expansion.py create mode 100644 tools/migrate_music_video_production.py diff --git a/.comfyignore b/.comfyignore index e8f24d9..f7d7211 100644 --- a/.comfyignore +++ b/.comfyignore @@ -8,9 +8,12 @@ __pycache__/ .github/ docs/ tests/ +benchmarks/ +tools/ GITHUB_RELEASE_CHECKLIST.md temp/ tmp/ +runtime_artifacts/ # Keep GitHub demo media out of the Comfy Registry install archive. *.mp4 diff --git a/.gitignore b/.gitignore index f35bb5e..80f5996 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,6 @@ venv/ output/ temp/ tmp/ +runtime_artifacts/ .DS_Store Thumbs.db diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..27637c3 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,55 @@ +# Changelog + +All notable changes to DiffusionGemma Director are recorded here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version numbers continue to follow the package metadata in `pyproject.toml`. + +## [Unreleased] + +### Added + +- Added 17 exported audio, timing, and production-planning nodes, bringing the registered ComfyUI surface to 33 nodes. +- Added decoded-song audition and locking with measured tempo, onset, tonal, clipping, silence, artifact, vocal-activity, recovery-window, excerpt, and whole-song diagnostics. Candidate and waveform-hash locks now fail closed instead of silently selecting different music. +- Added a custom-song path with a lazy upload node and independent **Generate with ACE-Step / Upload song** router. Uploaded songs reuse the established selector, excerpt, hash-lock, audio-guide, planner, and pristine final-mux path without waking dormant ACE candidate lanes. +- Added a single **Natural / audio-led sync**, **Dance / music sync**, or **Lyrics + lip sync** performance control shared by Director guidance, lyric selection, timed analysis, and H3 planning. +- Added lazy timed-lyrics analysis using local vocal separation and Whisper alignment. Only verified, soundtrack-hash-locked vocal events guide articulation; instrumental, missing, stale, weak, or failed evidence safely falls back to Natural/audio-led behavior. +- Added experimental ACE **Compose new / Cover reference** conditioning. Cover mode remains lazy and fails closed until compatible reference-audio conditioning is connected. +- Added a deterministic Project Master contract, audio-aware H3 generation-lane planner, separate H3 video-seed fanout, optional previous-lane relay reference, exact-frame assembler, and plan-only multi-format delivery manifest. +- Added dual-reference identity preparation and relay support. Two clean references can remain the identity authorities while a downscaled previous-lane tail is used only as optional continuity evidence. +- Added Experimental Long Horizon planning for LTX with four contiguous duration-scaled pacing phases, compact output budgets, advisory diagnostics, and an explicitly unexecuted offline 5-, 20-, and 60-second benchmark protocol and manifest. +- Added hash-guarded workflow migrations for the synchronized music-video graph, MiniMax-H3 expansion, Turbo/fast test path, dual-identity relay, timed lyrics V5, uploaded-song V6, and an isolated identity-relay smoke graph. +- Added the validated MiniMax-H3 synchronized music-video V6 graph as a checked-in example with a repository-local integrity and contract test, so the working production artifact is preserved independently of mutable Desktop and ComfyUI copies. +- Added regression coverage for audio QC and routing, timed lyrics, production planning, exact assembly, H3 dialogue and shot counts, reference-contract repair, identity relay, uploaded songs, camera capability, and long-horizon planning. + +### Changed + +- Separated MiniMax-H3 native `[Shot N]` blocks from duration-bounded generation lanes. A single H3 invocation may now retain several native shots, and up to four planned lanes can cover a 60-second project when the configured 15-second lane ceiling and capacity constraints permit it. +- Reworked H3 lane boundaries to prefer native cuts with measured recovery, then native or mixed evidence, with deterministic balanced seams as a safe fallback. Non-native seams carry the active source shot and rebase timestamped cues rather than changing the master timeline. +- Made Project Master duration, aspect, soundtrack hash, excerpt, lane ceiling, and deliverables authoritative while leaving native shot choreography to the Director and H3 target profile. +- Made MiniMax-H3 camera policy model-specific. H3 may preserve requested orbiting, swirling, sweeping, whip movement, pronounced parallax, and coherent compound paths; unspecified cameras inherit an explicit creativity-scaled direction instead of being rejected. +- Added **Stable** and **Advanced** camera capability to the LTX target contract. LTX keeps its conservative motion safeguards where needed without imposing those restrictions on H3. +- Updated SplatStage planning so requested genre, subgenre, era, instrumentation, groove, and production style override visual nightclub or dance cues. Scene evidence may shape visuals and lyrics but no longer forces unrelated music into EDM. +- Extended SplatStage duration and aspect handling, measured-audio Director context, source-passthrough semantics, production concepts, and reproducible song-seed fanout. +- Revised Director caching and workflow fixtures so unchanged verified branches can reuse their packet while explicit refresh remains a one-run diagnostic choice. +- Codified the tested MiniMax-H3 fast path around the pruned INT8 model, official four-step Turbo LoRA, separate video/audio sigma shifts, and Euler/simple sampling. EasyCache and TorchCompile remain disconnected bypasses in that workflow because the measured configuration reported no effective acceleration. + +### Fixed + +- Repaired MiniMax-H3 Ref2VA packets deterministically when model output contains malformed subject definitions, reference usage or retention rows, misplaced or short detailed descriptions, invalid cut timestamps, or omitted per-shot camera direction. +- Removed the one-shot Project Master mismatch that incorrectly compared H3 native shot blocks with the number of generation invocations. +- Prevented generic camera-safety text from making H3 output creatively anemic while retaining fail-closed validation for genuinely malformed camera contracts. +- Prevented Dance mode from forcing singing or mouth motion, and prevented raw written lyrics from acting as an unverified timing schedule. Lyrics mode now supplies articulation cues only during measured vocal intervals. +- Preserved soundtrack timing across lane-local lyric windows and exact-frame assembly, including explicit non-vocal handling for instrumental gaps. +- Reduced long-video identity drift by keeping clean identity references authoritative across lanes and making relay continuity optional, bounded, and independently lazy. +- Made missing ideal H3 seam evidence advisory rather than fatal while continuing to block invalid clocks, malformed shot structures, stale audio locks, impossible lane capacity, and bad identity manifests. +- Hardened workflow migrations with immutable-source hashes, additive policy markers, exact wiring checks, and regression tests for the validated Desktop and ComfyUI copies when those local artifacts are available. + +### Repository hygiene + +- Excluded generated runtime videos and identity/reference frames from Git and ComfyUI package archives. These files remain local and are not required by the source or tests. +- Kept migration tools and offline benchmark manifests in Git while excluding them from the install archive, and updated package metadata and the release checklist for the 33-node surface. +- Made the legacy external V5 Desktop/ComfyUI byte-equality audit explicitly opt-in; the default release suite now relies on the checked-in V6 workflow's hermetic hash and contract validation. + +## [0.2.0] - 2026-08-07 + +### Added + +- Introduced the model-specific DiffusionGemma Director core, grounding guard, fail-closed generation gates, LTX and MiniMax-H3 target profiles, and packaged example workflows. diff --git a/GITHUB_RELEASE_CHECKLIST.md b/GITHUB_RELEASE_CHECKLIST.md index 4404597..5d10f03 100644 --- a/GITHUB_RELEASE_CHECKLIST.md +++ b/GITHUB_RELEASE_CHECKLIST.md @@ -4,13 +4,15 @@ Use this checklist from the standalone `ComfyUI-DiffusionGemmaPromptBuilder` rep ## Product Boundary -- Keep the exported surface at sixteen node ids: +- Keep the exported surface at thirty-three node ids: - eleven stable Director nodes: Model Loader, Context Hub, H3 Reference Context, Grounding Guard Settings, CoT Generator, JSON Splitter, Generation Gate, Branch Generation Gate, and the LTX-2.5, MiniMax-H3, and Ideogram 4 target profiles - one deprecated universal Target Profile retained for saved-workflow compatibility - two optional reference-preparation helpers: Reference Prep and H3 Reference Pair Prep - two experimental SplatStage planners + - eleven audio/music-video controls: ten decoded-audio, source-routing, ACE, performance, and production-concept nodes plus Timed Lyrics Analyzer + - six production-planning controls: Project Master, Audio-Aware H3 Multi-Shot Planner, H3 Relay Reference Gate, Multi-Format Delivery Planner, H3 Shot Seed Fanout, and H3 Shot Assembler - Keep the two SplatStage planners visibly experimental. Their mapping ids stay compatible, their display names end in `(Experimental)`, and their category is `prompt/diffusiongemma/experimental-motion-planning`. -- Confirm `NODE_CLASS_MAPPINGS` and `NODE_DISPLAY_NAME_MAPPINGS` contain the same sixteen ids. +- Confirm `NODE_CLASS_MAPPINGS` and `NODE_DISPLAY_NAME_MAPPINGS` contain the same thirty-three ids. - Treat `ltx_reframe.py` and the reframe workflows as unexported prototypes. Do not describe them as installed nodes unless the package entry point and frontend are deliberately restored together. - Do not bundle model weights or generated tensor dumps. The NVFP4 bridge remains source code in `nodes.py`. @@ -36,9 +38,10 @@ node --check web/js/model_loader.js node --test tests/*.mjs ``` -- The unit suite must validate the exact sixteen-node surface, the dedicated target-node boundaries, the Director/optional/experimental category split, both bundled SplatStage schemas, and retained reframe helpers. +- The unit suite must validate the exact thirty-three-node surface, the dedicated target-node boundaries, the Director/optional/experimental/audio/production-planning category split, both bundled SplatStage schemas, and retained reframe helpers. - The readiness/schema smoke must finish with `Prompt Builder readiness/schema smoke passed`. - The JavaScript suite must exercise the shipped `model_loader.js`. No test may import the retired `ltx_reframe_layout.js`. +- The default release suite validates checked-in artifacts only. Set `DG_VERIFY_DEPLOYED_V5_ARTIFACTS=1` solely when intentionally auditing the superseded, mutable V5 Desktop and ComfyUI copies; divergence there is deployment evidence to reconcile, not a hermetic release gate. - Require all three CI jobs to pass on the release commit. ## Manual Runtime Gates @@ -49,23 +52,24 @@ node --test tests/*.mjs python proof_gates.py --model-path C:\ComfyUI\models\LLM\diffusiongemma-26B-A4B-it-NVFP4 ``` -2. Fresh-install the repository in a clean ComfyUI `0.30.1` custom-nodes folder and confirm all sixteen nodes appear: eleven stable Director nodes, one legacy compatibility target, two optional reference-preparation nodes, and two SplatStage planners only under the experimental motion-planning category. +2. Fresh-install the repository in a clean ComfyUI `0.30.1` custom-nodes folder and confirm all thirty-three nodes appear: eleven stable Director nodes, one legacy compatibility target, two optional reference-preparation nodes, two SplatStage planners only under the experimental motion-planning category, eleven audio/music-video controls, and six production-planning controls. 3. Copy `examples/assets/character_motion_transfer` to `ComfyUI/input/character_motion_transfer` and load `examples/07_ltx23_character_motion_transfer.json`. 4. Load the MiniMax H3 T2VA and Ref2VA examples and confirm the Generation Gate blocks invalid or empty prompt packets. -5. Treat longer experimental SplatStage and reframe workflows as separate opt-in validation, not as evidence for the stable Director compatibility promise. +5. Load `examples/15_minimax_h3_ref2va_music_video_v6.json`, replace both unbundled identity-image choices, and verify the default ACE source remains lazy with a blank upload. Exercise Upload song, Natural, Dance, Lyrics, and optional relay as separate branch tests; do not infer a successful media render from graph validation alone. +6. Treat longer experimental SplatStage and reframe workflows as separate opt-in validation, not as evidence for the stable Director compatibility promise. ## Files Tracked on GitHub -- Package entry point and source: `__init__.py`, `nodes.py`, `ltx_reframe.py`, `proof_gates.py` +- Package entry point and source: `__init__.py`, `nodes.py`, `audio_production_nodes.py`, `production_planning_nodes.py`, `timed_lyrics_nodes.py`, `ltx25_contract.py`, `ltx_reframe.py`, `proof_gates.py` - Metadata and policy: `README.md`, `LICENSE`, `requirements.txt`, `pyproject.toml`, `.gitignore`, `.comfyignore`, this checklist - Runtime contracts: `schemas/`, `web/`, `scripts/` - Verification: `tests/`, `.github/workflows/ci.yml` - Publishing: `.github/workflows/publish_action.yml` -- Documentation, current examples, and GitHub demo assets: `docs/`, `examples/` +- Documentation, current examples, workflow migrations, offline benchmarks, and GitHub demo assets: `docs/`, `examples/`, `tools/`, `benchmarks/` ## Registry Archive -- Keep `.github/`, `docs/`, `tests/`, caches, temporary files, and large demo video/GIF files out of the Registry archive through `.comfyignore`. +- Keep `.github/`, `docs/`, `tests/`, `tools/`, `benchmarks/`, runtime artifacts, caches, temporary files, and large demo video/GIF files out of the Registry archive through `.comfyignore`. - Confirm both SplatStage schemas remain in the Registry archive because the experimental planners load them at runtime. -- Inspect the archive before publishing and confirm it contains no model weights, local paths, logs, caches, or generated outputs. +- Inspect the archive before publishing and confirm it contains no model weights, migration-only local paths, logs, caches, or generated outputs. - Publish only after the GitHub release commit and version metadata agree. diff --git a/README.md b/README.md index 6e9cf76..9ff585e 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,13 @@ # ComfyUI DiffusionGemma Prompt Builder -DiffusionGemma Director provides a stable five-node prompt-authoring core for ComfyUI: choose one model-specific Target Profile node between Context Hub and the shared Director/validation path. Four stable Director companion nodes and two optional reference-preparation nodes extend that core. The package also exports two experimental SplatStage motion-planning nodes. DiffusionGemma writes and validates prompts or blueprints; it is not the downstream image or video sampler. +DiffusionGemma Director provides a stable five-node prompt-authoring core for ComfyUI: choose one model-specific Target Profile node between Context Hub and the shared Director/validation path. Four stable Director companion nodes, two optional reference-preparation nodes, eleven audio/music-video production controls, and six production-planning controls extend that core. The package also exports two experimental SplatStage motion-planning nodes. DiffusionGemma writes and validates prompts or blueprints; it is not the downstream image or video sampler. -The primary stable workflow is the working LTX 2.3 character motion-transfer graph in `examples/07_ltx23_character_motion_transfer.json`. Additional Director examples cover native MiniMax H3 T2VA and Ref2VA paths. +The primary stable workflow is the working LTX 2.3 character motion-transfer graph in `examples/07_ltx23_character_motion_transfer.json`. Additional Director examples cover native MiniMax H3 T2VA and Ref2VA paths. The accumulated synchronized music-video production graph is preserved in `examples/15_minimax_h3_ref2va_music_video_v6.json`; replace its two saved `LoadImage` choices with your own primary identity image and same-person contact sheet before running it. ## Exported Nodes -Sixteen nodes are registered in ComfyUI. Their stable, compatibility, optional, and experimental surfaces are intentionally separate. +Thirty-three nodes are registered in ComfyUI. Their stable, compatibility, optional, and experimental surfaces are intentionally separate. ### Stable Director Assistant @@ -19,7 +19,7 @@ The five-node core path used by the primary LTX workflow is: - `DiffusionGemmaModelLoader` - loads the local Transformers/NVFP4 DiffusionGemma runtime. - `DiffusionGemmaContextHub` - combines user text, optional image/video inputs, and optional `visual_description` into one `DG_CONTEXT`. - Choose exactly one model-specific target node: - - `DiffusionGemmaLTX25TargetProfile` - LTX generation mode, duration, style, joint audio/video guidance, and negative prompt controls. + - `DiffusionGemmaLTX25TargetProfile` - LTX generation mode, duration, Experimental Long Horizon planning, style, joint audio/video guidance, and negative prompt controls. - `DiffusionGemmaMiniMaxH3TargetProfile` - H3 T2VA/Ref2VA mode, duration, audio, shot count, dialogue, and integrated exclusion controls. - `DiffusionGemmaIdeogram4TargetProfile` - image aspect ratio, render style, exact visible text, JSON/prose representation, and negative prompt controls. It deliberately has no duration or audio widgets. - `DiffusionGemmaCoTGenerator` - asks DiffusionGemma for the final prompt packet and returns final JSON plus debug outputs. @@ -48,6 +48,46 @@ These larger planners are exported for opt-in SplatStage work, but they are not Both are labeled `(Experimental)` and appear under `prompt/diffusiongemma/experimental-motion-planning` in ComfyUI. Their schemas ship with this repository, while executing a resulting show still requires the appropriate downstream SplatStage workflow and nodes. +`DiffusionGemmaSplatStagePlanner` accepts any positive finite planning duration and any positive `W:H` ratio or `WxH` resolution expression. These values guide the creative blueprint only; they do not override a downstream renderer's frame clock or raster. The synchronized LTX + ACE workflow supplies those settings independently. Classic SplatStage production graphs remain fixed to their own legacy clip and resolution contract. + +### Decoded-Audio Production Controls + +These controls appear under `prompt/diffusiongemma/audio-production` and support the synchronized ACE-Step + LTX workflow: + +- `DiffusionGemmaMusicProductionConcept` is the single shared choice for both the SplatStage Planner and Song Blueprint Router. **Source passthrough means the authored ACE song blueprint passes through unchanged; it is not file-audio passthrough.** Source passthrough and Joint video-safe plan resolve to one ACE song; Audition and select activates a user-selected two to four candidates, with two as the bounded default. +- `DiffusionGemmaSongSeedFanout` derives four reproducible song-candidate seeds from a song seed that remains independent of the LTX sampling seed. +- `DiffusionGemmaUploadSong` provides a lazy-safe upload/selection widget for a custom soundtrack. A blank uploader cannot invalidate an ACE run, and a selected file is confined to ComfyUI's input directory before decoding. +- `DiffusionGemmaSongSourceRouter` is the independent soundtrack-origin toggle: **Generate with ACE-Step** preserves the existing candidate lanes, while **Upload song** keeps ACE audio generation dormant and submits the custom waveform to the same selector, excerpt, and hash-lock path. Uploaded BPM is optional (`0` uses signal-only analysis); uploaded lyrics are used only as downstream lyric evidence and may remain blank for Natural or Dance mode. +- `DiffusionGemmaAudioCandidateSelector` lazily renders only the requested candidate lanes, measures the decoded waveforms, selects a usable excerpt, and blocks LTX when no candidate passes. It can lock a candidate or exact waveform SHA-256 without silently substituting another song. +- `DiffusionGemmaLTXAudioGuide` separates the audio that conditions LTX from the untouched final soundtrack. `full_mix` is an identity path, `sync_safe` retains timing and center/vocal information while softening transient pressure, and `vocal_only` requires a connected vocal stem. +- `DiffusionGemmaLTXPerformancePrompt` sits after the validated Director gate and changes only prompt text. **Natural / audio-led sync** adds no lyric schedule and lets connected audio govern whether articulation naturally occurs. **Dance / music sync** deliberately suppresses singing, speaking, mouthing, and lip-sync while retaining beat-, phrase-, and dynamics-aware body motion. **Lyrics + lip sync** supplies a bounded authored-lyric window only as lexical/pronunciation candidates; it no longer orders a subject to sing every selected line. The node never changes the conditioning waveform or pristine final soundtrack. +- `DiffusionGemmaMusicVideoPerformanceMode` makes Natural, Dance, or Lyrics one shared choice before the video Director. It is the single authoritative mode supplied to target guidance, lyric-window selection, timed-lyrics analysis, and H3 lane planning. +- `DiffusionGemmaTimedLyricsAnalyzer` is lazy: Natural and Dance do not evaluate its separator or Whisper inputs. Lyrics mode validates a local Demucs vocal stem, transcribes only detected vocal intervals in chunks no longer than 15 seconds, aligns those phrases monotonically to authored lyric lines, and emits a song-hash-, lyric-hash-, and excerpt-locked timing report. Separator fallbacks, silence, weak alignment, stale evidence, or transcription/model errors produce a safe Natural/audio-led report instead of blocking video or inventing singing. Confirmed instrumental intervals are explicit non-vocal evidence. +- `DiffusionGemmaACEReferenceMode` and `DiffusionGemmaACECoverConditioning` expose a lazy Compose/Cover experiment. Cover fails closed until a valid reference-audio latent is connected and requires ACE semantic-code generation to be disabled. + +The production concepts are deliberately different workflows, not post-generation repairs. The SplatStage Planner receives the Context Hub image pixels on a pixel-capable backend, so its song, lyrics, performer, environment, palette, and effects can be co-authored from the same image and creative brief used by the video Director. Source passthrough preserves one jointly authored `ace_tags`/lyrics/BPM/key/meter bundle. Joint video-safe plan asks DiffusionGemma to author lower transient, tonal, section, and lyric pressure before ACE generates anything. Audition and select keeps that coherent bundle intact, varies only the deterministic song seed, then judges the waveform that actually exists. The Song Blueprint Router never injects chord symbols, BPM, key, or theory prose into `ace_tags`, and it never compacts already-authored lyrics. + +An explicitly requested soundtrack genre, subgenre, era, instrumentation, groove, or production style is authoritative over the image's visual setting. Neon, nightclub, dance, party, wardrobe, lighting, and other scene evidence may shape the visual lanes and lyrical imagery, but they do not turn another requested genre into EDM or a crossover. Words such as “juxtaposed” and “against” mean audiovisual contrast; the Planner creates a musical fusion only when the brief explicitly asks for one. Lyrics use ACE bracketed section labels such as `[Verse]` and `[Chorus]`. + +Decoded-audio QC is a lightweight CPU signal heuristic, not transcription, source separation, note-level tuning proof, or a universal definition of good music. A half-time accent is accepted as an advisory when its canonical tempo is within 5% of the requested BPM. A canonically aligned double-time reading is advisory when canonical error is within 5%, excerpt onset pressure is at most 4.0/s, vocal activity is present, and at least two of four supporting signals pass: visual-recovery coverage, excerpt score, tonal-family consistency, or transition stability. It remains score-penalized and visibly advisory. Dense or weakly supported double-time, canonically misaligned or undetected tempo, dense selected excerpts, source-channel clipping, silence, broadband noise/artifact-like spectra, and strong tonal discontinuity remain blocking. `minimum_score` is only the weighted numeric floor and cannot bypass those hard QC checks. Automatic selection favors direct/aligned-half candidates, then recovery coverage for accepted double-time candidates, the actual LTX excerpt score, and the whole-song score. Listen to the selected song, then lock its candidate/hash and excerpt start for repeatable production. A failed lock blocks rather than falling back. + +Uploaded songs use a separate source-locked posture because the user has already chosen the music. Invalid shape, excessive decoded size/duration, a track shorter than the requested excerpt, silence, clipping, and artifact-like broadband noise remain blocking. Tempo interpretation, vocal-presence proxy, onset pressure, tonal movement, and the generated-candidate production score remain measured and visible but advisory; they cannot replace or reject an otherwise technically usable uploaded song. ComfyUI still includes linked lazy ancestors in cache signatures, so changing a dormant upload selection may invalidate downstream cache entries even though the file is not decoded and ACE audio remains the only executed source. + +In the synchronized workflow, the selected report is also supplied to Director so camera and body motion can follow the measured excerpt instead of requested metadata. The selected pristine excerpt remains the final muxed soundtrack. A separate timing-identical guide is Audio-VAE encoded with a zero noise mask and supplied to both LTX sampling stages; the original waveform is never replaced by the guide. `A2V influence` remains neutral at `1.0` by default and should be tested cautiously with the same locked song and video seed. + +### Production Planning Controls + +These controls appear under `prompt/diffusiongemma/production-planning` and provide the first project-orchestration layer for synchronized MiniMax-H3 production: + +- `DiffusionGemmaProjectMasterContract` locks the approved song hash plus excerpt window, brief, duration, master aspect, H3 generation-lane ceiling, and requested deliverables into a deterministic project manifest. Its legacy `recommended_h3_shot_count` output means the number of duration-bounded H3 invocations, not the number of native camera cuts. +- `DiffusionGemmaAudioAwareMultiShotPlanner` divides a validated Ref2VA prompt into one to four H3 generation segments. One segment may preserve several consecutive native `[Shot N]` blocks. Boundary selection prefers native shot boundaries with measured low-density recovery, then native-only and mixed native/recovery sequences. If none can obey every hard lane-duration limit, the planner uses deterministic duration-balanced seams, records each seam's literal provenance, and carries the source shot already active at a non-native seam into the next lane so later native timestamps stay exact. Timestamped sub-cues are sliced with that carry: the latest elapsed cue becomes explicit opening-state history, in-lane cues are rebased, and future cues are deferred to the later lane instead of blocking or firing early. Each segment also carries a local clock, exact retained-frame allocation, continuity contract, and the shared Natural, Dance, or Lyrics performance mode. Lyrics mode accepts only a validated timed-lyrics report, clips verified events into each lane's local clock, marks fully instrumental lanes non-vocal, and otherwise falls back to Natural/audio-led behavior. +- `DiffusionGemmaH3RelayReferenceGate` optionally routes the retained tail of the previous H3 lane as a low-budget continuity reference for the next lane. The original identity references remain authoritative, relay is identity-first and off by default, and disabled downstream lanes do not request upstream media. +- `DiffusionGemmaH3ShotSeedFanout` derives deterministic per-generation-lane video seeds from the separate H3 root seed and project id. +- `DiffusionGemmaH3ShotAssembler` lazily requests only the planned H3 lanes, trims every decoded segment at its retained cut, verifies the master clock and soundtrack duration, concatenates exact frames, and passes the pristine audio object through unchanged. +- `DiffusionGemmaMultiFormatDeliveryPlanner` records requested reframes and cutdowns as plan-only deliverables; it never claims alternate media was rendered. + +The Project Contract is authoritative for aspect, maximum H3 generation-segment length, and resulting lane count. Director and the MiniMax-H3 Target Profile remain authoritative for the unique native `[Shot N]` schedule inside those lanes. Missing ideal cut evidence is advisory rather than fatal; the plan exposes boundary-policy revision 2, selected strategy, evidence booleans, carry-in fragments, realized lane durations, and whether the non-binding preferred duration was actually realizable. Structural errors such as invalid clocks, duplicate/gapped/empty native shot blocks, out-of-range timestamps, stale audio locks, malformed identity manifests, impossible minimum/maximum limits, or more than four required lanes still fail closed. Missing, stale, weak, or malformed lyric timing also remains non-fatal: the planner records a warning and uses Natural/audio-led articulation. Written lyrics are never treated as a timing schedule. H3-generated audio is intentionally discarded; only the locked ACE excerpt is muxed into the assembled video. + The former universal `DiffusionGemmaTargetProfile` remains registered and marked deprecated so existing saved workflows continue to load with their exact widget order. New workflows should use one of the three model-specific targets. Other compatibility and utility classes remain in source where exported nodes reuse their behavior internally. The `ltx_reframe.py` module and LTX reframe workflows are retained as unexported prototypes; the retired `ltx_reframe_layout.js` frontend is not part of this release. ## Packaged Workflow @@ -120,6 +160,12 @@ Use `DiffusionGemma LTX-2.5 Target Profile` and keep `generation_mode` on `Auto Connect the same first/last images to the native LTX conditioning nodes. Director uses the Context Hub copies only for visual analysis and contract validation; it does not secretly wire the LTX sampler. For I2V and first+last-frame work, Director requires one continuous take, checks the generated opening against verified first-frame facts, and rejects cuts or shot/action overload that cannot fit the selected duration. The compiler asks every shot to open with one of LTX's six canonical types (`extreme wide shot`, `wide shot`, `medium shot`, `medium close-up`, `close-up`, or `extreme close-up`) before describing its camera path; a later destination scale does not replace that opening type. A connected conditioning frame supplies otherwise-unstated opening scale and viewpoint geometry instead of making Director guess and block, while frame-free T2V and every post-cut shot remain strict. Compatible simultaneous or sequential camera-motion phases may form one physically continuous path and evolve to a new endpoint scale without becoming a cut; unusually dense camera choreography is diagnostic advice, not a hard numeric gate. Generation Gate reports corrective sentences rather than requiring users to decode validation identifiers. +`Experimental Long Horizon` is an LTX Target Profile planning control for unusually long continuous generations. Its default is `Off`, preserving saved-workflow behavior. `Auto (>20 seconds)` activates only when the resolved planning duration is strictly greater than 20 seconds; exactly 20 seconds remains on the standard contract. `On` forces the policy at any duration. + +When active, Director silently plans four duration-scaled phases—establish, commit, sustain/reveal, and settle/hold—then compiles them into one continuous paragraph of no more than 200 words and generally four to eight sentences. These phases are not chapters, shots, scene changes, emitted headings, or timecodes. I2V planning keeps only the minimal critical first-frame anchors needed for continuity, selects one physically continuous camera intention, preserves explicitly requested transformations, and defines a terminal composition. Missing phase, conservation, or terminal cues produce non-blocking diagnostics rather than a Generation Gate failure. + +The toggle improves semantic pacing; it does not add geometric conditioning or guarantee one-minute object reconstruction. Pair it with a first/last frame or a duration-matched depth/control sequence when the final composition or camera geometry must be constrained. The offline [5/20/60-second benchmark protocol](benchmarks/ltx25_long_horizon_v1/README.md) defines the unexecuted bare/current/long-horizon/structural comparison and preserves both sampler seeds without claiming render results that have not been collected. + All five creativity modes apply to LTX I2V and first+last-frame video. A still anchor fixes its visible pose, framing, and camera geometry only at that anchored instant; it does not prove a static future path. An explicit user or verified-media camera instruction—including a locked/static hold—always wins. Faithful preserves requested camera speed, direction, and compound phases exactly, and chooses the least-invasive suitable path only when motion is unspecified. Editorial, cinematic, concept-art, and wild may author increasingly expressive, tempo-appropriate compound camera choreography when the future path is unspecified, while retaining the exact anchors, one continuous take, and no cuts. `creative_strength` scales that motion ambition without imposing a numeric phase cap. The JSON Splitter's resolution controls are downstream sampler controls and do not invalidate the Director cache. Choose an explicit `resolution_aspect_ratio`, megapixel budget, and alignment multiple, then connect `resolution_width` and `resolution_height` to the native LTX generator. `Auto (target/source)` matches an attached LTX first frame to the nearest supported ratio and defaults frame-free LTX to `16:9`; it no longer inherits Ideogram's `1:1` default. @@ -134,7 +180,7 @@ See [Grounding Guard](docs/GROUNDING_GUARD.md) for the mode contract, evidence s `DiffusionGemma CoT Generator` has a `director_cache_mode` control. `reuse` (the default) lets ComfyUI keep an unchanged Director branch in its normal in-memory graph cache, so changing an LTX-only control does not rerun an independent MiniMax-H3 branch (and vice versa). It also builds a SHA-256 key from the model/checkpoint and processor identity, Director implementation and schemas, exact creative controls, Grounding Guard configuration, target profile, media metadata, and hashes of the ordered tensors actually sent to the processor. A verified ready packet is stored as small JSON/text in ComfyUI's private system-user cache. A disk hit is served before the full DiffusionGemma model is constructed or loaded and survives restarts, cache eviction, and equivalent Director nodes. The disk key does not include downstream H3 seed, steps, sampler, scheduler, LoRA, decode, preview, or save controls. -`refresh` forces a new Director run and atomically replaces an eligible disk entry; it does not randomize generation. Identical inputs with a fixed Grounding Guard/Director seed are intentionally reproducible, so change that seed (or its after-generate policy) when you want a new prompt variant. `creativity_mode` chooses the kind of compatible prompt detail and, for LTX video, camera choreography; `creative_strength` chooses its qualitative intensity and camera-path ambition. Neither is a sampling-temperature or RNG control. `off` disables disk lookup and writes and recomputes every queue. Because ComfyUI's in-memory cache cannot distinguish a ready packet from a failed or salvaged one, an unchanged blocked result in `reuse` remains blocked until an input changes or `refresh` is selected for one retry; the Branch Generation Gate status states this recovery step. Detailed grounding traces always bypass both reuse layers so their requested trace side effect is never silently skipped. Blocked, refused, salvaged, template-fallback, unverified-audit, and otherwise non-ready packets are not stored on disk. Cache files contain plaintext prompt/debug outputs; the default location is private, and `DG_DIRECTOR_CACHE_DIR` can select another local directory. +`refresh` forces a new Director run and atomically replaces an eligible disk entry; it does not randomize generation. It is a one-run diagnostic setting: queue once, then immediately return it to `reuse`, because leaving `refresh` selected reruns Director on every queue. Identical inputs with a fixed Grounding Guard/Director seed are intentionally reproducible, so change that seed (or its after-generate policy) when you want a new prompt variant. `creativity_mode` chooses the kind of compatible prompt detail and, for LTX video, camera choreography; `creative_strength` chooses its qualitative intensity and camera-path ambition. Neither is a sampling-temperature or RNG control. `off` disables disk lookup and writes and recomputes every queue. Because ComfyUI's in-memory cache cannot distinguish a ready packet from a failed or salvaged one, an unchanged blocked result in `reuse` remains blocked until an input changes or `refresh` is selected for one retry; the Branch Generation Gate status states this recovery step. Detailed grounding traces always bypass both reuse layers so their requested trace side effect is never silently skipped. Blocked, refused, salvaged, template-fallback, unverified-audit, and otherwise non-ready packets are not stored on disk. Cache files contain plaintext prompt/debug outputs; the default location is private, and `DG_DIRECTOR_CACHE_DIR` can select another local directory. The JSON Splitter keeps its normal `ltx_prompt` and `negative_prompt` outputs fail-closed, but also exposes appended `candidate_ltx_prompt` and `candidate_negative_prompt` diagnostics. Those candidate sockets update even when validation blocks generation, which prevents a Preview Any node from appearing to show a stale prior prompt. They are inspection-only and must never be connected directly to a native generator; generation continues through the normal prompt outputs and a Generation Gate. @@ -165,7 +211,9 @@ non_diegetic_music: ... The first shot has no timestamp. Later cuts use increasing instants such as `[Shot 2] At 00:03.500, the camera cuts to...`, all inside the selected duration. Hard cuts are the default; cross-dissolves, fades, and wipes are used only when the brief requests them. Synchronized visible action, speech, and scene sounds stay in `integrated_multimodal_description`; ambient sound and Foley belong in `overall_soundscape`; audience-only score belongs in `non_diegetic_music`, where instrumentation, tempo/rhythm, and dynamic development are described concretely instead of as an abstract mood. -`shot_count` on the MiniMax-H3 Target Profile controls the number of generated shots for both T2VA and Ref2VA. `auto` honors an exact count written in the creative brief and otherwise lets Director choose the fewest useful shots. Select `1` through `12`, or select `custom` and type a value from `1` through `99` in `custom_shot_count`. The custom number is ignored unless the selector is set to `custom`. Any explicit value requires exactly that many consecutive `[Shot N]` sections and overrides conflicting count wording in the brief. A shot is a camera/cut segment, not necessarily a narrative beat, chapter, or scene change; multiple beats can occur inside one shot. Director validates the result and makes a bounded repair attempt; if the model still returns the wrong count, Generation Gate blocks it. Counts above 12 generally need more duration and Director output-token budget. This is a storyboard/compiler control, independent of the Grounding Guard's `evidence_token_budget`. +Every H3 shot also carries one explicit camera-behavior sentence. H3 does not inherit LTX's Stable / base-model Camera Capability: requested or reference-derived camera choreography is preserved, and non-faithful creativity modes may author expressive movement proportional to creative strength. Orbit/arc, roll/rotation, swirl, sweep or whip movement, controlled shake, pronounced parallax, and coherent compound paths are valid H3 tools. Moving-shot prose names the motion type, meaningful speed/amplitude, direction, subject relationship, and ending frame; compound phases must be physically compatible or explicitly ordered. The exact locked-off sentence remains only a deterministic last resort for a genuinely unspecified shot, so a valid complex path is never overwritten or paired with a contradictory static hold. + +`shot_count` on the MiniMax-H3 Target Profile controls the number of native camera/cut blocks for both T2VA and Ref2VA. `auto` honors an exact count written in the creative brief and otherwise lets Director choose the fewest useful shots. Select `1` through `12`, or select `custom` and type a value from `1` through `99` in `custom_shot_count`. The custom number is ignored unless the selector is set to `custom`. Any explicit value requires exactly that many consecutive `[Shot N]` sections and overrides conflicting count wording in the brief. A shot is a camera/cut segment, not necessarily a narrative beat, chapter, scene change, or separate H3 generation pass; multiple native shots may execute inside one valid 4–15 second H3 clip. Do not connect the Project Master's generation-lane recommendation to this native shot-count control. Director validates the result and makes a bounded repair attempt; if the model still returns the wrong count, Generation Gate blocks it. Counts above 12 generally need more duration and Director output-token budget. This is a storyboard/compiler control, independent of the Grounding Guard's `evidence_token_budget`. ### MiniMax H3 dialogue controls @@ -346,6 +394,13 @@ Place in: ComfyUI/models/text_encoders ``` +Optional MiniMax-H3 timed-lyrics analysis: + +- [openai/whisper-large-v3-turbo](https://huggingface.co/openai/whisper-large-v3-turbo), placed as the complete local repository at `ComfyUI/models/whisper/whisper-large-v3-turbo`. +- Torchaudio's `HDEMUCS_HIGH_MUSDB_PLUS` checkpoint, installed through the torchaudio pipeline cache. On Windows this normally resolves below the user's `.cache/torch/hub/torchaudio/models` directory. + +The V5 workflow keeps both branches lazy outside Lyrics mode. Its Whisper loader has `download_missing=False`; install the exact local snapshot before selecting Lyrics so a network change cannot silently alter a repeatable run. + Latent upscaler: - [Lightricks/LTX-2.3 - ltx-2.3-spatial-upscaler-x2-1.1.safetensors](https://huggingface.co/Lightricks/LTX-2.3/blob/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors) @@ -366,6 +421,8 @@ Install missing packs through ComfyUI Manager when possible: - `comfyui_controlnet_aux` - `comfyui_essentials` - `comfyui-easy-use` +- `comfy-mtb` for the local Whisper loader +- `comfyui_fill-nodes` for Hybrid Demucs vocal separation - `RES4LYF` Core ComfyUI supplies several additional LTX nodes used by the workflow, including video loaders, LTX preprocessing/conditioning, samplers, latent/audio/video split and concat nodes, and latent upscaler loading. diff --git a/__init__.py b/__init__.py index 9e66ad1..bd9c949 100644 --- a/__init__.py +++ b/__init__.py @@ -1,7 +1,35 @@ # Copyright (c) 2026 exportAnything. All rights reserved. # SPDX-License-Identifier: MIT -from .nodes import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS +from .nodes import ( + NODE_CLASS_MAPPINGS as _DIRECTOR_NODE_CLASS_MAPPINGS, + NODE_DISPLAY_NAME_MAPPINGS as _DIRECTOR_NODE_DISPLAY_NAME_MAPPINGS, +) +from .audio_production_nodes import ( + NODE_CLASS_MAPPINGS as _AUDIO_NODE_CLASS_MAPPINGS, + NODE_DISPLAY_NAME_MAPPINGS as _AUDIO_NODE_DISPLAY_NAME_MAPPINGS, +) +from .production_planning_nodes import ( + NODE_CLASS_MAPPINGS as _PRODUCTION_PLANNING_NODE_CLASS_MAPPINGS, + NODE_DISPLAY_NAME_MAPPINGS as _PRODUCTION_PLANNING_NODE_DISPLAY_NAME_MAPPINGS, +) +from .timed_lyrics_nodes import ( + NODE_CLASS_MAPPINGS as _TIMED_LYRICS_NODE_CLASS_MAPPINGS, + NODE_DISPLAY_NAME_MAPPINGS as _TIMED_LYRICS_NODE_DISPLAY_NAME_MAPPINGS, +) + +NODE_CLASS_MAPPINGS = { + **_DIRECTOR_NODE_CLASS_MAPPINGS, + **_AUDIO_NODE_CLASS_MAPPINGS, + **_PRODUCTION_PLANNING_NODE_CLASS_MAPPINGS, + **_TIMED_LYRICS_NODE_CLASS_MAPPINGS, +} +NODE_DISPLAY_NAME_MAPPINGS = { + **_DIRECTOR_NODE_DISPLAY_NAME_MAPPINGS, + **_AUDIO_NODE_DISPLAY_NAME_MAPPINGS, + **_PRODUCTION_PLANNING_NODE_DISPLAY_NAME_MAPPINGS, + **_TIMED_LYRICS_NODE_DISPLAY_NAME_MAPPINGS, +} WEB_DIRECTORY = "./web" diff --git a/audio_production_nodes.py b/audio_production_nodes.py new file mode 100644 index 0000000..b637ec8 --- /dev/null +++ b/audio_production_nodes.py @@ -0,0 +1,2900 @@ +# Copyright (c) 2026 exportAnything. All rights reserved. +# SPDX-License-Identifier: MIT + +"""Lightweight decoded-audio production controls for ACE-Step and LTX. + +The analysis in this module is deliberately CPU-only and uses no learned model. +It measures the waveform that will actually condition LTX instead of trusting +soft text metadata such as a requested BPM or key. +""" + +from __future__ import annotations + +from collections import Counter +import hashlib +import json +import math +import os +import re +import struct +from typing import Any, Mapping + +import torch +import torch.nn.functional as torch_functional + +try: + from comfy_execution.graph_utils import ExecutionBlocker +except ModuleNotFoundError: # Standalone repository tests do not add ComfyUI. + class ExecutionBlocker: # type: ignore[no-redef] + def __init__(self, message: str | None) -> None: + self.message = message + + +CATEGORY = "prompt/diffusiongemma/audio-production" +ANALYSIS_SCHEMA = "diffusiongemma.decoded_audio_analysis" +SELECTION_REPORT_SCHEMA = "diffusiongemma.audio_candidate_selection" +GUIDE_REPORT_SCHEMA = "diffusiongemma.ltx_audio_guide" +PERFORMANCE_REPORT_SCHEMA = "diffusiongemma.ltx_performance_prompt" +ANALYSIS_VERSION = 1 +SELECTION_POLICY_REVISION = 4 +ANALYSIS_SAMPLE_RATE = 6000 +ANALYSIS_N_FFT = 512 +ANALYSIS_HOP = 128 +TONAL_WINDOW_SECONDS = 4.0 +MAX_CANONICAL_HALF_TIME_RELATIVE_ERROR = 0.05 +MAX_CANONICAL_DOUBLE_TIME_RELATIVE_ERROR = 0.05 +MAX_SAFE_DOUBLE_TIME_EXCERPT_ONSETS_PER_SECOND = 4.0 +MIN_SAFE_DOUBLE_TIME_VISUAL_RECOVERY_COVERAGE = 0.70 +MIN_SAFE_DOUBLE_TIME_EXCERPT_SCORE = 0.90 +MIN_SAFE_DOUBLE_TIME_TONAL_FAMILY_CONSISTENCY = 0.80 +MIN_SAFE_DOUBLE_TIME_TONAL_TRANSITION_STABILITY = 0.80 +MIN_SAFE_DOUBLE_TIME_SUPPORTING_SIGNAL_COUNT = 2 +SELECTION_MODES = ( + "auto_select", + "lock_candidate_1", + "lock_candidate_2", + "lock_candidate_3", + "lock_candidate_4", + "lock_by_hash", +) +GUIDE_MODES = ("full_mix", "sync_safe", "vocal_only") +LTX_PERFORMANCE_MODES = ( + "Dance / music sync", + "Lyrics + lip sync", + "Natural / audio-led sync", +) +MAX_LTX_PERFORMANCE_LYRIC_LINES = 8 +MAX_LTX_PERFORMANCE_LYRIC_CHARS = 1600 +PRODUCTION_CONCEPTS = ( + "Source passthrough", + "Joint video-safe plan", + "Audition and select", +) +ACE_REFERENCE_MODES = ("Compose new", "Cover reference") +SOUNDTRACK_SOURCES = ("Generate with ACE-Step", "Upload song") +AUDIO_SOURCE_POLICIES = ("ace_step", "uploaded_song") +MAX_UPLOAD_DURATION_SECONDS = 600.0 +MAX_UPLOAD_CHANNELS = 8 +MAX_UPLOAD_SAMPLE_RATE = 192_000 +MAX_UPLOAD_SCALAR_SAMPLES = 80_000_000 +_SHA256_RE = re.compile(r"^[0-9a-f]{64}$") +_KEY_NAMES = ("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B") +_MAJOR_PROFILE = (6.35, 2.23, 3.48, 2.33, 4.38, 4.09, 2.52, 5.19, 2.39, 3.66, 2.29, 2.88) +_MINOR_PROFILE = (6.33, 2.68, 3.52, 5.38, 2.60, 3.53, 2.54, 4.75, 3.98, 2.69, 3.34, 3.17) + + +def _json(value: Any) -> str: + return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def _clamp(value: float, lower: float = 0.0, upper: float = 1.0) -> float: + return max(lower, min(upper, float(value))) + + +def _db(value: float, floor: float = -120.0) -> float: + if not math.isfinite(value) or value <= 0.0: + return floor + return max(floor, 20.0 * math.log10(value)) + + +def _audio_parts(audio: Any, label: str = "audio") -> tuple[torch.Tensor, int]: + if not isinstance(audio, Mapping): + raise ValueError(f"{label} must be a ComfyUI AUDIO mapping.") + waveform = audio.get("waveform") + if not isinstance(waveform, torch.Tensor) or waveform.ndim != 3: + raise ValueError(f"{label} waveform must have shape [batch, channels, samples].") + if any(int(size) <= 0 for size in waveform.shape): + raise ValueError(f"{label} waveform dimensions must be non-empty.") + try: + sample_rate = int(audio.get("sample_rate", 0)) + except (TypeError, ValueError) as exc: + raise ValueError(f"{label} sample rate must be a positive integer.") from exc + if sample_rate <= 0: + raise ValueError(f"{label} sample rate must be a positive integer.") + return waveform, sample_rate + + +def waveform_sha256(audio: Any) -> str: + """Hash the exact waveform representation plus its timing metadata.""" + + waveform, sample_rate = _audio_parts(audio) + value = waveform.detach() + if value.device.type != "cpu": + value = value.to("cpu") + value = value.contiguous() + byte_tensor = value.view(torch.uint8) + array = byte_tensor.numpy() + payload = memoryview(array).cast("B") + digest = hashlib.sha256() + digest.update(b"diffusiongemma-audio-waveform@1\0") + digest.update(struct.pack(" tuple[torch.Tensor, int, dict[str, Any], dict[str, float]]: + waveform, sample_rate = _audio_parts(audio) + value = waveform.detach().to(device="cpu", dtype=torch.float32) + if not bool(torch.isfinite(value).all()): + raise ValueError("audio waveform contains NaN or infinite samples.") + source_peak = float(value.abs().max().item()) + source_rms = float(torch.sqrt(torch.mean(value.square())).item()) + source_clipped_fraction = float((value.abs() >= 0.999).to(torch.float32).mean().item()) + mono = value.mean(dim=(0, 1)).contiguous() + source_samples = int(mono.numel()) + duration = source_samples / float(sample_rate) + analysis_samples = max(1, int(round(duration * ANALYSIS_SAMPLE_RATE))) + if sample_rate != ANALYSIS_SAMPLE_RATE or analysis_samples != source_samples: + mono = torch_functional.interpolate( + mono.reshape(1, 1, -1), + size=analysis_samples, + mode="linear", + align_corners=False, + ).reshape(-1) + return ( + mono, + ANALYSIS_SAMPLE_RATE, + { + "sample_rate": sample_rate, + "shape": [int(size) for size in waveform.shape], + "dtype": str(waveform.dtype), + "duration_seconds": duration, + }, + { + "peak": source_peak, + "rms": source_rms, + "clipped_fraction": source_clipped_fraction, + }, + ) + + +def _normalized_correlation(left: torch.Tensor, right: torch.Tensor) -> float: + left = left.to(dtype=torch.float64) + right = right.to(dtype=torch.float64) + left = left - left.mean() + right = right - right.mean() + denominator = float(torch.linalg.vector_norm(left) * torch.linalg.vector_norm(right)) + if denominator <= 1.0e-12: + return 0.0 + return float(torch.dot(left, right) / denominator) + + +def _key_estimate(chroma: torch.Tensor) -> tuple[str, float]: + major = torch.tensor(_MAJOR_PROFILE, dtype=torch.float64) + minor = torch.tensor(_MINOR_PROFILE, dtype=torch.float64) + scores: list[tuple[float, str]] = [] + for root in range(12): + scores.append((_normalized_correlation(chroma, torch.roll(major, root)), f"{_KEY_NAMES[root]} major")) + scores.append((_normalized_correlation(chroma, torch.roll(minor, root)), f"{_KEY_NAMES[root]} minor")) + scores.sort(key=lambda item: (item[0], item[1]), reverse=True) + margin = scores[0][0] - scores[1][0] + return scores[0][1], _clamp((margin + 0.05) / 0.75) + + +def _key_family(key_name: str) -> str: + root_name, quality = key_name.split(" ", 1) + root = _KEY_NAMES.index(root_name) + major_root = root if quality == "major" else (root + 3) % 12 + minor_root = (major_root + 9) % 12 + return f"{_KEY_NAMES[major_root]} major / {_KEY_NAMES[minor_root]} minor" + + +def _key_transition_metrics(keys: list[str]) -> dict[str, float]: + if len(keys) < 2: + return { + "key_transition_rate": 0.0, + "tonal_family_transition_rate": 0.0, + "remote_tonal_jump_rate": 0.0, + "parallel_major_minor_flip_rate": 0.0, + "tonal_transition_stability": 1.0, + } + circle = (0, 7, 2, 9, 4, 11, 6, 1, 8, 3, 10, 5) + circle_position = {pitch: index for index, pitch in enumerate(circle)} + transitions = 0 + family_transitions = 0 + remote = 0 + parallel_flips = 0 + for left, right in zip(keys, keys[1:]): + left_root_name, left_quality = left.split(" ", 1) + right_root_name, right_quality = right.split(" ", 1) + left_root = _KEY_NAMES.index(left_root_name) + right_root = _KEY_NAMES.index(right_root_name) + if left != right: + transitions += 1 + left_family_root = left_root if left_quality == "major" else (left_root + 3) % 12 + right_family_root = right_root if right_quality == "major" else (right_root + 3) % 12 + if left_family_root != right_family_root: + family_transitions += 1 + distance = abs(circle_position[left_family_root] - circle_position[right_family_root]) + distance = min(distance, 12 - distance) + if distance >= 3: + remote += 1 + if left_root == right_root and left_quality != right_quality: + parallel_flips += 1 + denominator = len(keys) - 1 + transition_rate = transitions / denominator + family_rate = family_transitions / denominator + remote_rate = remote / denominator + parallel_rate = parallel_flips / denominator + stability = _clamp( + 1.0 + - 0.25 * transition_rate + - 0.25 * family_rate + - 0.35 * remote_rate + - 0.15 * parallel_rate + ) + return { + "key_transition_rate": transition_rate, + "tonal_family_transition_rate": family_rate, + "remote_tonal_jump_rate": remote_rate, + "parallel_major_minor_flip_rate": parallel_rate, + "tonal_transition_stability": stability, + } + + +def _tempo_metrics( + onset_envelope: torch.Tensor, + frames_per_second: float, + expected_bpm: float, +) -> dict[str, Any]: + centered = onset_envelope.to(dtype=torch.float64) + centered = centered - centered.mean() + minimum_lag = max(1, int(round(frames_per_second * 60.0 / 240.0))) + maximum_lag = min( + max(minimum_lag, int(round(frames_per_second * 60.0 / 40.0))), + max(minimum_lag, int(centered.numel()) // 2), + ) + correlations: list[tuple[float, float, int]] = [] + for lag in range(minimum_lag, maximum_lag + 1): + left = centered[:-lag] + right = centered[lag:] + denominator = float(torch.linalg.vector_norm(left) * torch.linalg.vector_norm(right)) + correlation = float(torch.dot(left, right) / denominator) if denominator > 1.0e-12 else 0.0 + bpm = 60.0 * frames_per_second / lag + correlations.append((correlation, bpm, lag)) + if not correlations: + return { + "raw_bpm": 0.0, + "canonical_bpm": 0.0, + "tempo_relation": "undetected", + "tempo_confidence": 0.0, + "tempo_equivalents": [], + } + target = float(expected_bpm) + target_equivalents = [ + value + for value in (target / 2.0, target, target * 2.0) + if target > 0.0 and 40.0 <= value <= 240.0 + ] + + def periodicity_rank(item: tuple[float, float, int]) -> tuple[float, float]: + correlation, bpm, _lag = item + if target_equivalents: + distance = min(abs(math.log2(bpm / value)) for value in target_equivalents) + # Reject unrelated third/subharmonic autocorrelation peaks while still + # allowing exact half- and double-time interpretations. + correlation -= 0.25 * distance + return (round(correlation, 6), bpm) + + # Prefer the faster periodic interpretation when correlations are effectively tied; + # the canonicalization below records whether that is a double-time pulse. + best = max(correlations, key=periodicity_rank) + if target_equivalents: + direct = min(correlations, key=lambda item: abs(math.log2(item[1] / target))) + if target * 2.0 <= 240.0: + doubled = min(correlations, key=lambda item: abs(math.log2(item[1] / (target * 2.0)))) + if doubled[0] >= max(0.30, 0.75 * direct[0]): + best = doubled + if best is direct and target / 2.0 >= 40.0: + halved = min(correlations, key=lambda item: abs(math.log2(item[1] / (target / 2.0)))) + if halved[0] >= max(0.30, direct[0] + 0.10): + best = halved + ordered = sorted(item[0] for item in correlations) + baseline = ordered[len(ordered) // 2] + confidence = _clamp((best[0] - baseline) / max(1.0e-6, 1.0 - baseline)) + raw_bpm = float(best[1]) + equivalents = sorted( + { + round(value, 6) + for value in (raw_bpm / 2.0, raw_bpm, raw_bpm * 2.0) + if 40.0 <= value <= 240.0 + } + ) + if math.isfinite(target) and target > 0.0: + canonical = min(equivalents, key=lambda value: (abs(math.log2(value / target)), abs(value - target))) + else: + canonical = raw_bpm + while canonical > 140.0 and canonical / 2.0 >= 40.0: + canonical /= 2.0 + while canonical < 70.0 and canonical * 2.0 <= 240.0: + canonical *= 2.0 + ratio = raw_bpm / canonical if canonical > 0.0 else 1.0 + if ratio > 1.75: + relation = "double_time_detected" + elif ratio < 0.625: + relation = "half_time_detected" + else: + relation = "direct" + return { + "raw_bpm": raw_bpm, + "canonical_bpm": canonical, + "tempo_relation": relation, + "tempo_confidence": confidence, + "tempo_equivalents": equivalents, + } + + +def _tonal_metrics(power: torch.Tensor, sample_rate: int) -> tuple[dict[str, Any], torch.Tensor]: + frequencies = torch.fft.rfftfreq(ANALYSIS_N_FFT, d=1.0 / sample_rate) + valid = (frequencies >= 55.0) & (frequencies <= min(3500.0, sample_rate / 2.0)) + selected_frequencies = frequencies[valid] + selected_power = power[valid] + midi = torch.round(69.0 + 12.0 * torch.log2(selected_frequencies / 440.0)).to(torch.long) + pitch_classes = torch.remainder(midi, 12) + chroma = torch.zeros((12, power.shape[1]), dtype=torch.float64) + chroma.index_add_(0, pitch_classes, selected_power.to(torch.float64)) + frames_per_window = max(1, int(round(TONAL_WINDOW_SECONDS * sample_rate / ANALYSIS_HOP))) + step = max(1, frames_per_window // 2) + windows: list[torch.Tensor] = [] + for start in range(0, chroma.shape[1], step): + end = min(chroma.shape[1], start + frames_per_window) + if end - start < max(1, frames_per_window // 2) and windows: + break + profile = chroma[:, start:end].sum(dim=1) + total = float(profile.sum()) + if total > 1.0e-12: + windows.append(profile / total) + if not windows: + windows = [torch.full((12,), 1.0 / 12.0, dtype=torch.float64)] + stack = torch.stack(windows) + centroid = stack.mean(dim=0) + centroid = centroid / max(float(centroid.sum()), 1.0e-12) + centroid_norm = max(float(torch.linalg.vector_norm(centroid)), 1.0e-12) + similarities = [ + float(torch.dot(window, centroid) / max(float(torch.linalg.vector_norm(window)) * centroid_norm, 1.0e-12)) + for window in windows + ] + keys = [_key_estimate(window)[0] for window in windows] + dominant_key, key_count = Counter(keys).most_common(1)[0] + key_agreement = key_count / len(keys) + entropy = -float(torch.sum(centroid * torch.log(centroid.clamp_min(1.0e-12)))) + clarity = _clamp(1.0 - entropy / math.log(12.0)) + key_name, key_confidence = _key_estimate(centroid) + stability = _clamp( + 0.45 * (sum(similarities) / len(similarities)) + + 0.30 * key_agreement + + 0.25 * clarity + ) + transitions = _key_transition_metrics(keys) + return ( + { + "tonal_window_stability": stability, + "tonal_centroid_similarity": sum(similarities) / len(similarities), + "tonal_center_agreement": key_agreement, + "tonal_clarity": clarity, + "dominant_key_estimate": key_name, + "dominant_key_confidence": key_confidence, + "tonal_window_count": len(windows), + "tonal_window_keys": keys, + **transitions, + }, + chroma, + ) + + +def _spectral_flatness_metrics(power: torch.Tensor, sample_rate: int) -> dict[str, float]: + """Return conservative broadband-noise proxies over active audible frames.""" + + frequencies = torch.fft.rfftfreq(ANALYSIS_N_FFT, d=1.0 / sample_rate) + audible = (frequencies >= 55.0) & (frequencies <= min(3500.0, sample_rate / 2.0)) + band = power[audible].to(torch.float64) + if band.numel() == 0 or band.shape[1] == 0: + values = torch.ones((1,), dtype=torch.float64) + else: + arithmetic = band.mean(dim=0) + peak_frame_energy = float(arithmetic.max()) + active = arithmetic > max(1.0e-14, peak_frame_energy * 1.0e-6) + if not bool(active.any()): + values = torch.ones((1,), dtype=torch.float64) + else: + active_band = band[:, active].clamp_min(1.0e-18) + geometric = torch.exp(torch.log(active_band).mean(dim=0)) + values = (geometric / active_band.mean(dim=0).clamp_min(1.0e-18)).clamp(0.0, 1.0) + return { + "spectral_flatness_mean": float(values.mean()), + "spectral_flatness_median": float(values.median()), + "spectral_flatness_p90": float(torch.quantile(values, 0.90)), + } + + +def _range_score(value: float, ideal_low: float, ideal_high: float, outer_low: float, outer_high: float) -> float: + if ideal_low <= value <= ideal_high: + return 1.0 + if value < ideal_low: + return _clamp((value - outer_low) / max(1.0e-9, ideal_low - outer_low)) + return _clamp((outer_high - value) / max(1.0e-9, outer_high - ideal_high)) + + +def _excerpt_metrics( + mono: torch.Tensor, + power: torch.Tensor, + chroma: torch.Tensor, + onset_peaks: torch.Tensor, + sample_rate: int, + excerpt_duration_seconds: float, + forced_start_seconds: float | None = None, +) -> dict[str, Any]: + duration = mono.numel() / float(sample_rate) + excerpt_duration = min(float(excerpt_duration_seconds), duration) + sample_count = max(1, int(round(excerpt_duration * sample_rate))) + frame_count = max(1, int(round(excerpt_duration * sample_rate / ANALYSIS_HOP))) + step_samples = max(1, int(round(min(1.0, excerpt_duration / 8.0) * sample_rate))) + frequency = torch.fft.rfftfreq(ANALYSIS_N_FFT, d=1.0 / sample_rate) + mid_band = (frequency >= 150.0) & (frequency <= min(3500.0, sample_rate / 2.0)) + audible_band = (frequency >= 55.0) & (frequency <= min(3500.0, sample_rate / 2.0)) + global_chroma = chroma.sum(dim=1) + global_chroma_norm = max(float(torch.linalg.vector_norm(global_chroma)), 1.0e-12) + candidates: list[dict[str, Any]] = [] + last_start = max(0, mono.numel() - sample_count) + if forced_start_seconds is not None: + forced = float(forced_start_seconds) + if not math.isfinite(forced) or forced < 0.0: + raise ValueError("locked_start_seconds must be a non-negative finite value.") + forced_sample = int(round(forced * sample_rate)) + if forced_sample > last_start: + raise ValueError("locked excerpt start does not leave enough audio for the requested duration.") + starts = [forced_sample] + else: + starts = list(range(0, last_start + 1, step_samples)) + if not starts or starts[-1] != last_start: + starts.append(last_start) + for start_sample in starts: + end_sample = min(mono.numel(), start_sample + sample_count) + segment = mono[start_sample:end_sample] + rms = float(torch.sqrt(torch.mean(segment.square())).item()) + peak = float(segment.abs().max().item()) + rms_dbfs = _db(rms) + crest_db = _db(peak / max(rms, 1.0e-12), floor=0.0) + start_frame = min(power.shape[1] - 1, max(0, start_sample // ANALYSIS_HOP)) + end_frame = min(power.shape[1], start_frame + frame_count) + local_power = power[:, start_frame:end_frame] + audible_energy = float(local_power[audible_band].sum()) + mid_ratio = float(local_power[mid_band].sum()) / max(audible_energy, 1.0e-12) + local_chroma = chroma[:, start_frame:end_frame].sum(dim=1) + tonal_similarity = float( + torch.dot(local_chroma, global_chroma) + / max(float(torch.linalg.vector_norm(local_chroma)) * global_chroma_norm, 1.0e-12) + ) + local_onsets = int(onset_peaks[start_frame:end_frame].sum().item()) + onset_density = local_onsets / max(excerpt_duration, 1.0e-9) + local_key_window_frames = max(1, int(round(2.0 * sample_rate / ANALYSIS_HOP))) + local_keys: list[str] = [] + local_key_details: list[dict[str, Any]] = [] + for local_start in range(start_frame, end_frame, local_key_window_frames): + local_end = min(end_frame, local_start + local_key_window_frames) + if local_end <= local_start: + continue + key_profile = chroma[:, local_start:local_end].sum(dim=1) + if float(key_profile.sum()) > 1.0e-12: + key_name, key_confidence = _key_estimate(key_profile) + local_key_details.append( + {"key": key_name, "confidence": key_confidence} + ) + if key_confidence >= 0.25: + local_keys.append(key_name) + local_families = [_key_family(key) for key in local_keys] + if local_families: + tonal_family, family_count = Counter(local_families).most_common(1)[0] + tonal_family_consistency = family_count / len(local_families) + else: + tonal_family = "undetected" + # No confident transition evidence is advisory rather than proof of + # instability. Global chroma clarity remains part of the score. + tonal_family_consistency = 1.0 + transition_metrics = _key_transition_metrics(local_keys) + activity_score = _range_score(rms_dbfs, -28.0, -8.0, -48.0, -2.0) + vocal_band_score = _clamp((mid_ratio - 0.30) / 0.55) + vocal_proxy = _clamp(0.60 * vocal_band_score + 0.40 * activity_score) + onset_score = _range_score(onset_density, 0.35, 3.75, 0.0, 7.0) + crest_score = _range_score(crest_db, 5.0, 16.0, 1.0, 26.0) + score = _clamp( + 0.20 * _clamp(tonal_similarity) + + 0.12 * tonal_family_consistency + + 0.13 * transition_metrics["tonal_transition_stability"] + + 0.20 * onset_score + + 0.18 * activity_score + + 0.12 * vocal_proxy + + 0.05 * crest_score + ) + candidates.append( + { + "start_seconds": start_sample / float(sample_rate), + "duration_seconds": excerpt_duration, + "score": score, + "rms_dbfs": rms_dbfs, + "crest_factor_db": crest_db, + "onset_density_per_second": onset_density, + "tonal_similarity": tonal_similarity, + "tonal_family": tonal_family, + "tonal_family_consistency": tonal_family_consistency, + "local_key_windows": local_keys, + "local_key_window_details": local_key_details, + "confident_key_transition_window_count": len(local_keys), + **transition_metrics, + "mid_band_energy_ratio": mid_ratio, + "vocal_presence_proxy": vocal_proxy, + "likely_vocal_active_proxy": bool(vocal_proxy >= 0.45 and rms_dbfs >= -40.0), + "start_was_locked": forced_start_seconds is not None, + } + ) + # A likely vocal-active window always outranks dead air. Lower start time is + # the deterministic tie-breaker. + chosen = max( + candidates, + key=lambda item: ( + bool(item["likely_vocal_active_proxy"]), + round(float(item["score"]), 9), + -float(item["start_seconds"]), + ), + ) + selected_start_sample = int(round(float(chosen["start_seconds"]) * sample_rate)) + selected_end_sample = min(mono.numel(), selected_start_sample + sample_count) + timeline_window_seconds = min(2.0, excerpt_duration) + timeline_window_samples = max(1, int(round(timeline_window_seconds * sample_rate))) + timeline_entries: list[dict[str, Any]] = [] + previous_profile: torch.Tensor | None = None + for relative_start_sample in range(0, max(1, selected_end_sample - selected_start_sample), timeline_window_samples): + absolute_start = selected_start_sample + relative_start_sample + absolute_end = min(selected_end_sample, absolute_start + timeline_window_samples) + if absolute_end <= absolute_start: + continue + segment = mono[absolute_start:absolute_end] + local_duration = (absolute_end - absolute_start) / float(sample_rate) + local_rms_dbfs = _db(float(torch.sqrt(torch.mean(segment.square())).item())) + start_frame = min(power.shape[1] - 1, max(0, absolute_start // ANALYSIS_HOP)) + end_frame = min( + power.shape[1], + max(start_frame + 1, int(math.ceil(absolute_end / ANALYSIS_HOP))), + ) + local_power = power[:, start_frame:end_frame] + local_audible = float(local_power[audible_band].sum()) + local_mid_ratio = float(local_power[mid_band].sum()) / max(local_audible, 1.0e-12) + local_profile = chroma[:, start_frame:end_frame].sum(dim=1) + local_key = _key_estimate(local_profile)[0] if float(local_profile.sum()) > 1.0e-12 else "undetected" + if previous_profile is None: + tonal_change = 0.0 + else: + tonal_change = 1.0 - float( + torch.dot(local_profile, previous_profile) + / max( + float(torch.linalg.vector_norm(local_profile)) + * float(torch.linalg.vector_norm(previous_profile)), + 1.0e-12, + ) + ) + previous_profile = local_profile + onset_density = float(onset_peaks[start_frame:end_frame].sum().item()) / max(local_duration, 1.0e-9) + activity = _range_score(local_rms_dbfs, -28.0, -8.0, -48.0, -2.0) + vocal_proxy = _clamp(0.60 * _clamp((local_mid_ratio - 0.30) / 0.55) + 0.40 * activity) + visual_recovery = bool( + local_rms_dbfs >= -45.0 + and onset_density <= 4.7 + and tonal_change <= 0.45 + ) + vocal_active_stable = bool(visual_recovery and vocal_proxy >= 0.45) + timeline_entries.append( + { + "relative_start_seconds": relative_start_sample / float(sample_rate), + "relative_end_seconds": (absolute_end - selected_start_sample) / float(sample_rate), + "onset_density_per_second": onset_density, + "rms_dbfs": local_rms_dbfs, + "mid_band_vocal_presence_proxy": vocal_proxy, + "key_proxy": local_key, + "tonal_change_proxy": _clamp(tonal_change), + "low_density_visual_recovery_proxy": visual_recovery, + "vocal_active_stable_proxy": vocal_active_stable, + } + ) + + def merged_intervals(flag: str) -> list[dict[str, Any]]: + intervals: list[dict[str, Any]] = [] + current: dict[str, Any] | None = None + for entry in timeline_entries: + if not entry[flag]: + if current is not None: + intervals.append(current) + current = None + continue + if current is None: + current = { + "relative_start_seconds": entry["relative_start_seconds"], + "relative_end_seconds": entry["relative_end_seconds"], + "window_count": 1, + "mean_onset_density_per_second": entry["onset_density_per_second"], + "maximum_tonal_change_proxy": entry["tonal_change_proxy"], + } + else: + count = int(current["window_count"]) + current["relative_end_seconds"] = entry["relative_end_seconds"] + current["window_count"] = count + 1 + current["mean_onset_density_per_second"] = ( + float(current["mean_onset_density_per_second"]) * count + + float(entry["onset_density_per_second"]) + ) / (count + 1) + current["maximum_tonal_change_proxy"] = max( + float(current["maximum_tonal_change_proxy"]), + float(entry["tonal_change_proxy"]), + ) + if current is not None: + intervals.append(current) + if len(intervals) > 8: + intervals = sorted( + intervals, + key=lambda item: ( + float(item["relative_end_seconds"]) - float(item["relative_start_seconds"]), + -float(item["mean_onset_density_per_second"]), + ), + reverse=True, + )[:8] + intervals.sort(key=lambda item: float(item["relative_start_seconds"])) + return intervals + + visual_recovery_intervals = merged_intervals("low_density_visual_recovery_proxy") + vocal_active_intervals = merged_intervals("vocal_active_stable_proxy") + timeline_duration = max(float(chosen["duration_seconds"]), 1.0e-9) + + def coverage_ratio(flag: str) -> float: + covered_seconds = sum( + max( + 0.0, + float(entry["relative_end_seconds"]) + - float(entry["relative_start_seconds"]), + ) + for entry in timeline_entries + if bool(entry[flag]) + ) + return _clamp(covered_seconds / timeline_duration) + + # Calculate coverage from the complete timeline before bounding the copy + # embedded in reports. These ratios let the selector distinguish a benign + # eighth-note/octave alias from sustained high-pressure double-time motion. + chosen["low_density_visual_recovery_coverage"] = coverage_ratio( + "low_density_visual_recovery_proxy" + ) + chosen["vocal_active_stable_coverage"] = coverage_ratio( + "vocal_active_stable_proxy" + ) + total_timeline_entries = len(timeline_entries) + if total_timeline_entries > 24: + selected_indices = sorted( + { + round(index * (total_timeline_entries - 1) / 23) + for index in range(24) + } + ) + timeline_entries = [timeline_entries[index] for index in selected_indices] + chosen["selected_excerpt_timeline"] = { + "window_seconds": timeline_window_seconds, + "entry_count_total": total_timeline_entries, + "entries_returned": len(timeline_entries), + "bounded_max_entries": 24, + "truncated": total_timeline_entries > len(timeline_entries), + "entries": timeline_entries, + } + chosen["low_density_visual_recovery_intervals"] = visual_recovery_intervals + chosen["vocal_active_stable_intervals"] = vocal_active_intervals + chosen["timeline_note"] = ( + "All entries are lightweight signal proxies relative to the selected excerpt. " + "Visual-recovery intervals do not require vocals; vocal-active intervals do. " + "These proxies are not vocal transcription or beat-grid ground truth." + ) + return chosen + + +def analyze_decoded_audio( + audio: Any, + *, + expected_bpm: float = 0.0, + excerpt_duration_seconds: float = 20.0, + locked_start_seconds: float | None = None, +) -> dict[str, Any]: + """Measure a decoded ComfyUI AUDIO mapping without using a learned model.""" + + expected = float(expected_bpm) + excerpt_duration = float(excerpt_duration_seconds) + if not math.isfinite(expected) or expected < 0.0 or expected > 300.0: + raise ValueError("expected_bpm must be 0 (auto) or a finite value from 1 to 300.") + if not math.isfinite(excerpt_duration) or excerpt_duration <= 0.0: + raise ValueError("excerpt_duration_seconds must be a positive finite number.") + mono, sample_rate, identity, source_metrics = _analysis_mono(audio) + duration = float(identity["duration_seconds"]) + peak = float(source_metrics["peak"]) + rms = float(source_metrics["rms"]) + crest = peak / max(rms, 1.0e-12) + clipped_fraction = float(source_metrics["clipped_fraction"]) + analysis_mono_peak = float(mono.abs().max().item()) + analysis_mono_rms = float(torch.sqrt(torch.mean(mono.square())).item()) + padded = mono + if padded.numel() < ANALYSIS_N_FFT: + padded = torch_functional.pad(padded, (0, ANALYSIS_N_FFT - padded.numel())) + window = torch.hann_window(ANALYSIS_N_FFT, dtype=torch.float32) + spectrum = torch.stft( + padded, + n_fft=ANALYSIS_N_FFT, + hop_length=ANALYSIS_HOP, + win_length=ANALYSIS_N_FFT, + window=window, + center=False, + return_complex=True, + ) + magnitude = spectrum.abs() + power = magnitude.square() + log_magnitude = torch.log1p(magnitude) + onset = torch.zeros(log_magnitude.shape[1], dtype=torch.float32) + if log_magnitude.shape[1] > 1: + onset[1:] = torch.relu(log_magnitude[:, 1:] - log_magnitude[:, :-1]).mean(dim=0) + onset = torch_functional.avg_pool1d( + torch_functional.pad(onset.reshape(1, 1, -1), (1, 1), mode="replicate"), + kernel_size=3, + stride=1, + ).reshape(-1) + threshold = float(onset.median() + 0.75 * onset.std(unbiased=False)) + local_max = torch_functional.max_pool1d( + torch_functional.pad(onset.reshape(1, 1, -1), (3, 3), mode="replicate"), + kernel_size=7, + stride=1, + ).reshape(-1) + onset_peaks = (onset >= local_max) & (onset > max(threshold, 1.0e-7)) + onset_count = int(onset_peaks.sum().item()) + onset_density = onset_count / max(duration, 1.0e-9) + frames_per_second = sample_rate / float(ANALYSIS_HOP) + tempo = _tempo_metrics(onset, frames_per_second, expected) + tonal, chroma = _tonal_metrics(power, sample_rate) + spectral_flatness = _spectral_flatness_metrics(power, sample_rate) + excerpt = _excerpt_metrics( + mono, + power, + chroma, + onset_peaks, + sample_rate, + excerpt_duration, + locked_start_seconds, + ) + rms_dbfs = _db(rms) + crest_db = _db(crest, floor=0.0) + canonical_tempo_relative_error = None + if expected > 0.0 and float(tempo["canonical_bpm"]) > 0.0: + canonical_tempo_relative_error = abs( + float(tempo["canonical_bpm"]) - expected + ) / expected + tempo_alignment = 1.0 + if expected > 0.0 and tempo["canonical_bpm"] > 0.0: + tempo_alignment = math.exp(-4.0 * abs(math.log2(float(tempo["canonical_bpm"]) / expected))) + tempo_score = _clamp(0.65 * float(tempo["tempo_confidence"]) + 0.35 * tempo_alignment) + aligned_half_time = ( + tempo["tempo_relation"] == "half_time_detected" + and canonical_tempo_relative_error is not None + and canonical_tempo_relative_error <= MAX_CANONICAL_HALF_TIME_RELATIVE_ERROR + ) + # With no requested BPM, half/double labels are only a signal-derived + # interpretation of autocorrelation peaks. Do not punish an otherwise + # usable song for that arbitrary canonicalization. + if expected > 0.0 and tempo["tempo_relation"] != "direct" and not aligned_half_time: + tempo_score *= 0.20 + onset_score = _range_score(onset_density, 0.35, 4.25, 0.0, 8.0) + rms_score = _range_score(rms_dbfs, -28.0, -8.0, -50.0, -1.0) + crest_score = _range_score(crest_db, 5.0, 18.0, 1.0, 30.0) + clipping_score = _clamp(1.0 - clipped_fraction / 0.02) + score = _clamp( + 0.32 * float(tonal["tonal_window_stability"]) + + 0.18 * tempo_score + + 0.17 * onset_score + + 0.12 * rms_score + + 0.08 * crest_score + + 0.05 * clipping_score + + 0.08 * float(excerpt["score"]) + ) + return { + "schema": ANALYSIS_SCHEMA, + "version": ANALYSIS_VERSION, + **identity, + "analysis_sample_rate": sample_rate, + "expected_bpm": expected, + "waveform_sha256": waveform_sha256(audio), + "peak_dbfs": _db(peak), + "rms_dbfs": rms_dbfs, + "crest_factor_db": crest_db, + "clipped_sample_fraction": clipped_fraction, + "analysis_mono_peak_dbfs": _db(analysis_mono_peak), + "analysis_mono_rms_dbfs": _db(analysis_mono_rms), + "onset_count": onset_count, + "onset_density_per_second": onset_density, + "detected_bpm_raw": float(tempo["raw_bpm"]), + "detected_bpm": float(tempo["canonical_bpm"]), + "tempo_relation": tempo["tempo_relation"], + "tempo_confidence": float(tempo["tempo_confidence"]), + "tempo_equivalents": [float(value) for value in tempo["tempo_equivalents"]], + "canonical_tempo_relative_error": canonical_tempo_relative_error, + **tonal, + **spectral_flatness, + "suggested_excerpt": excerpt, + "production_score": score, + "analysis_notes": [ + "Key and vocal activity are signal-derived proxies, not transcription or note-level proof.", + "Spectral flatness is a conservative broadband-noise/artifact proxy, not a genre judgment.", + "Half/double tempo equivalents are compared before scoring against expected BPM.", + "A half-time accent pattern is advisory and unpenalized when its canonical tempo matches the requested BPM within 5%.", + "A canonically aligned double-time reading is advisory when the selected excerpt proves low transient pressure and vocal activity plus at least two supporting recovery, excerpt-score, tonal-family, or transition-stability signals; ordinary hard QC gates still apply, and its tempo subscore remains penalized.", + "QC limits are empirical provisional thresholds for this music-video workflow, not universal music-quality claims.", + ], + } + + +def _is_canonically_aligned_low_pressure_double_time( + analysis: Mapping[str, Any], +) -> bool: + if str(analysis.get("tempo_relation", "")) != "double_time_detected": + return False + relative_error = analysis.get("canonical_tempo_relative_error") + if not isinstance(relative_error, (int, float)) or not math.isfinite( + float(relative_error) + ): + return False + excerpt = analysis.get("suggested_excerpt") + if not isinstance(excerpt, Mapping): + return False + supporting_signals = ( + float(excerpt.get("low_density_visual_recovery_coverage", 0.0)) + >= MIN_SAFE_DOUBLE_TIME_VISUAL_RECOVERY_COVERAGE, + float(excerpt.get("score", 0.0)) >= MIN_SAFE_DOUBLE_TIME_EXCERPT_SCORE, + float(excerpt.get("tonal_family_consistency", 0.0)) + >= MIN_SAFE_DOUBLE_TIME_TONAL_FAMILY_CONSISTENCY, + float(excerpt.get("tonal_transition_stability", 0.0)) + >= MIN_SAFE_DOUBLE_TIME_TONAL_TRANSITION_STABILITY, + ) + # An octave-related autocorrelation peak is a tempo interpretation, not an + # independent quality failure. Canonical alignment, measured onset pressure, + # and vocal activity are mandatory. The four partly overlapping quality + # proxies form a deterministic evidence bundle: two are sufficient, so one + # conservative proxy cannot veto several stronger independent measurements. + # Clipping, artifacts, silence, duration, tonal failure, and the user-selected + # production-score floor remain independently enforced in _candidate_failures(). + return bool( + float(relative_error) <= MAX_CANONICAL_DOUBLE_TIME_RELATIVE_ERROR + and float(excerpt.get("onset_density_per_second", math.inf)) + <= MAX_SAFE_DOUBLE_TIME_EXCERPT_ONSETS_PER_SECOND + and bool(excerpt.get("likely_vocal_active_proxy")) + and sum(bool(value) for value in supporting_signals) + >= MIN_SAFE_DOUBLE_TIME_SUPPORTING_SIGNAL_COUNT + ) + + +def _normalize_audio_source_policy(value: Any) -> str: + normalized = str(value or "ace_step").strip().casefold().replace("-", "_").replace(" ", "_") + aliases = { + "ace": "ace_step", + "ace_step": "ace_step", + "generated": "ace_step", + "generated_candidates": "ace_step", + "upload": "uploaded_song", + "uploaded": "uploaded_song", + "upload_song": "uploaded_song", + "uploaded_song": "uploaded_song", + } + if normalized not in aliases: + raise ValueError( + f"source_policy must be one of {', '.join(AUDIO_SOURCE_POLICIES)}." + ) + return aliases[normalized] + + +def _candidate_advisories( + analysis: Mapping[str, Any], + *, + source_policy: str = "ace_step", + minimum_score: float = 0.52, +) -> list[str]: + policy = _normalize_audio_source_policy(source_policy) + relation = str(analysis.get("tempo_relation", "")) + relative_error = analysis.get("canonical_tempo_relative_error") + advisories: list[str] = [] + if ( + relation == "half_time_detected" + and isinstance(relative_error, (int, float)) + and math.isfinite(float(relative_error)) + and float(relative_error) <= MAX_CANONICAL_HALF_TIME_RELATIVE_ERROR + ): + advisories.append("canonically_aligned_half_time_pulse") + elif _is_canonically_aligned_low_pressure_double_time(analysis): + advisories.append("canonically_aligned_low_pressure_double_time_pulse") + if policy != "uploaded_song": + return advisories + + advisories.insert(0, "source_locked_uploaded_song") + excerpt = analysis["suggested_excerpt"] + if float(analysis["tonal_window_stability"]) < 0.25: + advisories.append("source_locked_advisory_unstable_tonal_windows") + if float(analysis["onset_density_per_second"]) > 8.0: + advisories.append("source_locked_advisory_excessive_onset_density") + if float(excerpt["onset_density_per_second"]) > 4.7: + advisories.append("source_locked_advisory_dense_selected_excerpt") + expected_bpm = float(analysis.get("expected_bpm", 0.0)) + if relation != "direct" and not any( + value.startswith("canonically_aligned_") for value in advisories + ): + advisories.append( + "source_locked_advisory_signal_only_tempo_interpretation" + if expected_bpm <= 0.0 + else "source_locked_advisory_requested_tempo_mismatch" + ) + transition_evidence = int(excerpt.get("confident_key_transition_window_count", 0)) + if transition_evidence >= 3 and float(excerpt.get("tonal_family_consistency", 0.0)) < 0.60: + advisories.append("source_locked_advisory_tonal_family_variation") + if transition_evidence >= 4 and float(excerpt.get("remote_tonal_jump_rate", 0.0)) > 0.34: + advisories.append("source_locked_advisory_remote_tonal_jumps") + if transition_evidence >= 4 and float(excerpt.get("parallel_major_minor_flip_rate", 0.0)) > 0.34: + advisories.append("source_locked_advisory_parallel_mode_variation") + if transition_evidence >= 4 and float(excerpt.get("tonal_transition_stability", 0.0)) < 0.50: + advisories.append("source_locked_advisory_tonal_transition_variation") + global_tonal_windows = int(analysis.get("tonal_window_count", 0)) + if global_tonal_windows >= 4 and float(analysis.get("remote_tonal_jump_rate", 0.0)) > 0.34: + advisories.append("source_locked_advisory_global_remote_tonal_jumps") + if global_tonal_windows >= 4 and float(analysis.get("tonal_transition_stability", 0.0)) < 0.50: + advisories.append("source_locked_advisory_global_tonal_variation") + if not bool(excerpt["likely_vocal_active_proxy"]): + advisories.append("source_locked_advisory_no_vocal_proxy") + if float(analysis["production_score"]) < float(minimum_score): + advisories.append("source_locked_advisory_below_generated_candidate_score") + return advisories + + +def _candidate_failures( + analysis: Mapping[str, Any], + *, + excerpt_duration_seconds: float, + minimum_score: float, + source_policy: str = "ace_step", +) -> list[str]: + policy = _normalize_audio_source_policy(source_policy) + failures: list[str] = [] + # ACE-Step quantizes duration to a 25 Hz latent clock (40 ms per step). + # Treat one rounded latent step as equivalent to the requested wall clock; + # larger shortages still fail closed. + ace_duration_tolerance_seconds = 0.05 + if ( + float(analysis["duration_seconds"]) + ace_duration_tolerance_seconds + < excerpt_duration_seconds + ): + failures.append("audio_shorter_than_requested_excerpt") + if float(analysis["rms_dbfs"]) < -48.0: + failures.append("silent_or_near_silent") + if float(analysis["clipped_sample_fraction"]) > 0.02: + failures.append("excessive_clipping") + if ( + float(analysis.get("spectral_flatness_mean", 1.0)) > 0.35 + and float(analysis.get("tonal_clarity", 0.0)) < 0.04 + ): + failures.append("broadband_noise_or_artifact_like_spectrum") + # An uploaded song is user-selected source material, not an ACE audition + # candidate. Preserve only technical integrity gates; musical style, + # tempo, vocal presence, onset pressure, tonal movement, and the generated- + # candidate score remain visible advisories but cannot substitute or reject + # the user's soundtrack. + if policy == "uploaded_song": + return failures + if float(analysis["tonal_window_stability"]) < 0.25: + failures.append("unstable_tonal_windows") + if float(analysis["onset_density_per_second"]) > 8.0: + failures.append("excessive_onset_density") + excerpt = analysis["suggested_excerpt"] + if float(excerpt["onset_density_per_second"]) > 4.7: + failures.append("selected_excerpt_onset_density_above_empirical_limit") + # Tempo autocorrelation can label ordinary subdivisions as an octave alias. + # Aligned half-time is harmless. Aligned double-time remains riskier, but is + # admitted when the actual selected excerpt independently proves low onset + # pressure and vocal activity plus a two-of-four supporting evidence bundle. + # Recovery coverage ranks accepted candidates, while the ordinary tonal, + # artifact, and score checks below remain hard gates. Unlike aligned half-time, + # accepted double-time keeps its tempo-score penalty. + tempo_relation = str(analysis.get("tempo_relation")) + tempo_advisories = _candidate_advisories(analysis) + if tempo_relation != "direct" and not tempo_advisories: + if tempo_relation == "double_time_detected": + failures.append("double_time_outside_low_pressure_contract") + elif tempo_relation == "half_time_detected": + failures.append("half_time_outside_canonical_alignment_contract") + else: + failures.append("tempo_undetected_or_unrelated") + transition_evidence = int(excerpt.get("confident_key_transition_window_count", 0)) + if transition_evidence >= 3 and float(excerpt.get("tonal_family_consistency", 0.0)) < 0.60: + failures.append("selected_excerpt_tonal_family_inconsistent") + if transition_evidence >= 4 and float(excerpt.get("remote_tonal_jump_rate", 0.0)) > 0.34: + failures.append("selected_excerpt_remote_tonal_jumps") + if transition_evidence >= 4 and float(excerpt.get("parallel_major_minor_flip_rate", 0.0)) > 0.34: + failures.append("selected_excerpt_parallel_mode_instability") + if transition_evidence >= 4 and float(excerpt.get("tonal_transition_stability", 0.0)) < 0.50: + failures.append("selected_excerpt_tonal_transition_instability") + global_tonal_windows = int(analysis.get("tonal_window_count", 0)) + if global_tonal_windows >= 4 and float(analysis.get("remote_tonal_jump_rate", 0.0)) > 0.34: + failures.append("global_remote_tonal_jumps") + if global_tonal_windows >= 4 and float(analysis.get("tonal_transition_stability", 0.0)) < 0.50: + failures.append("global_tonal_transition_instability") + if not bool(excerpt["likely_vocal_active_proxy"]): + failures.append("no_non_silent_vocal_active_proxy_window") + if float(analysis["production_score"]) < minimum_score: + failures.append("production_score_below_threshold") + return failures + + +def _selection_failure( + report: dict[str, Any], + message: str, +) -> tuple[Any, float, Any, Any, str, str, bool]: + report["ready"] = False + report["status"] = message + return ( + ExecutionBlocker(message), + 0.0, + # The Project Master Contract consumes this output as its immutable + # audio identity. Returning an empty STRING let that independent + # branch execute and replace the useful QC diagnosis with a misleading + # "invalid SHA-256" exception. Propagate the same blocker so every + # song-dependent branch stops at the actual selection failure. + ExecutionBlocker(message), + # The compact report is a hard scheduling dependency of Director in + # the production workflow. Block it as well as AUDIO so a failed + # audition cannot spend minutes running Director before LTX stops. + ExecutionBlocker(message), + _json(report), + message, + False, + ) + + +def _candidate_summary(entry: Mapping[str, Any]) -> dict[str, Any]: + summary: dict[str, Any] = { + "index": entry.get("index"), + "present": bool(entry.get("present")), + "passed": bool(entry.get("passed")), + "failures": list(entry.get("failures", []))[:12], + "advisories": list(entry.get("advisories", []))[:12], + } + analysis = entry.get("analysis") + if isinstance(analysis, Mapping): + summary.update( + { + "waveform_sha256": analysis.get("waveform_sha256", ""), + "production_score": analysis.get("production_score"), + "expected_bpm": analysis.get("expected_bpm"), + "detected_bpm_raw": analysis.get("detected_bpm_raw"), + "detected_bpm": analysis.get("detected_bpm"), + "tempo_relation": analysis.get("tempo_relation"), + "canonical_tempo_relative_error": analysis.get( + "canonical_tempo_relative_error" + ), + "onset_density_per_second": analysis.get("onset_density_per_second"), + "tonal_window_stability": analysis.get("tonal_window_stability"), + "tonal_clarity": analysis.get("tonal_clarity"), + "spectral_flatness_mean": analysis.get("spectral_flatness_mean"), + "suggested_excerpt_score": analysis.get("suggested_excerpt", {}).get( + "score" + ), + "suggested_excerpt_start_seconds": analysis.get( + "suggested_excerpt", {} + ).get("start_seconds"), + "suggested_excerpt_visual_recovery_coverage": analysis.get( + "suggested_excerpt", {} + ).get("low_density_visual_recovery_coverage"), + "suggested_excerpt_vocal_active_coverage": analysis.get( + "suggested_excerpt", {} + ).get("vocal_active_stable_coverage"), + } + ) + if entry.get("error"): + summary["error"] = str(entry["error"])[:400] + return summary + + +def _compact_director_report( + audit_report: Mapping[str, Any], + selected_analysis: Mapping[str, Any] | None = None, +) -> dict[str, Any]: + settings = audit_report.get("settings", {}) + compact: dict[str, Any] = { + "schema": "diffusiongemma.music_audition_report", + "version": ANALYSIS_VERSION, + "selection_policy_revision": audit_report.get( + "selection_policy_revision", SELECTION_POLICY_REVISION + ), + "status": audit_report.get("status", ""), + "ready": bool(audit_report.get("ready")), + "selected_candidate_index": audit_report.get("selected_candidate_index"), + "selected_audio_sha256": audit_report.get("selected_waveform_sha256", ""), + "selection_lock_token": audit_report.get("selection_lock_token", ""), + "lock": { + key: audit_report.get("lock", {}).get(key) + for key in ( + "active", + "satisfied", + "excerpt_start_locked", + "resolved_candidate_index", + "resolved_waveform_sha256", + "resolved_start_seconds", + "failure_reason", + ) + if key in audit_report.get("lock", {}) + }, + "settings": { + "candidate_count": settings.get("candidate_count"), + "selection_mode": settings.get("selection_mode"), + "expected_bpm": settings.get("expected_bpm"), + "excerpt_duration_seconds": settings.get("excerpt_duration_seconds"), + "minimum_score": settings.get("minimum_score"), + "empirical_provisional_thresholds": settings.get("empirical_provisional_thresholds", {}), + }, + "candidate_summaries": [ + _candidate_summary(entry) + for entry in list(audit_report.get("candidates", []))[:4] + if isinstance(entry, Mapping) + ], + } + if isinstance(selected_analysis, Mapping): + excerpt = selected_analysis.get("suggested_excerpt", {}) + timeline = excerpt.get("selected_excerpt_timeline", {}) if isinstance(excerpt, Mapping) else {} + compact["qc"] = { + key: selected_analysis.get(key) + for key in ( + "production_score", + "duration_seconds", + "expected_bpm", + "detected_bpm_raw", + "detected_bpm", + "tempo_relation", + "tempo_confidence", + "onset_density_per_second", + "rms_dbfs", + "crest_factor_db", + "tonal_window_stability", + "tonal_transition_stability", + "tonal_clarity", + "spectral_flatness_mean", + "dominant_key_estimate", + "dominant_key_confidence", + ) + } + compact["selected_excerpt"] = { + "start_seconds": excerpt.get("start_seconds"), + "duration_seconds": excerpt.get("duration_seconds"), + "score": excerpt.get("score"), + "onset_rate_hz": excerpt.get("onset_density_per_second"), + "rms_dbfs": excerpt.get("rms_dbfs"), + "tonal_family_stability": excerpt.get("tonal_family_consistency"), + "tonal_transition_stability": excerpt.get("tonal_transition_stability"), + "vocal_presence_proxy": excerpt.get("vocal_presence_proxy"), + "likely_vocal_active_proxy": excerpt.get("likely_vocal_active_proxy"), + "low_density_visual_recovery_coverage": excerpt.get( + "low_density_visual_recovery_coverage" + ), + "vocal_active_stable_coverage": excerpt.get( + "vocal_active_stable_coverage" + ), + "timeline": { + "window_seconds": timeline.get("window_seconds"), + "entry_count_total": timeline.get("entry_count_total"), + "truncated": timeline.get("truncated"), + "entries": list(timeline.get("entries", []))[:24], + }, + "low_density_visual_recovery_intervals": list( + excerpt.get("low_density_visual_recovery_intervals", []) + )[:8], + "vocal_active_stable_intervals": list( + excerpt.get("vocal_active_stable_intervals", []) + )[:8], + "proxy_note": excerpt.get("timeline_note", ""), + } + encoded = _json(compact) + if len(encoded) > 12_000 and "selected_excerpt" in compact: + compact["selected_excerpt"]["timeline"]["entries"] = compact["selected_excerpt"]["timeline"]["entries"][:12] + compact["selected_excerpt"]["timeline"]["truncated"] = True + compact["selected_excerpt"]["low_density_visual_recovery_intervals"] = compact["selected_excerpt"]["low_density_visual_recovery_intervals"][:4] + compact["selected_excerpt"]["vocal_active_stable_intervals"] = compact["selected_excerpt"]["vocal_active_stable_intervals"][:4] + encoded = _json(compact) + if len(encoded) > 12_000: + compact["candidate_summaries"] = compact["candidate_summaries"][:1] + compact["report_compacted_to_fit_director"] = True + return compact + + +def _normalize_selection_mode(value: Any) -> str: + mode = str(value or "").strip().casefold().replace(" ", "_") + if mode not in SELECTION_MODES: + raise ValueError(f"selection_mode must be one of {', '.join(SELECTION_MODES)}.") + return mode + + +class DiffusionGemmaAudioCandidateSelector: + """Measure decoded song candidates and fail closed unless one passes QC.""" + + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "candidate_count": ("INT", {"default": 2, "min": 1, "max": 4, "step": 1}), + "selection_mode": (list(SELECTION_MODES), {"default": "auto_select"}), + "expected_bpm": ( + "FLOAT", + { + "default": 0.0, + "min": 0.0, + "max": 300.0, + "step": 0.1, + "tooltip": "Requested tempo used to interpret equivalent pulse rates. Canonically aligned half-time is advisory; an aligned double-time subdivision is advisory only with <=5% canonical error, <=4.0 excerpt onsets/s, vocal activity, and at least two supporting recovery/score/tonal signals; other tempo aliases block. Use 0 for signal-only analysis.", + }, + ), + "excerpt_duration_seconds": ( + "FLOAT", + {"default": 20.0, "min": 0.5, "max": 600.0, "step": 0.1}, + ), + "minimum_score": ( + "FLOAT", + { + "default": 0.52, + "min": 0.0, + "max": 1.0, + "step": 0.01, + "tooltip": "Numeric production-score floor only. Independent duration, clipping, tempo, onset, tonal, vocal-activity, and artifact failures still block selection.", + }, + ), + }, + "optional": { + "locked_waveform_sha256": ( + "STRING", + { + "default": "", + "multiline": False, + "tooltip": "Required by lock_by_hash; any mismatch fails closed.", + }, + ), + "locked_start_seconds": ( + "FLOAT", + { + "default": -1.0, + "min": -1.0, + "max": 2000.0, + "step": 0.1, + "tooltip": "-1 uses deterministic auto-start; non-negative values lock the exact excerpt start.", + }, + ), + "candidate_1": ("AUDIO", {"lazy": True}), + "candidate_2": ("AUDIO", {"lazy": True}), + "candidate_3": ("AUDIO", {"lazy": True}), + "candidate_4": ("AUDIO", {"lazy": True}), + "source_policy": ( + "STRING", + { + "forceInput": True, + "tooltip": ( + "ace_step applies generated-candidate audition gates. uploaded_song " + "source-locks the user's track: technical integrity remains blocking " + "while tempo, vocals, style, and production-score heuristics are advisory." + ), + }, + ), + }, + } + + RETURN_TYPES = ("AUDIO", "FLOAT", "STRING", "STRING", "STRING", "STRING", "BOOLEAN") + RETURN_NAMES = ( + "selected_audio", + "suggested_start_seconds", + "waveform_sha256", + "director_report_json", + "audit_report_json", + "status", + "ready", + ) + FUNCTION = "select" + CATEGORY = CATEGORY + DESCRIPTION = ( + "QC-checks one decoded song for Source/Joint production, or auditions two to four songs. " + "Auto-select favors direct/aligned-half tempo, then evidence-qualified double-time recovery, actual excerpt quality, and whole-song score. " + "An uploaded song uses source-locked technical-integrity gates while musical heuristics remain advisory. " + "A locked candidate or hash never silently falls back to another song." + ) + + @classmethod + def check_lazy_status(cls, **kwargs): + count = max(1, min(4, int(kwargs.get("candidate_count", 2)))) + mode = _normalize_selection_mode(kwargs.get("selection_mode", "auto_select")) + if mode == "lock_by_hash": + lock_hash = str(kwargs.get("locked_waveform_sha256", "") or "").strip().casefold() + # Let select() emit the explicit fail-closed report before resolving + # any expensive ACE lane when the lock itself cannot possibly match. + if not _SHA256_RE.fullmatch(lock_hash): + return [] + locked_match = re.fullmatch(r"lock_candidate_([1-4])", mode) + if locked_match is not None: + index = int(locked_match.group(1)) + names = [f"candidate_{index}"] if index <= count else [] + else: + names = [f"candidate_{index}" for index in range(1, count + 1)] + # Comfy omits an unconnected optional input entirely. Request only a + # connected-but-unresolved lazy socket; requesting an absent socket + # raises NodeInputError before our friendly fail-closed result can run. + return [name for name in names if name in kwargs and kwargs[name] is None] + + def select( + self, + candidate_count, + selection_mode, + expected_bpm, + excerpt_duration_seconds, + minimum_score, + locked_waveform_sha256="", + locked_start_seconds=-1.0, + candidate_1=None, + candidate_2=None, + candidate_3=None, + candidate_4=None, + source_policy="ace_step", + ): + count = int(candidate_count) + if count < 1 or count > 4: + raise ValueError("candidate_count must be from 1 to 4.") + mode = _normalize_selection_mode(selection_mode) + policy = _normalize_audio_source_policy(source_policy) + expected = float(expected_bpm) + excerpt_duration = float(excerpt_duration_seconds) + threshold = float(minimum_score) + if not math.isfinite(threshold) or not 0.0 <= threshold <= 1.0: + raise ValueError("minimum_score must be a finite value from 0 to 1.") + candidates = [candidate_1, candidate_2, candidate_3, candidate_4] + lock_hash = str(locked_waveform_sha256 or "").strip().casefold() + locked_start = float(locked_start_seconds) + if not math.isfinite(locked_start) or locked_start < -1.0: + raise ValueError("locked_start_seconds must be -1 (auto) or a non-negative finite value.") + lock_match = re.fullmatch(r"lock_candidate_([1-4])", mode) + indices = [int(lock_match.group(1))] if lock_match is not None else list(range(1, count + 1)) + report: dict[str, Any] = { + "schema": SELECTION_REPORT_SCHEMA, + "version": ANALYSIS_VERSION, + "selection_policy_revision": SELECTION_POLICY_REVISION, + "settings": { + "candidate_count": count, + "selection_mode": mode, + "expected_bpm": expected, + "excerpt_duration_seconds": excerpt_duration, + "minimum_score": threshold, + "source_policy": policy, + "locked_start_seconds": locked_start, + "empirical_provisional_thresholds": { + "maximum_selected_excerpt_onsets_per_second": 4.7, + "minimum_selected_excerpt_tonal_family_consistency": 0.60, + "maximum_noise_like_spectral_flatness_mean": 0.35, + "minimum_global_tonal_transition_stability": 0.50, + "maximum_global_remote_tonal_jump_rate": 0.34, + "maximum_audio_duration_shortfall_seconds": 0.05, + "aligned_half_time_policy": "advisory_without_tempo_score_penalty", + "maximum_aligned_half_time_relative_error": MAX_CANONICAL_HALF_TIME_RELATIVE_ERROR, + "double_time_policy": "mandatory_alignment_pressure_vocal_plus_two_of_four_quality_signals", + "maximum_aligned_double_time_relative_error": MAX_CANONICAL_DOUBLE_TIME_RELATIVE_ERROR, + "maximum_safe_double_time_excerpt_onsets_per_second": MAX_SAFE_DOUBLE_TIME_EXCERPT_ONSETS_PER_SECOND, + "minimum_safe_double_time_visual_recovery_coverage": MIN_SAFE_DOUBLE_TIME_VISUAL_RECOVERY_COVERAGE, + "minimum_safe_double_time_excerpt_score": MIN_SAFE_DOUBLE_TIME_EXCERPT_SCORE, + "minimum_safe_double_time_tonal_family_consistency": MIN_SAFE_DOUBLE_TIME_TONAL_FAMILY_CONSISTENCY, + "minimum_safe_double_time_tonal_transition_stability": MIN_SAFE_DOUBLE_TIME_TONAL_TRANSITION_STABILITY, + "minimum_safe_double_time_supporting_signal_count": MIN_SAFE_DOUBLE_TIME_SUPPORTING_SIGNAL_COUNT, + "double_time_supporting_signal_policy": "at_least_two_of_recovery_excerpt_score_tonal_family_transition_stability", + "accepted_double_time_tempo_score_policy": "retain_non_direct_penalty", + "misaligned_or_undetected_tempo_policy": "hard_failure", + "scope": ( + "ACE-Step candidate audition heuristic" + if policy == "ace_step" + else "source-locked uploaded song; technical integrity gates only" + ), + }, + "auto_selection_order": [ + "tempo_safety_class_descending", + "double_time_visual_recovery_coverage_descending", + "selected_excerpt_score_descending", + "full_song_production_score_descending", + "candidate_index_ascending", + ], + }, + "lock": { + "active": mode != "auto_select", + "requested_waveform_sha256": lock_hash, + "requested_start_seconds": locked_start, + "excerpt_start_locked": mode != "auto_select" and locked_start >= 0.0, + "satisfied": False, + "failure_reason": "", + }, + "candidates": [], + "selected_candidate_index": None, + "selected_waveform_sha256": "", + } + if lock_match is not None and indices[0] > count: + message = f"Audio selection is locked to candidate {indices[0]}, outside candidate_count={count}." + report["lock"]["failure_reason"] = "locked_candidate_outside_candidate_count" + return _selection_failure(report, message) + if mode == "lock_by_hash" and not _SHA256_RE.fullmatch(lock_hash): + message = "Audio selection is locked by hash, but no valid lowercase/uppercase SHA-256 was supplied." + report["lock"]["failure_reason"] = "invalid_locked_waveform_sha256" + return _selection_failure(report, message) + + measured: dict[int, dict[str, Any]] = {} + missing: list[int] = [] + for index in indices: + audio = candidates[index - 1] + if audio is None: + missing.append(index) + report["candidates"].append( + {"index": index, "present": False, "passed": False, "failures": ["candidate_missing"]} + ) + continue + try: + analysis = analyze_decoded_audio( + audio, + expected_bpm=expected, + excerpt_duration_seconds=excerpt_duration, + locked_start_seconds=( + locked_start + if mode != "auto_select" and locked_start >= 0.0 + else None + ), + ) + failures = _candidate_failures( + analysis, + excerpt_duration_seconds=excerpt_duration, + minimum_score=threshold, + source_policy=policy, + ) + entry = { + "index": index, + "present": True, + "passed": not failures, + "failures": failures, + "advisories": _candidate_advisories( + analysis, + source_policy=policy, + minimum_score=threshold, + ), + "analysis": analysis, + } + except (RuntimeError, TypeError, ValueError) as exc: + entry = { + "index": index, + "present": True, + "passed": False, + "failures": ["analysis_error"], + "error": str(exc), + } + report["candidates"].append(entry) + measured[index] = entry + + if mode in {"auto_select", "lock_by_hash"} and missing: + message = f"Audio audition expected {count} candidates; missing lanes: {', '.join(map(str, missing))}." + if mode == "lock_by_hash": + report["lock"]["failure_reason"] = "candidate_lane_missing" + return _selection_failure(report, message) + + selected_index: int | None = None + if lock_match is not None: + selected_index = indices[0] + entry = measured.get(selected_index) + if not entry or not bool(entry.get("passed")): + report["lock"]["failure_reason"] = "locked_candidate_failed_qc" + failure_codes = ", ".join( + str(value) for value in (entry or {}).get("failures", []) + ) or "unspecified_qc_failure" + return _selection_failure( + report, + f"Audio selection is locked to candidate {selected_index}, but that candidate did not pass decoded-audio QC: {failure_codes}.", + ) + elif mode == "lock_by_hash": + hash_matches = [ + index + for index, entry in measured.items() + if entry.get("analysis", {}).get("waveform_sha256") == lock_hash + ] + if not hash_matches: + report["lock"]["failure_reason"] = "locked_hash_not_present" + return _selection_failure(report, "The locked waveform hash is not present among the audition candidates.") + selected_index = min(hash_matches) + if not bool(measured[selected_index].get("passed")): + report["lock"]["failure_reason"] = "locked_hash_failed_qc" + failure_codes = ", ".join( + str(value) + for value in measured[selected_index].get("failures", []) + ) or "unspecified_qc_failure" + return _selection_failure( + report, + "The locked waveform is present but did not pass decoded-audio QC: " + f"{failure_codes}.", + ) + else: + passing = [entry for entry in measured.values() if bool(entry.get("passed"))] + if passing: + selected_entry = max( + passing, + key=lambda entry: ( + 0 + if "canonically_aligned_low_pressure_double_time_pulse" + in entry.get("advisories", []) + else 1, + round( + float( + entry["analysis"]["suggested_excerpt"].get( + "low_density_visual_recovery_coverage", 0.0 + ) + ), + 9, + ) + if "canonically_aligned_low_pressure_double_time_pulse" + in entry.get("advisories", []) + else 1.0, + round( + float( + entry["analysis"]["suggested_excerpt"].get( + "score", 0.0 + ) + ), + 9, + ), + round(float(entry["analysis"]["production_score"]), 9), + -int(entry["index"]), + ), + ) + selected_index = int(selected_entry["index"]) + + if selected_index is None: + hard_failure_details = "; ".join( + f"candidate {int(entry.get('index', 0))}: " + + ", ".join(str(value) for value in entry.get("failures", [])[:4]) + for entry in report["candidates"] + if entry.get("failures") + ) + message = ( + "No decoded song candidate passed decoded-audio QC. minimum_score is only " + "the numeric score floor; independent hard QC gates still apply." + ) + if hard_failure_details: + message += f" Hard QC — {hard_failure_details}." + return _selection_failure(report, message) + selected_entry = measured[selected_index] + selected_analysis = selected_entry["analysis"] + selected_hash = str(selected_analysis["waveform_sha256"]) + selected_start = float(selected_analysis["suggested_excerpt"]["start_seconds"]) + lock_token_payload = ( + f"diffusiongemma-audio-selection-lock@1|{selected_hash}|" + f"{selected_start:.9f}|{excerpt_duration:.9f}" + ) + selection_lock_token = hashlib.sha256(lock_token_payload.encode("utf-8")).hexdigest() + report["selected_candidate_index"] = selected_index + report["selected_waveform_sha256"] = selected_hash + report["selected_suggested_excerpt"] = selected_analysis["suggested_excerpt"] + report["selection_lock_token"] = selection_lock_token + report["ready"] = True + report["lock"].update( + { + "satisfied": mode != "auto_select", + "resolved_candidate_index": selected_index, + "resolved_waveform_sha256": selected_hash, + "resolved_start_seconds": selected_start, + "selection_lock_token": selection_lock_token, + } + ) + selected_excerpt_score = float( + selected_analysis["suggested_excerpt"].get("score", 0.0) + ) + advisory_values = list(selected_entry.get("advisories", [])) + advisory_text = "" + if "canonically_aligned_half_time_pulse" in advisory_values: + advisory_text = ( + "; accepted half-time pulse " + f"{float(selected_analysis['detected_bpm_raw']):.1f} BPM as canonical " + f"{float(selected_analysis['detected_bpm']):.1f} BPM versus requested " + f"{float(selected_analysis['expected_bpm']):.1f} BPM (advisory)" + ) + elif "canonically_aligned_low_pressure_double_time_pulse" in advisory_values: + selected_excerpt = selected_analysis["suggested_excerpt"] + advisory_text = ( + "; accepted low-pressure double-time subdivision " + f"{float(selected_analysis['detected_bpm_raw']):.1f} BPM as canonical " + f"{float(selected_analysis['detected_bpm']):.1f} BPM versus requested " + f"{float(selected_analysis['expected_bpm']):.1f} BPM; excerpt onset density " + f"{float(selected_excerpt['onset_density_per_second']):.2f}/s, recovery " + f"{100.0 * float(selected_excerpt['low_density_visual_recovery_coverage']):.0f}% " + "(advisory; tempo-score penalty retained)" + ) + elif advisory_values: + advisory_text = "; advisory " + ", ".join( + str(value) for value in advisory_values + ) + status_prefix = ( + "Source-locked upload candidate" + if policy == "uploaded_song" + else "Decoded-audio QC selected candidate" + ) + status = ( + f"{status_prefix} {selected_index} at excerpt score " + f"{selected_excerpt_score:.3f} (full-song score " + f"{float(selected_analysis['production_score']):.3f}){advisory_text}; " + f"waveform lock {selected_hash[:12]}…." + ) + if policy == "uploaded_song": + status = status.replace( + " at excerpt score", + " passed technical integrity; measured excerpt score", + 1, + ) + report["status"] = status + director_report = _compact_director_report(report, selected_analysis) + selected_audio = candidates[selected_index - 1] + # Return the exact upstream waveform object. The SHA-256 output is its + # immutable identity; no normalization, resampling, or gain is applied. + return ( + selected_audio, + selected_start, + selected_hash, + _json(director_report), + _json(report), + status, + True, + ) + + +def _fit_stem_to_reference(stem: Any, final_audio: Any) -> torch.Tensor: + stem_waveform, stem_rate = _audio_parts(stem, "vocal_stem") + final_waveform, final_rate = _audio_parts(final_audio, "final_audio") + value = stem_waveform.detach().to(device="cpu", dtype=torch.float32) + final_shape = tuple(int(size) for size in final_waveform.shape) + if stem_rate != final_rate: + target_length = max(1, int(round(value.shape[-1] * final_rate / float(stem_rate)))) + value = torch_functional.interpolate(value, size=target_length, mode="linear", align_corners=False) + if value.shape[0] == 1 and final_shape[0] > 1: + value = value.repeat(final_shape[0], 1, 1) + if value.shape[0] != final_shape[0]: + raise ValueError("vocal_stem batch count must equal final_audio batch count or be one.") + if value.shape[1] == 1 and final_shape[1] > 1: + value = value.repeat(1, final_shape[1], 1) + elif final_shape[1] == 1 and value.shape[1] > 1: + value = value.mean(dim=1, keepdim=True) + elif value.shape[1] != final_shape[1]: + raise ValueError("vocal_stem channels cannot be aligned with final_audio channels.") + if value.shape[-1] < final_shape[-1]: + value = torch_functional.pad(value, (0, final_shape[-1] - value.shape[-1])) + else: + value = value[..., : final_shape[-1]] + if not bool(torch.isfinite(value).all()): + raise ValueError("vocal_stem contains NaN or infinite samples.") + return value.contiguous() + + +def _sync_safe_guide(final_audio: Any, vocal_stem: Any = None) -> tuple[dict[str, Any], dict[str, Any]]: + final_waveform, sample_rate = _audio_parts(final_audio, "final_audio") + source = final_waveform.detach().to(device="cpu", dtype=torch.float32) + if not bool(torch.isfinite(source).all()): + raise ValueError("final_audio contains NaN or infinite samples.") + if source.shape[1] > 1: + center = source.mean(dim=1, keepdim=True) + source_centered = center + 0.35 * (source - center) + else: + source_centered = source + used_stem = vocal_stem is not None + if used_stem: + vocals = _fit_stem_to_reference(vocal_stem, final_audio) + guide = vocals + 0.25 * (source_centered - vocals) + else: + guide = source_centered + kernel = max(3, int(round(sample_rate * 0.00075))) + if kernel % 2 == 0: + kernel += 1 + kernel = min(kernel, max(3, int(guide.shape[-1]) // 2 * 2 - 1)) + if kernel >= 3 and guide.shape[-1] > kernel: + padding = kernel // 2 + smoothed = torch_functional.avg_pool1d( + torch_functional.pad(guide, (padding, padding), mode="reflect"), + kernel_size=kernel, + stride=1, + ) + guide = smoothed + 0.45 * (guide - smoothed) + source_rms = torch.sqrt(torch.mean(source.square(), dim=-1, keepdim=True)).clamp_min(1.0e-8) + guide_rms = torch.sqrt(torch.mean(guide.square(), dim=-1, keepdim=True)).clamp_min(1.0e-8) + gain = (source_rms / guide_rms).clamp(0.5, 1.35) + guide = guide * gain + peak = guide.abs().amax(dim=-1, keepdim=True).clamp_min(1.0e-8) + guide = guide * torch.minimum(torch.ones_like(peak), 0.98 / peak) + output = {"waveform": guide.contiguous(), "sample_rate": sample_rate} + return output, { + "used_vocal_stem": used_stem, + "center_channel_emphasis": bool(source.shape[1] > 1), + "accompaniment_gain_with_stem": 0.25 if used_stem else None, + "high_frequency_residual_gain": 0.45, + "peak_limit": 0.98, + } + + +class DiffusionGemmaLTXAudioGuide: + """Build a low-risk LTX guide while preserving the untouched final master.""" + + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "final_audio": ("AUDIO",), + "mode": (list(GUIDE_MODES), {"default": "sync_safe"}), + }, + "optional": {"vocal_stem": ("AUDIO", {"lazy": True})}, + } + + RETURN_TYPES = ("AUDIO", "AUDIO", "STRING", "STRING", "STRING", "BOOLEAN") + RETURN_NAMES = ( + "conditioning_audio", + "final_audio", + "conditioning_sha256", + "guide_report_json", + "status", + "ready", + ) + FUNCTION = "build" + CATEGORY = CATEGORY + DESCRIPTION = ( + "Separates the audio LTX hears from the untouched soundtrack that is muxed. " + "sync_safe uses center emphasis and lightweight transient softening only." + ) + + @classmethod + def check_lazy_status(cls, **kwargs): + normalized = str(kwargs.get("mode", "") or "").strip().casefold() + if normalized == "vocal_only" and "vocal_stem" in kwargs and kwargs["vocal_stem"] is None: + return ["vocal_stem"] + return [] + + def build(self, final_audio, mode, vocal_stem=None): + normalized = str(mode or "").strip().casefold() + report: dict[str, Any] = { + "schema": GUIDE_REPORT_SCHEMA, + "version": ANALYSIS_VERSION, + "mode": normalized, + "final_audio_preserved": True, + } + try: + final_hash = waveform_sha256(final_audio) + if normalized not in GUIDE_MODES: + raise ValueError(f"mode must be one of {', '.join(GUIDE_MODES)}.") + if normalized == "full_mix": + conditioning = final_audio + processing = {"operation": "identity"} + elif normalized == "vocal_only": + if vocal_stem is None: + message = "vocal_only LTX guidance requires a connected vocal stem." + report.update( + { + "ready": False, + "status": message, + "final_waveform_sha256": final_hash, + "failure_reason": "vocal_stem_missing", + } + ) + return (ExecutionBlocker(None), final_audio, "", _json(report), message, False) + waveform = _fit_stem_to_reference(vocal_stem, final_audio) + _final_waveform, sample_rate = _audio_parts(final_audio, "final_audio") + conditioning = {"waveform": waveform, "sample_rate": sample_rate} + processing = {"operation": "aligned_vocal_stem", "used_vocal_stem": True} + else: + # sync_safe is intentionally a lightweight full-mix transform. + # A connected stem separator must remain unevaluated unless the + # user explicitly selects vocal_only. + conditioning, processing = _sync_safe_guide(final_audio, None) + conditioning_hash = waveform_sha256(conditioning) + except (RuntimeError, TypeError, ValueError) as exc: + message = f"LTX audio guide is blocked: {exc}" + report.update({"ready": False, "status": message, "failure_reason": "invalid_audio"}) + return (ExecutionBlocker(None), final_audio, "", _json(report), message, False) + status = f"LTX audio guide ready in {normalized} mode; final master remains untouched." + report.update( + { + "ready": True, + "status": status, + "processing": processing, + "final_waveform_sha256": final_hash, + "conditioning_waveform_sha256": conditioning_hash, + } + ) + return (conditioning, final_audio, conditioning_hash, _json(report), status, True) + + +def _normalize_ltx_performance_mode(value: Any) -> str: + normalized = " ".join(str(value or "").strip().casefold().replace("_", " ").split()) + aliases = { + "dance": "Dance / music sync", + "music sync": "Dance / music sync", + "dance/music sync": "Dance / music sync", + "dance / music sync": "Dance / music sync", + "lyrics": "Lyrics + lip sync", + "lip sync": "Lyrics + lip sync", + "lyrics+lip sync": "Lyrics + lip sync", + "lyrics + lip sync": "Lyrics + lip sync", + "natural": "Natural / audio-led sync", + "audio led": "Natural / audio-led sync", + "audio-led": "Natural / audio-led sync", + "audio led sync": "Natural / audio-led sync", + "audio-led sync": "Natural / audio-led sync", + "natural/audio-led sync": "Natural / audio-led sync", + "natural / audio led sync": "Natural / audio-led sync", + "natural / audio-led sync": "Natural / audio-led sync", + } + try: + return aliases[normalized] + except KeyError as exc: + raise ValueError( + "performance_mode must be Dance / music sync, Lyrics + lip sync, " + "or Natural / audio-led sync." + ) from exc + + +def _authored_sung_lyric_lines(value: Any) -> tuple[str, list[str]]: + """Return normalized source text and exact complete sung lines. + + Only line-ending and outer-whitespace normalization is applied. Standalone + bracketed section directives are intentionally excluded: LTX should see the + words a performer may articulate, not ``[Verse]`` or ``[Instrumental]``. + """ + + source = str(value or "").replace("\r\n", "\n").replace("\r", "\n").strip() + sung_lines: list[str] = [] + for raw_line in source.split("\n"): + line = raw_line.strip() + if not line: + continue + if re.fullmatch(r"\[[^\]\n]{1,120}\]", line): + continue + sung_lines.append(line) + return source, sung_lines + + +def _lyric_word_count(value: str) -> int: + return len(re.findall(r"\b[\w’'-]+\b", value, flags=re.UNICODE)) + + +def _bounded_proportional_lyric_window( + lyrics: Any, + *, + song_duration_seconds: Any, + excerpt_start_seconds: Any, + excerpt_duration_seconds: Any, +) -> tuple[str, dict[str, Any]]: + """Choose a deterministic, complete-line lyric window for an audio excerpt. + + ACE/QC currently provides no transcript or word timestamps. The selection is + therefore a transparent planning heuristic: sung lines are treated as evenly + distributed over the source-song clock, then a one-line context margin is + added and bounded by the LTX speech-density, line-count, and character caps. + """ + + source, sung_lines = _authored_sung_lyric_lines(lyrics) + if not sung_lines: + raise ValueError( + "Lyrics + lip sync requires at least one complete sung lyric line; " + "section labels and [Instrumental] do not count." + ) + try: + song_duration = float(song_duration_seconds) + excerpt_start = float(excerpt_start_seconds) + excerpt_duration = float(excerpt_duration_seconds) + except (TypeError, ValueError) as exc: + raise ValueError("Song and excerpt timing values must be finite numbers.") from exc + if not math.isfinite(song_duration) or song_duration <= 0.0: + raise ValueError("song_duration_seconds must be a positive finite number.") + if not math.isfinite(excerpt_start) or excerpt_start < 0.0: + raise ValueError("excerpt_start_seconds must be a non-negative finite number.") + if not math.isfinite(excerpt_duration) or excerpt_duration <= 0.0: + raise ValueError("excerpt_duration_seconds must be a positive finite number.") + + line_count = len(sung_lines) + clamped_start = min(excerpt_start, song_duration) + clamped_end = min(song_duration, clamped_start + excerpt_duration) + if clamped_end <= clamped_start: + # An excerpt that starts exactly at/past the source end maps to its last + # authored line rather than wrapping around to the beginning. + raw_first = line_count - 1 + raw_last = line_count - 1 + else: + raw_first = min( + line_count - 1, + int(math.floor((clamped_start / song_duration) * line_count)), + ) + raw_last = min( + line_count - 1, + max(raw_first, int(math.ceil((clamped_end / song_duration) * line_count)) - 1), + ) + + first = max(0, raw_first - 1) + last = min(line_count - 1, raw_last + 1) + target_center = (raw_first + raw_last) / 2.0 + + while last - first + 1 > MAX_LTX_PERFORMANCE_LYRIC_LINES: + if target_center - first > last - target_center: + first += 1 + else: + last -= 1 + + # Match the established LTX spoken-word planning ceiling. Complete lines + # are removed from the farther edge; individual lyric lines are never cut. + word_budget = max(1, int(math.floor(excerpt_duration * 2.4))) + + def selected_text() -> str: + return "\n".join(sung_lines[first : last + 1]) + + while first < last: + candidate = selected_text() + if ( + _lyric_word_count(candidate) <= word_budget + and len(candidate) <= MAX_LTX_PERFORMANCE_LYRIC_CHARS + ): + break + if target_center - first > last - target_center: + first += 1 + else: + last -= 1 + + selected = selected_text() + selected_words = _lyric_word_count(selected) + if selected_words > word_budget: + raise ValueError( + "No complete authored lyric line fits the selected excerpt's " + f"{word_budget}-word LTX speech budget. Increase the video duration " + "or use Natural / audio-led sync or Dance / music sync." + ) + if len(selected) > MAX_LTX_PERFORMANCE_LYRIC_CHARS: + raise ValueError( + "No complete authored lyric line fits the LTX lyric prompt character cap." + ) + + metadata = { + "mapping_method": "uniform_sung_line_proportion_with_one_line_context", + "alignment": "deterministic_planning_heuristic_not_asr_or_word_alignment", + "source_lyrics_sha256": hashlib.sha256(source.encode("utf-8")).hexdigest(), + "source_sung_line_count": line_count, + "raw_proportional_line_range_1_based": [raw_first + 1, raw_last + 1], + "selected_line_range_1_based": [first + 1, last + 1], + "selected_line_count": last - first + 1, + "selected_word_count": selected_words, + "speech_word_budget": word_budget, + "selected_character_count": len(selected), + "selected_lyrics_sha256": hashlib.sha256(selected.encode("utf-8")).hexdigest(), + "selection_role": "lexical_and_pronunciation_candidates_only", + "is_timing_schedule": False, + "requires_every_selected_line_performed": False, + "section_directives_excluded": True, + "lyrics_preserved_verbatim_by_complete_line": True, + "song_duration_seconds": song_duration, + "requested_excerpt_start_seconds": excerpt_start, + "requested_excerpt_duration_seconds": excerpt_duration, + "mapped_excerpt_start_seconds": clamped_start, + "mapped_excerpt_end_seconds": clamped_end, + } + return selected, metadata + + +class DiffusionGemmaLTXPerformancePrompt: + """Apply a dance, lyric-reference, or natural audio-led LTX prompt suffix.""" + + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "ltx_prompt": ("STRING", {"forceInput": True, "multiline": True}), + "performance_mode": ( + list(LTX_PERFORMANCE_MODES), + { + "default": "Natural / audio-led sync", + "tooltip": "Dance suppresses visible vocal articulation. Lyrics supplies bounded lexical/pronunciation candidates but never timing. Natural lets connected audio alone govern articulation.", + }, + ), + "song_duration_seconds": ( + "FLOAT", + {"default": 90.0, "min": 0.01, "max": 86400.0, "step": 0.01}, + ), + "excerpt_start_seconds": ( + "FLOAT", + {"default": 0.0, "min": 0.0, "max": 86400.0, "step": 0.01}, + ), + "excerpt_duration_seconds": ( + "FLOAT", + {"default": 20.0, "min": 0.01, "max": 86400.0, "step": 0.01}, + ), + }, + "optional": { + "lyrics": ("STRING", {"forceInput": True, "multiline": True}), + "performance_mode_override": ( + "STRING", + { + "default": "", + "forceInput": True, + "tooltip": "Optional typed upstream source of truth. When connected, this overrides the legacy local dropdown without removing it from older workflows.", + }, + ), + }, + } + + RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING", "STRING") + RETURN_NAMES = ( + "ltx_prompt", + "selected_lyrics", + "status", + "performance_report_json", + "performance_mode", + ) + FUNCTION = "apply" + CATEGORY = CATEGORY + DESCRIPTION = ( + "Post-processes a validated LTX prompt without touching the frozen audio guide or final master. " + "Dance suppresses visible vocal articulation; Lyrics supplies bounded lexical/pronunciation " + "candidates for verified timing; Natural leaves articulation entirely audio-led." + ) + + def apply( + self, + ltx_prompt, + performance_mode, + song_duration_seconds, + excerpt_start_seconds, + excerpt_duration_seconds, + lyrics="", + performance_mode_override="", + ): + override = str(performance_mode_override or "").strip() + mode = _normalize_ltx_performance_mode(override or performance_mode) + incoming_prompt = str(ltx_prompt or "") + report: dict[str, Any] = { + "schema": PERFORMANCE_REPORT_SCHEMA, + "version": ANALYSIS_VERSION, + "mode": mode, + "audio_conditioning_changed": False, + "final_soundtrack_changed": False, + "selected_lyrics_are_timing_schedule": False, + "selected_lyrics_require_every_line_performed": False, + } + if not incoming_prompt.strip(): + status = ( + "LTX performance prompt blocked: the upstream generation gate returned an empty prompt." + ) + report.update( + { + "ready": False, + "status": status, + "failure_reason": "empty_upstream_prompt", + "lyrics_included": False, + "selected_lyrics_role": "none", + "articulation_timing_authority": "none_generation_blocked", + } + ) + return ("", "", status, _json(report), mode) + + if mode == "Dance / music sync": + selected_lyrics = "" + directive = ( + "Performance mode — Dance / music sync (authoritative): preserve the connected " + "soundtrack exactly, but no visible person sings, speaks, mouths words, or lip-syncs. " + "Any visible performer keeps their lips gently closed, jaw relaxed, and mouth free of " + "phoneme-shaped articulation throughout. Synchronize full-body choreography, footwork, " + "weight shifts, gestures, expression, hair and fabric motion, scene changes, and camera " + "accents to the music's beat, phrasing, dynamics, lulls, and transitions. This final mode " + "contract overrides any earlier vocal-performance wording." + ) + status = ( + "Dance / music sync ready: lyric text is excluded and the soundtrack guides body, " + "scene, and camera timing only." + ) + report.update( + { + "ready": True, + "status": status, + "lyrics_included": False, + "visible_vocal_articulation": "suppressed", + "selected_lyrics_role": "none", + "articulation_timing_authority": "dance_mode_suppression", + "unverified_timing_fallback": "not_applicable", + "non_vocal_or_ambiguous_gap_policy": "visible_vocal_articulation_suppressed", + } + ) + elif mode == "Natural / audio-led sync": + selected_lyrics = "" + directive = ( + "Performance mode — Natural / audio-led sync (authoritative): preserve the connected " + "soundtrack exactly. Let the connected audio alone govern whether and when any visible " + "articulation naturally occurs. Do not pre-script mouth shapes, facial articulation, or " + "vocal performance. During non-vocal or ambiguous gaps, keep facial behavior natural " + "and never invent or pantomime words. Synchronize body motion, scene changes, and camera " + "accents naturally to the audible performance. This final mode contract overrides any " + "earlier instruction that schedules or suppresses vocal articulation." + ) + status = ( + "Natural / audio-led sync ready: lyric text is excluded and connected audio alone " + "governs whether and when natural articulation occurs." + ) + report.update( + { + "ready": True, + "status": status, + "lyrics_included": False, + "visible_vocal_articulation": "audio_led_not_prescheduled", + "selected_lyrics_role": "none", + "articulation_timing_authority": "connected_audio_alone", + "unverified_timing_fallback": "Natural / audio-led sync", + "non_vocal_or_ambiguous_gap_policy": "no_invented_or_pantomimed_words", + } + ) + else: + selected_lyrics, lyric_report = _bounded_proportional_lyric_window( + lyrics, + song_duration_seconds=song_duration_seconds, + excerpt_start_seconds=excerpt_start_seconds, + excerpt_duration_seconds=excerpt_duration_seconds, + ) + quoted_lyrics = "\n".join( + json.dumps(line, ensure_ascii=False) + for line in selected_lyrics.splitlines() + ) + directive = ( + "Performance mode — Lyrics + lip sync (authoritative): the connected audio and " + "downstream verified vocal timing are the only authorities for whether and when visible " + "articulation occurs. The exact authored lines below are lexical and pronunciation " + "candidates only: they are not timing evidence, do not schedule articulation, and do " + "not require every supplied line to be performed. Candidate text never overrides the " + "audio. Use a candidate word only where it is actually audible in a verified vocal " + "interval; never infer vocal action from this proportional text selection. Wherever " + "verified timing is absent, fall back to Natural / audio-led sync and let connected " + "audio alone govern natural articulation. During instrumental, non-vocal, or ambiguous " + "gaps, never invent or pantomime words. Never paraphrase, reorder, or vocalize section " + "labels. Each candidate line is supplied in ordinary straight quotes.\n\nCandidate " + "authored lyric lines (lexical/pronunciation reference only):\n" + + quoted_lyrics + ) + status = ( + "Lyrics + lip sync ready with " + f"{lyric_report['selected_line_count']} candidate authored lines " + f"({lyric_report['selected_word_count']} words). They are lexical/pronunciation " + "reference only, never a schedule or performance checklist. Downstream verified vocal " + "timing is authoritative; intervals without it fall back to Natural / audio-led sync." + ) + report.update( + { + "ready": True, + "status": status, + "lyrics_included": True, + "visible_vocal_articulation": "permitted_only_by_verified_timing_and_audio", + "selected_lyrics_role": "lexical_and_pronunciation_candidates_only", + "articulation_timing_authority": "downstream_verified_vocal_timing_then_connected_audio", + "unverified_timing_fallback": "Natural / audio-led sync", + "non_vocal_or_ambiguous_gap_policy": "no_invented_or_pantomimed_words", + "lyric_window": lyric_report, + "lyric_lines_supplied_in_straight_quotes": True, + } + ) + + # Preserve the validated incoming prompt byte-for-byte as the prefix. + final_prompt = incoming_prompt + "\n\n" + directive + report["incoming_prompt_preserved_verbatim"] = final_prompt.startswith(incoming_prompt) + report["incoming_prompt_character_count"] = len(incoming_prompt) + report["final_prompt_character_count"] = len(final_prompt) + return (final_prompt, selected_lyrics, status, _json(report), mode) + + +class DiffusionGemmaMusicVideoPerformanceMode: + """Compile one pre-Director performance choice into H3 audio guidance.""" + + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "base_audio_guidance": ( + "STRING", + {"default": "", "multiline": True, "forceInput": True}, + ), + "performance_mode": ( + list(LTX_PERFORMANCE_MODES), + {"default": "Natural / audio-led sync"}, + ), + } + } + + RETURN_TYPES = ("STRING", "STRING", "STRING") + RETURN_NAMES = ("performance_mode", "target_audio_guidance", "status") + FUNCTION = "compile" + CATEGORY = CATEGORY + DESCRIPTION = ( + "Makes Dance/Lyrics/Natural a single pre-Director source of truth. It changes only prompt " + "guidance, never the selected song, conditioning waveform, or final soundtrack." + ) + + def compile(self, base_audio_guidance, performance_mode): + mode = _normalize_ltx_performance_mode(performance_mode) + base = str(base_audio_guidance or "").strip() + if mode == "Dance / music sync": + directive = ( + "Performance mode is Dance / music sync. Stage readable full-body choreography and " + "musical scene accents, but no visible person sings, speaks, mouths words, or " + "lip-syncs; keep facial motion naturally non-vocal. Do not author H3 spoken-" + "dialogue blocks." + ) + elif mode == "Natural / audio-led sync": + directive = ( + "Performance mode is Natural / audio-led sync. The connected audio alone governs " + "whether and when natural visible articulation occurs. Do not pre-script mouth or " + "facial articulation. Non-vocal or ambiguous gaps contain no invented or pantomimed " + "words. Do not author H3 spoken-dialogue blocks." + ) + else: + directive = ( + "Performance mode is Lyrics + lip sync. Do not reserve or command a face to perform " + "lyrics, and do not author shot-level or timestamped vocal actions. Downstream verified " + "vocal timing is the sole authority for scheduling visible articulation; selected lyric " + "text supplied later is lexical/pronunciation reference only. Wherever verified timing " + "is absent, fall back to Natural / audio-led sync: connected audio alone governs natural " + "articulation, with no invented or pantomimed words during non-vocal or ambiguous gaps. " + "Do not author H3 spoken-dialogue blocks." + ) + guidance = (base + "\n\n" + directive).strip() + return ( + mode, + guidance, + f"{mode} is the shared pre-Director performance contract; audio is unchanged.", + ) + + +def _reference_mode_token(value: Any) -> str: + normalized = str(value or "").strip().casefold().replace("_", " ") + if normalized in {"compose", "compose new"}: + return "compose_new" + if normalized in {"cover", "cover reference"}: + return "cover_reference" + raise ValueError("ACE reference mode must be Compose new or Cover reference.") + + +class DiffusionGemmaACEReferenceMode: + @classmethod + def INPUT_TYPES(cls): + return {"required": {"mode": (list(ACE_REFERENCE_MODES), {"default": "Compose new"})}} + + RETURN_TYPES = ("BOOLEAN", "STRING") + RETURN_NAMES = ("generate_audio_codes", "mode_token") + FUNCTION = "route" + CATEGORY = CATEGORY + DESCRIPTION = "Compose generates ACE semantic codes; Cover uses a lazy reference-audio latent." + + def route(self, mode): + token = _reference_mode_token(mode) + return (token == "compose_new", token) + + +class DiffusionGemmaACECoverConditioning: + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "conditioning": ("CONDITIONING",), + "mode_token": ("STRING", {"forceInput": True}), + }, + "optional": {"reference_latent": ("LATENT", {"lazy": True})}, + } + + RETURN_TYPES = ("CONDITIONING", "STRING", "BOOLEAN") + RETURN_NAMES = ("conditioning", "status", "ready") + FUNCTION = "apply" + CATEGORY = CATEGORY + DESCRIPTION = "Passes Compose conditioning through, or fail-closed attaches a lazy Cover timbre latent." + + @classmethod + def check_lazy_status(cls, **kwargs): + try: + mode = _reference_mode_token(kwargs.get("mode_token", "")) + except ValueError: + return [] + if ( + mode == "cover_reference" + and "reference_latent" in kwargs + and kwargs["reference_latent"] is None + ): + return ["reference_latent"] + return [] + + def apply(self, conditioning, mode_token, reference_latent=None): + try: + mode = _reference_mode_token(mode_token) + except ValueError as exc: + return (ExecutionBlocker(None), str(exc), False) + if mode == "compose_new": + return (conditioning, "ACE Compose mode: semantic audio-code generation remains enabled.", True) + if not isinstance(reference_latent, Mapping) or not isinstance(reference_latent.get("samples"), torch.Tensor): + return ( + ExecutionBlocker(None), + "ACE Cover mode is blocked because no valid reference audio latent is connected.", + False, + ) + try: + import node_helpers + + routed = node_helpers.conditioning_set_values( + conditioning, + {"reference_audio_timbre_latents": [reference_latent["samples"]]}, + append=True, + ) + except (ImportError, RuntimeError, TypeError, ValueError) as exc: + return (ExecutionBlocker(None), f"ACE Cover conditioning is blocked: {exc}", False) + return (routed, "ACE Cover mode: reference timbre latent attached; semantic code generation should be disabled.", True) + + +def _resolve_uploaded_song_path(audio_file: Any) -> str: + """Resolve an uploaded song without allowing reads outside ComfyUI input.""" + + try: + import folder_paths + except ModuleNotFoundError as exc: # Standalone tests do not add ComfyUI. + raise ValueError("ComfyUI's input directory is unavailable.") from exc + relative_name, annotated_base = folder_paths.annotated_filepath(str(audio_file or "")) + input_dir = os.path.realpath(folder_paths.get_input_directory()) + if annotated_base is not None and os.path.realpath(annotated_base) != input_dir: + raise ValueError("Uploaded songs must be selected from ComfyUI's input directory.") + audio_path = os.path.realpath(os.path.join(input_dir, relative_name)) + try: + inside_input = os.path.commonpath((input_dir, audio_path)) == input_dir + except ValueError: + inside_input = False + if not inside_input: + raise ValueError("Uploaded songs must be selected from ComfyUI's input directory.") + if not str(relative_name).strip() or not os.path.isfile(audio_path): + raise ValueError("Choose or upload a song before selecting Upload song.") + return audio_path + + +def _validate_uploaded_decode_shape(channels: int, samples: int, sample_rate: int) -> None: + channel_count = int(channels) + sample_count = int(samples) + rate = int(sample_rate) + if channel_count < 1 or channel_count > MAX_UPLOAD_CHANNELS: + raise ValueError( + f"Uploaded songs must have from 1 to {MAX_UPLOAD_CHANNELS} audio channels." + ) + if rate < 1 or rate > MAX_UPLOAD_SAMPLE_RATE: + raise ValueError( + f"Uploaded song sample rate must be from 1 to {MAX_UPLOAD_SAMPLE_RATE} Hz." + ) + if sample_count < 1: + raise ValueError("Uploaded song contains no decoded samples.") + duration = sample_count / float(rate) + if duration > MAX_UPLOAD_DURATION_SECONDS: + raise ValueError( + f"Uploaded song exceeds the {MAX_UPLOAD_DURATION_SECONDS:.0f}-second decode limit." + ) + if channel_count * sample_count > MAX_UPLOAD_SCALAR_SAMPLES: + raise ValueError("Uploaded song exceeds the bounded decoded-PCM sample limit.") + + +def _load_uploaded_audio_bounded(audio_path: str) -> tuple[torch.Tensor, int]: + """Decode with hard duration/channel/sample bounds instead of unbounded accumulation.""" + + try: + import av + from comfy_extras.nodes_audio import f32_pcm + except ImportError as exc: + raise ValueError("ComfyUI's audio decoder is unavailable.") from exc + try: + with av.open(audio_path) as audio_file: + if not audio_file.streams.audio: + raise ValueError("No audio stream was found in the uploaded file.") + stream = audio_file.streams.audio[0] + sample_rate = int(stream.codec_context.sample_rate or 0) + channels = int(stream.channels or 0) + _validate_uploaded_decode_shape(channels, 1, sample_rate) + frames: list[torch.Tensor] = [] + decoded_samples = 0 + for frame in audio_file.decode(streams=stream.index): + buffer = torch.from_numpy(frame.to_ndarray()) + if buffer.ndim != 2: + raise ValueError("Decoded audio frame does not have two dimensions.") + if int(buffer.shape[0]) != channels: + if int(buffer.numel()) % channels: + raise ValueError("Decoded audio frame cannot be aligned to its channel count.") + buffer = buffer.reshape(-1, channels).t() + prospective_samples = decoded_samples + int(buffer.shape[1]) + _validate_uploaded_decode_shape(channels, prospective_samples, sample_rate) + frames.append(buffer) + decoded_samples = prospective_samples + if not frames: + raise ValueError("No audio frames were decoded from the uploaded file.") + waveform = f32_pcm(torch.cat(frames, dim=1)) + except (OSError, RuntimeError, TypeError, ValueError) as exc: + raise ValueError(str(exc)) from exc + _validate_uploaded_decode_shape( + int(waveform.shape[0]), int(waveform.shape[1]), sample_rate + ) + return waveform, sample_rate + + +class DiffusionGemmaUploadSong: + """Lazy-safe ComfyUI-input loader for an optional custom soundtrack branch.""" + + @classmethod + def INPUT_TYPES(cls): + try: + import folder_paths + + input_dir = folder_paths.get_input_directory() + os.makedirs(input_dir, exist_ok=True) + files = folder_paths.filter_files_content_types( + os.listdir(input_dir), + ["audio", "video"], + ) + except ModuleNotFoundError: # Standalone repository tests. + files = [] + return { + "required": { + "audio_file": ( + [""] + sorted(files), + { + "audio_upload": True, + "tooltip": ( + "Upload or choose a song from ComfyUI input. The file is decoded only " + "when Soundtrack source is set to Upload song." + ), + }, + ), + } + } + + RETURN_TYPES = ("AUDIO", "FLOAT", "STRING", "STRING", "BOOLEAN") + RETURN_NAMES = ( + "audio", + "duration_seconds", + "waveform_sha256", + "status", + "ready", + ) + FUNCTION = "load_audio" + CATEGORY = CATEGORY + DESCRIPTION = ( + "Uploads a custom soundtrack without waking the branch while ACE-Step is selected. " + "The waveform is returned unchanged after decoding and is measured again by the shared audition/QC node." + ) + + @classmethod + def VALIDATE_INPUTS(cls, audio_file): + # Comfy validates dormant lazy branches. Defer file validation until + # this branch is actually selected so a blank uploader cannot poison + # an otherwise valid ACE-Step queue. + return True + + @classmethod + def IS_CHANGED(cls, audio_file): + try: + path = _resolve_uploaded_song_path(audio_file) + stat = os.stat(path) + # Comfy includes lazy ancestors in cache signatures even when they + # do not execute. Avoid SHA-reading a dormant upload on every ACE + # queue while still invalidating when the selected file changes. + return ( + f"stat@1:{str(audio_file)}:{int(stat.st_size)}:" + f"{int(stat.st_mtime_ns)}" + ) + except (OSError, ValueError): + return f"unselected:{str(audio_file or '').strip()}" + + def load_audio(self, audio_file): + audio_path = _resolve_uploaded_song_path(audio_file) + try: + waveform, sample_rate = _load_uploaded_audio_bounded(audio_path) + except (OSError, RuntimeError, TypeError, ValueError) as exc: + raise ValueError(f"Uploaded song could not be decoded: {exc}") from exc + audio = {"waveform": waveform.unsqueeze(0), "sample_rate": int(sample_rate)} + decoded, decoded_rate = _audio_parts(audio, "uploaded_audio") + duration = decoded.shape[-1] / float(decoded_rate) + digest = waveform_sha256(audio) + status = ( + f"Uploaded song decoded: {duration:.3f}s at {decoded_rate} Hz; " + f"waveform {digest[:12]}…." + ) + return (audio, duration, digest, status, True) + + +def _normalize_soundtrack_source(value: Any) -> str: + normalized = str(value or "").strip().casefold().replace("_", " ").replace("-", " ") + normalized = " ".join(normalized.split()) + aliases = { + "generate with ace step": "Generate with ACE-Step", + "ace step": "Generate with ACE-Step", + "generated candidates": "Generate with ACE-Step", + "upload song": "Upload song", + "uploaded song": "Upload song", + } + if normalized not in aliases: + raise ValueError(f"source_mode must be one of {', '.join(SOUNDTRACK_SOURCES)}.") + return aliases[normalized] + + +class DiffusionGemmaSongSourceRouter: + """Lazily choose ACE candidates or one uploaded song before shared QC.""" + + @classmethod + def INPUT_TYPES(cls): + lazy_force = {"lazy": True, "forceInput": True} + return { + "required": { + "source_mode": ( + list(SOUNDTRACK_SOURCES), + { + "default": "Generate with ACE-Step", + "tooltip": ( + "Generate keeps the existing ACE audition. Upload bypasses all ACE audio " + "lanes and sends one custom song through the same QC, hash lock, excerpt, " + "H3 conditioning, and final mux." + ), + }, + ), + "uploaded_expected_bpm": ( + "FLOAT", + { + "default": 0.0, + "min": 0.0, + "max": 300.0, + "step": 0.1, + "tooltip": "Optional known BPM for the uploaded song. Leave 0 for signal-only tempo analysis.", + }, + ), + "uploaded_lyrics": ( + "STRING", + { + "default": "", + "multiline": True, + "tooltip": ( + "Optional exact lyrics for an uploaded vocal song. Leave blank for Dance " + "or Natural mode; Lyrics + lip sync requires real sung lyrics." + ), + }, + ), + }, + "optional": { + "generated_candidate_count": ("INT", dict(lazy_force)), + "generated_expected_bpm": ("FLOAT", dict(lazy_force)), + "generated_lyrics": ( + "STRING", + {**lazy_force, "multiline": True}, + ), + "generated_duration_seconds": ("FLOAT", dict(lazy_force)), + "generated_candidate_1": ("AUDIO", {"lazy": True}), + "generated_candidate_2": ("AUDIO", {"lazy": True}), + "generated_candidate_3": ("AUDIO", {"lazy": True}), + "generated_candidate_4": ("AUDIO", {"lazy": True}), + "uploaded_audio": ("AUDIO", {"lazy": True}), + "uploaded_duration_seconds": ("FLOAT", dict(lazy_force)), + "uploaded_waveform_sha256": ("STRING", dict(lazy_force)), + "uploaded_status": ("STRING", dict(lazy_force)), + "uploaded_ready": ("BOOLEAN", dict(lazy_force)), + }, + } + + RETURN_TYPES = ( + "AUDIO", + "AUDIO", + "AUDIO", + "AUDIO", + "INT", + "FLOAT", + "STRING", + "FLOAT", + "STRING", + "STRING", + "BOOLEAN", + ) + RETURN_NAMES = ( + "candidate_1", + "candidate_2", + "candidate_3", + "candidate_4", + "effective_candidate_count", + "effective_expected_bpm", + "selected_lyrics", + "selected_duration_seconds", + "source_token", + "status", + "ready", + ) + FUNCTION = "route" + CATEGORY = CATEGORY + DESCRIPTION = ( + "A lazy soundtrack-origin gate. Upload mode never evaluates ACE candidates; ACE mode never " + "loads the uploaded file. Both routes converge before the existing decoded-audio QC and hash lock." + ) + + @classmethod + def check_lazy_status(cls, **kwargs): + try: + mode = _normalize_soundtrack_source(kwargs.get("source_mode", "Generate with ACE-Step")) + except ValueError: + return [] + if mode == "Upload song": + names = ( + "uploaded_audio", + "uploaded_duration_seconds", + "uploaded_waveform_sha256", + "uploaded_status", + "uploaded_ready", + ) + return [name for name in names if name in kwargs and kwargs[name] is None] + + metadata_names = ( + "generated_candidate_count", + "generated_expected_bpm", + "generated_lyrics", + "generated_duration_seconds", + ) + pending = [name for name in metadata_names if name in kwargs and kwargs[name] is None] + if pending: + return pending + try: + count = int(kwargs.get("generated_candidate_count")) + except (TypeError, ValueError): + return [] + if count < 1 or count > 4: + return [] + names = [f"generated_candidate_{index}" for index in range(1, count + 1)] + return [name for name in names if name in kwargs and kwargs[name] is None] + + def route( + self, + source_mode, + uploaded_expected_bpm, + uploaded_lyrics, + generated_candidate_count=None, + generated_expected_bpm=None, + generated_lyrics=None, + generated_duration_seconds=None, + generated_candidate_1=None, + generated_candidate_2=None, + generated_candidate_3=None, + generated_candidate_4=None, + uploaded_audio=None, + uploaded_duration_seconds=None, + uploaded_waveform_sha256=None, + uploaded_status=None, + uploaded_ready=None, + ): + mode = _normalize_soundtrack_source(source_mode) + if mode == "Upload song": + if uploaded_audio is None: + raise ValueError("Upload song is selected, but no song is connected. Upload or choose a song and queue again.") + waveform, sample_rate = _audio_parts(uploaded_audio, "uploaded_audio") + duration = waveform.shape[-1] / float(sample_rate) + if not math.isfinite(duration) or duration <= 0.0: + raise ValueError("The uploaded song must have a positive finite duration.") + if uploaded_duration_seconds is not None: + claimed_duration = float(uploaded_duration_seconds) + if not math.isfinite(claimed_duration) or abs(claimed_duration - duration) > 1.0e-6: + raise ValueError("The uploaded song duration metadata does not match its decoded waveform.") + expected_bpm = float(uploaded_expected_bpm) + if not math.isfinite(expected_bpm) or not 0.0 <= expected_bpm <= 300.0: + raise ValueError("uploaded_expected_bpm must be a finite value from 0 to 300.") + if uploaded_ready is False: + raise ValueError(str(uploaded_status or "The uploaded song loader is not ready.")) + supplied_hash = str(uploaded_waveform_sha256 or "").strip().casefold() + if supplied_hash and not _SHA256_RE.fullmatch(supplied_hash): + raise ValueError("The uploaded waveform SHA-256 metadata is invalid.") + if supplied_hash: + actual_hash = waveform_sha256(uploaded_audio) + if supplied_hash != actual_hash: + raise ValueError( + "The uploaded waveform SHA-256 metadata does not match its decoded audio." + ) + lyrics = str(uploaded_lyrics or "").strip() + candidates = (uploaded_audio,) * 4 + bpm_status = f"known BPM {expected_bpm:.1f}" if expected_bpm > 0.0 else "signal-only BPM analysis" + status = ( + f"Upload song selected: {duration:.3f}s, {bpm_status}; ACE audio generation is dormant. " + "The uploaded waveform now enters shared decoded-audio QC and hash locking." + ) + return (*candidates, 1, expected_bpm, lyrics, duration, "uploaded_song", status, True) + + if generated_candidate_count is None: + raise ValueError("ACE-Step source is selected, but generated_candidate_count is not connected.") + count = int(generated_candidate_count) + if count < 1 or count > 4: + raise ValueError("generated_candidate_count must be from 1 to 4.") + if generated_expected_bpm is None: + raise ValueError("ACE-Step source is selected, but generated_expected_bpm is not connected.") + expected_bpm = float(generated_expected_bpm) + if not math.isfinite(expected_bpm) or not 0.0 <= expected_bpm <= 300.0: + raise ValueError("generated_expected_bpm must be a finite value from 0 to 300.") + if generated_duration_seconds is None: + raise ValueError("ACE-Step source is selected, but generated_duration_seconds is not connected.") + duration = float(generated_duration_seconds) + if not math.isfinite(duration) or duration <= 0.0: + raise ValueError("generated_duration_seconds must be positive and finite.") + generated = [ + generated_candidate_1, + generated_candidate_2, + generated_candidate_3, + generated_candidate_4, + ] + missing = [index for index in range(1, count + 1) if generated[index - 1] is None] + if missing: + raise ValueError( + "ACE-Step source expected generated candidate lanes: " + + ", ".join(map(str, missing)) + + "." + ) + first = generated[0] + candidates = tuple(value if value is not None else first for value in generated) + lyrics = str(generated_lyrics or "").strip() + status = ( + f"ACE-Step source selected: {count} decoded candidate{'s' if count != 1 else ''}; " + "the upload loader is dormant and shared decoded-audio QC remains authoritative." + ) + return (*candidates, count, expected_bpm, lyrics, duration, "ace_step", status, True) + + +def _splatstage_seed(root_seed: int, kind: str) -> int: + message = f"splatstage-autodirect@1|{int(root_seed)}|{kind}|0" + return int.from_bytes( + hashlib.blake2b(message.encode("utf-8"), digest_size=8).digest(), + "big", + ) & 0x7FFF_FFFF_FFFF_FFFF + + +def _audition_seed(root_seed: int, index: int) -> int: + return _splatstage_seed(root_seed, f"music:audition:{int(index)}") + + +class DiffusionGemmaSongSeedFanout: + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "root_seed": ( + "INT", + {"default": 26073001, "min": 0, "max": 0x7FFF_FFFF_FFFF_FFFF}, + ), + "production_concept": ( + list(PRODUCTION_CONCEPTS), + {"default": "Source passthrough"}, + ), + } + } + + RETURN_TYPES = ("INT", "INT", "INT", "INT", "STRING") + RETURN_NAMES = ( + "candidate_1_seed", + "candidate_2_seed", + "candidate_3_seed", + "candidate_4_seed", + "seed_report_json", + ) + FUNCTION = "fanout" + CATEGORY = CATEGORY + DESCRIPTION = ( + "Derives ACE song seeds that exactly match the SplatStage Router: one music seed for " + "Source/Joint production, or four zero-based audition seeds." + ) + + def fanout(self, root_seed, production_concept): + root = int(root_seed) + concept = str(production_concept) + if concept not in PRODUCTION_CONCEPTS: + raise ValueError(f"production_concept must be one of {', '.join(PRODUCTION_CONCEPTS)}.") + audition_seeds = [_audition_seed(root, index) for index in range(4)] + if concept == "Audition and select": + seeds = audition_seeds + effective_seeds = seeds + derivation = "splatstage-autodirect@1|{root}|music:audition:{zero_based_index}|0" + audition_indices: list[int] = [0, 1, 2, 3] + else: + music_seed = _splatstage_seed(root, "music") + # Only lane 1 is requested when candidate_count=1. Repeating the + # one production seed on dormant outputs avoids implying that + # Source/Joint mode secretly authored additional candidates. + seeds = [music_seed] * 4 + effective_seeds = [music_seed] + derivation = "splatstage-autodirect@1|{root}|music|0" + audition_indices = [] + report = { + "schema": "diffusiongemma.song_seed_fanout", + "version": 1, + "root_seed": root, + "production_concept": concept, + "derivation": derivation, + "candidate_seeds": effective_seeds, + "output_lane_seeds": seeds, + "audition_indices": audition_indices, + "independent_from_ltx_seed": True, + "matches_splatstage_router": True, + } + return (*seeds, _json(report)) + + +class DiffusionGemmaMusicProductionConcept: + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "production_concept": ( + list(PRODUCTION_CONCEPTS), + {"default": "Source passthrough"}, + ), + "audition_candidate_count": ( + "INT", + {"default": 2, "min": 2, "max": 4, "step": 1}, + ), + } + } + + # Legacy list-valued combo inputs (Planner) require the concrete option + # list, while V3 COMBO inputs (Router) explicitly accept list outputs. + RETURN_TYPES = (list(PRODUCTION_CONCEPTS), list(PRODUCTION_CONCEPTS), "INT") + RETURN_NAMES = ("planner_mode", "router_mode", "candidate_count") + FUNCTION = "route" + CATEGORY = CATEGORY + DESCRIPTION = "One shared production choice for Planner and Router; this node does not mutate music." + + def route(self, production_concept, audition_candidate_count): + value = str(production_concept) + if value not in PRODUCTION_CONCEPTS: + raise ValueError(f"production_concept must be one of {', '.join(PRODUCTION_CONCEPTS)}.") + audition_count = int(audition_candidate_count) + if audition_count < 2 or audition_count > 4: + raise ValueError("audition_candidate_count must be from 2 to 4.") + effective_count = audition_count if value == "Audition and select" else 1 + return (value, value, effective_count) + + +NODE_CLASS_MAPPINGS = { + "DiffusionGemmaAudioCandidateSelector": DiffusionGemmaAudioCandidateSelector, + "DiffusionGemmaUploadSong": DiffusionGemmaUploadSong, + "DiffusionGemmaSongSourceRouter": DiffusionGemmaSongSourceRouter, + "DiffusionGemmaLTXAudioGuide": DiffusionGemmaLTXAudioGuide, + "DiffusionGemmaLTXPerformancePrompt": DiffusionGemmaLTXPerformancePrompt, + "DiffusionGemmaMusicVideoPerformanceMode": DiffusionGemmaMusicVideoPerformanceMode, + "DiffusionGemmaACEReferenceMode": DiffusionGemmaACEReferenceMode, + "DiffusionGemmaACECoverConditioning": DiffusionGemmaACECoverConditioning, + "DiffusionGemmaSongSeedFanout": DiffusionGemmaSongSeedFanout, + "DiffusionGemmaMusicProductionConcept": DiffusionGemmaMusicProductionConcept, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "DiffusionGemmaAudioCandidateSelector": "DiffusionGemma Decoded Song Audition & Lock", + "DiffusionGemmaUploadSong": "DiffusionGemma Upload Song", + "DiffusionGemmaSongSourceRouter": "DiffusionGemma Soundtrack Source", + "DiffusionGemmaLTXAudioGuide": "DiffusionGemma LTX Sync-Safe Audio Guide", + "DiffusionGemmaLTXPerformancePrompt": "DiffusionGemma LTX Performance Prompt", + "DiffusionGemmaMusicVideoPerformanceMode": "DiffusionGemma Music-Video Performance Mode", + "DiffusionGemmaACEReferenceMode": "DiffusionGemma ACE Compose / Cover Mode", + "DiffusionGemmaACECoverConditioning": "DiffusionGemma ACE Cover Conditioning Gate", + "DiffusionGemmaSongSeedFanout": "DiffusionGemma Song Audition Seed Fanout", + "DiffusionGemmaMusicProductionConcept": "DiffusionGemma Music Production Concept", +} diff --git a/benchmarks/ltx25_long_horizon_v1/README.md b/benchmarks/ltx25_long_horizon_v1/README.md new file mode 100644 index 0000000..8b5a520 --- /dev/null +++ b/benchmarks/ltx25_long_horizon_v1/README.md @@ -0,0 +1,40 @@ +# LTX-2.5 Experimental Long Horizon benchmark + +This directory defines an **unexecuted benchmark protocol** for the Director's +optional long-horizon policy. It is not a claim that the comparison has already +been rendered or scored. Before running it, map the four asset IDs listed in +the manifest to one first frame and three duration-matched depth guides. The +protocol then uses the same first frame at 5, 20, and 60 seconds so duration is +the principal changing condition. + +The four variants are: + +- `bare`: the one-line user brief with no Director expansion. +- `current_director`: the existing duration-aware LTX contract with long-horizon + planning off. +- `long_horizon`: Experimental Long Horizon forced on. +- `long_horizon_structural`: the same long-horizon prompt plus a duration-matched + depth guide. This fourth arm intentionally measures prompt plus structural + conditioning and is not part of the prompt-only A/B/C comparison. + +Every arm keeps model, resolution, frame rate, sampler, scheduler, step counts, +CFG, negative prompt, and both sampler seeds fixed. The manifest uses 121, 481, +and 1,441 frames at 24 fps, corresponding to 5, 20, and 60 seconds under LTX's +`(frames - 1) / fps` convention. + +The locked sampler settings mirror the audited 60-second Director run: +`euler_ancestral`, `bong_tangent`, 12 first-stage steps, and three refinement +evaluations. Results remain empty until all four variants have actually been +run for every listed seed pair and scored against the rubric. + +For each seed pair, rate camera monotonicity, anchor persistence, duplication, +spatial drift, abrupt reframing, terminal-composition accuracy, prompt +adherence, and audio continuity. Rate at regular five-second checkpoints for +the 20- and 60-second cases. Treat a single successful seed as anecdotal; the +paired matrix is the acceptance evidence. + +The manifest also records the prompt-contract rubric. Long-horizon prompts must +remain one paragraph of at most 200 words and generally four to eight +sentences. The four internal phases are planning concerns, not chapters, shots, +scene changes, emitted headings, or timecodes. Missing phase or terminal cues +are diagnostics and must not block generation. diff --git a/benchmarks/ltx25_long_horizon_v1/manifest.json b/benchmarks/ltx25_long_horizon_v1/manifest.json new file mode 100644 index 0000000..e4990e4 --- /dev/null +++ b/benchmarks/ltx25_long_horizon_v1/manifest.json @@ -0,0 +1,263 @@ +{ + "schema_version": "dg-ltx25-long-horizon-benchmark/1", + "name": "LTX-2.5 experimental long-horizon duration benchmark v1", + "description": "Controlled 5, 20, and 60 second I2V cases comparing a bare brief, the current Director contract, Experimental Long Horizon, and the same long-horizon prompt with structural conditioning.", + "execution_status": "protocol_only_unexecuted", + "asset_requirements": [ + "mushroom_tableau_first_frame", + "mushroom_tableau_depth_5s", + "mushroom_tableau_depth_20s", + "mushroom_tableau_depth_60s" + ], + "results": [], + "seed_pairs": [ + { + "stage_1": 17, + "stage_2": 42 + }, + { + "stage_1": 101, + "stage_2": 420 + }, + { + "stage_1": 809, + "stage_2": 421 + } + ], + "variant_order": [ + "bare", + "current_director", + "long_horizon", + "long_horizon_structural" + ], + "cases": [ + { + "id": "i2v_tableau_5s", + "mode": "image_to_video", + "duration_seconds": 5.0, + "fps": 24, + "frames": 121, + "brief": "Create a mind-bending shot grounded in the supplied first frame.", + "critical_anchors": [ + "woman in a blue dress", + "chair", + "brick fireplace" + ], + "terminal_composition": "A slightly wider elevated view holds on the unchanged anchor group.", + "expected_auto_long_horizon_active": false, + "fixed_generation_control": { + "model": "ltx-2.5-22b-distilled", + "text_encoder": "gemma4-12b-with-projection", + "precision": "int8-convrot", + "width": 1344, + "height": 768, + "sampler": "euler_ancestral", + "scheduler": "bong_tangent", + "stage_1_steps": 12, + "stage_2_steps": 3, + "video_cfg": 1.0, + "audio_cfg": 1.0, + "negative_prompt": "cuts, transitions, optical zoom, object duplication, subject replacement, subtitles, captions, logos, watermarks", + "prompt_enhancer": false, + "first_frame_asset_id": "mushroom_tableau_first_frame" + }, + "variants": { + "bare": { + "prompt_producer": "bare_brief", + "long_horizon_mode": "off", + "prompt": "Create a mind-bending shot grounded in the supplied first frame.", + "structural_conditioning": "first_frame" + }, + "current_director": { + "prompt_producer": "diffusiongemma_current_ltx_contract", + "long_horizon_mode": "off", + "prompt": "A wide shot begins from the exact supplied first-frame viewpoint, preserving the woman in a sleeveless blue dress beside the chair and brick fireplace in the surreal mushroom meadow. The camera slowly dollies backward and rises while keeping the woman centered. She brushes one mushroom stalk as the fire flickers and the grass moves in a light breeze. Natural parallax reveals more rooted mushrooms, accompanied by fireplace crackle, wind, and restrained lo-fi trip-hop. The camera finishes on a slightly wider elevated composition.", + "structural_conditioning": "first_frame" + }, + "long_horizon": { + "prompt_producer": "diffusiongemma_experimental_long_horizon", + "long_horizon_mode": "on", + "prompt": "An eye-level wide shot begins from the supplied first frame, preserving the woman in the blue dress beside the chair and brick fireplace as the critical anchor group. Initially, for a brief opening moment, the camera holds while the flame flickers and grass moves in a light breeze. It then commits to one smooth backward-and-upward physical move with a fixed wide-angle lens, keeping the anchor group centered through natural parallax. Through most of the take, the surrounding rooted mushrooms are revealed by travel rather than growth or duplication, and steady wind and fireplace crackle continue. The woman, blue dress, chair, brickwork, mushroom colors, daylight, and relative positions remain stable, while only the surrounding field enters the widening frame. Wind, flame crackle, and distant birds persist as one seamless audio bed without any change of source or tempo. Only near the end does the movement decelerate into a wider elevated composition and hold on the unchanged tableau.", + "structural_conditioning": "first_frame" + }, + "long_horizon_structural": { + "prompt_producer": "diffusiongemma_experimental_long_horizon", + "long_horizon_mode": "on", + "prompt": "An eye-level wide shot begins from the supplied first frame, preserving the woman in the blue dress beside the chair and brick fireplace as the critical anchor group. Initially, for a brief opening moment, the camera holds while the flame flickers and grass moves in a light breeze. It then commits to one smooth backward-and-upward physical move with a fixed wide-angle lens, keeping the anchor group centered through natural parallax. Through most of the take, the surrounding rooted mushrooms are revealed by travel rather than growth or duplication, and steady wind and fireplace crackle continue. The woman, blue dress, chair, brickwork, mushroom colors, daylight, and relative positions remain stable, while only the surrounding field enters the widening frame. Wind, flame crackle, and distant birds persist as one seamless audio bed without any change of source or tempo. Only near the end does the movement decelerate into a wider elevated composition and hold on the unchanged tableau.", + "structural_conditioning": "first_frame_plus_depth", + "structural_asset_id": "mushroom_tableau_depth_5s" + } + }, + "rubric": { + "phase_names": [ + "establish", + "commit", + "sustain_reveal", + "settle_hold" + ], + "min_words": 150, + "max_words": 200, + "sentence_range": [ + 4, + 8 + ], + "max_cuts": 0, + "require_one_paragraph": true, + "forbid_timecodes": true, + "diagnostics_block_generation": false + } + }, + { + "id": "i2v_tableau_20s", + "mode": "image_to_video", + "duration_seconds": 20.0, + "fps": 24, + "frames": 481, + "brief": "Create a mind-bending shot grounded in the supplied first frame.", + "critical_anchors": [ + "woman in a blue dress", + "chair", + "brick fireplace" + ], + "terminal_composition": "A wide elevated view holds on the unchanged anchor group within the larger meadow.", + "expected_auto_long_horizon_active": false, + "fixed_generation_control": { + "model": "ltx-2.5-22b-distilled", + "text_encoder": "gemma4-12b-with-projection", + "precision": "int8-convrot", + "width": 1344, + "height": 768, + "sampler": "euler_ancestral", + "scheduler": "bong_tangent", + "stage_1_steps": 12, + "stage_2_steps": 3, + "video_cfg": 1.0, + "audio_cfg": 1.0, + "negative_prompt": "cuts, transitions, optical zoom, object duplication, subject replacement, subtitles, captions, logos, watermarks", + "prompt_enhancer": false, + "first_frame_asset_id": "mushroom_tableau_first_frame" + }, + "variants": { + "bare": { + "prompt_producer": "bare_brief", + "long_horizon_mode": "off", + "prompt": "Create a mind-bending shot grounded in the supplied first frame.", + "structural_conditioning": "first_frame" + }, + "current_director": { + "prompt_producer": "diffusiongemma_current_ltx_contract", + "long_horizon_mode": "off", + "prompt": "A wide shot begins from the exact supplied first-frame viewpoint, preserving the woman in a sleeveless blue dress beside the chair and brick fireplace in the surreal mushroom meadow. The camera holds briefly, then slowly dollies backward and rises while keeping the original tableau centered. She brushes one mushroom stalk as the fire flickers, embers lift, and the grass moves in a light breeze. The camera continues its retreat across the meadow, revealing more rooted mushrooms through natural parallax. Fireplace crackle, wind, distant birds, and restrained lo-fi trip-hop remain synchronized with the scene. The camera finishes on a wider elevated composition that frames the anchor group against the distant fields.", + "structural_conditioning": "first_frame" + }, + "long_horizon": { + "prompt_producer": "diffusiongemma_experimental_long_horizon", + "long_horizon_mode": "on", + "prompt": "An eye-level wide shot begins exactly from the supplied first frame, preserving the woman in the blue dress, chair, and brick fireplace as the critical anchor group. During the opening moment, the camera holds while the fire flickers and a light breeze moves her hair, dress, and nearby grass. It then commits to one stabilized backward-and-upward physical path with a fixed wide-angle lens and a gentle downward tilt that keeps the group centered. Through most of the take, that motion continues at an even pace, revealing the already rooted mushroom meadow through natural parallax while subject identities, counts, colors, and relative positions remain stable. Fireplace crackle, soft wind, distant birds, and restrained lo-fi trip-hop form one continuous audio identity without an abrupt change in source, volume, or musical tempo. Only near the end does the camera decelerate into a wide elevated composition, settle, and hold on the unchanged tableau within the larger field.", + "structural_conditioning": "first_frame" + }, + "long_horizon_structural": { + "prompt_producer": "diffusiongemma_experimental_long_horizon", + "long_horizon_mode": "on", + "prompt": "An eye-level wide shot begins exactly from the supplied first frame, preserving the woman in the blue dress, chair, and brick fireplace as the critical anchor group. During the opening moment, the camera holds while the fire flickers and a light breeze moves her hair, dress, and nearby grass. It then commits to one stabilized backward-and-upward physical path with a fixed wide-angle lens and a gentle downward tilt that keeps the group centered. Through most of the take, that motion continues at an even pace, revealing the already rooted mushroom meadow through natural parallax while subject identities, counts, colors, and relative positions remain stable. Fireplace crackle, soft wind, distant birds, and restrained lo-fi trip-hop form one continuous audio identity without an abrupt change in source, volume, or musical tempo. Only near the end does the camera decelerate into a wide elevated composition, settle, and hold on the unchanged tableau within the larger field.", + "structural_conditioning": "first_frame_plus_depth", + "structural_asset_id": "mushroom_tableau_depth_20s" + } + }, + "rubric": { + "phase_names": [ + "establish", + "commit", + "sustain_reveal", + "settle_hold" + ], + "min_words": 150, + "max_words": 200, + "sentence_range": [ + 4, + 8 + ], + "max_cuts": 0, + "require_one_paragraph": true, + "forbid_timecodes": true, + "diagnostics_block_generation": false + } + }, + { + "id": "i2v_tableau_60s", + "mode": "image_to_video", + "duration_seconds": 60.0, + "fps": 24, + "frames": 1441, + "brief": "Create a mind-bending shot grounded in the supplied first frame.", + "critical_anchors": [ + "woman in a blue dress", + "chair", + "brick fireplace" + ], + "terminal_composition": "An extreme-wide elevated view holds with the original anchor group still readable at the visual center.", + "expected_auto_long_horizon_active": true, + "fixed_generation_control": { + "model": "ltx-2.5-22b-distilled", + "text_encoder": "gemma4-12b-with-projection", + "precision": "int8-convrot", + "width": 1344, + "height": 768, + "sampler": "euler_ancestral", + "scheduler": "bong_tangent", + "stage_1_steps": 12, + "stage_2_steps": 3, + "video_cfg": 1.0, + "audio_cfg": 1.0, + "negative_prompt": "cuts, transitions, optical zoom, object duplication, subject replacement, subtitles, captions, logos, watermarks", + "prompt_enhancer": false, + "first_frame_asset_id": "mushroom_tableau_first_frame" + }, + "variants": { + "bare": { + "prompt_producer": "bare_brief", + "long_horizon_mode": "off", + "prompt": "Create a mind-bending shot grounded in the supplied first frame.", + "structural_conditioning": "first_frame" + }, + "current_director": { + "prompt_producer": "diffusiongemma_current_ltx_contract", + "long_horizon_mode": "off", + "prompt": "A wide shot captures a surreal outdoor space where a woman with long dark hair, wearing a sleeveless blue dress, stands with her back to the camera facing a blue upholstered chair and a patterned rug. Surrounded by numerous oversized fantasy mushrooms with red, white, and blue spotted caps, the scene overlooks a vast green agricultural landscape under a clear sky. To the right, a brick fireplace contains a crackling orange fire. The lighting is bright and even, casting soft shadows on the grey-toned floor. The camera starts at a static eye-level wide-angle perspective, then begins a slow, cinematic dolly-out and slight upward tilt, moving away from the woman. As the woman reaches out to gently touch the stalk of a large white mushroom, the mushrooms begin to vibrate slightly with a magical shimmering light. The fire in the fireplace flickers intensely, sending embers dancing into the air. The camera continues its retreat, revealing more of the surreal field of mushrooms as they begin to sway gently in an invisible breeze. A lofi trip hop beat plays in the background, layered with the rhythmic crackle of the fire and the soft rustle of wind through the giant fungi. The shot ends on a wider composition, framing the entire surreal arrangement against the backdrop of the distant fields.", + "structural_conditioning": "first_frame" + }, + "long_horizon": { + "prompt_producer": "diffusiongemma_experimental_long_horizon", + "long_horizon_mode": "on", + "prompt": "An eye-level wide shot begins exactly from the supplied first frame, preserving the woman in the blue dress, chair, and brick fireplace as the critical anchor group. During the opening five seconds, the camera holds while the fire flickers and a light breeze moves her hair, dress, and nearby grass. It then commits gradually to one stabilized backward-and-upward physical path with a fixed wide-angle lens, using a gentle downward tilt to keep the group centered. Through most of the take, the camera sustains that direction at an even speed, revealing the already rooted mushroom meadow through natural parallax rather than growth, appearance, or duplication. The woman, chair, fireplace, and nearby mushrooms retain their identities, proportions, colors, and relative positions while increasingly distant scenery supplies the visual development. Fireplace crackle, soft wind, distant birds, and restrained lo-fi trip-hop continue as one unbroken audio environment. Only during the final nine seconds does the movement decelerate into an extreme-wide elevated composition, ease to a stop, and hold with the original tableau still readable at the visual center.", + "structural_conditioning": "first_frame" + }, + "long_horizon_structural": { + "prompt_producer": "diffusiongemma_experimental_long_horizon", + "long_horizon_mode": "on", + "prompt": "An eye-level wide shot begins exactly from the supplied first frame, preserving the woman in the blue dress, chair, and brick fireplace as the critical anchor group. During the opening five seconds, the camera holds while the fire flickers and a light breeze moves her hair, dress, and nearby grass. It then commits gradually to one stabilized backward-and-upward physical path with a fixed wide-angle lens, using a gentle downward tilt to keep the group centered. Through most of the take, the camera sustains that direction at an even speed, revealing the already rooted mushroom meadow through natural parallax rather than growth, appearance, or duplication. The woman, chair, fireplace, and nearby mushrooms retain their identities, proportions, colors, and relative positions while increasingly distant scenery supplies the visual development. Fireplace crackle, soft wind, distant birds, and restrained lo-fi trip-hop continue as one unbroken audio environment. Only during the final nine seconds does the movement decelerate into an extreme-wide elevated composition, ease to a stop, and hold with the original tableau still readable at the visual center.", + "structural_conditioning": "first_frame_plus_depth", + "structural_asset_id": "mushroom_tableau_depth_60s" + } + }, + "rubric": { + "phase_names": [ + "establish", + "commit", + "sustain_reveal", + "settle_hold" + ], + "min_words": 150, + "max_words": 200, + "sentence_range": [ + 4, + 8 + ], + "max_cuts": 0, + "require_one_paragraph": true, + "forbid_timecodes": true, + "diagnostics_block_generation": false + } + } + ] +} diff --git a/examples/13_ltx25_i2v_director.json b/examples/13_ltx25_i2v_director.json index 98ba155..357d245 100644 --- a/examples/13_ltx25_i2v_director.json +++ b/examples/13_ltx25_i2v_director.json @@ -1 +1 @@ -{"id":"a8f90e1a-c77d-48d4-b52c-2b55d09c0e25","revision":0,"last_node_id":511,"last_link_id":27,"nodes":[{"id":116,"type":"MarkdownNote","pos":[-1220.0,-980.0],"size":[3700.0,290.0],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[],"title":"START HERE — clean DiffusionGemma + LTX-2.5 Image-to-Video","properties":{},"widgets_values":["# Clean DiffusionGemma → LTX-2.5 Image-to-Video\n\n1. Replace **First-frame image** and edit the **Creative brief**. The same image is already connected to the Director Context Hub and native LTX first-frame conditioning.\n2. Leave Context Hub **video** and **last_frame_image** empty. Auto mode will resolve this graph to **Image to video**.\n3. The shared duration controls both Director planning and LTX generation. On **Node 7**, choose the output aspect ratio and megapixel target; the 16:9 / 0.5 MP baseline drives native LTX at **960×544**. Increase resolution only after a clean baseline render.\n4. The native LTX prompt enhancer is off. DiffusionGemma's gated positive prompt and generated negative prompt feed LTX directly.\n5. Grounding starts in **audit** mode for a faster first test. Switch it to **strict** after the baseline works.\n\nThis workflow intentionally contains no MiniMax-H3 Reference Context, Ref2VA manifest, H3 target profile, or H3 sampler nodes.\n\nCandidate prompt previews are diagnostic only: they update even when validation blocks a render. Native LTX receives the positive prompt through the standard fail-closed Generation Gate and the negative prompt directly from the fail-closed Splitter output; never route a candidate socket directly to the generator. Refresh recomputes but does not randomize a fixed Director seed."],"color":"#222","bgcolor":"#000"},{"id":177,"type":"PrimitiveStringMultiline","pos":[-1220.0,-620.0],"size":[620.0,300.0],"flags":{},"order":1,"mode":0,"inputs":[],"outputs":[{"name":"STRING","type":"STRING","links":[1]}],"title":"1. Creative brief — describe motion from the supplied frame","properties":{"cnr_id":"comfy-core","ver":"0.24.0","Node name for S&R":"PrimitiveStringMultiline"},"widgets_values":["Create a five-second continuous live-action shot grounded in the supplied first frame. Preserve the officer's identity, uniform, roadside setting, daylight, and opening composition. He shifts his weight, turns his attention toward something just off-camera, and takes one measured step as a light breeze moves his hair and clothing. Use one subtle stabilized camera push with no cuts, no new people, and no change of location. Natural roadside ambience and soft clothing movement are heard; no dialogue or intelligible speech."],"color":"#232","bgcolor":"#353"},{"id":178,"type":"PrimitiveFloat","pos":[-1220.0,-260.0],"size":[300.0,80.0],"flags":{},"order":2,"mode":0,"inputs":[],"outputs":[{"name":"FLOAT","type":"FLOAT","links":[16,17]}],"title":"2. Shared duration seconds — Director + LTX","properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"PrimitiveFloat"},"widgets_values":[5.0],"color":"#322","bgcolor":"#533"},{"id":179,"type":"LoadImage","pos":[-1220.0,-120.0],"size":[620.0,700.0],"flags":{},"order":3,"mode":0,"inputs":[],"outputs":[{"name":"IMAGE","type":"IMAGE","links":[2,19]},{"name":"MASK","type":"MASK","links":null}],"title":"3. First-frame image — shared with Context Hub + LTX","properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"LoadImage"},"widgets_values":["ComfyUI_00001_.png","image"]},{"id":182,"type":"DiffusionGemmaModelLoader","pos":[-540.0,-560.0],"size":[500.0,310.0],"flags":{},"order":4,"mode":0,"inputs":[],"outputs":[{"name":"model_config","type":"DG_MODEL_CONFIG","links":[3]},{"name":"runtime_status_json","type":"STRING","links":null}],"title":"4a. Load DiffusionGemma Director — unload before LTX","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaModelLoader"},"widgets_values":["C:\\ComfyUI\\app\\models\\LLM\\diffusiongemma-26B-A4B-it-NVFP4","transformers_inprocess","auto","modelopt_nvfp4",true,"unload_after_run","20.0 GB - safe practical",0.35]},{"id":183,"type":"DiffusionGemmaContextHub","pos":[-20.0,-560.0],"size":[500.0,520.0],"flags":{},"order":5,"mode":0,"inputs":[{"localized_name":"user_prompt","name":"user_prompt","type":"STRING","link":1},{"localized_name":"image","name":"image","shape":7,"type":"IMAGE","link":2},{"localized_name":"video","name":"video","shape":7,"type":"VIDEO","link":null},{"localized_name":"sample_fps","name":"sample_fps","type":"FLOAT","widget":{"name":"sample_fps"},"link":null},{"localized_name":"max_duration_seconds","name":"max_duration_seconds","type":"FLOAT","widget":{"name":"max_duration_seconds"},"link":null},{"localized_name":"max_frames","name":"max_frames","type":"INT","widget":{"name":"max_frames"},"link":null},{"localized_name":"overlong_policy","name":"overlong_policy","type":"COMBO","widget":{"name":"overlong_policy"},"link":null},{"localized_name":"include_image_with_video","name":"include_image_with_video","type":"BOOLEAN","widget":{"name":"include_image_with_video"},"link":null},{"localized_name":"visual_description","name":"visual_description","shape":7,"type":"STRING","widget":{"name":"visual_description"},"link":null},{"localized_name":"media_synthesis_mode","name":"media_synthesis_mode","shape":7,"type":"COMBO","widget":{"name":"media_synthesis_mode"},"link":null},{"localized_name":"last_frame_image","name":"last_frame_image","shape":7,"type":"IMAGE","link":null}],"outputs":[{"localized_name":"gemma_context","name":"gemma_context","type":"DG_CONTEXT","links":[4,8]},{"localized_name":"context_json","name":"context_json","type":"STRING","links":null},{"localized_name":"context_preview","name":"context_preview","type":"STRING","links":null}],"properties":{"Node name for S&R":"DiffusionGemmaContextHub"},"widgets_values":[1.0,60.0,60,"trim",false,"","video_recreation"],"title":"4. LTX first-frame Context Hub"},{"id":510,"type":"DiffusionGemmaLTX25TargetProfile","pos":[-20.0,20.0],"size":[500.0,430.0],"flags":{},"order":6,"mode":0,"inputs":[{"name":"target_duration_seconds","type":"FLOAT","widget":{"name":"target_duration_seconds"},"link":16}],"outputs":[{"name":"target_profile_config","type":"DG_TARGET_PROFILE_CONFIG","links":[5,9]},{"name":"target_profile_json","type":"STRING","links":null}],"properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaLTX25TargetProfile"},"widgets_values":["Auto (recommended)",0.0,"Naturalistic live-action continuity; preserve the supplied first-frame identity, clothing, setting, lighting, and viewpoint.","auto_scene_audio","","custom","video game, CGI, cartoon, duplicate people, deformed face, warped hands, subtitles, captions, logos, watermarks"],"title":"5. LTX-2.5 target profile — Auto resolves to I2V"},{"id":185,"type":"DiffusionGemmaGroundingGuardSettings","pos":[-20.0,500.0],"size":[500.0,330.0],"flags":{},"order":7,"mode":0,"showAdvanced":true,"inputs":[{"name":"external_evidence_json","shape":7,"type":"STRING","link":null}],"outputs":[{"name":"grounding_guard_config","type":"DG_GROUNDING_GUARD_CONFIG","links":[6]},{"name":"config_json","type":"STRING","links":null}],"title":"5b. Grounding Guard — audit baseline; strict after success","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaGroundingGuardSettings"},"widgets_values":["audit",true,"checkpoint_defaults",7,"fixed",false,"diffusiongemma_grounding","auto"]},{"id":418,"type":"SeedNode","pos":[2520.0,270.0],"size":[340.0,85.0],"flags":{},"order":8,"mode":0,"inputs":[],"outputs":[{"name":"seed","type":"INT","links":[21]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"SeedNode"},"widgets_values":[347267244880135,"fixed"],"title":"LTX seed"},{"id":459,"type":"CM_FloatToInt","pos":[2520.0,400.0],"size":[270.0,90.0],"flags":{},"order":9,"mode":0,"inputs":[{"name":"a","type":"FLOAT","widget":{"name":"a"},"link":17}],"outputs":[{"name":"INT","type":"INT","links":[20]}],"properties":{"cnr_id":"ComfyMath","ver":"c01177221c31b8e5fbc062778fc8254aeb541638","Node name for S&R":"CM_FloatToInt"},"widgets_values":[0],"title":"Shared duration → integer seconds"},{"id":186,"type":"DiffusionGemmaCoTGenerator","pos":[540.0,-560.0],"size":[450.0,340.0],"flags":{},"order":10,"mode":0,"inputs":[{"name":"model_config","type":"DG_MODEL_CONFIG","link":3},{"name":"gemma_context","type":"DG_CONTEXT","link":4},{"name":"target_profile_config","type":"DG_TARGET_PROFILE_CONFIG","link":5},{"name":"grounding_guard_config","shape":7,"type":"DG_GROUNDING_GUARD_CONFIG","link":6}],"outputs":[{"name":"final_json","type":"STRING","links":[7]},{"name":"reasoning_text","type":"STRING","links":null},{"name":"raw_response","type":"STRING","links":null},{"name":"metadata_json","type":"STRING","links":null},{"name":"grounding_status","type":"STRING","links":[14]},{"name":"grounding_report_json","type":"STRING","links":[15]}],"title":"6. Build grounded LTX-2.5 prompt","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaCoTGenerator"},"widgets_values":[0.45,"faithful",0.2,"off",1024,"reuse"]},{"id":187,"type":"DiffusionGemmaJSONSplitter","pos":[540.0,-150.0],"size":[450.0,520.0],"flags":{},"order":11,"mode":0,"inputs":[{"name":"final_json","type":"STRING","link":7},{"name":"gemma_context","shape":7,"type":"DG_CONTEXT","link":8},{"name":"target_profile_config","shape":7,"type":"DG_TARGET_PROFILE_CONFIG","link":9}],"outputs":[{"name":"ltx_prompt","type":"STRING","links":[10]},{"name":"ideogram_prompt","type":"STRING","links":null},{"name":"negative_prompt","type":"STRING","links":[24]},{"name":"aspect_ratio","type":"STRING","links":null},{"name":"metadata_json","type":"STRING","links":[12]},{"name":"scene_segments_json","type":"STRING","links":null},{"name":"local_prompts","type":"STRING","links":null},{"name":"segment_lengths","type":"STRING","links":null},{"name":"is_valid","type":"BOOLEAN","links":null},{"name":"resolution_selector_preset","type":"STRING","links":null},{"name":"resolution_width","type":"INT","links":[26]},{"name":"resolution_height","type":"INT","links":[27]},{"name":"ready_for_generation","type":"BOOLEAN","links":[11]},{"name":"minimax_h3_prompt","type":"STRING","links":null},{"name":"candidate_ltx_prompt","type":"STRING","links":[13]},{"name":"candidate_negative_prompt","type":"STRING","links":[25]}],"title":"7. Route LTX prompts + select output resolution","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaJSONSplitter"},"widgets_values":["",0.5,32,"16:9 (Widescreen)"],"shape":2},{"id":188,"type":"DiffusionGemmaGenerationGate","pos":[1050.0,-560.0],"size":[540.0,155.0],"flags":{},"order":12,"mode":0,"inputs":[{"name":"prompt","type":"STRING","link":10},{"name":"ready_for_generation","type":"BOOLEAN","link":11},{"name":"metadata_json","shape":7,"type":"STRING","link":12}],"outputs":[{"name":"prompt","type":"STRING","links":[18]}],"title":"8. Fail-closed LTX-2.5 generation gate","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaGenerationGate"},"widgets_values":[],"color":"#5b2222","bgcolor":"#8b3333"},{"id":189,"type":"PreviewAny","pos":[1650.0,-560.0],"size":[800.0,410.0],"flags":{},"order":13,"mode":0,"inputs":[{"name":"source","type":"*","link":13}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"Candidate LTX positive prompt — diagnostic only","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#23364d","bgcolor":"#354f6e"},{"id":511,"type":"PreviewAny","pos":[1650.0,-90.0],"size":[800.0,220.0],"flags":{},"order":14,"mode":0,"inputs":[{"name":"source","type":"*","link":25}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"Candidate LTX negative prompt — diagnostic only","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#244d3b","bgcolor":"#356e55"},{"id":190,"type":"PreviewAny","pos":[1050.0,-330.0],"size":[540.0,140.0],"flags":{},"order":15,"mode":0,"inputs":[{"name":"source","type":"*","link":14}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"Grounding status","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#2a363b","bgcolor":"#3f5159"},{"id":191,"type":"PreviewAny","pos":[1050.0,-110.0],"size":[540.0,500.0],"flags":{},"order":16,"mode":0,"inputs":[{"name":"source","type":"*","link":15}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"Grounding report","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#2a363b","bgcolor":"#3f5159"},{"id":456,"type":"d9d4c7f2-3c3b-4c2a-9f8b-2a1e3d4c5b6a","pos":[2520.0,-560.0],"size":[720.0,760.0],"flags":{},"order":17,"mode":0,"inputs":[{"label":"first_frame","name":"input","type":"IMAGE,MASK","link":19},{"label":"prompt","name":"value","type":"STRING","widget":{"name":"value"},"link":18},{"label":"prompt_enhance","name":"value_1","type":"BOOLEAN","link":null},{"label":"duration","name":"value_2","type":"INT","widget":{"name":"value_2"},"link":20},{"label":"width","name":"value_3","type":"INT","widget":{"name":"value_3"},"link":26},{"label":"height","name":"value_4","type":"INT","widget":{"name":"value_4"},"link":27},{"name":"noise_seed","type":"INT","widget":{"name":"noise_seed"},"link":21},{"label":"frame_rate","name":"value_5","type":"INT","widget":{"name":"value_5"},"link":null},{"label":"video_vae","name":"vae_name","type":"COMBO","widget":{"name":"vae_name"},"link":null},{"label":"audio_vae","name":"vae_name_1","type":"COMBO","widget":{"name":"vae_name_1"},"link":null},{"label":"upscale_model","name":"model_name","type":"COMBO","widget":{"name":"model_name"},"link":null},{"label":"prompt_enhance_model","name":"clip_name_1","type":"COMBO","link":null},{"label":"negative_prompt","name":"negative_prompt","type":"STRING","link":24}],"outputs":[{"name":"VIDEO","type":"VIDEO","links":[22]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.0","previewExposures":[]},"widgets_values":["",5,992,544,347267244880135,24,"ltx-2.5-22b-distilled-transformer-comfy-int8-convrot.safetensors","ltx-2.5-video-vae-bf16.safetensors","ltx-2.5-audio-vae-bf16.safetensors","gemma4-12b-with-proj-ltx-2.5-comfy-int8-convrot.safetensors","ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors"],"title":"9. Native two-stage LTX-2.5 I2V — prompt enhancer OFF"},{"id":483,"type":"easy cleanGpuUsed","pos":[3300.0,-300.0],"size":[230.0,65.0],"flags":{},"order":18,"mode":0,"inputs":[{"name":"anything","type":"*","link":22}],"outputs":[{"name":"output","type":"*","links":[23]}],"properties":{"cnr_id":"comfyui-easy-use","ver":"1.3.6","Node name for S&R":"easy cleanGpuUsed"},"widgets_values":[],"title":"Unload LTX models after render"},{"id":481,"type":"SaveVideo","pos":[3580.0,-560.0],"size":[1050.0,760.0],"flags":{},"order":19,"mode":0,"inputs":[{"name":"video","type":"VIDEO","link":23}],"outputs":[{"name":"video","type":"VIDEO","links":null}],"properties":{"cnr_id":"comfy-core","ver":"0.14.1","Node name for S&R":"SaveVideo","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["video/ltx2.5_diffusiongemma_i2v","auto","auto"],"title":"10. Save DiffusionGemma LTX-2.5 I2V"}],"links":[[1,177,0,183,0,"STRING"],[2,179,0,183,1,"IMAGE"],[3,182,0,186,0,"DG_MODEL_CONFIG"],[4,183,0,186,1,"DG_CONTEXT"],[5,510,0,186,2,"DG_TARGET_PROFILE_CONFIG"],[6,185,0,186,3,"DG_GROUNDING_GUARD_CONFIG"],[7,186,0,187,0,"STRING"],[8,183,0,187,1,"DG_CONTEXT"],[9,510,0,187,2,"DG_TARGET_PROFILE_CONFIG"],[10,187,0,188,0,"STRING"],[11,187,12,188,1,"BOOLEAN"],[12,187,4,188,2,"STRING"],[13,187,14,189,0,"STRING"],[14,186,4,190,0,"STRING"],[15,186,5,191,0,"STRING"],[16,178,0,510,0,"FLOAT"],[17,178,0,459,0,"FLOAT"],[18,188,0,456,1,"STRING"],[19,179,0,456,0,"IMAGE"],[20,459,0,456,3,"INT"],[21,418,0,456,6,"INT"],[22,456,0,483,0,"VIDEO"],[23,483,0,481,0,"VIDEO"],[24,187,2,456,12,"STRING"],[25,187,15,511,0,"STRING"],[26,187,10,456,4,"INT"],[27,187,11,456,5,"INT"]],"groups":[{"id":1,"title":"1. Inputs + first-frame anchor","bounding":[-1260.0,-660.0,700.0,1320.0],"color":"#3f789e","flags":{}},{"id":2,"title":"2. DiffusionGemma LTX-2.5 Director","bounding":[-570.0,-660.0,1580.0,1530.0],"color":"#6b5b95","flags":{}},{"id":3,"title":"3. Verified prompt handoff","bounding":[1020.0,-660.0,1460.0,1100.0],"color":"#4f7f65","flags":{}},{"id":4,"title":"4. Native LTX-2.5 Image-to-Video","bounding":[2490.0,-660.0,2180.0,1190.0],"color":"#a86f32","flags":{}}],"definitions":{"subgraphs":[{"id":"d9d4c7f2-3c3b-4c2a-9f8b-2a1e3d4c5b6a","version":1,"state":{"lastGroupId":28,"lastNodeId":508,"lastLinkId":861,"lastRerouteId":0},"revision":0,"config":{},"name":"Image to Video (LTX-2.5, DiffusionGemma prompts)","inputNode":{"id":-10,"bounding":[-640,6460,183.814453125,348]},"outputNode":{"id":-20,"bounding":[5540,6496,128,68]},"inputs":[{"id":"075be400-91e7-40a7-8f4e-d5c907af36e8","name":"input","type":"IMAGE,MASK","linkIds":[763],"label":"first_frame","pos":[-480.185546875,6484]},{"id":"5dab3f68-2044-46e7-b01f-4bf4b8bf4e79","name":"value","type":"STRING","linkIds":[765],"label":"prompt","pos":[-480.185546875,6504]},{"id":"21c9d37e-1f04-47f8-b752-22667180790c","name":"value_1","type":"BOOLEAN","linkIds":[],"label":"prompt_enhance","pos":[-480.185546875,6524]},{"id":"00f26a0c-569d-4aa1-aa8a-281ad2f3c4e0","name":"value_2","type":"INT","linkIds":[767],"label":"duration","pos":[-480.185546875,6544]},{"id":"5d05d885-6c96-43dd-9cdb-f1d0c48045b5","name":"value_3","type":"INT","linkIds":[768],"label":"width","pos":[-480.185546875,6564]},{"id":"c646ee59-a1e0-433e-b2f5-f1d8217fe526","name":"value_4","type":"INT","linkIds":[769],"label":"height","pos":[-480.185546875,6584]},{"id":"7072a79b-5168-42ee-9088-e3f92ac07791","name":"noise_seed","type":"INT","linkIds":[770],"pos":[-480.185546875,6604]},{"id":"85a2fb6d-1b63-40a7-adb6-5acc97a7cc99","name":"value_5","type":"INT","linkIds":[776],"label":"frame_rate","pos":[-480.185546875,6624]},{"id":"cbb7ddb9-95d0-4e63-a473-f37c329fbcda","name":"unet_name","type":"COMBO","linkIds":[777],"pos":[-480.185546875,6644]},{"id":"dd0f8943-da6e-4182-8265-efb74da42c33","name":"vae_name","type":"COMBO","linkIds":[778],"label":"video_vae","pos":[-480.185546875,6664]},{"id":"69b9a13b-ee5a-4525-abd9-281d4c257277","name":"vae_name_1","type":"COMBO","linkIds":[779],"label":"audio_vae","pos":[-480.185546875,6684]},{"id":"de6a02d4-1e94-43e7-bf67-2e06f8688943","name":"clip_name","type":"COMBO","linkIds":[780],"pos":[-480.185546875,6704]},{"id":"83db7bd8-4276-4950-8d15-ee1803e29646","name":"model_name","type":"COMBO","linkIds":[781],"label":"upscale_model","pos":[-480.185546875,6724]},{"id":"e5ca018e-1483-44ba-a318-3fc83c7f19ba","name":"clip_name_1","type":"COMBO","linkIds":[],"label":"prompt_enhance_model","pos":[-480.185546875,6744]},{"id":"8e0b9cf6-f939-4a31-983d-8a76d52dd2d9","name":"negative_prompt","type":"STRING","linkIds":[861],"label":"negative_prompt","pos":[-480.185546875,6764.0]}],"outputs":[{"id":"b92869b1-7119-47c1-8a9c-c52c131eb1f1","name":"VIDEO","type":"VIDEO","linkIds":[714],"localized_name":"VIDEO","pos":[5564,6520]}],"widgets":[],"nodes":[{"id":419,"type":"CLIPTextEncode","pos":[1160,6040],"size":[550,738.96875],"flags":{},"order":11,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":732},{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":813}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","links":[696]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"CLIPTextEncode","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[""],"color":"#232","bgcolor":"#353"},{"id":420,"type":"PrimitiveStringMultiline","pos":[150,6080],"size":[368.96875,348.96875],"flags":{},"order":12,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"STRING","widget":{"name":"value"},"link":765}],"outputs":[{"localized_name":"STRING","name":"STRING","type":"STRING","links":[813]}],"title":"Prompt","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveStringMultiline","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["Egyptian royal in blue-and-gold headdress and high collar, white dress with golden embroidery and armbands, desert, robot soldiers in formation left and right. She walks steadily forward, head held level and gaze fixed ahead—no dipping or lowering of the head. The camera performs a single, smooth push-in only: starting in a wider shot of her, the robots, and the desert, it moves steadily forward until she is in a medium or medium-close frame, then holds. She stops, posture and head still upright, and says: “The old gods are silent. I am not.” Robot soldiers shift or march in place; sand and fabric move with the wind. No pull-back; the only camera move is the continuous push-in."]},{"id":421,"type":"UNETLoader","pos":[650,6200],"size":[418.96875,129.375],"flags":{},"order":13,"mode":0,"inputs":[{"localized_name":"unet_name","name":"unet_name","type":"COMBO","widget":{"name":"unet_name"},"link":777}],"outputs":[{"localized_name":"MODEL","name":"MODEL","type":"MODEL","links":[771,772,888]}],"properties":{"cnr_id":"comfy-core","ver":"0.29.0","Node name for S&R":"UNETLoader","models":[{"name":"ltx-2.5-22b-distilled-transformer-comfy-int8-convrot.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/diffusion_models/ltx-2.5-22b-distilled-transformer-comfy-int8-convrot.safetensors","directory":"diffusion_models"}]},"widgets_values":["ltx-2.5-22b-distilled-transformer-comfy-int8-convrot.safetensors","default"]},{"id":422,"type":"PrimitiveInt","pos":[150,6630],"size":[368.96875,108.96875],"flags":{},"order":14,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"INT","widget":{"name":"value"},"link":767}],"outputs":[{"localized_name":"INT","name":"INT","type":"INT","links":[715]}],"title":"Duration","properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"PrimitiveInt","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[5,"fixed"]},{"id":363,"type":"PrimitiveBoolean","pos":[160,6480],"size":[368.96875,98.96875],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[{"localized_name":"BOOLEAN","name":"BOOLEAN","type":"BOOLEAN","links":[683,693]}],"title":"Switch to Text to Video?","properties":{"cnr_id":"comfy-core","ver":"0.16.0","Node name for S&R":"PrimitiveBoolean","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[false]},{"id":423,"type":"LTXVConditioning","pos":[1810,6480],"size":[278.96875,129.375],"flags":{},"order":15,"mode":0,"inputs":[{"localized_name":"positive","name":"positive","type":"CONDITIONING","link":696},{"localized_name":"negative","name":"negative","type":"CONDITIONING","link":697},{"localized_name":"frame_rate","name":"frame_rate","type":"FLOAT","widget":{"name":"frame_rate"},"link":698}],"outputs":[{"localized_name":"positive","name":"positive","type":"CONDITIONING","links":[735,755]},{"localized_name":"negative","name":"negative","type":"CONDITIONING","links":[736,756]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"LTXVConditioning","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[24]},{"id":424,"type":"VAELoader","pos":[650,6398.844815215871],"size":[409.375,70],"flags":{},"order":16,"mode":0,"inputs":[{"localized_name":"vae_name","name":"vae_name","type":"COMBO","widget":{"name":"vae_name"},"link":778}],"outputs":[{"localized_name":"VAE","name":"VAE","type":"VAE","links":[727,773,774,775]}],"properties":{"cnr_id":"comfy-core","ver":"0.29.0","Node name for S&R":"VAELoader","models":[{"name":"ltx-2.5-video-vae-bf16.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/vae/ltx-2.5-video-vae-bf16.safetensors","directory":"vae"}]},"widgets_values":["ltx-2.5-video-vae-bf16.safetensors"]},{"id":425,"type":"VAELoader","pos":[650,6560],"size":[400,88.96875],"flags":{},"order":17,"mode":0,"inputs":[{"localized_name":"vae_name","name":"vae_name","type":"COMBO","widget":{"name":"vae_name"},"link":779}],"outputs":[{"localized_name":"VAE","name":"VAE","type":"VAE","links":[729,730]}],"properties":{"cnr_id":"comfy-core","ver":"0.29.0","Node name for S&R":"VAELoader","models":[{"name":"ltx-2.5-audio-vae-bf16.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/vae/ltx-2.5-audio-vae-bf16.safetensors","directory":"vae"}]},"widgets_values":["ltx-2.5-audio-vae-bf16.safetensors"]},{"id":426,"type":"PrimitiveInt","pos":[150,6780],"size":[368.96875,108.96875],"flags":{},"order":18,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"INT","widget":{"name":"value"},"link":768}],"outputs":[{"localized_name":"INT","name":"INT","type":"INT","links":[687]}],"title":"Width","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveInt","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[1280,"fixed"]},{"id":427,"type":"CLIPTextEncode","pos":[1170,6880],"size":[528.96875,238.96875],"flags":{},"order":19,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":731}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","links":[697]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"CLIPTextEncode","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[""],"color":"#323","bgcolor":"#535","title":"Negative prompt — from DiffusionGemma"},{"id":428,"type":"CLIPLoader","pos":[650,6730],"size":[400,141.921875],"flags":{},"order":20,"mode":0,"showAdvanced":true,"inputs":[{"localized_name":"clip_name","name":"clip_name","type":"COMBO","widget":{"name":"clip_name"},"link":780}],"outputs":[{"localized_name":"CLIP","name":"CLIP","type":"CLIP","links":[731,732]}],"properties":{"cnr_id":"comfy-core","ver":"0.29.0","Node name for S&R":"CLIPLoader","models":[{"name":"gemma4-12b-with-proj-ltx-2.5-comfy-int8-convrot.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/text_encoders/gemma4-12b-with-proj-ltx-2.5-comfy-int8-convrot.safetensors","directory":"text_encoders"}]},"widgets_values":["gemma4-12b-with-proj-ltx-2.5-comfy-int8-convrot.safetensors","ltxv","default"]},{"id":429,"type":"PrimitiveInt","pos":[150,6930],"size":[368.96875,108.96875],"flags":{},"order":21,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"INT","widget":{"name":"value"},"link":769}],"outputs":[{"localized_name":"INT","name":"INT","type":"INT","links":[688]}],"title":"Height","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveInt","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[720,"fixed"]},{"id":430,"type":"KSamplerSelect","pos":[2224.3008005573674,6709.40359723377],"size":[278.96875,108.96875],"flags":{},"order":1,"mode":0,"inputs":[],"outputs":[{"localized_name":"SAMPLER","name":"SAMPLER","type":"SAMPLER","links":[671]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"KSamplerSelect","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["euler_ancestral"]},{"id":431,"type":"RandomNoise","pos":[2190,6300],"size":[278.96875,108.96875],"flags":{},"order":22,"mode":0,"inputs":[{"localized_name":"noise_seed","name":"noise_seed","type":"INT","widget":{"name":"noise_seed"},"link":770}],"outputs":[{"localized_name":"NOISE","name":"NOISE","type":"NOISE","links":[670]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"RandomNoise","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[900359092894726,"randomize"]},{"id":397,"type":"ManualSigmas","pos":[2195.0564044977027,6895.64484593597],"size":[500,98.96875],"flags":{},"order":2,"mode":0,"inputs":[],"outputs":[{"localized_name":"SIGMAS","name":"SIGMAS","type":"SIGMAS","links":[896]}],"properties":{"cnr_id":"comfy-core","ver":"0.14.1","Node name for S&R":"ManualSigmas"},"widgets_values":["1.0, 0.99375, 0.9875, 0.98125, 0.975, 0.909375, 0.725, 0.421875, 0.0"]},{"id":432,"type":"PrimitiveInt","pos":[150,7080],"size":[368.96875,108.96875],"flags":{},"order":23,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"INT","widget":{"name":"value"},"link":776}],"outputs":[{"localized_name":"INT","name":"INT","type":"INT","links":[695,716]}],"title":"Frame Rate","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveInt","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[24,"fixed"]},{"id":433,"type":"LatentUpscaleModelLoader","pos":[640.6800332933674,6971.0077671585605],"size":[409.375,138.96875],"flags":{},"order":24,"mode":0,"inputs":[{"localized_name":"model_name","name":"model_name","type":"COMBO","widget":{"name":"model_name"},"link":781}],"outputs":[{"localized_name":"LATENT_UPSCALE_MODEL","name":"LATENT_UPSCALE_MODEL","type":"LATENT_UPSCALE_MODEL","links":[678]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LatentUpscaleModelLoader","models":[{"name":"ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/latent_upscale_models/ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors","directory":"latent_upscale_models"}],"enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors"]},{"id":434,"type":"LTXVDualCFGGuider","pos":[2215.9956793671613,6502.287759672367],"size":[269.046875,159.046875],"flags":{},"order":25,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":771},{"localized_name":"positive","name":"positive","type":"CONDITIONING","link":735},{"localized_name":"negative","name":"negative","type":"CONDITIONING","link":736}],"outputs":[{"localized_name":"GUIDER","name":"GUIDER","type":"GUIDER","links":[733]}],"properties":{"Node name for S&R":"LTXVDualCFGGuider","cnr_id":"comfy-core","ver":"0.28.0","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[0.5,1]},{"id":435,"type":"SamplerCustomAdvanced","pos":[2610,6510],"size":[228.96875,170],"flags":{},"order":26,"mode":0,"inputs":[{"localized_name":"noise","name":"noise","type":"NOISE","link":670},{"localized_name":"guider","name":"guider","type":"GUIDER","link":733},{"localized_name":"sampler","name":"sampler","type":"SAMPLER","link":671},{"localized_name":"sigmas","name":"sigmas","type":"SIGMAS","link":896},{"localized_name":"latent_image","name":"latent_image","type":"LATENT","link":672}],"outputs":[{"localized_name":"output","name":"output","type":"LATENT","links":[702]},{"localized_name":"denoised_output","name":"denoised_output","type":"LATENT","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.60","Node name for S&R":"SamplerCustomAdvanced","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":357,"type":"LTXVImgToVideoInplace","pos":[2070,7390],"size":[278.96875,179.375],"flags":{},"order":10,"mode":0,"inputs":[{"localized_name":"vae","name":"vae","type":"VAE","link":727},{"localized_name":"image","name":"image","type":"IMAGE","link":691},{"localized_name":"latent","name":"latent","type":"LATENT","link":692},{"localized_name":"bypass","name":"bypass","type":"BOOLEAN","widget":{"name":"bypass"},"link":693}],"outputs":[{"localized_name":"latent","name":"latent","type":"LATENT","links":[699]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVImgToVideoInplace","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[0.7,false]},{"id":436,"type":"LTXVEmptyLatentAudio","pos":[1620,7370],"size":[278.96875,170],"flags":{},"order":27,"mode":0,"inputs":[{"localized_name":"audio_vae","name":"audio_vae","type":"VAE","link":729},{"localized_name":"frames_number","name":"frames_number","type":"INT","widget":{"name":"frames_number"},"link":717},{"localized_name":"frame_rate","name":"frame_rate","type":"FLOAT,INT","widget":{"name":"frame_rate"},"link":701}],"outputs":[{"localized_name":"Latent","name":"Latent","type":"LATENT","links":[700]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.68","Node name for S&R":"LTXVEmptyLatentAudio","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[97,25,1]},{"id":437,"type":"LTXVSeparateAVLatent","pos":[2890,6520],"size":[250,98.96875],"flags":{},"order":28,"mode":0,"inputs":[{"localized_name":"av_latent","name":"av_latent","type":"LATENT","link":702}],"outputs":[{"localized_name":"video_latent","name":"video_latent","type":"LATENT","links":[677]},{"localized_name":"audio_latent","name":"audio_latent","type":"LATENT","links":[666]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"LTXVSeparateAVLatent","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":438,"type":"LTXVConcatAVLatent","pos":[2470,7390],"size":[238.96875,98.96875],"flags":{},"order":29,"mode":0,"inputs":[{"localized_name":"video_latent","name":"video_latent","type":"LATENT","link":699},{"localized_name":"audio_latent","name":"audio_latent","type":"LATENT","link":700}],"outputs":[{"localized_name":"latent","name":"latent","type":"LATENT","links":[672]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVConcatAVLatent","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":351,"type":"ResizeImageMaskNode","pos":[190,7480],"size":[300,117.921875],"flags":{},"order":9,"mode":0,"inputs":[{"localized_name":"input","name":"input","type":"IMAGE,MASK","link":763}],"outputs":[{"localized_name":"resized","name":"resized","type":"IMAGE,MASK","links":[752]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"ResizeImageMaskNode","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["scale longer dimension",1536,"lanczos"]},{"id":439,"type":"ComfyMathExpression","pos":[1170,7470],"size":[225,0],"flags":{"collapsed":true},"order":30,"mode":0,"inputs":[{"label":"a","localized_name":"values.a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":687},{"label":"b","localized_name":"values.b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"localized_name":"FLOAT","name":"FLOAT","type":"FLOAT","links":[]},{"localized_name":"INT","name":"INT","type":"INT","links":[689]},{"localized_name":"BOOL","name":"BOOL","type":"BOOLEAN","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"ComfyMathExpression","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["a/2"]},{"id":440,"type":"ComfyMathExpression","pos":[1170,7530],"size":[225,0],"flags":{"collapsed":true},"order":31,"mode":0,"inputs":[{"label":"a","localized_name":"values.a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":688},{"label":"b","localized_name":"values.b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"localized_name":"FLOAT","name":"FLOAT","type":"FLOAT","links":[]},{"localized_name":"INT","name":"INT","type":"INT","links":[690]},{"localized_name":"BOOL","name":"BOOL","type":"BOOLEAN","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"ComfyMathExpression","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["a/2"]},{"id":350,"type":"LTXVPreprocess","pos":[620,7480],"size":[288.96875,108.96875],"flags":{},"order":8,"mode":0,"inputs":[{"localized_name":"image","name":"image","type":"IMAGE","link":752}],"outputs":[{"localized_name":"output_image","name":"output_image","type":"IMAGE","links":[681,691]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVPreprocess","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[18]},{"id":441,"type":"EmptyLTXVLatentVideo","pos":[1630,7600],"size":[278.96875,198.96875],"flags":{},"order":32,"mode":0,"inputs":[{"localized_name":"width","name":"width","type":"INT","widget":{"name":"width"},"link":689},{"localized_name":"height","name":"height","type":"INT","widget":{"name":"height"},"link":690},{"localized_name":"length","name":"length","type":"INT","widget":{"name":"length"},"link":718}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","links":[692]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.60","Node name for S&R":"EmptyLTXVLatentVideo","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[768,512,97,1]},{"id":442,"type":"LTXVLatentUpsampler","pos":[3260,6410],"size":[328.96875,120],"flags":{},"order":33,"mode":0,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":677},{"localized_name":"upscale_model","name":"upscale_model","type":"LATENT_UPSCALE_MODEL","link":678},{"localized_name":"vae","name":"vae","type":"VAE","link":773}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","links":[682]}],"properties":{"cnr_id":"comfy-core","ver":"0.14.1","Node name for S&R":"LTXVLatentUpsampler","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":349,"type":"LTXVImgToVideoInplace","pos":[3270,6620],"size":[300,179.375],"flags":{},"order":7,"mode":0,"inputs":[{"localized_name":"vae","name":"vae","type":"VAE","link":774},{"localized_name":"image","name":"image","type":"IMAGE","link":681},{"localized_name":"latent","name":"latent","type":"LATENT","link":682},{"localized_name":"bypass","name":"bypass","type":"BOOLEAN","widget":{"name":"bypass"},"link":683}],"outputs":[{"localized_name":"latent","name":"latent","type":"LATENT","links":[665]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVImgToVideoInplace","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[1,false]},{"id":443,"type":"ComfyMathExpression","pos":[1170,7670],"size":[225,0],"flags":{"collapsed":true},"order":34,"mode":0,"inputs":[{"label":"a","localized_name":"values.a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":695},{"label":"b","localized_name":"values.b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"localized_name":"FLOAT","name":"FLOAT","type":"FLOAT","links":[698,713]},{"localized_name":"INT","name":"INT","type":"INT","links":[701]},{"localized_name":"BOOL","name":"BOOL","type":"BOOLEAN","links":[]}],"title":"Math Expression (fps)","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"ComfyMathExpression","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["a"]},{"id":444,"type":"ComfyMathExpression","pos":[1180,7770],"size":[225,0],"flags":{"collapsed":true},"order":35,"mode":0,"inputs":[{"label":"a","localized_name":"values.a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":715},{"label":"b","localized_name":"values.b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":716},{"label":"c","localized_name":"values.c","name":"values.c","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"localized_name":"FLOAT","name":"FLOAT","type":"FLOAT","links":[]},{"localized_name":"INT","name":"INT","type":"INT","links":[717,718]},{"localized_name":"BOOL","name":"BOOL","type":"BOOLEAN","links":[]}],"title":"Math Expression (length)","properties":{"cnr_id":"comfy-core","ver":"0.18.1","Node name for S&R":"ComfyMathExpression","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.7"}},"widgets_values":["a * b + 1"]},{"id":445,"type":"RandomNoise","pos":[3710,6150],"size":[278.96875,108.96875],"flags":{},"order":3,"mode":0,"inputs":[],"outputs":[{"localized_name":"NOISE","name":"NOISE","type":"NOISE","links":[703]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.75","Node name for S&R":"RandomNoise","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[42,"fixed"]},{"id":446,"type":"LTXVConcatAVLatent","pos":[3710,6760],"size":[278.96875,98.96875],"flags":{},"order":36,"mode":0,"inputs":[{"localized_name":"video_latent","name":"video_latent","type":"LATENT","link":665},{"localized_name":"audio_latent","name":"audio_latent","type":"LATENT","link":666}],"outputs":[{"localized_name":"latent","name":"latent","type":"LATENT","links":[707]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"LTXVConcatAVLatent","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":396,"type":"ManualSigmas","pos":[3710,6980],"size":[288.96875,108.96875],"flags":{},"order":4,"mode":0,"inputs":[],"outputs":[{"localized_name":"SIGMAS","name":"SIGMAS","type":"SIGMAS","links":[751]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"ManualSigmas","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["0.85, 0.7250, 0.4219, 0.0"]},{"id":447,"type":"LTXVDualCFGGuider","pos":[3711.811554084113,6320.869184637932],"size":[269.046875,159.046875],"flags":{},"order":37,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":772},{"localized_name":"positive","name":"positive","type":"CONDITIONING","link":755},{"localized_name":"negative","name":"negative","type":"CONDITIONING","link":756}],"outputs":[{"localized_name":"GUIDER","name":"GUIDER","type":"GUIDER","links":[744]}],"properties":{"Node name for S&R":"LTXVDualCFGGuider","cnr_id":"comfy-core","ver":"0.28.0","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[1,1]},{"id":448,"type":"KSamplerSelect","pos":[3710,6560],"size":[278.96875,108.96875],"flags":{},"order":5,"mode":0,"inputs":[],"outputs":[{"localized_name":"SAMPLER","name":"SAMPLER","type":"SAMPLER","links":[705]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.75","Node name for S&R":"KSamplerSelect","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["res_2s"]},{"id":449,"type":"SamplerCustomAdvanced","pos":[4070,6500],"size":[228.96875,170],"flags":{},"order":38,"mode":0,"inputs":[{"localized_name":"noise","name":"noise","type":"NOISE","link":703},{"localized_name":"guider","name":"guider","type":"GUIDER","link":744},{"localized_name":"sampler","name":"sampler","type":"SAMPLER","link":705},{"localized_name":"sigmas","name":"sigmas","type":"SIGMAS","link":751},{"localized_name":"latent_image","name":"latent_image","type":"LATENT","link":707}],"outputs":[{"localized_name":"output","name":"output","type":"LATENT","links":[708]},{"localized_name":"denoised_output","name":"denoised_output","type":"LATENT","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.75","Node name for S&R":"SamplerCustomAdvanced","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":450,"type":"LTXVSeparateAVLatent","pos":[4370,6500],"size":[228.96875,98.96875],"flags":{},"order":39,"mode":0,"inputs":[{"localized_name":"av_latent","name":"av_latent","type":"LATENT","link":708}],"outputs":[{"localized_name":"video_latent","name":"video_latent","type":"LATENT","links":[709]},{"localized_name":"audio_latent","name":"audio_latent","type":"LATENT","links":[694]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"LTXVSeparateAVLatent","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":451,"type":"VAEDecodeTiled","pos":[4760,6360],"size":[278.96875,198.96875],"flags":{},"order":40,"mode":0,"showAdvanced":true,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":709},{"localized_name":"vae","name":"vae","type":"VAE","link":775}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[711]}],"properties":{"cnr_id":"comfy-core","ver":"0.14.1","Node name for S&R":"VAEDecodeTiled","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[512,64,64,16]},{"id":452,"type":"LTXVAudioVAEDecode","pos":[4760,6650],"size":[268.96875,98.96875],"flags":{},"order":41,"mode":0,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":694},{"label":"Audio VAE","localized_name":"audio_vae","name":"audio_vae","type":"VAE","link":730}],"outputs":[{"localized_name":"Audio","name":"Audio","type":"AUDIO","links":[712]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVAudioVAEDecode","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":453,"type":"CreateVideo","pos":[5200,6460],"size":[278.96875,129.375],"flags":{},"order":42,"mode":0,"inputs":[{"localized_name":"images","name":"images","type":"IMAGE","link":711},{"localized_name":"audio","name":"audio","shape":7,"type":"AUDIO","link":712},{"localized_name":"fps","name":"fps","type":"FLOAT","widget":{"name":"fps"},"link":713}],"outputs":[{"localized_name":"VIDEO","name":"VIDEO","type":"VIDEO","links":[714]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"CreateVideo","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[24,8]},{"id":508,"type":"BasicScheduler","pos":[1836.2732329122807,6878.830222687924],"size":[268.75,117.921875],"flags":{},"order":6,"mode":4,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":888}],"outputs":[{"localized_name":"SIGMAS","name":"SIGMAS","type":"SIGMAS","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"BasicScheduler"},"widgets_values":["linear_quadratic",25,1]}],"groups":[{"id":1,"title":"Model","bounding":[620,5950,480,1270],"color":"#3f789e","flags":{}},{"id":3,"title":"Prompt","bounding":[1130,5950,980,1270],"color":"#3f789e","flags":{}},{"id":19,"title":"Video Settings","bounding":[100,5950,490,1270],"color":"#3f789e","flags":{}},{"id":2,"title":"Generate Low Resolution","bounding":[2140,5950,1020,1270],"color":"#3f789e","flags":{}},{"id":7,"title":"Latent Upscale","bounding":[3190,5950,460,1270],"color":"#3f789e","flags":{}},{"id":20,"title":"Image Preprocessing","bounding":[100,7250,1000,610],"color":"#3f789e","flags":{}},{"id":21,"title":"Empty Latent","bounding":[1480,7250,1680,610],"color":"#3f789e","flags":{}},{"id":22,"title":"Number conversion","bounding":[1130,7250,320,610],"color":"#3f789e","flags":{}},{"id":6,"title":"Generate High Resolution","bounding":[3680,5950,960,1270],"color":"#3f789e","flags":{}}],"links":[{"id":732,"origin_id":428,"origin_slot":0,"target_id":419,"target_slot":0,"type":"CLIP"},{"id":696,"origin_id":419,"origin_slot":0,"target_id":423,"target_slot":0,"type":"CONDITIONING"},{"id":697,"origin_id":427,"origin_slot":0,"target_id":423,"target_slot":1,"type":"CONDITIONING"},{"id":698,"origin_id":443,"origin_slot":0,"target_id":423,"target_slot":2,"type":"FLOAT"},{"id":731,"origin_id":428,"origin_slot":0,"target_id":427,"target_slot":0,"type":"CLIP"},{"id":735,"origin_id":423,"origin_slot":0,"target_id":434,"target_slot":1,"type":"CONDITIONING"},{"id":736,"origin_id":423,"origin_slot":1,"target_id":434,"target_slot":2,"type":"CONDITIONING"},{"id":670,"origin_id":431,"origin_slot":0,"target_id":435,"target_slot":0,"type":"NOISE"},{"id":733,"origin_id":434,"origin_slot":0,"target_id":435,"target_slot":1,"type":"GUIDER"},{"id":671,"origin_id":430,"origin_slot":0,"target_id":435,"target_slot":2,"type":"SAMPLER"},{"id":672,"origin_id":438,"origin_slot":0,"target_id":435,"target_slot":4,"type":"LATENT"},{"id":727,"origin_id":424,"origin_slot":0,"target_id":357,"target_slot":0,"type":"VAE"},{"id":691,"origin_id":350,"origin_slot":0,"target_id":357,"target_slot":1,"type":"IMAGE"},{"id":692,"origin_id":441,"origin_slot":0,"target_id":357,"target_slot":2,"type":"LATENT"},{"id":693,"origin_id":363,"origin_slot":0,"target_id":357,"target_slot":3,"type":"BOOLEAN"},{"id":729,"origin_id":425,"origin_slot":0,"target_id":436,"target_slot":0,"type":"VAE"},{"id":717,"origin_id":444,"origin_slot":1,"target_id":436,"target_slot":1,"type":"INT"},{"id":701,"origin_id":443,"origin_slot":1,"target_id":436,"target_slot":2,"type":"INT"},{"id":702,"origin_id":435,"origin_slot":0,"target_id":437,"target_slot":0,"type":"LATENT"},{"id":699,"origin_id":357,"origin_slot":0,"target_id":438,"target_slot":0,"type":"LATENT"},{"id":700,"origin_id":436,"origin_slot":0,"target_id":438,"target_slot":1,"type":"LATENT"},{"id":687,"origin_id":426,"origin_slot":0,"target_id":439,"target_slot":0,"type":"INT"},{"id":688,"origin_id":429,"origin_slot":0,"target_id":440,"target_slot":0,"type":"INT"},{"id":752,"origin_id":351,"origin_slot":0,"target_id":350,"target_slot":0,"type":"IMAGE"},{"id":689,"origin_id":439,"origin_slot":1,"target_id":441,"target_slot":0,"type":"INT"},{"id":690,"origin_id":440,"origin_slot":1,"target_id":441,"target_slot":1,"type":"INT"},{"id":718,"origin_id":444,"origin_slot":1,"target_id":441,"target_slot":2,"type":"INT"},{"id":677,"origin_id":437,"origin_slot":0,"target_id":442,"target_slot":0,"type":"LATENT"},{"id":678,"origin_id":433,"origin_slot":0,"target_id":442,"target_slot":1,"type":"LATENT_UPSCALE_MODEL"},{"id":681,"origin_id":350,"origin_slot":0,"target_id":349,"target_slot":1,"type":"IMAGE"},{"id":682,"origin_id":442,"origin_slot":0,"target_id":349,"target_slot":2,"type":"LATENT"},{"id":683,"origin_id":363,"origin_slot":0,"target_id":349,"target_slot":3,"type":"BOOLEAN"},{"id":695,"origin_id":432,"origin_slot":0,"target_id":443,"target_slot":0,"type":"INT"},{"id":715,"origin_id":422,"origin_slot":0,"target_id":444,"target_slot":0,"type":"INT"},{"id":716,"origin_id":432,"origin_slot":0,"target_id":444,"target_slot":1,"type":"INT"},{"id":665,"origin_id":349,"origin_slot":0,"target_id":446,"target_slot":0,"type":"LATENT"},{"id":666,"origin_id":437,"origin_slot":1,"target_id":446,"target_slot":1,"type":"LATENT"},{"id":755,"origin_id":423,"origin_slot":0,"target_id":447,"target_slot":1,"type":"CONDITIONING"},{"id":756,"origin_id":423,"origin_slot":1,"target_id":447,"target_slot":2,"type":"CONDITIONING"},{"id":703,"origin_id":445,"origin_slot":0,"target_id":449,"target_slot":0,"type":"NOISE"},{"id":744,"origin_id":447,"origin_slot":0,"target_id":449,"target_slot":1,"type":"GUIDER"},{"id":705,"origin_id":448,"origin_slot":0,"target_id":449,"target_slot":2,"type":"SAMPLER"},{"id":751,"origin_id":396,"origin_slot":0,"target_id":449,"target_slot":3,"type":"SIGMAS"},{"id":707,"origin_id":446,"origin_slot":0,"target_id":449,"target_slot":4,"type":"LATENT"},{"id":708,"origin_id":449,"origin_slot":0,"target_id":450,"target_slot":0,"type":"LATENT"},{"id":709,"origin_id":450,"origin_slot":0,"target_id":451,"target_slot":0,"type":"LATENT"},{"id":694,"origin_id":450,"origin_slot":1,"target_id":452,"target_slot":0,"type":"LATENT"},{"id":730,"origin_id":425,"origin_slot":0,"target_id":452,"target_slot":1,"type":"VAE"},{"id":711,"origin_id":451,"origin_slot":0,"target_id":453,"target_slot":0,"type":"IMAGE"},{"id":712,"origin_id":452,"origin_slot":0,"target_id":453,"target_slot":1,"type":"AUDIO"},{"id":713,"origin_id":443,"origin_slot":0,"target_id":453,"target_slot":2,"type":"FLOAT"},{"id":714,"origin_id":453,"origin_slot":0,"target_id":-20,"target_slot":0,"type":"VIDEO"},{"id":763,"origin_id":-10,"origin_slot":0,"target_id":351,"target_slot":0,"type":"IMAGE,MASK"},{"id":765,"origin_id":-10,"origin_slot":1,"target_id":420,"target_slot":0,"type":"STRING"},{"id":767,"origin_id":-10,"origin_slot":3,"target_id":422,"target_slot":0,"type":"INT"},{"id":768,"origin_id":-10,"origin_slot":4,"target_id":426,"target_slot":0,"type":"INT"},{"id":769,"origin_id":-10,"origin_slot":5,"target_id":429,"target_slot":0,"type":"INT"},{"id":770,"origin_id":-10,"origin_slot":6,"target_id":431,"target_slot":0,"type":"INT"},{"id":771,"origin_id":421,"origin_slot":0,"target_id":434,"target_slot":0,"type":"MODEL"},{"id":772,"origin_id":421,"origin_slot":0,"target_id":447,"target_slot":0,"type":"MODEL"},{"id":773,"origin_id":424,"origin_slot":0,"target_id":442,"target_slot":2,"type":"VAE"},{"id":774,"origin_id":424,"origin_slot":0,"target_id":349,"target_slot":0,"type":"VAE"},{"id":775,"origin_id":424,"origin_slot":0,"target_id":451,"target_slot":1,"type":"VAE"},{"id":776,"origin_id":-10,"origin_slot":7,"target_id":432,"target_slot":0,"type":"INT"},{"id":777,"origin_id":-10,"origin_slot":8,"target_id":421,"target_slot":0,"type":"COMBO"},{"id":778,"origin_id":-10,"origin_slot":9,"target_id":424,"target_slot":0,"type":"COMBO"},{"id":779,"origin_id":-10,"origin_slot":10,"target_id":425,"target_slot":0,"type":"COMBO"},{"id":780,"origin_id":-10,"origin_slot":11,"target_id":428,"target_slot":0,"type":"COMBO"},{"id":781,"origin_id":-10,"origin_slot":12,"target_id":433,"target_slot":0,"type":"COMBO"},{"id":813,"origin_id":420,"origin_slot":0,"target_id":419,"target_slot":1,"type":"STRING"},{"id":888,"origin_id":421,"origin_slot":0,"target_id":508,"target_slot":0,"type":"MODEL"},{"id":896,"origin_id":397,"origin_slot":0,"target_id":435,"target_slot":3,"type":"SIGMAS"},{"id":861,"origin_id":-10,"origin_slot":14,"target_id":427,"target_slot":1,"type":"STRING"}],"extra":{},"description":"Native two-stage LTX-2.5 I2V with external DiffusionGemma positive and negative prompts; built-in prompt enhancement remains off."}]},"config":{},"extra":{"frontendVersion":"1.47.12","VHS_latentpreview":false,"VHS_latentpreviewrate":0,"VHS_MetadataImage":true,"VHS_KeepIntermediate":true,"workflow_note":"Clean DiffusionGemma LTX-2.5 Image-to-Video baseline. Context Hub first frame and native LTX first frame share one LoadImage; no H3 Ref2VA nodes.","ds":{"scale":0.28,"offset":[400.0,420.0]},"seed_widgets":{"185":3,"418":0,"456":4}},"version":0.4} +{"id":"a8f90e1a-c77d-48d4-b52c-2b55d09c0e25","revision":0,"last_node_id":511,"last_link_id":27,"nodes":[{"id":116,"type":"MarkdownNote","pos":[-1220.0,-980.0],"size":[3700.0,290.0],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[],"title":"START HERE — clean DiffusionGemma + LTX-2.5 Image-to-Video","properties":{},"widgets_values":["# Clean DiffusionGemma → LTX-2.5 Image-to-Video\n\n1. Replace **First-frame image** and edit the **Creative brief**. The same image is already connected to the Director Context Hub and native LTX first-frame conditioning.\n2. Leave Context Hub **video** and **last_frame_image** empty. Auto mode will resolve this graph to **Image to video**.\n3. The shared duration controls both Director planning and LTX generation. On **Node 7**, choose the output aspect ratio and megapixel target; the 16:9 / 0.5 MP baseline drives native LTX at **960×544**. Increase resolution only after a clean baseline render.\n4. The native LTX prompt enhancer is off. DiffusionGemma's gated positive prompt and generated negative prompt feed LTX directly.\n5. Grounding starts in **audit** mode for a faster first test. Switch it to **strict** after the baseline works.\n\nThis workflow intentionally contains no MiniMax-H3 Reference Context, Ref2VA manifest, H3 target profile, or H3 sampler nodes.\n\nCandidate prompt previews are diagnostic only: they update even when validation blocks a render. Native LTX receives the positive prompt through the standard fail-closed Generation Gate and the negative prompt directly from the fail-closed Splitter output; never route a candidate socket directly to the generator. Refresh recomputes but does not randomize a fixed Director seed."],"color":"#222","bgcolor":"#000"},{"id":177,"type":"PrimitiveStringMultiline","pos":[-1220.0,-620.0],"size":[620.0,300.0],"flags":{},"order":1,"mode":0,"inputs":[],"outputs":[{"name":"STRING","type":"STRING","links":[1]}],"title":"1. Creative brief — describe motion from the supplied frame","properties":{"cnr_id":"comfy-core","ver":"0.24.0","Node name for S&R":"PrimitiveStringMultiline"},"widgets_values":["Create a five-second continuous live-action shot grounded in the supplied first frame. Preserve the officer's identity, uniform, roadside setting, daylight, and opening composition. He shifts his weight, turns his attention toward something just off-camera, and takes one measured step as a light breeze moves his hair and clothing. Use one subtle stabilized camera push with no cuts, no new people, and no change of location. Natural roadside ambience and soft clothing movement are heard; no dialogue or intelligible speech."],"color":"#232","bgcolor":"#353"},{"id":178,"type":"PrimitiveFloat","pos":[-1220.0,-260.0],"size":[300.0,80.0],"flags":{},"order":2,"mode":0,"inputs":[],"outputs":[{"name":"FLOAT","type":"FLOAT","links":[16,17]}],"title":"2. Shared duration seconds — Director + LTX","properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"PrimitiveFloat"},"widgets_values":[5.0],"color":"#322","bgcolor":"#533"},{"id":179,"type":"LoadImage","pos":[-1220.0,-120.0],"size":[620.0,700.0],"flags":{},"order":3,"mode":0,"inputs":[],"outputs":[{"name":"IMAGE","type":"IMAGE","links":[2,19]},{"name":"MASK","type":"MASK","links":null}],"title":"3. First-frame image — shared with Context Hub + LTX","properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"LoadImage"},"widgets_values":["ComfyUI_00001_.png","image"]},{"id":182,"type":"DiffusionGemmaModelLoader","pos":[-540.0,-560.0],"size":[500.0,310.0],"flags":{},"order":4,"mode":0,"inputs":[],"outputs":[{"name":"model_config","type":"DG_MODEL_CONFIG","links":[3]},{"name":"runtime_status_json","type":"STRING","links":null}],"title":"4a. Load DiffusionGemma Director — unload before LTX","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaModelLoader"},"widgets_values":["C:\\ComfyUI\\app\\models\\LLM\\diffusiongemma-26B-A4B-it-NVFP4","transformers_inprocess","auto","modelopt_nvfp4",true,"unload_after_run","20.0 GB - safe practical",0.35]},{"id":183,"type":"DiffusionGemmaContextHub","pos":[-20.0,-560.0],"size":[500.0,520.0],"flags":{},"order":5,"mode":0,"inputs":[{"localized_name":"user_prompt","name":"user_prompt","type":"STRING","link":1},{"localized_name":"image","name":"image","shape":7,"type":"IMAGE","link":2},{"localized_name":"video","name":"video","shape":7,"type":"VIDEO","link":null},{"localized_name":"sample_fps","name":"sample_fps","type":"FLOAT","widget":{"name":"sample_fps"},"link":null},{"localized_name":"max_duration_seconds","name":"max_duration_seconds","type":"FLOAT","widget":{"name":"max_duration_seconds"},"link":null},{"localized_name":"max_frames","name":"max_frames","type":"INT","widget":{"name":"max_frames"},"link":null},{"localized_name":"overlong_policy","name":"overlong_policy","type":"COMBO","widget":{"name":"overlong_policy"},"link":null},{"localized_name":"include_image_with_video","name":"include_image_with_video","type":"BOOLEAN","widget":{"name":"include_image_with_video"},"link":null},{"localized_name":"visual_description","name":"visual_description","shape":7,"type":"STRING","widget":{"name":"visual_description"},"link":null},{"localized_name":"media_synthesis_mode","name":"media_synthesis_mode","shape":7,"type":"COMBO","widget":{"name":"media_synthesis_mode"},"link":null},{"localized_name":"last_frame_image","name":"last_frame_image","shape":7,"type":"IMAGE","link":null}],"outputs":[{"localized_name":"gemma_context","name":"gemma_context","type":"DG_CONTEXT","links":[4,8]},{"localized_name":"context_json","name":"context_json","type":"STRING","links":null},{"localized_name":"context_preview","name":"context_preview","type":"STRING","links":null}],"properties":{"Node name for S&R":"DiffusionGemmaContextHub"},"widgets_values":[1.0,60.0,60,"trim",false,"","video_recreation"],"title":"4. LTX first-frame Context Hub"},{"id":510,"type":"DiffusionGemmaLTX25TargetProfile","pos":[-20.0,20.0],"size":[500.0,430.0],"flags":{},"order":6,"mode":0,"inputs":[{"name":"target_duration_seconds","type":"FLOAT","widget":{"name":"target_duration_seconds"},"link":16}],"outputs":[{"name":"target_profile_config","type":"DG_TARGET_PROFILE_CONFIG","links":[5,9]},{"name":"target_profile_json","type":"STRING","links":null}],"properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaLTX25TargetProfile"},"widgets_values":["Auto (recommended)",0.0,"Naturalistic live-action continuity; preserve the supplied first-frame identity, clothing, setting, lighting, and viewpoint.","auto_scene_audio","","custom","video game, CGI, cartoon, duplicate people, deformed face, warped hands, subtitles, captions, logos, watermarks","Off"],"title":"5. LTX-2.5 target profile — Auto resolves to I2V"},{"id":185,"type":"DiffusionGemmaGroundingGuardSettings","pos":[-20.0,500.0],"size":[500.0,330.0],"flags":{},"order":7,"mode":0,"showAdvanced":true,"inputs":[{"name":"external_evidence_json","shape":7,"type":"STRING","link":null}],"outputs":[{"name":"grounding_guard_config","type":"DG_GROUNDING_GUARD_CONFIG","links":[6]},{"name":"config_json","type":"STRING","links":null}],"title":"5b. Grounding Guard — audit baseline; strict after success","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaGroundingGuardSettings"},"widgets_values":["audit",true,"checkpoint_defaults",7,"fixed",false,"diffusiongemma_grounding","auto"]},{"id":418,"type":"SeedNode","pos":[2520.0,270.0],"size":[340.0,85.0],"flags":{},"order":8,"mode":0,"inputs":[],"outputs":[{"name":"seed","type":"INT","links":[21]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"SeedNode"},"widgets_values":[347267244880135,"fixed"],"title":"LTX seed"},{"id":459,"type":"CM_FloatToInt","pos":[2520.0,400.0],"size":[270.0,90.0],"flags":{},"order":9,"mode":0,"inputs":[{"name":"a","type":"FLOAT","widget":{"name":"a"},"link":17}],"outputs":[{"name":"INT","type":"INT","links":[20]}],"properties":{"cnr_id":"ComfyMath","ver":"c01177221c31b8e5fbc062778fc8254aeb541638","Node name for S&R":"CM_FloatToInt"},"widgets_values":[0],"title":"Shared duration → integer seconds"},{"id":186,"type":"DiffusionGemmaCoTGenerator","pos":[540.0,-560.0],"size":[450.0,340.0],"flags":{},"order":10,"mode":0,"inputs":[{"name":"model_config","type":"DG_MODEL_CONFIG","link":3},{"name":"gemma_context","type":"DG_CONTEXT","link":4},{"name":"target_profile_config","type":"DG_TARGET_PROFILE_CONFIG","link":5},{"name":"grounding_guard_config","shape":7,"type":"DG_GROUNDING_GUARD_CONFIG","link":6}],"outputs":[{"name":"final_json","type":"STRING","links":[7]},{"name":"reasoning_text","type":"STRING","links":null},{"name":"raw_response","type":"STRING","links":null},{"name":"metadata_json","type":"STRING","links":null},{"name":"grounding_status","type":"STRING","links":[14]},{"name":"grounding_report_json","type":"STRING","links":[15]}],"title":"6. Build grounded LTX-2.5 prompt","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaCoTGenerator"},"widgets_values":[0.45,"faithful",0.2,"off",1024,"reuse"]},{"id":187,"type":"DiffusionGemmaJSONSplitter","pos":[540.0,-150.0],"size":[450.0,520.0],"flags":{},"order":11,"mode":0,"inputs":[{"name":"final_json","type":"STRING","link":7},{"name":"gemma_context","shape":7,"type":"DG_CONTEXT","link":8},{"name":"target_profile_config","shape":7,"type":"DG_TARGET_PROFILE_CONFIG","link":9}],"outputs":[{"name":"ltx_prompt","type":"STRING","links":[10]},{"name":"ideogram_prompt","type":"STRING","links":null},{"name":"negative_prompt","type":"STRING","links":[24]},{"name":"aspect_ratio","type":"STRING","links":null},{"name":"metadata_json","type":"STRING","links":[12]},{"name":"scene_segments_json","type":"STRING","links":null},{"name":"local_prompts","type":"STRING","links":null},{"name":"segment_lengths","type":"STRING","links":null},{"name":"is_valid","type":"BOOLEAN","links":null},{"name":"resolution_selector_preset","type":"STRING","links":null},{"name":"resolution_width","type":"INT","links":[26]},{"name":"resolution_height","type":"INT","links":[27]},{"name":"ready_for_generation","type":"BOOLEAN","links":[11]},{"name":"minimax_h3_prompt","type":"STRING","links":null},{"name":"candidate_ltx_prompt","type":"STRING","links":[13]},{"name":"candidate_negative_prompt","type":"STRING","links":[25]}],"title":"7. Route LTX prompts + select output resolution","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaJSONSplitter"},"widgets_values":["",0.5,32,"16:9 (Widescreen)"],"shape":2},{"id":188,"type":"DiffusionGemmaGenerationGate","pos":[1050.0,-560.0],"size":[540.0,155.0],"flags":{},"order":12,"mode":0,"inputs":[{"name":"prompt","type":"STRING","link":10},{"name":"ready_for_generation","type":"BOOLEAN","link":11},{"name":"metadata_json","shape":7,"type":"STRING","link":12}],"outputs":[{"name":"prompt","type":"STRING","links":[18]}],"title":"8. Fail-closed LTX-2.5 generation gate","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaGenerationGate"},"widgets_values":[],"color":"#5b2222","bgcolor":"#8b3333"},{"id":189,"type":"PreviewAny","pos":[1650.0,-560.0],"size":[800.0,410.0],"flags":{},"order":13,"mode":0,"inputs":[{"name":"source","type":"*","link":13}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"Candidate LTX positive prompt — diagnostic only","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#23364d","bgcolor":"#354f6e"},{"id":511,"type":"PreviewAny","pos":[1650.0,-90.0],"size":[800.0,220.0],"flags":{},"order":14,"mode":0,"inputs":[{"name":"source","type":"*","link":25}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"Candidate LTX negative prompt — diagnostic only","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#244d3b","bgcolor":"#356e55"},{"id":190,"type":"PreviewAny","pos":[1050.0,-330.0],"size":[540.0,140.0],"flags":{},"order":15,"mode":0,"inputs":[{"name":"source","type":"*","link":14}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"Grounding status","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#2a363b","bgcolor":"#3f5159"},{"id":191,"type":"PreviewAny","pos":[1050.0,-110.0],"size":[540.0,500.0],"flags":{},"order":16,"mode":0,"inputs":[{"name":"source","type":"*","link":15}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"Grounding report","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#2a363b","bgcolor":"#3f5159"},{"id":456,"type":"d9d4c7f2-3c3b-4c2a-9f8b-2a1e3d4c5b6a","pos":[2520.0,-560.0],"size":[720.0,760.0],"flags":{},"order":17,"mode":0,"inputs":[{"label":"first_frame","name":"input","type":"IMAGE,MASK","link":19},{"label":"prompt","name":"value","type":"STRING","widget":{"name":"value"},"link":18},{"label":"prompt_enhance","name":"value_1","type":"BOOLEAN","link":null},{"label":"duration","name":"value_2","type":"INT","widget":{"name":"value_2"},"link":20},{"label":"width","name":"value_3","type":"INT","widget":{"name":"value_3"},"link":26},{"label":"height","name":"value_4","type":"INT","widget":{"name":"value_4"},"link":27},{"name":"noise_seed","type":"INT","widget":{"name":"noise_seed"},"link":21},{"label":"frame_rate","name":"value_5","type":"INT","widget":{"name":"value_5"},"link":null},{"label":"negative_prompt","name":"negative_prompt","type":"STRING","link":24},{"label":"video_vae","name":"vae_name","type":"COMBO","widget":{"name":"vae_name"},"link":null},{"label":"audio_vae","name":"vae_name_1","type":"COMBO","widget":{"name":"vae_name_1"},"link":null},{"label":"upscale_model","name":"model_name","type":"COMBO","widget":{"name":"model_name"},"link":null},{"label":"prompt_enhance_model","name":"clip_name_1","type":"COMBO","link":null}],"outputs":[{"name":"VIDEO","type":"VIDEO","links":[22]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.0","previewExposures":[]},"widgets_values":["",5,992,544,347267244880135,24,"","ltx-2.5-22b-distilled-transformer-comfy-int8-convrot.safetensors","ltx-2.5-video-vae-bf16.safetensors","ltx-2.5-audio-vae-bf16.safetensors","gemma4-12b-with-proj-ltx-2.5-comfy-int8-convrot.safetensors","ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors"],"title":"9. Native two-stage LTX-2.5 I2V — prompt enhancer OFF"},{"id":483,"type":"easy cleanGpuUsed","pos":[3300.0,-300.0],"size":[230.0,65.0],"flags":{},"order":18,"mode":0,"inputs":[{"name":"anything","type":"*","link":22}],"outputs":[{"name":"output","type":"*","links":[23]}],"properties":{"cnr_id":"comfyui-easy-use","ver":"1.3.6","Node name for S&R":"easy cleanGpuUsed"},"widgets_values":[],"title":"Unload LTX models after render"},{"id":481,"type":"SaveVideo","pos":[3580.0,-560.0],"size":[1050.0,760.0],"flags":{},"order":19,"mode":0,"inputs":[{"name":"video","type":"VIDEO","link":23}],"outputs":[{"name":"video","type":"VIDEO","links":null}],"properties":{"cnr_id":"comfy-core","ver":"0.14.1","Node name for S&R":"SaveVideo","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["video/ltx2.5_diffusiongemma_i2v","auto","auto"],"title":"10. Save DiffusionGemma LTX-2.5 I2V"}],"links":[[1,177,0,183,0,"STRING"],[2,179,0,183,1,"IMAGE"],[3,182,0,186,0,"DG_MODEL_CONFIG"],[4,183,0,186,1,"DG_CONTEXT"],[5,510,0,186,2,"DG_TARGET_PROFILE_CONFIG"],[6,185,0,186,3,"DG_GROUNDING_GUARD_CONFIG"],[7,186,0,187,0,"STRING"],[8,183,0,187,1,"DG_CONTEXT"],[9,510,0,187,2,"DG_TARGET_PROFILE_CONFIG"],[10,187,0,188,0,"STRING"],[11,187,12,188,1,"BOOLEAN"],[12,187,4,188,2,"STRING"],[13,187,14,189,0,"STRING"],[14,186,4,190,0,"STRING"],[15,186,5,191,0,"STRING"],[16,178,0,510,0,"FLOAT"],[17,178,0,459,0,"FLOAT"],[18,188,0,456,1,"STRING"],[19,179,0,456,0,"IMAGE"],[20,459,0,456,3,"INT"],[21,418,0,456,6,"INT"],[22,456,0,483,0,"VIDEO"],[23,483,0,481,0,"VIDEO"],[24,187,2,456,8,"STRING"],[25,187,15,511,0,"STRING"],[26,187,10,456,4,"INT"],[27,187,11,456,5,"INT"]],"groups":[{"id":1,"title":"1. Inputs + first-frame anchor","bounding":[-1260.0,-660.0,700.0,1320.0],"color":"#3f789e","flags":{}},{"id":2,"title":"2. DiffusionGemma LTX-2.5 Director","bounding":[-570.0,-660.0,1580.0,1530.0],"color":"#6b5b95","flags":{}},{"id":3,"title":"3. Verified prompt handoff","bounding":[1020.0,-660.0,1460.0,1100.0],"color":"#4f7f65","flags":{}},{"id":4,"title":"4. Native LTX-2.5 Image-to-Video","bounding":[2490.0,-660.0,2180.0,1190.0],"color":"#a86f32","flags":{}}],"definitions":{"subgraphs":[{"id":"d9d4c7f2-3c3b-4c2a-9f8b-2a1e3d4c5b6a","version":1,"state":{"lastGroupId":28,"lastNodeId":509,"lastLinkId":897,"lastRerouteId":0},"revision":0,"config":{},"name":"Image to Video (LTX-2.5, DiffusionGemma prompts)","inputNode":{"id":-10,"bounding":[-640,6460,183.814453125,348]},"outputNode":{"id":-20,"bounding":[5540,6496,128,68]},"inputs":[{"id":"075be400-91e7-40a7-8f4e-d5c907af36e8","name":"input","type":"IMAGE,MASK","linkIds":[763],"label":"first_frame","pos":[-480.185546875,6484]},{"id":"5dab3f68-2044-46e7-b01f-4bf4b8bf4e79","name":"value","type":"STRING","linkIds":[765],"label":"prompt","pos":[-480.185546875,6504]},{"id":"21c9d37e-1f04-47f8-b752-22667180790c","name":"value_1","type":"BOOLEAN","linkIds":[],"label":"prompt_enhance","pos":[-480.185546875,6524]},{"id":"00f26a0c-569d-4aa1-aa8a-281ad2f3c4e0","name":"value_2","type":"INT","linkIds":[767],"label":"duration","pos":[-480.185546875,6544]},{"id":"5d05d885-6c96-43dd-9cdb-f1d0c48045b5","name":"value_3","type":"INT","linkIds":[768],"label":"width","pos":[-480.185546875,6564]},{"id":"c646ee59-a1e0-433e-b2f5-f1d8217fe526","name":"value_4","type":"INT","linkIds":[769],"label":"height","pos":[-480.185546875,6584]},{"id":"7072a79b-5168-42ee-9088-e3f92ac07791","name":"noise_seed","type":"INT","linkIds":[770],"pos":[-480.185546875,6604]},{"id":"85a2fb6d-1b63-40a7-adb6-5acc97a7cc99","name":"value_5","type":"INT","linkIds":[776],"label":"frame_rate","pos":[-480.185546875,6624]},{"id":"8e0b9cf6-f939-4a31-983d-8a76d52dd2d9","name":"negative_prompt","type":"STRING","linkIds":[861],"label":"negative_prompt","pos":[-480.185546875,6644]},{"id":"cbb7ddb9-95d0-4e63-a473-f37c329fbcda","name":"unet_name","type":"COMBO","linkIds":[777],"pos":[-480.185546875,6664]},{"id":"dd0f8943-da6e-4182-8265-efb74da42c33","name":"vae_name","type":"COMBO","linkIds":[778],"label":"video_vae","pos":[-480.185546875,6684]},{"id":"69b9a13b-ee5a-4525-abd9-281d4c257277","name":"vae_name_1","type":"COMBO","linkIds":[779],"label":"audio_vae","pos":[-480.185546875,6704]},{"id":"de6a02d4-1e94-43e7-bf67-2e06f8688943","name":"clip_name","type":"COMBO","linkIds":[780],"pos":[-480.185546875,6724]},{"id":"83db7bd8-4276-4950-8d15-ee1803e29646","name":"model_name","type":"COMBO","linkIds":[781],"label":"upscale_model","pos":[-480.185546875,6744]},{"id":"e5ca018e-1483-44ba-a318-3fc83c7f19ba","name":"clip_name_1","type":"COMBO","linkIds":[],"label":"prompt_enhance_model","pos":[-480.185546875,6764.0]}],"outputs":[{"id":"b92869b1-7119-47c1-8a9c-c52c131eb1f1","name":"VIDEO","type":"VIDEO","linkIds":[714],"localized_name":"VIDEO","pos":[5564,6520]}],"widgets":[],"nodes":[{"id":419,"type":"CLIPTextEncode","pos":[1160,6040],"size":[550,738.96875],"flags":{},"order":11,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":732},{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":813}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","links":[696]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"CLIPTextEncode","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[""],"color":"#232","bgcolor":"#353"},{"id":420,"type":"PrimitiveStringMultiline","pos":[150,6080],"size":[368.96875,348.96875],"flags":{},"order":12,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"STRING","widget":{"name":"value"},"link":765}],"outputs":[{"localized_name":"STRING","name":"STRING","type":"STRING","links":[813]}],"title":"Prompt","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveStringMultiline","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["Egyptian royal in blue-and-gold headdress and high collar, white dress with golden embroidery and armbands, desert, robot soldiers in formation left and right. She walks steadily forward, head held level and gaze fixed ahead—no dipping or lowering of the head. The camera performs a single, smooth push-in only: starting in a wider shot of her, the robots, and the desert, it moves steadily forward until she is in a medium or medium-close frame, then holds. She stops, posture and head still upright, and says: “The old gods are silent. I am not.” Robot soldiers shift or march in place; sand and fabric move with the wind. No pull-back; the only camera move is the continuous push-in."]},{"id":421,"type":"UNETLoader","pos":[650,6200],"size":[418.96875,129.375],"flags":{},"order":13,"mode":0,"inputs":[{"localized_name":"unet_name","name":"unet_name","type":"COMBO","widget":{"name":"unet_name"},"link":777}],"outputs":[{"localized_name":"MODEL","name":"MODEL","type":"MODEL","links":[771,772,888]}],"properties":{"cnr_id":"comfy-core","ver":"0.29.0","Node name for S&R":"UNETLoader","models":[{"name":"ltx-2.5-22b-distilled-transformer-comfy-int8-convrot.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/diffusion_models/ltx-2.5-22b-distilled-transformer-comfy-int8-convrot.safetensors","directory":"diffusion_models"}]},"widgets_values":["ltx-2.5-22b-distilled-transformer-comfy-int8-convrot.safetensors","default"]},{"id":422,"type":"PrimitiveInt","pos":[150,6630],"size":[368.96875,108.96875],"flags":{},"order":14,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"INT","widget":{"name":"value"},"link":767}],"outputs":[{"localized_name":"INT","name":"INT","type":"INT","links":[715]}],"title":"Duration","properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"PrimitiveInt","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[5,"fixed"]},{"id":363,"type":"PrimitiveBoolean","pos":[160,6480],"size":[368.96875,98.96875],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[{"localized_name":"BOOLEAN","name":"BOOLEAN","type":"BOOLEAN","links":[683,693]}],"title":"Switch to Text to Video?","properties":{"cnr_id":"comfy-core","ver":"0.16.0","Node name for S&R":"PrimitiveBoolean","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[false]},{"id":423,"type":"LTXVConditioning","pos":[1810,6480],"size":[278.96875,129.375],"flags":{},"order":15,"mode":0,"inputs":[{"localized_name":"positive","name":"positive","type":"CONDITIONING","link":696},{"localized_name":"negative","name":"negative","type":"CONDITIONING","link":697},{"localized_name":"frame_rate","name":"frame_rate","type":"FLOAT","widget":{"name":"frame_rate"},"link":698}],"outputs":[{"localized_name":"positive","name":"positive","type":"CONDITIONING","links":[735,755]},{"localized_name":"negative","name":"negative","type":"CONDITIONING","links":[736,756]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"LTXVConditioning","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[24]},{"id":424,"type":"VAELoader","pos":[650,6398.844815215871],"size":[409.375,70],"flags":{},"order":16,"mode":0,"inputs":[{"localized_name":"vae_name","name":"vae_name","type":"COMBO","widget":{"name":"vae_name"},"link":778}],"outputs":[{"localized_name":"VAE","name":"VAE","type":"VAE","links":[727,773,774,775]}],"properties":{"cnr_id":"comfy-core","ver":"0.29.0","Node name for S&R":"VAELoader","models":[{"name":"ltx-2.5-video-vae-bf16.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/vae/ltx-2.5-video-vae-bf16.safetensors","directory":"vae"}]},"widgets_values":["ltx-2.5-video-vae-bf16.safetensors"]},{"id":425,"type":"VAELoader","pos":[650,6560],"size":[400,88.96875],"flags":{},"order":17,"mode":0,"inputs":[{"localized_name":"vae_name","name":"vae_name","type":"COMBO","widget":{"name":"vae_name"},"link":779}],"outputs":[{"localized_name":"VAE","name":"VAE","type":"VAE","links":[729,730]}],"properties":{"cnr_id":"comfy-core","ver":"0.29.0","Node name for S&R":"VAELoader","models":[{"name":"ltx-2.5-audio-vae-bf16.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/vae/ltx-2.5-audio-vae-bf16.safetensors","directory":"vae"}]},"widgets_values":["ltx-2.5-audio-vae-bf16.safetensors"]},{"id":426,"type":"PrimitiveInt","pos":[150,6780],"size":[368.96875,108.96875],"flags":{},"order":18,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"INT","widget":{"name":"value"},"link":768}],"outputs":[{"localized_name":"INT","name":"INT","type":"INT","links":[687]}],"title":"Width","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveInt","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[1280,"fixed"]},{"id":427,"type":"CLIPTextEncode","pos":[1170,6880],"size":[528.96875,238.96875],"flags":{},"order":19,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":731},{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":897}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","links":[697]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"CLIPTextEncode","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[""],"color":"#323","bgcolor":"#535","title":"Negative prompt — from DiffusionGemma"},{"id":428,"type":"CLIPLoader","pos":[650,6730],"size":[400,141.921875],"flags":{},"order":20,"mode":0,"showAdvanced":true,"inputs":[{"localized_name":"clip_name","name":"clip_name","type":"COMBO","widget":{"name":"clip_name"},"link":780}],"outputs":[{"localized_name":"CLIP","name":"CLIP","type":"CLIP","links":[731,732]}],"properties":{"cnr_id":"comfy-core","ver":"0.29.0","Node name for S&R":"CLIPLoader","models":[{"name":"gemma4-12b-with-proj-ltx-2.5-comfy-int8-convrot.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/text_encoders/gemma4-12b-with-proj-ltx-2.5-comfy-int8-convrot.safetensors","directory":"text_encoders"}]},"widgets_values":["gemma4-12b-with-proj-ltx-2.5-comfy-int8-convrot.safetensors","ltxv","default"]},{"id":429,"type":"PrimitiveInt","pos":[150,6930],"size":[368.96875,108.96875],"flags":{},"order":21,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"INT","widget":{"name":"value"},"link":769}],"outputs":[{"localized_name":"INT","name":"INT","type":"INT","links":[688]}],"title":"Height","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveInt","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[720,"fixed"]},{"id":430,"type":"KSamplerSelect","pos":[2224.3008005573674,6709.40359723377],"size":[278.96875,108.96875],"flags":{},"order":1,"mode":0,"inputs":[],"outputs":[{"localized_name":"SAMPLER","name":"SAMPLER","type":"SAMPLER","links":[671]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"KSamplerSelect","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["euler_ancestral"]},{"id":431,"type":"RandomNoise","pos":[2190,6300],"size":[278.96875,108.96875],"flags":{},"order":22,"mode":0,"inputs":[{"localized_name":"noise_seed","name":"noise_seed","type":"INT","widget":{"name":"noise_seed"},"link":770}],"outputs":[{"localized_name":"NOISE","name":"NOISE","type":"NOISE","links":[670]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"RandomNoise","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[900359092894726,"randomize"]},{"id":397,"type":"ManualSigmas","pos":[2195.0564044977027,6895.64484593597],"size":[500,98.96875],"flags":{},"order":2,"mode":0,"inputs":[],"outputs":[{"localized_name":"SIGMAS","name":"SIGMAS","type":"SIGMAS","links":[896]}],"properties":{"cnr_id":"comfy-core","ver":"0.14.1","Node name for S&R":"ManualSigmas"},"widgets_values":["1.0, 0.99375, 0.9875, 0.98125, 0.975, 0.909375, 0.725, 0.421875, 0.0"]},{"id":432,"type":"PrimitiveInt","pos":[150,7080],"size":[368.96875,108.96875],"flags":{},"order":23,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"INT","widget":{"name":"value"},"link":776}],"outputs":[{"localized_name":"INT","name":"INT","type":"INT","links":[695,716]}],"title":"Frame Rate","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveInt","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[24,"fixed"]},{"id":433,"type":"LatentUpscaleModelLoader","pos":[640.6800332933674,6971.0077671585605],"size":[409.375,138.96875],"flags":{},"order":24,"mode":0,"inputs":[{"localized_name":"model_name","name":"model_name","type":"COMBO","widget":{"name":"model_name"},"link":781}],"outputs":[{"localized_name":"LATENT_UPSCALE_MODEL","name":"LATENT_UPSCALE_MODEL","type":"LATENT_UPSCALE_MODEL","links":[678]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LatentUpscaleModelLoader","models":[{"name":"ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/latent_upscale_models/ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors","directory":"latent_upscale_models"}],"enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors"]},{"id":434,"type":"LTXVDualCFGGuider","pos":[2215.9956793671613,6502.287759672367],"size":[269.046875,159.046875],"flags":{},"order":25,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":771},{"localized_name":"positive","name":"positive","type":"CONDITIONING","link":735},{"localized_name":"negative","name":"negative","type":"CONDITIONING","link":736}],"outputs":[{"localized_name":"GUIDER","name":"GUIDER","type":"GUIDER","links":[733]}],"properties":{"Node name for S&R":"LTXVDualCFGGuider","cnr_id":"comfy-core","ver":"0.28.0","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[0.5,1]},{"id":435,"type":"SamplerCustomAdvanced","pos":[2610,6510],"size":[228.96875,170],"flags":{},"order":26,"mode":0,"inputs":[{"localized_name":"noise","name":"noise","type":"NOISE","link":670},{"localized_name":"guider","name":"guider","type":"GUIDER","link":733},{"localized_name":"sampler","name":"sampler","type":"SAMPLER","link":671},{"localized_name":"sigmas","name":"sigmas","type":"SIGMAS","link":896},{"localized_name":"latent_image","name":"latent_image","type":"LATENT","link":672}],"outputs":[{"localized_name":"output","name":"output","type":"LATENT","links":[702]},{"localized_name":"denoised_output","name":"denoised_output","type":"LATENT","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.60","Node name for S&R":"SamplerCustomAdvanced","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":357,"type":"LTXVImgToVideoInplace","pos":[2070,7390],"size":[278.96875,179.375],"flags":{},"order":10,"mode":0,"inputs":[{"localized_name":"vae","name":"vae","type":"VAE","link":727},{"localized_name":"image","name":"image","type":"IMAGE","link":691},{"localized_name":"latent","name":"latent","type":"LATENT","link":692},{"localized_name":"bypass","name":"bypass","type":"BOOLEAN","widget":{"name":"bypass"},"link":693}],"outputs":[{"localized_name":"latent","name":"latent","type":"LATENT","links":[699]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVImgToVideoInplace","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[0.7,false]},{"id":436,"type":"LTXVEmptyLatentAudio","pos":[1620,7370],"size":[278.96875,170],"flags":{},"order":27,"mode":0,"inputs":[{"localized_name":"audio_vae","name":"audio_vae","type":"VAE","link":729},{"localized_name":"frames_number","name":"frames_number","type":"INT","widget":{"name":"frames_number"},"link":717},{"localized_name":"frame_rate","name":"frame_rate","type":"FLOAT,INT","widget":{"name":"frame_rate"},"link":701}],"outputs":[{"localized_name":"Latent","name":"Latent","type":"LATENT","links":[700]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.68","Node name for S&R":"LTXVEmptyLatentAudio","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[97,25,1]},{"id":437,"type":"LTXVSeparateAVLatent","pos":[2890,6520],"size":[250,98.96875],"flags":{},"order":28,"mode":0,"inputs":[{"localized_name":"av_latent","name":"av_latent","type":"LATENT","link":702}],"outputs":[{"localized_name":"video_latent","name":"video_latent","type":"LATENT","links":[677]},{"localized_name":"audio_latent","name":"audio_latent","type":"LATENT","links":[666]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"LTXVSeparateAVLatent","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":438,"type":"LTXVConcatAVLatent","pos":[2470,7390],"size":[238.96875,98.96875],"flags":{},"order":29,"mode":0,"inputs":[{"localized_name":"video_latent","name":"video_latent","type":"LATENT","link":699},{"localized_name":"audio_latent","name":"audio_latent","type":"LATENT","link":700}],"outputs":[{"localized_name":"latent","name":"latent","type":"LATENT","links":[672]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVConcatAVLatent","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":351,"type":"ResizeImageMaskNode","pos":[190,7480],"size":[300,117.921875],"flags":{},"order":9,"mode":0,"inputs":[{"localized_name":"input","name":"input","type":"IMAGE,MASK","link":763}],"outputs":[{"localized_name":"resized","name":"resized","type":"IMAGE,MASK","links":[752]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"ResizeImageMaskNode","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["scale longer dimension",1536,"lanczos"]},{"id":439,"type":"ComfyMathExpression","pos":[1170,7470],"size":[225,0],"flags":{"collapsed":true},"order":30,"mode":0,"inputs":[{"label":"a","localized_name":"values.a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":687},{"label":"b","localized_name":"values.b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"localized_name":"FLOAT","name":"FLOAT","type":"FLOAT","links":[]},{"localized_name":"INT","name":"INT","type":"INT","links":[689]},{"localized_name":"BOOL","name":"BOOL","type":"BOOLEAN","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"ComfyMathExpression","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["a/2"]},{"id":440,"type":"ComfyMathExpression","pos":[1170,7530],"size":[225,0],"flags":{"collapsed":true},"order":31,"mode":0,"inputs":[{"label":"a","localized_name":"values.a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":688},{"label":"b","localized_name":"values.b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"localized_name":"FLOAT","name":"FLOAT","type":"FLOAT","links":[]},{"localized_name":"INT","name":"INT","type":"INT","links":[690]},{"localized_name":"BOOL","name":"BOOL","type":"BOOLEAN","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"ComfyMathExpression","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["a/2"]},{"id":350,"type":"LTXVPreprocess","pos":[620,7480],"size":[288.96875,108.96875],"flags":{},"order":8,"mode":0,"inputs":[{"localized_name":"image","name":"image","type":"IMAGE","link":752}],"outputs":[{"localized_name":"output_image","name":"output_image","type":"IMAGE","links":[681,691]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVPreprocess","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[18]},{"id":441,"type":"EmptyLTXVLatentVideo","pos":[1630,7600],"size":[278.96875,198.96875],"flags":{},"order":32,"mode":0,"inputs":[{"localized_name":"width","name":"width","type":"INT","widget":{"name":"width"},"link":689},{"localized_name":"height","name":"height","type":"INT","widget":{"name":"height"},"link":690},{"localized_name":"length","name":"length","type":"INT","widget":{"name":"length"},"link":718}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","links":[692]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.60","Node name for S&R":"EmptyLTXVLatentVideo","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[768,512,97,1]},{"id":442,"type":"LTXVLatentUpsampler","pos":[3260,6410],"size":[328.96875,120],"flags":{},"order":33,"mode":0,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":677},{"localized_name":"upscale_model","name":"upscale_model","type":"LATENT_UPSCALE_MODEL","link":678},{"localized_name":"vae","name":"vae","type":"VAE","link":773}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","links":[682]}],"properties":{"cnr_id":"comfy-core","ver":"0.14.1","Node name for S&R":"LTXVLatentUpsampler","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":349,"type":"LTXVImgToVideoInplace","pos":[3270,6620],"size":[300,179.375],"flags":{},"order":7,"mode":0,"inputs":[{"localized_name":"vae","name":"vae","type":"VAE","link":774},{"localized_name":"image","name":"image","type":"IMAGE","link":681},{"localized_name":"latent","name":"latent","type":"LATENT","link":682},{"localized_name":"bypass","name":"bypass","type":"BOOLEAN","widget":{"name":"bypass"},"link":683}],"outputs":[{"localized_name":"latent","name":"latent","type":"LATENT","links":[665]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVImgToVideoInplace","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[1,false]},{"id":443,"type":"ComfyMathExpression","pos":[1170,7670],"size":[225,0],"flags":{"collapsed":true},"order":34,"mode":0,"inputs":[{"label":"a","localized_name":"values.a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":695},{"label":"b","localized_name":"values.b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"localized_name":"FLOAT","name":"FLOAT","type":"FLOAT","links":[698,713]},{"localized_name":"INT","name":"INT","type":"INT","links":[701]},{"localized_name":"BOOL","name":"BOOL","type":"BOOLEAN","links":[]}],"title":"Math Expression (fps)","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"ComfyMathExpression","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["a"]},{"id":444,"type":"ComfyMathExpression","pos":[1180,7770],"size":[225,0],"flags":{"collapsed":true},"order":35,"mode":0,"inputs":[{"label":"a","localized_name":"values.a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":715},{"label":"b","localized_name":"values.b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":716},{"label":"c","localized_name":"values.c","name":"values.c","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"localized_name":"FLOAT","name":"FLOAT","type":"FLOAT","links":[]},{"localized_name":"INT","name":"INT","type":"INT","links":[717,718]},{"localized_name":"BOOL","name":"BOOL","type":"BOOLEAN","links":[]}],"title":"Math Expression (length)","properties":{"cnr_id":"comfy-core","ver":"0.18.1","Node name for S&R":"ComfyMathExpression","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.7"}},"widgets_values":["a * b + 1"]},{"id":445,"type":"RandomNoise","pos":[3710,6150],"size":[278.96875,108.96875],"flags":{},"order":3,"mode":0,"inputs":[],"outputs":[{"localized_name":"NOISE","name":"NOISE","type":"NOISE","links":[703]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.75","Node name for S&R":"RandomNoise","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[42,"fixed"]},{"id":446,"type":"LTXVConcatAVLatent","pos":[3710,6760],"size":[278.96875,98.96875],"flags":{},"order":36,"mode":0,"inputs":[{"localized_name":"video_latent","name":"video_latent","type":"LATENT","link":665},{"localized_name":"audio_latent","name":"audio_latent","type":"LATENT","link":666}],"outputs":[{"localized_name":"latent","name":"latent","type":"LATENT","links":[707]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"LTXVConcatAVLatent","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":396,"type":"ManualSigmas","pos":[3710,6980],"size":[288.96875,108.96875],"flags":{},"order":4,"mode":0,"inputs":[],"outputs":[{"localized_name":"SIGMAS","name":"SIGMAS","type":"SIGMAS","links":[751]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"ManualSigmas","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["0.85, 0.7250, 0.4219, 0.0"]},{"id":447,"type":"LTXVDualCFGGuider","pos":[3711.811554084113,6320.869184637932],"size":[269.046875,159.046875],"flags":{},"order":37,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":772},{"localized_name":"positive","name":"positive","type":"CONDITIONING","link":755},{"localized_name":"negative","name":"negative","type":"CONDITIONING","link":756}],"outputs":[{"localized_name":"GUIDER","name":"GUIDER","type":"GUIDER","links":[744]}],"properties":{"Node name for S&R":"LTXVDualCFGGuider","cnr_id":"comfy-core","ver":"0.28.0","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[1,1]},{"id":448,"type":"KSamplerSelect","pos":[3710,6560],"size":[278.96875,108.96875],"flags":{},"order":5,"mode":0,"inputs":[],"outputs":[{"localized_name":"SAMPLER","name":"SAMPLER","type":"SAMPLER","links":[705]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.75","Node name for S&R":"KSamplerSelect","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["res_2s"]},{"id":449,"type":"SamplerCustomAdvanced","pos":[4070,6500],"size":[228.96875,170],"flags":{},"order":38,"mode":0,"inputs":[{"localized_name":"noise","name":"noise","type":"NOISE","link":703},{"localized_name":"guider","name":"guider","type":"GUIDER","link":744},{"localized_name":"sampler","name":"sampler","type":"SAMPLER","link":705},{"localized_name":"sigmas","name":"sigmas","type":"SIGMAS","link":751},{"localized_name":"latent_image","name":"latent_image","type":"LATENT","link":707}],"outputs":[{"localized_name":"output","name":"output","type":"LATENT","links":[708]},{"localized_name":"denoised_output","name":"denoised_output","type":"LATENT","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.75","Node name for S&R":"SamplerCustomAdvanced","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":450,"type":"LTXVSeparateAVLatent","pos":[4370,6500],"size":[228.96875,98.96875],"flags":{},"order":39,"mode":0,"inputs":[{"localized_name":"av_latent","name":"av_latent","type":"LATENT","link":708}],"outputs":[{"localized_name":"video_latent","name":"video_latent","type":"LATENT","links":[709]},{"localized_name":"audio_latent","name":"audio_latent","type":"LATENT","links":[694]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"LTXVSeparateAVLatent","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":451,"type":"VAEDecodeTiled","pos":[4760,6360],"size":[278.96875,198.96875],"flags":{},"order":40,"mode":0,"showAdvanced":true,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":709},{"localized_name":"vae","name":"vae","type":"VAE","link":775}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[711]}],"properties":{"cnr_id":"comfy-core","ver":"0.14.1","Node name for S&R":"VAEDecodeTiled","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[512,64,64,16]},{"id":452,"type":"LTXVAudioVAEDecode","pos":[4760,6650],"size":[268.96875,98.96875],"flags":{},"order":41,"mode":0,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":694},{"label":"Audio VAE","localized_name":"audio_vae","name":"audio_vae","type":"VAE","link":730}],"outputs":[{"localized_name":"Audio","name":"Audio","type":"AUDIO","links":[712]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVAudioVAEDecode","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":453,"type":"CreateVideo","pos":[5200,6460],"size":[278.96875,129.375],"flags":{},"order":42,"mode":0,"inputs":[{"localized_name":"images","name":"images","type":"IMAGE","link":711},{"localized_name":"audio","name":"audio","shape":7,"type":"AUDIO","link":712},{"localized_name":"fps","name":"fps","type":"FLOAT","widget":{"name":"fps"},"link":713}],"outputs":[{"localized_name":"VIDEO","name":"VIDEO","type":"VIDEO","links":[714]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"CreateVideo","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[24,8]},{"id":508,"type":"BasicScheduler","pos":[1836.2732329122807,6878.830222687924],"size":[268.75,117.921875],"flags":{},"order":6,"mode":4,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":888}],"outputs":[{"localized_name":"SIGMAS","name":"SIGMAS","type":"SIGMAS","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"BasicScheduler"},"widgets_values":["linear_quadratic",25,1]},{"id":509,"type":"PrimitiveStringMultiline","pos":[150,6740],"size":[368.96875,198.96875],"flags":{},"order":43,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"STRING","widget":{"name":"value"},"link":861}],"outputs":[{"localized_name":"STRING","name":"STRING","type":"STRING","links":[897]}],"title":"Negative Prompt","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveStringMultiline","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[""],"color":"#323","bgcolor":"#535"}],"groups":[{"id":1,"title":"Model","bounding":[620,5950,480,1270],"color":"#3f789e","flags":{}},{"id":3,"title":"Prompt","bounding":[1130,5950,980,1270],"color":"#3f789e","flags":{}},{"id":19,"title":"Video Settings","bounding":[100,5950,490,1270],"color":"#3f789e","flags":{}},{"id":2,"title":"Generate Low Resolution","bounding":[2140,5950,1020,1270],"color":"#3f789e","flags":{}},{"id":7,"title":"Latent Upscale","bounding":[3190,5950,460,1270],"color":"#3f789e","flags":{}},{"id":20,"title":"Image Preprocessing","bounding":[100,7250,1000,610],"color":"#3f789e","flags":{}},{"id":21,"title":"Empty Latent","bounding":[1480,7250,1680,610],"color":"#3f789e","flags":{}},{"id":22,"title":"Number conversion","bounding":[1130,7250,320,610],"color":"#3f789e","flags":{}},{"id":6,"title":"Generate High Resolution","bounding":[3680,5950,960,1270],"color":"#3f789e","flags":{}}],"links":[{"id":732,"origin_id":428,"origin_slot":0,"target_id":419,"target_slot":0,"type":"CLIP"},{"id":696,"origin_id":419,"origin_slot":0,"target_id":423,"target_slot":0,"type":"CONDITIONING"},{"id":697,"origin_id":427,"origin_slot":0,"target_id":423,"target_slot":1,"type":"CONDITIONING"},{"id":698,"origin_id":443,"origin_slot":0,"target_id":423,"target_slot":2,"type":"FLOAT"},{"id":731,"origin_id":428,"origin_slot":0,"target_id":427,"target_slot":0,"type":"CLIP"},{"id":735,"origin_id":423,"origin_slot":0,"target_id":434,"target_slot":1,"type":"CONDITIONING"},{"id":736,"origin_id":423,"origin_slot":1,"target_id":434,"target_slot":2,"type":"CONDITIONING"},{"id":670,"origin_id":431,"origin_slot":0,"target_id":435,"target_slot":0,"type":"NOISE"},{"id":733,"origin_id":434,"origin_slot":0,"target_id":435,"target_slot":1,"type":"GUIDER"},{"id":671,"origin_id":430,"origin_slot":0,"target_id":435,"target_slot":2,"type":"SAMPLER"},{"id":672,"origin_id":438,"origin_slot":0,"target_id":435,"target_slot":4,"type":"LATENT"},{"id":727,"origin_id":424,"origin_slot":0,"target_id":357,"target_slot":0,"type":"VAE"},{"id":691,"origin_id":350,"origin_slot":0,"target_id":357,"target_slot":1,"type":"IMAGE"},{"id":692,"origin_id":441,"origin_slot":0,"target_id":357,"target_slot":2,"type":"LATENT"},{"id":693,"origin_id":363,"origin_slot":0,"target_id":357,"target_slot":3,"type":"BOOLEAN"},{"id":729,"origin_id":425,"origin_slot":0,"target_id":436,"target_slot":0,"type":"VAE"},{"id":717,"origin_id":444,"origin_slot":1,"target_id":436,"target_slot":1,"type":"INT"},{"id":701,"origin_id":443,"origin_slot":1,"target_id":436,"target_slot":2,"type":"INT"},{"id":702,"origin_id":435,"origin_slot":0,"target_id":437,"target_slot":0,"type":"LATENT"},{"id":699,"origin_id":357,"origin_slot":0,"target_id":438,"target_slot":0,"type":"LATENT"},{"id":700,"origin_id":436,"origin_slot":0,"target_id":438,"target_slot":1,"type":"LATENT"},{"id":687,"origin_id":426,"origin_slot":0,"target_id":439,"target_slot":0,"type":"INT"},{"id":688,"origin_id":429,"origin_slot":0,"target_id":440,"target_slot":0,"type":"INT"},{"id":752,"origin_id":351,"origin_slot":0,"target_id":350,"target_slot":0,"type":"IMAGE"},{"id":689,"origin_id":439,"origin_slot":1,"target_id":441,"target_slot":0,"type":"INT"},{"id":690,"origin_id":440,"origin_slot":1,"target_id":441,"target_slot":1,"type":"INT"},{"id":718,"origin_id":444,"origin_slot":1,"target_id":441,"target_slot":2,"type":"INT"},{"id":677,"origin_id":437,"origin_slot":0,"target_id":442,"target_slot":0,"type":"LATENT"},{"id":678,"origin_id":433,"origin_slot":0,"target_id":442,"target_slot":1,"type":"LATENT_UPSCALE_MODEL"},{"id":681,"origin_id":350,"origin_slot":0,"target_id":349,"target_slot":1,"type":"IMAGE"},{"id":682,"origin_id":442,"origin_slot":0,"target_id":349,"target_slot":2,"type":"LATENT"},{"id":683,"origin_id":363,"origin_slot":0,"target_id":349,"target_slot":3,"type":"BOOLEAN"},{"id":695,"origin_id":432,"origin_slot":0,"target_id":443,"target_slot":0,"type":"INT"},{"id":715,"origin_id":422,"origin_slot":0,"target_id":444,"target_slot":0,"type":"INT"},{"id":716,"origin_id":432,"origin_slot":0,"target_id":444,"target_slot":1,"type":"INT"},{"id":665,"origin_id":349,"origin_slot":0,"target_id":446,"target_slot":0,"type":"LATENT"},{"id":666,"origin_id":437,"origin_slot":1,"target_id":446,"target_slot":1,"type":"LATENT"},{"id":755,"origin_id":423,"origin_slot":0,"target_id":447,"target_slot":1,"type":"CONDITIONING"},{"id":756,"origin_id":423,"origin_slot":1,"target_id":447,"target_slot":2,"type":"CONDITIONING"},{"id":703,"origin_id":445,"origin_slot":0,"target_id":449,"target_slot":0,"type":"NOISE"},{"id":744,"origin_id":447,"origin_slot":0,"target_id":449,"target_slot":1,"type":"GUIDER"},{"id":705,"origin_id":448,"origin_slot":0,"target_id":449,"target_slot":2,"type":"SAMPLER"},{"id":751,"origin_id":396,"origin_slot":0,"target_id":449,"target_slot":3,"type":"SIGMAS"},{"id":707,"origin_id":446,"origin_slot":0,"target_id":449,"target_slot":4,"type":"LATENT"},{"id":708,"origin_id":449,"origin_slot":0,"target_id":450,"target_slot":0,"type":"LATENT"},{"id":709,"origin_id":450,"origin_slot":0,"target_id":451,"target_slot":0,"type":"LATENT"},{"id":694,"origin_id":450,"origin_slot":1,"target_id":452,"target_slot":0,"type":"LATENT"},{"id":730,"origin_id":425,"origin_slot":0,"target_id":452,"target_slot":1,"type":"VAE"},{"id":711,"origin_id":451,"origin_slot":0,"target_id":453,"target_slot":0,"type":"IMAGE"},{"id":712,"origin_id":452,"origin_slot":0,"target_id":453,"target_slot":1,"type":"AUDIO"},{"id":713,"origin_id":443,"origin_slot":0,"target_id":453,"target_slot":2,"type":"FLOAT"},{"id":714,"origin_id":453,"origin_slot":0,"target_id":-20,"target_slot":0,"type":"VIDEO"},{"id":763,"origin_id":-10,"origin_slot":0,"target_id":351,"target_slot":0,"type":"IMAGE,MASK"},{"id":765,"origin_id":-10,"origin_slot":1,"target_id":420,"target_slot":0,"type":"STRING"},{"id":767,"origin_id":-10,"origin_slot":3,"target_id":422,"target_slot":0,"type":"INT"},{"id":768,"origin_id":-10,"origin_slot":4,"target_id":426,"target_slot":0,"type":"INT"},{"id":769,"origin_id":-10,"origin_slot":5,"target_id":429,"target_slot":0,"type":"INT"},{"id":770,"origin_id":-10,"origin_slot":6,"target_id":431,"target_slot":0,"type":"INT"},{"id":771,"origin_id":421,"origin_slot":0,"target_id":434,"target_slot":0,"type":"MODEL"},{"id":772,"origin_id":421,"origin_slot":0,"target_id":447,"target_slot":0,"type":"MODEL"},{"id":773,"origin_id":424,"origin_slot":0,"target_id":442,"target_slot":2,"type":"VAE"},{"id":774,"origin_id":424,"origin_slot":0,"target_id":349,"target_slot":0,"type":"VAE"},{"id":775,"origin_id":424,"origin_slot":0,"target_id":451,"target_slot":1,"type":"VAE"},{"id":776,"origin_id":-10,"origin_slot":7,"target_id":432,"target_slot":0,"type":"INT"},{"id":777,"origin_id":-10,"origin_slot":9,"target_id":421,"target_slot":0,"type":"COMBO"},{"id":778,"origin_id":-10,"origin_slot":10,"target_id":424,"target_slot":0,"type":"COMBO"},{"id":779,"origin_id":-10,"origin_slot":11,"target_id":425,"target_slot":0,"type":"COMBO"},{"id":780,"origin_id":-10,"origin_slot":12,"target_id":428,"target_slot":0,"type":"COMBO"},{"id":781,"origin_id":-10,"origin_slot":13,"target_id":433,"target_slot":0,"type":"COMBO"},{"id":813,"origin_id":420,"origin_slot":0,"target_id":419,"target_slot":1,"type":"STRING"},{"id":888,"origin_id":421,"origin_slot":0,"target_id":508,"target_slot":0,"type":"MODEL"},{"id":896,"origin_id":397,"origin_slot":0,"target_id":435,"target_slot":3,"type":"SIGMAS"},{"id":861,"origin_id":-10,"origin_slot":8,"target_id":509,"target_slot":0,"type":"STRING"},{"id":897,"origin_id":509,"origin_slot":0,"target_id":427,"target_slot":1,"type":"STRING"}],"extra":{},"description":"Native two-stage LTX-2.5 I2V with external DiffusionGemma positive and negative prompts; built-in prompt enhancement remains off."}]},"config":{},"extra":{"frontendVersion":"1.47.12","VHS_latentpreview":false,"VHS_latentpreviewrate":0,"VHS_MetadataImage":true,"VHS_KeepIntermediate":true,"workflow_note":"Clean DiffusionGemma LTX-2.5 Image-to-Video baseline. Context Hub first frame and native LTX first frame share one LoadImage; no H3 Ref2VA nodes.","ds":{"scale":0.28,"offset":[400.0,420.0]},"seed_widgets":{"185":3,"418":0,"456":4}},"version":0.4} diff --git a/examples/14_ltx25_i2v_vs_minimax_h3_ref2va_comparison.json b/examples/14_ltx25_i2v_vs_minimax_h3_ref2va_comparison.json index 0892848..e2b387d 100644 --- a/examples/14_ltx25_i2v_vs_minimax_h3_ref2va_comparison.json +++ b/examples/14_ltx25_i2v_vs_minimax_h3_ref2va_comparison.json @@ -1 +1 @@ -{"id":"8e24c8f7-c092-4e1d-a78d-9f172b4a55c0","revision":0,"last_node_id":544,"last_link_id":911,"nodes":[{"id":116,"type":"MarkdownNote","pos":[-1845.1552810668936,-976.5838584899902],"size":[1267.65625,255.796875],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[],"title":"START HERE — LTX-2.5 I2V vs MiniMax-H3 Ref2VA comparison","properties":{},"widgets_values":["# DiffusionGemma comparison — LTX-2.5 I2V vs MiniMax-H3 Ref2VA\n\n1. Replace the **shared image** and edit the **shared creative brief**. The image feeds LTX as an exact first-frame anchor, while H3 receives it as ****, a full visual reference.\n2. Keep the two Director branches model-specific: the upper branch uses **LTX Context Hub + LTX target**; the lower branch uses **H3 Reference Context + H3 Ref2VA target**. Do not cross-wire these contexts.\n3. The same image is connected directly to both native model paths. H3 needs both the Director reference manifest and its native **ref_image_0** connection.\n4. Each splitter controls its own raster. This stable baseline uses LTX at **1.0 MP / 16:9** and H3 at **0.4 MP / 16:9**. The shared **10-second** duration maps H3 to **243 frames**, and H3 Sage Attention is set to **auto** for a compatible GPU-specific backend.\n5. The two Branch Generation Gates isolate validation failures: a blocked branch skips only its own native render, while the other branch can continue. A branch gate status means that model-specific packet passed generation validation; the separate Grounding status/report previews show the evidence audit result.\n6. Both Grounding Guards are set to **audit** so grounding diagnostics remain visible without canceling either comparison render. Use strict only for a later compliance run. The H3 Director uses a 2048-token output budget for its longer Ref2VA contract.\n7. H3 `expected_subject_count` is **1**. One connected `` means one reference asset, not one semantic Subject. The count requires exactly one tracked `` definition; ordinary props, environment, lighting, composition, style, actions, and effects remain folded into that hero/whole-scene Subject and its timeline.\n\nImportant: this is a practical visual comparison, not identical conditioning. LTX I2V preserves the supplied opening frame; MiniMax-H3 Ref2VA treats the image as a reference that may be recomposed.\n\nCandidate prompt previews are diagnostic only: they update even when validation blocks a render. Native LTX receives the positive prompt through its Branch Generation Gate and the negative prompt directly from the fail-closed Splitter output; never route a candidate socket directly to the generator. Refresh recomputes but does not randomize a fixed Director seed."],"color":"#222","bgcolor":"#000"},{"id":177,"type":"PrimitiveStringMultiline","pos":[-1310.6767027883088,-248.98693165686993],"size":[618.75,298.125],"flags":{},"order":1,"mode":0,"inputs":[],"outputs":[{"name":"STRING","type":"STRING","links":[1,872]}],"title":"1. Creative brief — describe motion from the supplied frame","properties":{"cnr_id":"comfy-core","ver":"0.24.0","Node name for S&R":"PrimitiveStringMultiline"},"widgets_values":["Create a ten-second continuous live-action shot grounded in the supplied first frame. Keep the officer as the only human and the only independently tracked semantic subject. Preserve his identity, uniform, roadside setting, daylight, and opening composition. Treat vehicles, road, buildings, and other background details as unnumbered scene elements; do not introduce another person, creature, or independently acting subject. He shifts his weight, looks toward the distance, and takes one measured step backward as the camera makes a slow eye-level dolly in; no cuts."],"color":"#232","bgcolor":"#353"},{"id":178,"type":"PrimitiveFloat","pos":[-1151.3738148451273,1346.8611402190197],"size":[338.453125,79.375],"flags":{},"order":2,"mode":0,"inputs":[],"outputs":[{"name":"FLOAT","type":"FLOAT","links":[16,17,873,902]}],"title":"2. Shared duration seconds — Director + LTX","properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"PrimitiveFloat"},"widgets_values":[10],"color":"#322","bgcolor":"#533"},{"id":179,"type":"LoadImage","pos":[-1310.2844629557683,163.21786143836945],"size":[618.75,698.125],"flags":{},"order":3,"mode":0,"inputs":[],"outputs":[{"name":"IMAGE","type":"IMAGE","links":[2,19,871,898]},{"name":"MASK","type":"MASK","links":null}],"title":"3. First-frame image — shared with Context Hub + LTX","properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"LoadImage"},"widgets_values":["ComfyUI_00001_.png","image"]},{"id":182,"type":"DiffusionGemmaModelLoader","pos":[-1242.4214641092578,956.6292192723117],"size":[500,309.828125],"flags":{},"order":4,"mode":0,"inputs":[],"outputs":[{"name":"model_config","type":"DG_MODEL_CONFIG","links":[3,904]},{"name":"runtime_status_json","type":"STRING","links":null}],"title":"4a. Load DiffusionGemma Director — unload before LTX","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaModelLoader"},"widgets_values":["C:\\ComfyUI\\app\\models\\LLM\\diffusiongemma-26B-A4B-it-NVFP4","transformers_inprocess","auto","modelopt_nvfp4",true,"unload_after_run","20.0 GB - safe practical",0.35]},{"id":183,"type":"DiffusionGemmaContextHub","pos":[-20,-560],"size":[500,520],"flags":{},"order":19,"mode":0,"inputs":[{"name":"user_prompt","type":"STRING","link":1},{"name":"image","shape":7,"type":"IMAGE","link":2},{"name":"video","shape":7,"type":"VIDEO","link":null},{"name":"last_frame_image","shape":7,"type":"IMAGE","link":null}],"outputs":[{"name":"gemma_context","type":"DG_CONTEXT","links":[4,8]},{"name":"context_json","type":"STRING","links":null},{"name":"context_preview","type":"STRING","links":null}],"title":"4. LTX first-frame Context Hub","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaContextHub"},"widgets_values":[1,60,60,"trim",false,"","video_recreation"]},{"id":510,"type":"DiffusionGemmaLTX25TargetProfile","pos":[-20,20],"size":[500,429.953125],"flags":{},"order":15,"mode":0,"inputs":[{"name":"target_duration_seconds","type":"FLOAT","widget":{"name":"target_duration_seconds"},"link":16}],"outputs":[{"name":"target_profile_config","type":"DG_TARGET_PROFILE_CONFIG","links":[5,9]},{"name":"target_profile_json","type":"STRING","links":null}],"title":"5. LTX-2.5 target profile — Auto resolves to I2V","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaLTX25TargetProfile"},"widgets_values":["Auto (recommended)",0,"Reality-show","auto_scene_audio","","custom","video game, CGI, cartoon, duplicate people, deformed face, warped hands, subtitles, captions, logos, watermarks"]},{"id":185,"type":"DiffusionGemmaGroundingGuardSettings","pos":[-556.3353380475719,-555.5900344848619],"size":[500,329.953125],"flags":{},"order":5,"mode":0,"showAdvanced":true,"inputs":[{"name":"external_evidence_json","shape":7,"type":"STRING","link":null}],"outputs":[{"name":"grounding_guard_config","type":"DG_GROUNDING_GUARD_CONFIG","links":[6]},{"name":"config_json","type":"STRING","links":null}],"title":"5b. LTX Grounding Guard — audit comparison baseline","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaGroundingGuardSettings"},"widgets_values":["audit",true,"checkpoint_defaults",7,"fixed",false,"diffusiongemma_grounding","auto"]},{"id":418,"type":"SeedNode","pos":[2520,270],"size":[339.953125,84.953125],"flags":{},"order":6,"mode":0,"inputs":[],"outputs":[{"name":"seed","type":"INT","links":[21]}],"title":"LTX seed","properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"SeedNode"},"widgets_values":[347267244880135,"fixed"]},{"id":459,"type":"CM_FloatToInt","pos":[2535.399883319805,428.2324258383219],"size":[273.609375,89.953125],"flags":{},"order":16,"mode":0,"inputs":[{"name":"a","type":"FLOAT","widget":{"name":"a"},"link":17}],"outputs":[{"name":"INT","type":"INT","links":[20]}],"title":"Shared duration → integer seconds","properties":{"cnr_id":"ComfyMath","ver":"c01177221c31b8e5fbc062778fc8254aeb541638","Node name for S&R":"CM_FloatToInt"},"widgets_values":[0]},{"id":186,"type":"DiffusionGemmaCoTGenerator","pos":[540,-560],"size":[450,339.953125],"flags":{},"order":23,"mode":0,"inputs":[{"name":"model_config","type":"DG_MODEL_CONFIG","link":3},{"name":"gemma_context","type":"DG_CONTEXT","link":4},{"name":"target_profile_config","type":"DG_TARGET_PROFILE_CONFIG","link":5},{"name":"grounding_guard_config","shape":7,"type":"DG_GROUNDING_GUARD_CONFIG","link":6}],"outputs":[{"name":"final_json","type":"STRING","links":[7]},{"name":"reasoning_text","type":"STRING","links":null},{"name":"raw_response","type":"STRING","links":null},{"name":"metadata_json","type":"STRING","links":null},{"name":"grounding_status","type":"STRING","links":[14]},{"name":"grounding_report_json","type":"STRING","links":[15]}],"title":"6. Build grounded LTX-2.5 prompt","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaCoTGenerator"},"widgets_values":[0.45,"faithful",0.2,"off",1024,"reuse"]},{"id":187,"type":"DiffusionGemmaJSONSplitter","pos":[540,-150],"size":[450,520],"flags":{},"order":26,"mode":0,"inputs":[{"name":"final_json","type":"STRING","link":7},{"name":"gemma_context","shape":7,"type":"DG_CONTEXT","link":8},{"name":"target_profile_config","shape":7,"type":"DG_TARGET_PROFILE_CONFIG","link":9}],"outputs":[{"name":"ltx_prompt","type":"STRING","links":[10]},{"name":"ideogram_prompt","type":"STRING","links":null},{"name":"negative_prompt","type":"STRING","links":[24]},{"name":"aspect_ratio","type":"STRING","links":null},{"name":"metadata_json","type":"STRING","links":[12]},{"name":"scene_segments_json","type":"STRING","links":null},{"name":"local_prompts","type":"STRING","links":null},{"name":"segment_lengths","type":"STRING","links":null},{"name":"is_valid","type":"BOOLEAN","links":null},{"name":"resolution_selector_preset","type":"STRING","links":null},{"name":"resolution_width","type":"INT","links":[26]},{"name":"resolution_height","type":"INT","links":[27]},{"name":"ready_for_generation","type":"BOOLEAN","links":[11]},{"name":"minimax_h3_prompt","type":"STRING","links":null},{"name":"candidate_ltx_prompt","type":"STRING","links":[911]},{"name":"candidate_negative_prompt","type":"STRING","links":[25]}],"title":"7. Route LTX prompts + select output resolution","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaJSONSplitter"},"widgets_values":["",1,32,"16:9 (Widescreen)"],"shape":2},{"id":188,"type":"DiffusionGemmaBranchGenerationGate","pos":[1050,-560],"size":[539.953125,154.953125],"flags":{},"order":32,"mode":0,"inputs":[{"name":"prompt","type":"STRING","link":10},{"name":"ready_for_generation","type":"BOOLEAN","link":11},{"name":"metadata_json","shape":7,"type":"STRING","link":12}],"outputs":[{"name":"prompt","type":"STRING","links":[18]},{"name":"status","type":"STRING","links":[13]},{"name":"ready","type":"BOOLEAN","links":null}],"title":"8. Isolated LTX-2.5 branch generation gate","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaBranchGenerationGate"},"widgets_values":[],"color":"#5b2222","bgcolor":"#8b3333"},{"id":189,"type":"PreviewAny","pos":[1650,-560],"size":[800,409.953125],"flags":{},"order":34,"mode":0,"inputs":[{"name":"source","type":"*","link":13}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"LTX-2.5 branch gate status","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#244d3b","bgcolor":"#356e55"},{"id":511,"type":"PreviewAny","pos":[1650,-90],"size":[800,220],"flags":{},"order":31,"mode":0,"inputs":[{"name":"source","type":"*","link":25}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"Candidate LTX negative prompt — diagnostic only","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#244d3b","bgcolor":"#356e55"},{"id":190,"type":"PreviewAny","pos":[1050,-330],"size":[539.953125,139.953125],"flags":{},"order":27,"mode":0,"inputs":[{"name":"source","type":"*","link":14}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"Grounding status","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#2a363b","bgcolor":"#3f5159"},{"id":191,"type":"PreviewAny","pos":[1050,-110],"size":[539.953125,499.953125],"flags":{},"order":28,"mode":0,"inputs":[{"name":"source","type":"*","link":15}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"Grounding report","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#2a363b","bgcolor":"#3f5159"},{"id":456,"type":"d9d4c7f2-3c3b-4c2a-9f8b-2a1e3d4c5b6a","pos":[2520,-560],"size":[719.953125,759.953125],"flags":{},"order":35,"mode":0,"inputs":[{"label":"first_frame","name":"input","type":"IMAGE,MASK","link":19},{"label":"prompt","name":"value","type":"STRING","widget":{"name":"value"},"link":18},{"label":"prompt_enhance","name":"value_1","type":"BOOLEAN","link":null},{"label":"duration","name":"value_2","type":"INT","widget":{"name":"value_2"},"link":20},{"label":"width","name":"value_3","type":"INT","widget":{"name":"value_3"},"link":26},{"label":"height","name":"value_4","type":"INT","widget":{"name":"value_4"},"link":27},{"name":"noise_seed","type":"INT","widget":{"name":"noise_seed"},"link":21},{"label":"frame_rate","name":"value_5","type":"INT","widget":{"name":"value_5"},"link":null},{"label":"video_vae","name":"vae_name","type":"COMBO","widget":{"name":"vae_name"},"link":null},{"label":"audio_vae","name":"vae_name_1","type":"COMBO","widget":{"name":"vae_name_1"},"link":null},{"label":"upscale_model","name":"model_name","type":"COMBO","widget":{"name":"model_name"},"link":null},{"label":"prompt_enhance_model","name":"clip_name_1","type":"COMBO","link":null},{"label":"negative_prompt","name":"negative_prompt","type":"STRING","link":24}],"outputs":[{"name":"VIDEO","type":"VIDEO","links":[22]}],"title":"9. Native two-stage LTX-2.5 I2V — prompt enhancer OFF","properties":{"cnr_id":"comfy-core","ver":"0.30.0","previewExposures":[]},"widgets_values":["",5,992,544,347267244880135,24,"ltx-2.5-22b-distilled-transformer-comfy-int8-convrot.safetensors","ltx-2.5-video-vae-bf16.safetensors","ltx-2.5-audio-vae-bf16.safetensors","gemma4-12b-with-proj-ltx-2.5-comfy-int8-convrot.safetensors","ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors"]},{"id":483,"type":"easy cleanGpuUsed","pos":[3300,-557.7640642438612],"size":[249.9375,64.953125],"flags":{},"order":37,"mode":0,"inputs":[{"name":"anything","type":"*","link":22}],"outputs":[{"name":"output","type":"*","links":[23]}],"title":"Unload LTX models after render","properties":{"cnr_id":"comfyui-easy-use","ver":"1.3.6","Node name for S&R":"easy cleanGpuUsed"},"widgets_values":[]},{"id":481,"type":"SaveVideo","pos":[3303.6025565011164,-410.9316471644813],"size":[1329.59375,910.265625],"flags":{},"order":39,"mode":0,"inputs":[{"name":"video","type":"VIDEO","link":23}],"outputs":[{"name":"video","type":"VIDEO","links":null}],"title":"10. Save DiffusionGemma LTX-2.5 I2V","properties":{"cnr_id":"comfy-core","ver":"0.14.1","Node name for S&R":"SaveVideo","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["video/ltx2.5_diffusiongemma_i2v","auto","auto"]},{"id":513,"type":"DiffusionGemmaH3ReferenceContext","pos":[-29.270162054729614,618.5876835010446],"size":[500,590],"flags":{},"order":20,"mode":0,"inputs":[{"name":"user_prompt","type":"STRING","link":872},{"name":"reference_images","shape":7,"type":"IMAGE","link":871},{"name":"reference_video","shape":7,"type":"VIDEO","link":null}],"outputs":[{"name":"gemma_context","type":"DG_CONTEXT","links":[863,867]},{"name":"context_json","type":"STRING","links":null},{"name":"context_preview","type":"STRING","links":null}],"title":"4. H3 ordered reference context — one shared image","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaH3ReferenceContext"},"widgets_values":[": [dg:identity,appearance,color,environment,lighting,composition] sole visual reference for visible subject and scene attributes.",1,60,60,"trim","","1 image - all visual attributes",1]},{"id":515,"type":"DiffusionGemmaGroundingGuardSettings","pos":[-556.2148941971532,622.8978035358848],"size":[500,329.4375],"flags":{},"order":7,"mode":0,"showAdvanced":true,"inputs":[{"name":"external_evidence_json","shape":7,"type":"STRING","link":null}],"outputs":[{"name":"grounding_guard_config","type":"DG_GROUNDING_GUARD_CONFIG","links":[865]},{"name":"config_json","type":"STRING","links":null}],"title":"5b. H3 Grounding Guard — audit comparison baseline","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaGroundingGuardSettings"},"widgets_values":["audit",true,"checkpoint_defaults",7,"fixed",false,"diffusiongemma_grounding","auto"]},{"id":516,"type":"DiffusionGemmaCoTGenerator","pos":[537.3151138519959,601.4657424243728],"size":[450,349.84375],"flags":{},"order":24,"mode":0,"inputs":[{"name":"model_config","type":"DG_MODEL_CONFIG","link":904},{"name":"gemma_context","type":"DG_CONTEXT","link":863},{"name":"target_profile_config","type":"DG_TARGET_PROFILE_CONFIG","link":870},{"name":"grounding_guard_config","shape":7,"type":"DG_GROUNDING_GUARD_CONFIG","link":865}],"outputs":[{"name":"final_json","type":"STRING","links":[866]},{"name":"reasoning_text","type":"STRING","links":null},{"name":"raw_response","type":"STRING","links":null},{"name":"metadata_json","type":"STRING","links":null},{"name":"grounding_status","type":"STRING","links":[]},{"name":"grounding_report_json","type":"STRING","links":[]}],"title":"6. Build grounded MiniMax-H3 Ref2VA prompt","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaCoTGenerator"},"widgets_values":[0.45,"faithful",0.2,"off",2048,"reuse"]},{"id":517,"type":"DiffusionGemmaJSONSplitter","pos":[530.7298379452703,1028.587683501045],"size":[450,520],"flags":{},"order":29,"mode":0,"inputs":[{"name":"final_json","type":"STRING","link":866},{"name":"gemma_context","shape":7,"type":"DG_CONTEXT","link":867},{"name":"target_profile_config","shape":7,"type":"DG_TARGET_PROFILE_CONFIG","link":869}],"outputs":[{"name":"ltx_prompt","type":"STRING","links":[]},{"name":"ideogram_prompt","type":"STRING","links":null},{"name":"negative_prompt","type":"STRING","links":[]},{"name":"aspect_ratio","type":"STRING","links":null},{"name":"metadata_json","type":"STRING","links":[908]},{"name":"scene_segments_json","type":"STRING","links":null},{"name":"local_prompts","type":"STRING","links":null},{"name":"segment_lengths","type":"STRING","links":null},{"name":"is_valid","type":"BOOLEAN","links":null},{"name":"resolution_selector_preset","type":"STRING","links":null},{"name":"resolution_width","type":"INT","links":[900]},{"name":"resolution_height","type":"INT","links":[901]},{"name":"ready_for_generation","type":"BOOLEAN","links":[907]},{"name":"minimax_h3_prompt","type":"STRING","links":[906]}],"title":"7. Route MiniMax-H3 prompt + select output resolution","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaJSONSplitter"},"widgets_values":["",0.4,32,"16:9 (Widescreen)"],"shape":2},{"id":518,"type":"DiffusionGemmaMiniMaxH3TargetProfile","pos":[-27.219616252359916,1189.9471823525093],"size":[502.25,505.796875],"flags":{"collapsed":false},"order":17,"mode":0,"inputs":[{"name":"target_duration_seconds","type":"FLOAT","widget":{"name":"target_duration_seconds"},"link":873}],"outputs":[{"name":"target_profile_config","type":"DG_TARGET_PROFILE_CONFIG","links":[869,870]},{"name":"target_profile_json","type":"STRING","links":null}],"properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaMiniMaxH3TargetProfile"},"widgets_values":["ref2va",0,"auto_scene_audio","","auto",12,"auto",2,"","empty",""],"title":"5. MiniMax-H3 Ref2VA target profile"},{"id":519,"type":"UNETLoader","pos":[1134.6112589095078,731.0985272955096],"size":[637.5,88.75],"flags":{},"order":8,"mode":0,"inputs":[],"outputs":[{"name":"MODEL","type":"MODEL","links":[905]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"UNETLoader","models":[{"name":"minimax_h3_ref2va_int8_convrot.safetensors","url":"https://huggingface.co/Comfy-Org/MiniMax-H3/resolve/main/diffusion_models/minimax_h3_ref2va_int8_convrot.safetensors","directory":"diffusion_models"}]},"widgets_values":["minimax_h3_ref2va_pruned_fp8_scaled.safetensors","default"]},{"id":520,"type":"CLIPLoader","pos":[1134.6112589095078,881.0985272955088],"size":[637.5,120],"flags":{},"order":9,"mode":0,"inputs":[],"outputs":[{"name":"CLIP","type":"CLIP","links":[875]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"CLIPLoader","models":[{"name":"qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors","url":"https://huggingface.co/Comfy-Org/MiniMax-H3/resolve/main/text_encoders/qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors","directory":"text_encoders"}]},"widgets_values":["qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors","minimax","default"]},{"id":521,"type":"ComfyMathExpression","pos":[1282.2131527489764,1956.3305770876827],"size":[225,0],"flags":{"collapsed":true},"order":18,"mode":0,"inputs":[{"label":"a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":902},{"label":"b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"name":"FLOAT","type":"FLOAT","links":null},{"name":"INT","type":"INT","links":[903]},{"name":"BOOL","type":"BOOLEAN","links":null}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"ComfyMathExpression"},"widgets_values":["max(5, round(a * 24)) + (5 - (max(5, round(a * 24)) % 17)) % 17"]},{"id":522,"type":"VAELoader","pos":[1134.6112589095078,1051.0985272955095],"size":[637.5,70],"flags":{},"order":10,"mode":0,"inputs":[],"outputs":[{"name":"VAE","type":"VAE","links":[876,887]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"VAELoader","models":[{"name":"minimax_h3_video_vae_fp16.safetensors","url":"https://huggingface.co/Comfy-Org/MiniMax-H3/resolve/main/vae/minimax_h3_video_vae_fp16.safetensors","directory":"vae"}]},"widgets_values":["minimax_h3_video_vae_fp16.safetensors"]},{"id":523,"type":"VAELoader","pos":[1134.6112589095078,1181.0985272955104],"size":[650,70],"flags":{},"order":11,"mode":0,"inputs":[],"outputs":[{"name":"VAE","type":"VAE","links":[877,889]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"VAELoader","models":[{"name":"minimax_h3_audio_vae_fp32.safetensors","url":"https://huggingface.co/Comfy-Org/MiniMax-H3/resolve/main/vae/minimax_h3_audio_vae_fp32.safetensors","directory":"vae"}]},"widgets_values":["minimax_h3_audio_vae_fp32.safetensors"]},{"id":524,"type":"RandomNoise","pos":[1807.4959184851828,1585.682072373795],"size":[359.375,88.75],"flags":{},"order":12,"mode":0,"inputs":[],"outputs":[{"name":"NOISE","type":"NOISE","links":[881]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"RandomNoise"},"widgets_values":[1000000101010,"fixed"]},{"id":525,"type":"KSamplerSelect","pos":[1801.791989408122,1742.236950170994],"size":[368.75,70],"flags":{},"order":13,"mode":0,"inputs":[],"outputs":[{"name":"SAMPLER","type":"SAMPLER","links":[883]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"KSamplerSelect"},"widgets_values":["euler_ancestral"]},{"id":526,"type":"BasicScheduler","pos":[1801.7922272886276,1879.1823085009742],"size":[368.75,129.375],"flags":{},"order":30,"mode":0,"inputs":[{"name":"model","type":"MODEL","link":874}],"outputs":[{"name":"SIGMAS","type":"SIGMAS","links":[884]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"BasicScheduler"},"widgets_values":["simple",20,1]},{"id":527,"type":"MiniMaxH3ReferenceToVideo","pos":[1284.8406950235349,1542.0306309661514],"size":[468.75,353.875],"flags":{},"order":33,"mode":0,"inputs":[{"name":"clip","type":"CLIP","link":875},{"name":"vae","type":"VAE","link":876},{"name":"audio_vae","type":"VAE","link":877},{"label":"ref_image_0","name":"ref_images.ref_image_0","shape":7,"type":"IMAGE","link":878},{"label":"ref_video_0","name":"ref_videos.ref_video_0","shape":7,"type":"IMAGE","link":null},{"label":"ref_video_audio_0","name":"ref_video_audios.ref_video_audio_0","shape":7,"type":"AUDIO","link":null},{"label":"ref_audio_0","name":"ref_audios.ref_audio_0","shape":7,"type":"AUDIO","link":null},{"name":"prompt","type":"STRING","widget":{"name":"prompt"},"link":909},{"name":"width","type":"INT","widget":{"name":"width"},"link":900},{"name":"height","type":"INT","widget":{"name":"height"},"link":901},{"name":"length","type":"INT","widget":{"name":"length"},"link":903},{"label":"ref_image_1","name":"ref_images.ref_image_1","shape":7,"type":"IMAGE","link":null}],"outputs":[{"name":"positive","type":"CONDITIONING","links":[880]},{"name":"LATENT","type":"LATENT","links":[885]}],"title":"9. Native MiniMax-H3 Ref2VA conditioning","properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"MiniMaxH3ReferenceToVideo"},"widgets_values":["",864,480,481,"match"]},{"id":528,"type":"BasicGuider","pos":[1812.575469537352,2077.6946270894073],"size":[359.375,57.5],"flags":{},"order":36,"mode":0,"inputs":[{"name":"model","type":"MODEL","link":879},{"name":"conditioning","type":"CONDITIONING","link":880}],"outputs":[{"name":"GUIDER","type":"GUIDER","links":[882]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"BasicGuider"},"widgets_values":[]},{"id":529,"type":"SamplerCustomAdvanced","pos":[2255.626811156978,1598.5311397952596],"size":[228.125,138.75],"flags":{},"order":38,"mode":0,"inputs":[{"name":"noise","type":"NOISE","link":881},{"name":"guider","type":"GUIDER","link":882},{"name":"sampler","type":"SAMPLER","link":883},{"name":"sigmas","type":"SIGMAS","link":884},{"name":"latent_image","type":"LATENT","link":885}],"outputs":[{"name":"output","type":"LATENT","links":[886,888]},{"name":"denoised_output","type":"LATENT","links":null}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"SamplerCustomAdvanced"},"widgets_values":[]},{"id":530,"type":"VAEDecode","pos":[2252.286496011532,1810.873166113142],"size":[228.125,57.5],"flags":{"collapsed":false},"order":40,"mode":0,"inputs":[{"name":"samples","type":"LATENT","link":886},{"name":"vae","type":"VAE","link":887}],"outputs":[{"name":"IMAGE","type":"IMAGE","links":[890]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"VAEDecode"},"widgets_values":[]},{"id":531,"type":"VAEDecodeAudio","pos":[2248.467236029842,1941.9612727874842],"size":[228.125,57.5],"flags":{"collapsed":false},"order":41,"mode":0,"inputs":[{"name":"samples","type":"LATENT","link":888},{"name":"vae","type":"VAE","link":889}],"outputs":[{"name":"AUDIO","type":"AUDIO","links":[891]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"VAEDecodeAudio"},"widgets_values":[]},{"id":532,"type":"CreateVideo","pos":[2561.9426903489993,1862.5224262021243],"size":[268.75,109.921875],"flags":{},"order":42,"mode":0,"inputs":[{"name":"images","type":"IMAGE","link":890},{"name":"audio","shape":7,"type":"AUDIO","link":891}],"outputs":[{"name":"VIDEO","type":"VIDEO","links":[893]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"CreateVideo"},"widgets_values":[24,8]},{"id":533,"type":"SaveVideo","pos":[2924.3572390269305,699.999641676696],"size":[1635.671875,1048.375],"flags":{},"order":44,"mode":0,"inputs":[{"name":"video","type":"VIDEO","link":892}],"outputs":[{"name":"video","type":"VIDEO","links":null}],"title":"10. Save MiniMax-H3 Ref2VA comparison","properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"SaveVideo"},"widgets_values":["video/minimax_h3/diffusiongemma_director_ref2va","mp4","h264","auto"]},{"id":534,"type":"easy cleanGpuUsed","pos":[2585.7365260676925,2046.3043003960834],"size":[225,57.9375],"flags":{},"order":43,"mode":0,"inputs":[{"name":"anything","type":"*","link":893}],"outputs":[{"name":"output","type":"*","links":[892]}],"properties":{"cnr_id":"comfyui-easy-use","ver":"1.3.6","Node name for S&R":"easy cleanGpuUsed"},"widgets_values":[]},{"id":535,"type":"PathchSageAttentionKJ","pos":[1855.4164967630563,732.537790400303],"size":[384.375,113.921875],"flags":{"collapsed":false},"order":22,"mode":0,"inputs":[{"name":"model","type":"MODEL","link":905}],"outputs":[{"name":"MODEL","type":"MODEL","links":[896]}],"properties":{"cnr_id":"comfyui-kjnodes","ver":"1289b52fbb6d64a339a4047b9ea74cf7758ccf1e","Node name for S&R":"PathchSageAttentionKJ","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.8"}},"widgets_values":["auto",false]},{"id":537,"type":"MiniMaxH3SigmaShift","pos":[1458.8989102697196,2078.845774264639],"size":[268.75,89.921875],"flags":{},"order":25,"mode":0,"inputs":[{"name":"model","type":"MODEL","link":896}],"outputs":[{"name":"MODEL","type":"MODEL","links":[874,879]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.0","Node name for S&R":"MiniMaxH3SigmaShift","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{}}},"widgets_values":[12,6]},{"id":540,"type":"Reroute","pos":[1116.5069026766316,1539.0182086955522],"size":[75,23.125],"flags":{},"order":14,"mode":0,"inputs":[{"name":"","type":"*","link":null}],"outputs":[{"name":"","type":"*","links":null}],"properties":{"showOutputText":false,"horizontal":false}},{"id":541,"type":"Reroute","pos":[1116.8459410493742,1633.1468431220214],"size":[75,25.453125],"flags":{},"order":21,"mode":0,"inputs":[{"name":"","type":"*","link":898}],"outputs":[{"name":"","type":"IMAGE","links":[878]}],"properties":{"showOutputText":false,"horizontal":false}},{"id":542,"type":"DiffusionGemmaBranchGenerationGate","pos":[1025,1320],"size":[360,180],"flags":{},"order":45,"mode":0,"inputs":[{"name":"prompt","type":"STRING","link":906},{"name":"ready_for_generation","type":"BOOLEAN","link":907},{"name":"metadata_json","shape":7,"type":"STRING","link":908}],"outputs":[{"name":"prompt","type":"STRING","links":[909]},{"name":"status","type":"STRING","links":[910]},{"name":"ready","type":"BOOLEAN","links":null}],"title":"8. Isolated MiniMax-H3 branch generation gate","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaBranchGenerationGate"},"widgets_values":[],"color":"#5b2222","bgcolor":"#8b3333"},{"id":543,"type":"PreviewAny","pos":[1420,1320],"size":[800,180],"flags":{},"order":46,"mode":0,"inputs":[{"name":"source","type":"*","link":910}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"MiniMax-H3 branch gate status","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#2a363b","bgcolor":"#3f5159"},{"id":544,"type":"PreviewAny","pos":[1660.0,370.0],"size":[800.0,300.0],"flags":{},"order":47,"mode":0,"inputs":[{"name":"source","type":"*","link":911}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"Candidate LTX positive prompt — diagnostic only","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#23364d","bgcolor":"#354f6e"}],"links":[[1,177,0,183,0,"STRING"],[2,179,0,183,1,"IMAGE"],[3,182,0,186,0,"DG_MODEL_CONFIG"],[4,183,0,186,1,"DG_CONTEXT"],[5,510,0,186,2,"DG_TARGET_PROFILE_CONFIG"],[6,185,0,186,3,"DG_GROUNDING_GUARD_CONFIG"],[7,186,0,187,0,"STRING"],[8,183,0,187,1,"DG_CONTEXT"],[9,510,0,187,2,"DG_TARGET_PROFILE_CONFIG"],[10,187,0,188,0,"STRING"],[11,187,12,188,1,"BOOLEAN"],[12,187,4,188,2,"STRING"],[13,188,1,189,0,"STRING"],[14,186,4,190,0,"STRING"],[15,186,5,191,0,"STRING"],[16,178,0,510,0,"FLOAT"],[17,178,0,459,0,"FLOAT"],[18,188,0,456,1,"STRING"],[19,179,0,456,0,"IMAGE"],[20,459,0,456,3,"INT"],[21,418,0,456,6,"INT"],[22,456,0,483,0,"VIDEO"],[23,483,0,481,0,"VIDEO"],[24,187,2,456,12,"STRING"],[25,187,15,511,0,"STRING"],[26,187,10,456,4,"INT"],[27,187,11,456,5,"INT"],[863,513,0,516,1,"DG_CONTEXT"],[865,515,0,516,3,"DG_GROUNDING_GUARD_CONFIG"],[866,516,0,517,0,"STRING"],[867,513,0,517,1,"DG_CONTEXT"],[869,518,0,517,2,"DG_TARGET_PROFILE_CONFIG"],[870,518,0,516,2,"DG_TARGET_PROFILE_CONFIG"],[871,179,0,513,1,"IMAGE"],[872,177,0,513,0,"STRING"],[873,178,0,518,0,"FLOAT"],[874,537,0,526,0,"MODEL"],[875,520,0,527,0,"CLIP"],[876,522,0,527,1,"VAE"],[877,523,0,527,2,"VAE"],[878,541,0,527,3,"IMAGE"],[879,537,0,528,0,"MODEL"],[880,527,0,528,1,"CONDITIONING"],[881,524,0,529,0,"NOISE"],[882,528,0,529,1,"GUIDER"],[883,525,0,529,2,"SAMPLER"],[884,526,0,529,3,"SIGMAS"],[885,527,1,529,4,"LATENT"],[886,529,0,530,0,"LATENT"],[887,522,0,530,1,"VAE"],[888,529,0,531,0,"LATENT"],[889,523,0,531,1,"VAE"],[890,530,0,532,0,"IMAGE"],[891,531,0,532,1,"AUDIO"],[892,534,0,533,0,"VIDEO"],[893,532,0,534,0,"VIDEO"],[896,535,0,537,0,"MODEL"],[898,179,0,541,0,"IMAGE"],[900,517,10,527,8,"INT"],[901,517,11,527,9,"INT"],[902,178,0,521,0,"FLOAT"],[903,521,1,527,10,"INT"],[904,182,0,516,0,"DG_MODEL_CONFIG"],[905,519,0,535,0,"MODEL"],[906,517,13,542,0,"STRING"],[907,517,12,542,1,"BOOLEAN"],[908,517,4,542,2,"STRING"],[909,542,0,527,7,"STRING"],[910,542,1,543,0,"STRING"],[911,187,14,544,0,"STRING"]],"groups":[{"id":1,"title":"1. Inputs + first-frame anchor","bounding":[-1372.8535257230408,-430.2395989344056,726.6388884752423,1898.122793520093],"color":"#3f789e","flags":{}},{"id":2,"title":"2. DiffusionGemma LTX-2.5 Director","bounding":[-570,-660,1583.4162074497767,1140.559076581683],"color":"#6b5b95","flags":{}},{"id":3,"title":"3. Verified prompt handoff","bounding":[1020,-660,1460,1100],"color":"#4f7f65","flags":{}},{"id":4,"title":"4. Native LTX-2.5 Image-to-Video","bounding":[2490,-660,2180,1190],"color":"#a86f32","flags":{}},{"id":29,"title":"2B. DiffusionGemma MiniMax-H3 Ref2VA Director","bounding":[-563.652152759948,515.3004237179819,1578.1993342808291,1210.745015825543],"color":"#88A","flags":{}},{"id":30,"title":"4B. Native MiniMax-H3 Ref2VA","bounding":[1073.669321363001,577.0661462184072,3545.049750085717,1702.4317298737458],"color":"#b58b2a","flags":{}},{"id":31,"title":"NATIVE REF2VA CONDITIONING","bounding":[1238.8340223444825,1447.4393598469765,1636.5432372205755,764.2573625168106],"color":"#3f789e","flags":{}},{"id":32,"title":"25-STEP SAMPLING","bounding":[1775.8263994741528,1502.8849279584897,731.8965690286641,671.1869170680311],"color":"#355c4a","flags":{}},{"id":33,"title":"DECODE + SAVE","bounding":[2531.5806096019596,1766.1370478749477,331.32124510848917,374.613419338585],"color":"#75524a","flags":{}}],"definitions":{"subgraphs":[{"id":"d9d4c7f2-3c3b-4c2a-9f8b-2a1e3d4c5b6a","version":1,"state":{"lastGroupId":33,"lastNodeId":541,"lastLinkId":905,"lastRerouteId":0},"revision":0,"config":{},"name":"Image to Video (LTX-2.5, DiffusionGemma prompts)","description":"Native two-stage LTX-2.5 I2V with external DiffusionGemma positive and negative prompts; built-in prompt enhancement remains off.","inputNode":{"id":-10,"bounding":[-640,6460,183.814453125,348]},"outputNode":{"id":-20,"bounding":[5540,6496,128,68]},"inputs":[{"id":"075be400-91e7-40a7-8f4e-d5c907af36e8","name":"input","type":"IMAGE,MASK","linkIds":[763],"label":"first_frame","pos":[-480.185546875,6484]},{"id":"5dab3f68-2044-46e7-b01f-4bf4b8bf4e79","name":"value","type":"STRING","linkIds":[765],"label":"prompt","pos":[-480.185546875,6504]},{"id":"21c9d37e-1f04-47f8-b752-22667180790c","name":"value_1","type":"BOOLEAN","linkIds":[],"label":"prompt_enhance","pos":[-480.185546875,6524]},{"id":"00f26a0c-569d-4aa1-aa8a-281ad2f3c4e0","name":"value_2","type":"INT","linkIds":[767],"label":"duration","pos":[-480.185546875,6544]},{"id":"5d05d885-6c96-43dd-9cdb-f1d0c48045b5","name":"value_3","type":"INT","linkIds":[768],"label":"width","pos":[-480.185546875,6564]},{"id":"c646ee59-a1e0-433e-b2f5-f1d8217fe526","name":"value_4","type":"INT","linkIds":[769],"label":"height","pos":[-480.185546875,6584]},{"id":"7072a79b-5168-42ee-9088-e3f92ac07791","name":"noise_seed","type":"INT","linkIds":[770],"pos":[-480.185546875,6604]},{"id":"85a2fb6d-1b63-40a7-adb6-5acc97a7cc99","name":"value_5","type":"INT","linkIds":[776],"label":"frame_rate","pos":[-480.185546875,6624]},{"id":"cbb7ddb9-95d0-4e63-a473-f37c329fbcda","name":"unet_name","type":"COMBO","linkIds":[777],"pos":[-480.185546875,6644]},{"id":"dd0f8943-da6e-4182-8265-efb74da42c33","name":"vae_name","type":"COMBO","linkIds":[778],"label":"video_vae","pos":[-480.185546875,6664]},{"id":"69b9a13b-ee5a-4525-abd9-281d4c257277","name":"vae_name_1","type":"COMBO","linkIds":[779],"label":"audio_vae","pos":[-480.185546875,6684]},{"id":"de6a02d4-1e94-43e7-bf67-2e06f8688943","name":"clip_name","type":"COMBO","linkIds":[780],"pos":[-480.185546875,6704]},{"id":"83db7bd8-4276-4950-8d15-ee1803e29646","name":"model_name","type":"COMBO","linkIds":[781],"label":"upscale_model","pos":[-480.185546875,6724]},{"id":"e5ca018e-1483-44ba-a318-3fc83c7f19ba","name":"clip_name_1","type":"COMBO","linkIds":[],"label":"prompt_enhance_model","pos":[-480.185546875,6744]},{"id":"8e0b9cf6-f939-4a31-983d-8a76d52dd2d9","name":"negative_prompt","type":"STRING","linkIds":[861],"label":"negative_prompt","pos":[-480.185546875,6764]}],"outputs":[{"id":"b92869b1-7119-47c1-8a9c-c52c131eb1f1","name":"VIDEO","type":"VIDEO","linkIds":[714],"localized_name":"VIDEO","pos":[5564,6520]}],"widgets":[],"nodes":[{"id":419,"type":"CLIPTextEncode","pos":[1160,6040],"size":[550,738.96875],"flags":{},"order":10,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":732},{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":813}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","links":[696]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"CLIPTextEncode","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[""],"color":"#232","bgcolor":"#353"},{"id":420,"type":"PrimitiveStringMultiline","pos":[150,6080],"size":[368.96875,348.96875],"flags":{},"order":11,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"STRING","widget":{"name":"value"},"link":765}],"outputs":[{"localized_name":"STRING","name":"STRING","type":"STRING","links":[813]}],"title":"Prompt","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveStringMultiline","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["Egyptian royal in blue-and-gold headdress and high collar, white dress with golden embroidery and armbands, desert, robot soldiers in formation left and right. She walks steadily forward, head held level and gaze fixed ahead—no dipping or lowering of the head. The camera performs a single, smooth push-in only: starting in a wider shot of her, the robots, and the desert, it moves steadily forward until she is in a medium or medium-close frame, then holds. She stops, posture and head still upright, and says: “The old gods are silent. I am not.” Robot soldiers shift or march in place; sand and fabric move with the wind. No pull-back; the only camera move is the continuous push-in."]},{"id":421,"type":"UNETLoader","pos":[650,6200],"size":[418.96875,129.375],"flags":{},"order":12,"mode":0,"inputs":[{"localized_name":"unet_name","name":"unet_name","type":"COMBO","widget":{"name":"unet_name"},"link":777}],"outputs":[{"localized_name":"MODEL","name":"MODEL","type":"MODEL","links":[771,772,888]}],"properties":{"cnr_id":"comfy-core","ver":"0.29.0","Node name for S&R":"UNETLoader","models":[{"name":"ltx-2.5-22b-distilled-transformer-comfy-int8-convrot.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/diffusion_models/ltx-2.5-22b-distilled-transformer-comfy-int8-convrot.safetensors","directory":"diffusion_models"}]},"widgets_values":["ltx-2.5-22b-distilled-transformer-comfy-int8-convrot.safetensors","default"]},{"id":422,"type":"PrimitiveInt","pos":[150,6630],"size":[368.96875,108.96875],"flags":{},"order":13,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"INT","widget":{"name":"value"},"link":767}],"outputs":[{"localized_name":"INT","name":"INT","type":"INT","links":[715]}],"title":"Duration","properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"PrimitiveInt","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[5,"fixed"]},{"id":363,"type":"PrimitiveBoolean","pos":[160,6480],"size":[368.96875,98.96875],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[{"localized_name":"BOOLEAN","name":"BOOLEAN","type":"BOOLEAN","links":[683,693]}],"title":"Switch to Text to Video?","properties":{"cnr_id":"comfy-core","ver":"0.16.0","Node name for S&R":"PrimitiveBoolean","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[false]},{"id":423,"type":"LTXVConditioning","pos":[1810,6480],"size":[278.96875,129.375],"flags":{},"order":14,"mode":0,"inputs":[{"localized_name":"positive","name":"positive","type":"CONDITIONING","link":696},{"localized_name":"negative","name":"negative","type":"CONDITIONING","link":697},{"localized_name":"frame_rate","name":"frame_rate","type":"FLOAT","widget":{"name":"frame_rate"},"link":698}],"outputs":[{"localized_name":"positive","name":"positive","type":"CONDITIONING","links":[735,755]},{"localized_name":"negative","name":"negative","type":"CONDITIONING","links":[736,756]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"LTXVConditioning","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[24]},{"id":424,"type":"VAELoader","pos":[650,6398.844815215871],"size":[409.375,70],"flags":{},"order":15,"mode":0,"inputs":[{"localized_name":"vae_name","name":"vae_name","type":"COMBO","widget":{"name":"vae_name"},"link":778}],"outputs":[{"localized_name":"VAE","name":"VAE","type":"VAE","links":[727,773,774,775]}],"properties":{"cnr_id":"comfy-core","ver":"0.29.0","Node name for S&R":"VAELoader","models":[{"name":"ltx-2.5-video-vae-bf16.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/vae/ltx-2.5-video-vae-bf16.safetensors","directory":"vae"}]},"widgets_values":["ltx-2.5-video-vae-bf16.safetensors"]},{"id":425,"type":"VAELoader","pos":[650,6560],"size":[400,88.96875],"flags":{},"order":16,"mode":0,"inputs":[{"localized_name":"vae_name","name":"vae_name","type":"COMBO","widget":{"name":"vae_name"},"link":779}],"outputs":[{"localized_name":"VAE","name":"VAE","type":"VAE","links":[729,730]}],"properties":{"cnr_id":"comfy-core","ver":"0.29.0","Node name for S&R":"VAELoader","models":[{"name":"ltx-2.5-audio-vae-bf16.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/vae/ltx-2.5-audio-vae-bf16.safetensors","directory":"vae"}]},"widgets_values":["ltx-2.5-audio-vae-bf16.safetensors"]},{"id":426,"type":"PrimitiveInt","pos":[150,6780],"size":[368.96875,108.96875],"flags":{},"order":17,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"INT","widget":{"name":"value"},"link":768}],"outputs":[{"localized_name":"INT","name":"INT","type":"INT","links":[687]}],"title":"Width","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveInt","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[1280,"fixed"]},{"id":427,"type":"CLIPTextEncode","pos":[1170,6880],"size":[528.96875,238.96875],"flags":{},"order":18,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":731}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","links":[697]}],"title":"Negative prompt — from DiffusionGemma","properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"CLIPTextEncode","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[""],"color":"#323","bgcolor":"#535"},{"id":428,"type":"CLIPLoader","pos":[650,6730],"size":[400,141.921875],"flags":{},"order":19,"mode":0,"showAdvanced":true,"inputs":[{"localized_name":"clip_name","name":"clip_name","type":"COMBO","widget":{"name":"clip_name"},"link":780}],"outputs":[{"localized_name":"CLIP","name":"CLIP","type":"CLIP","links":[731,732]}],"properties":{"cnr_id":"comfy-core","ver":"0.29.0","Node name for S&R":"CLIPLoader","models":[{"name":"gemma4-12b-with-proj-ltx-2.5-comfy-int8-convrot.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/text_encoders/gemma4-12b-with-proj-ltx-2.5-comfy-int8-convrot.safetensors","directory":"text_encoders"}]},"widgets_values":["gemma4-12b-with-proj-ltx-2.5-comfy-int8-convrot.safetensors","ltxv","default"]},{"id":429,"type":"PrimitiveInt","pos":[150,6930],"size":[368.96875,108.96875],"flags":{},"order":20,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"INT","widget":{"name":"value"},"link":769}],"outputs":[{"localized_name":"INT","name":"INT","type":"INT","links":[688]}],"title":"Height","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveInt","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[720,"fixed"]},{"id":430,"type":"KSamplerSelect","pos":[2224.3008005573674,6709.40359723377],"size":[278.96875,108.96875],"flags":{},"order":1,"mode":0,"inputs":[],"outputs":[{"localized_name":"SAMPLER","name":"SAMPLER","type":"SAMPLER","links":[671]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"KSamplerSelect","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["euler_ancestral"]},{"id":431,"type":"RandomNoise","pos":[2190,6300],"size":[278.96875,108.96875],"flags":{},"order":21,"mode":0,"inputs":[{"localized_name":"noise_seed","name":"noise_seed","type":"INT","widget":{"name":"noise_seed"},"link":770}],"outputs":[{"localized_name":"NOISE","name":"NOISE","type":"NOISE","links":[670]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"RandomNoise","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[900359092894726,"randomize"]},{"id":397,"type":"ManualSigmas","pos":[2195.0564044977027,6895.64484593597],"size":[500,98.96875],"flags":{},"order":2,"mode":0,"inputs":[],"outputs":[{"localized_name":"SIGMAS","name":"SIGMAS","type":"SIGMAS","links":[896]}],"properties":{"cnr_id":"comfy-core","ver":"0.14.1","Node name for S&R":"ManualSigmas"},"widgets_values":["1.0, 0.99375, 0.9875, 0.98125, 0.975, 0.909375, 0.725, 0.421875, 0.0"]},{"id":432,"type":"PrimitiveInt","pos":[150,7080],"size":[368.96875,108.96875],"flags":{},"order":22,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"INT","widget":{"name":"value"},"link":776}],"outputs":[{"localized_name":"INT","name":"INT","type":"INT","links":[695,716]}],"title":"Frame Rate","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveInt","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[24,"fixed"]},{"id":433,"type":"LatentUpscaleModelLoader","pos":[640.6800332933674,6971.0077671585605],"size":[409.375,138.96875],"flags":{},"order":23,"mode":0,"inputs":[{"localized_name":"model_name","name":"model_name","type":"COMBO","widget":{"name":"model_name"},"link":781}],"outputs":[{"localized_name":"LATENT_UPSCALE_MODEL","name":"LATENT_UPSCALE_MODEL","type":"LATENT_UPSCALE_MODEL","links":[678]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LatentUpscaleModelLoader","models":[{"name":"ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/latent_upscale_models/ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors","directory":"latent_upscale_models"}],"enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors"]},{"id":434,"type":"LTXVDualCFGGuider","pos":[2215.9956793671613,6502.287759672367],"size":[269.046875,159.046875],"flags":{},"order":24,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":771},{"localized_name":"positive","name":"positive","type":"CONDITIONING","link":735},{"localized_name":"negative","name":"negative","type":"CONDITIONING","link":736}],"outputs":[{"localized_name":"GUIDER","name":"GUIDER","type":"GUIDER","links":[733]}],"properties":{"Node name for S&R":"LTXVDualCFGGuider","cnr_id":"comfy-core","ver":"0.28.0","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[0.5,1]},{"id":435,"type":"SamplerCustomAdvanced","pos":[2610,6510],"size":[228.96875,170],"flags":{},"order":25,"mode":0,"inputs":[{"localized_name":"noise","name":"noise","type":"NOISE","link":670},{"localized_name":"guider","name":"guider","type":"GUIDER","link":733},{"localized_name":"sampler","name":"sampler","type":"SAMPLER","link":671},{"localized_name":"sigmas","name":"sigmas","type":"SIGMAS","link":896},{"localized_name":"latent_image","name":"latent_image","type":"LATENT","link":672}],"outputs":[{"localized_name":"output","name":"output","type":"LATENT","links":[702]},{"localized_name":"denoised_output","name":"denoised_output","type":"LATENT","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.60","Node name for S&R":"SamplerCustomAdvanced","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":357,"type":"LTXVImgToVideoInplace","pos":[2070,7390],"size":[278.96875,179.375],"flags":{},"order":9,"mode":0,"inputs":[{"localized_name":"vae","name":"vae","type":"VAE","link":727},{"localized_name":"image","name":"image","type":"IMAGE","link":691},{"localized_name":"latent","name":"latent","type":"LATENT","link":692},{"localized_name":"bypass","name":"bypass","type":"BOOLEAN","widget":{"name":"bypass"},"link":693}],"outputs":[{"localized_name":"latent","name":"latent","type":"LATENT","links":[699]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVImgToVideoInplace","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[0.7,false]},{"id":436,"type":"LTXVEmptyLatentAudio","pos":[1620,7370],"size":[278.96875,170],"flags":{},"order":26,"mode":0,"inputs":[{"localized_name":"audio_vae","name":"audio_vae","type":"VAE","link":729},{"localized_name":"frames_number","name":"frames_number","type":"INT","widget":{"name":"frames_number"},"link":717},{"localized_name":"frame_rate","name":"frame_rate","type":"FLOAT,INT","widget":{"name":"frame_rate"},"link":701}],"outputs":[{"localized_name":"Latent","name":"Latent","type":"LATENT","links":[700]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.68","Node name for S&R":"LTXVEmptyLatentAudio","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[97,25,1]},{"id":437,"type":"LTXVSeparateAVLatent","pos":[2890,6520],"size":[250,98.96875],"flags":{},"order":27,"mode":0,"inputs":[{"localized_name":"av_latent","name":"av_latent","type":"LATENT","link":702}],"outputs":[{"localized_name":"video_latent","name":"video_latent","type":"LATENT","links":[677]},{"localized_name":"audio_latent","name":"audio_latent","type":"LATENT","links":[666]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"LTXVSeparateAVLatent","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":438,"type":"LTXVConcatAVLatent","pos":[2470,7390],"size":[238.96875,98.96875],"flags":{},"order":28,"mode":0,"inputs":[{"localized_name":"video_latent","name":"video_latent","type":"LATENT","link":699},{"localized_name":"audio_latent","name":"audio_latent","type":"LATENT","link":700}],"outputs":[{"localized_name":"latent","name":"latent","type":"LATENT","links":[672]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVConcatAVLatent","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":351,"type":"ResizeImageMaskNode","pos":[190,7480],"size":[300,106],"flags":{},"order":8,"mode":0,"inputs":[{"localized_name":"input","name":"input","type":"IMAGE,MASK","link":763}],"outputs":[{"localized_name":"resized","name":"resized","type":"IMAGE,MASK","links":[752]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"ResizeImageMaskNode","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["scale longer dimension",1536,"lanczos"]},{"id":439,"type":"ComfyMathExpression","pos":[1170,7470],"size":[225,74],"flags":{"collapsed":true},"order":29,"mode":0,"inputs":[{"label":"a","localized_name":"values.a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":687},{"label":"b","localized_name":"values.b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"localized_name":"FLOAT","name":"FLOAT","type":"FLOAT","links":[]},{"localized_name":"INT","name":"INT","type":"INT","links":[689]},{"localized_name":"BOOL","name":"BOOL","type":"BOOLEAN","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"ComfyMathExpression","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["a/2"]},{"id":440,"type":"ComfyMathExpression","pos":[1170,7530],"size":[225,74],"flags":{"collapsed":true},"order":30,"mode":0,"inputs":[{"label":"a","localized_name":"values.a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":688},{"label":"b","localized_name":"values.b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"localized_name":"FLOAT","name":"FLOAT","type":"FLOAT","links":[]},{"localized_name":"INT","name":"INT","type":"INT","links":[690]},{"localized_name":"BOOL","name":"BOOL","type":"BOOLEAN","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"ComfyMathExpression","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["a/2"]},{"id":350,"type":"LTXVPreprocess","pos":[620,7480],"size":[288.96875,108.96875],"flags":{},"order":7,"mode":0,"inputs":[{"localized_name":"image","name":"image","type":"IMAGE","link":752}],"outputs":[{"localized_name":"output_image","name":"output_image","type":"IMAGE","links":[681,691]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVPreprocess","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[18]},{"id":441,"type":"EmptyLTXVLatentVideo","pos":[1630,7600],"size":[278.96875,198.96875],"flags":{},"order":31,"mode":0,"inputs":[{"localized_name":"width","name":"width","type":"INT","widget":{"name":"width"},"link":689},{"localized_name":"height","name":"height","type":"INT","widget":{"name":"height"},"link":690},{"localized_name":"length","name":"length","type":"INT","widget":{"name":"length"},"link":718}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","links":[692]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.60","Node name for S&R":"EmptyLTXVLatentVideo","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[768,512,97,1]},{"id":442,"type":"LTXVLatentUpsampler","pos":[3260,6410],"size":[328.96875,120],"flags":{},"order":32,"mode":0,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":677},{"localized_name":"upscale_model","name":"upscale_model","type":"LATENT_UPSCALE_MODEL","link":678},{"localized_name":"vae","name":"vae","type":"VAE","link":773}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","links":[682]}],"properties":{"cnr_id":"comfy-core","ver":"0.14.1","Node name for S&R":"LTXVLatentUpsampler","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":349,"type":"LTXVImgToVideoInplace","pos":[3270,6620],"size":[300,179.375],"flags":{},"order":6,"mode":0,"inputs":[{"localized_name":"vae","name":"vae","type":"VAE","link":774},{"localized_name":"image","name":"image","type":"IMAGE","link":681},{"localized_name":"latent","name":"latent","type":"LATENT","link":682},{"localized_name":"bypass","name":"bypass","type":"BOOLEAN","widget":{"name":"bypass"},"link":683}],"outputs":[{"localized_name":"latent","name":"latent","type":"LATENT","links":[665]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVImgToVideoInplace","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[1,false]},{"id":443,"type":"ComfyMathExpression","pos":[1170,7670],"size":[225,74],"flags":{"collapsed":true},"order":33,"mode":0,"inputs":[{"label":"a","localized_name":"values.a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":695},{"label":"b","localized_name":"values.b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"localized_name":"FLOAT","name":"FLOAT","type":"FLOAT","links":[698,713]},{"localized_name":"INT","name":"INT","type":"INT","links":[701]},{"localized_name":"BOOL","name":"BOOL","type":"BOOLEAN","links":[]}],"title":"Math Expression (fps)","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"ComfyMathExpression","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["a"]},{"id":444,"type":"ComfyMathExpression","pos":[1180,7770],"size":[225,94],"flags":{"collapsed":true},"order":34,"mode":0,"inputs":[{"label":"a","localized_name":"values.a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":715},{"label":"b","localized_name":"values.b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":716},{"label":"c","localized_name":"values.c","name":"values.c","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"localized_name":"FLOAT","name":"FLOAT","type":"FLOAT","links":[]},{"localized_name":"INT","name":"INT","type":"INT","links":[717,718]},{"localized_name":"BOOL","name":"BOOL","type":"BOOLEAN","links":[]}],"title":"Math Expression (length)","properties":{"cnr_id":"comfy-core","ver":"0.18.1","Node name for S&R":"ComfyMathExpression","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.7"}},"widgets_values":["a * b + 1"]},{"id":445,"type":"RandomNoise","pos":[3710,6150],"size":[278.96875,108.96875],"flags":{},"order":3,"mode":0,"inputs":[],"outputs":[{"localized_name":"NOISE","name":"NOISE","type":"NOISE","links":[703]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.75","Node name for S&R":"RandomNoise","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[42,"fixed"]},{"id":446,"type":"LTXVConcatAVLatent","pos":[3710,6760],"size":[278.96875,98.96875],"flags":{},"order":35,"mode":0,"inputs":[{"localized_name":"video_latent","name":"video_latent","type":"LATENT","link":665},{"localized_name":"audio_latent","name":"audio_latent","type":"LATENT","link":666}],"outputs":[{"localized_name":"latent","name":"latent","type":"LATENT","links":[707]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"LTXVConcatAVLatent","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":396,"type":"ManualSigmas","pos":[3710,6980],"size":[288.96875,108.96875],"flags":{},"order":4,"mode":0,"inputs":[],"outputs":[{"localized_name":"SIGMAS","name":"SIGMAS","type":"SIGMAS","links":[751]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"ManualSigmas","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["0.85, 0.7250, 0.4219, 0.0"]},{"id":447,"type":"LTXVDualCFGGuider","pos":[3711.811554084113,6320.869184637932],"size":[269.046875,159.046875],"flags":{},"order":36,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":772},{"localized_name":"positive","name":"positive","type":"CONDITIONING","link":755},{"localized_name":"negative","name":"negative","type":"CONDITIONING","link":756}],"outputs":[{"localized_name":"GUIDER","name":"GUIDER","type":"GUIDER","links":[744]}],"properties":{"Node name for S&R":"LTXVDualCFGGuider","cnr_id":"comfy-core","ver":"0.28.0","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[1,1]},{"id":448,"type":"KSamplerSelect","pos":[3710,6560],"size":[278.96875,108.96875],"flags":{},"order":5,"mode":0,"inputs":[],"outputs":[{"localized_name":"SAMPLER","name":"SAMPLER","type":"SAMPLER","links":[705]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.75","Node name for S&R":"KSamplerSelect","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["res_2s"]},{"id":449,"type":"SamplerCustomAdvanced","pos":[4070,6500],"size":[228.96875,170],"flags":{},"order":37,"mode":0,"inputs":[{"localized_name":"noise","name":"noise","type":"NOISE","link":703},{"localized_name":"guider","name":"guider","type":"GUIDER","link":744},{"localized_name":"sampler","name":"sampler","type":"SAMPLER","link":705},{"localized_name":"sigmas","name":"sigmas","type":"SIGMAS","link":751},{"localized_name":"latent_image","name":"latent_image","type":"LATENT","link":707}],"outputs":[{"localized_name":"output","name":"output","type":"LATENT","links":[708]},{"localized_name":"denoised_output","name":"denoised_output","type":"LATENT","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.75","Node name for S&R":"SamplerCustomAdvanced","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":450,"type":"LTXVSeparateAVLatent","pos":[4370,6500],"size":[228.96875,98.96875],"flags":{},"order":38,"mode":0,"inputs":[{"localized_name":"av_latent","name":"av_latent","type":"LATENT","link":708}],"outputs":[{"localized_name":"video_latent","name":"video_latent","type":"LATENT","links":[709]},{"localized_name":"audio_latent","name":"audio_latent","type":"LATENT","links":[694]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"LTXVSeparateAVLatent","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":451,"type":"VAEDecodeTiled","pos":[4760,6360],"size":[278.96875,198.96875],"flags":{},"order":39,"mode":0,"showAdvanced":true,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":709},{"localized_name":"vae","name":"vae","type":"VAE","link":775}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[711]}],"properties":{"cnr_id":"comfy-core","ver":"0.14.1","Node name for S&R":"VAEDecodeTiled","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[512,64,64,16]},{"id":452,"type":"LTXVAudioVAEDecode","pos":[4760,6650],"size":[268.96875,98.96875],"flags":{},"order":40,"mode":0,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":694},{"label":"Audio VAE","localized_name":"audio_vae","name":"audio_vae","type":"VAE","link":730}],"outputs":[{"localized_name":"Audio","name":"Audio","type":"AUDIO","links":[712]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVAudioVAEDecode","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":453,"type":"CreateVideo","pos":[5200,6460],"size":[278.96875,129.375],"flags":{},"order":41,"mode":0,"inputs":[{"localized_name":"images","name":"images","type":"IMAGE","link":711},{"localized_name":"audio","name":"audio","shape":7,"type":"AUDIO","link":712},{"localized_name":"fps","name":"fps","type":"FLOAT","widget":{"name":"fps"},"link":713}],"outputs":[{"localized_name":"VIDEO","name":"VIDEO","type":"VIDEO","links":[714]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"CreateVideo","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[24,8]},{"id":508,"type":"BasicScheduler","pos":[1836.2732329122807,6878.830222687924],"size":[268.75,117.921875],"flags":{},"order":42,"mode":4,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":888}],"outputs":[{"localized_name":"SIGMAS","name":"SIGMAS","type":"SIGMAS","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"BasicScheduler"},"widgets_values":["linear_quadratic",25,1]}],"groups":[{"id":1,"title":"Model","bounding":[620,5950,480,1270],"color":"#3f789e","flags":{}},{"id":3,"title":"Prompt","bounding":[1130,5950,980,1270],"color":"#3f789e","flags":{}},{"id":19,"title":"Video Settings","bounding":[100,5950,490,1270],"color":"#3f789e","flags":{}},{"id":2,"title":"Generate Low Resolution","bounding":[2140,5950,1020,1270],"color":"#3f789e","flags":{}},{"id":7,"title":"Latent Upscale","bounding":[3190,5950,460,1270],"color":"#3f789e","flags":{}},{"id":20,"title":"Image Preprocessing","bounding":[100,7250,1000,610],"color":"#3f789e","flags":{}},{"id":21,"title":"Empty Latent","bounding":[1480,7250,1680,610],"color":"#3f789e","flags":{}},{"id":22,"title":"Number conversion","bounding":[1130,7250,320,610],"color":"#3f789e","flags":{}},{"id":6,"title":"Generate High Resolution","bounding":[3680,5950,960,1270],"color":"#3f789e","flags":{}}],"links":[{"id":732,"origin_id":428,"origin_slot":0,"target_id":419,"target_slot":0,"type":"CLIP"},{"id":696,"origin_id":419,"origin_slot":0,"target_id":423,"target_slot":0,"type":"CONDITIONING"},{"id":697,"origin_id":427,"origin_slot":0,"target_id":423,"target_slot":1,"type":"CONDITIONING"},{"id":698,"origin_id":443,"origin_slot":0,"target_id":423,"target_slot":2,"type":"FLOAT"},{"id":731,"origin_id":428,"origin_slot":0,"target_id":427,"target_slot":0,"type":"CLIP"},{"id":735,"origin_id":423,"origin_slot":0,"target_id":434,"target_slot":1,"type":"CONDITIONING"},{"id":736,"origin_id":423,"origin_slot":1,"target_id":434,"target_slot":2,"type":"CONDITIONING"},{"id":670,"origin_id":431,"origin_slot":0,"target_id":435,"target_slot":0,"type":"NOISE"},{"id":733,"origin_id":434,"origin_slot":0,"target_id":435,"target_slot":1,"type":"GUIDER"},{"id":671,"origin_id":430,"origin_slot":0,"target_id":435,"target_slot":2,"type":"SAMPLER"},{"id":672,"origin_id":438,"origin_slot":0,"target_id":435,"target_slot":4,"type":"LATENT"},{"id":727,"origin_id":424,"origin_slot":0,"target_id":357,"target_slot":0,"type":"VAE"},{"id":691,"origin_id":350,"origin_slot":0,"target_id":357,"target_slot":1,"type":"IMAGE"},{"id":692,"origin_id":441,"origin_slot":0,"target_id":357,"target_slot":2,"type":"LATENT"},{"id":693,"origin_id":363,"origin_slot":0,"target_id":357,"target_slot":3,"type":"BOOLEAN"},{"id":729,"origin_id":425,"origin_slot":0,"target_id":436,"target_slot":0,"type":"VAE"},{"id":717,"origin_id":444,"origin_slot":1,"target_id":436,"target_slot":1,"type":"INT"},{"id":701,"origin_id":443,"origin_slot":1,"target_id":436,"target_slot":2,"type":"INT"},{"id":702,"origin_id":435,"origin_slot":0,"target_id":437,"target_slot":0,"type":"LATENT"},{"id":699,"origin_id":357,"origin_slot":0,"target_id":438,"target_slot":0,"type":"LATENT"},{"id":700,"origin_id":436,"origin_slot":0,"target_id":438,"target_slot":1,"type":"LATENT"},{"id":687,"origin_id":426,"origin_slot":0,"target_id":439,"target_slot":0,"type":"INT"},{"id":688,"origin_id":429,"origin_slot":0,"target_id":440,"target_slot":0,"type":"INT"},{"id":752,"origin_id":351,"origin_slot":0,"target_id":350,"target_slot":0,"type":"IMAGE"},{"id":689,"origin_id":439,"origin_slot":1,"target_id":441,"target_slot":0,"type":"INT"},{"id":690,"origin_id":440,"origin_slot":1,"target_id":441,"target_slot":1,"type":"INT"},{"id":718,"origin_id":444,"origin_slot":1,"target_id":441,"target_slot":2,"type":"INT"},{"id":677,"origin_id":437,"origin_slot":0,"target_id":442,"target_slot":0,"type":"LATENT"},{"id":678,"origin_id":433,"origin_slot":0,"target_id":442,"target_slot":1,"type":"LATENT_UPSCALE_MODEL"},{"id":681,"origin_id":350,"origin_slot":0,"target_id":349,"target_slot":1,"type":"IMAGE"},{"id":682,"origin_id":442,"origin_slot":0,"target_id":349,"target_slot":2,"type":"LATENT"},{"id":683,"origin_id":363,"origin_slot":0,"target_id":349,"target_slot":3,"type":"BOOLEAN"},{"id":695,"origin_id":432,"origin_slot":0,"target_id":443,"target_slot":0,"type":"INT"},{"id":715,"origin_id":422,"origin_slot":0,"target_id":444,"target_slot":0,"type":"INT"},{"id":716,"origin_id":432,"origin_slot":0,"target_id":444,"target_slot":1,"type":"INT"},{"id":665,"origin_id":349,"origin_slot":0,"target_id":446,"target_slot":0,"type":"LATENT"},{"id":666,"origin_id":437,"origin_slot":1,"target_id":446,"target_slot":1,"type":"LATENT"},{"id":755,"origin_id":423,"origin_slot":0,"target_id":447,"target_slot":1,"type":"CONDITIONING"},{"id":756,"origin_id":423,"origin_slot":1,"target_id":447,"target_slot":2,"type":"CONDITIONING"},{"id":703,"origin_id":445,"origin_slot":0,"target_id":449,"target_slot":0,"type":"NOISE"},{"id":744,"origin_id":447,"origin_slot":0,"target_id":449,"target_slot":1,"type":"GUIDER"},{"id":705,"origin_id":448,"origin_slot":0,"target_id":449,"target_slot":2,"type":"SAMPLER"},{"id":751,"origin_id":396,"origin_slot":0,"target_id":449,"target_slot":3,"type":"SIGMAS"},{"id":707,"origin_id":446,"origin_slot":0,"target_id":449,"target_slot":4,"type":"LATENT"},{"id":708,"origin_id":449,"origin_slot":0,"target_id":450,"target_slot":0,"type":"LATENT"},{"id":709,"origin_id":450,"origin_slot":0,"target_id":451,"target_slot":0,"type":"LATENT"},{"id":694,"origin_id":450,"origin_slot":1,"target_id":452,"target_slot":0,"type":"LATENT"},{"id":730,"origin_id":425,"origin_slot":0,"target_id":452,"target_slot":1,"type":"VAE"},{"id":711,"origin_id":451,"origin_slot":0,"target_id":453,"target_slot":0,"type":"IMAGE"},{"id":712,"origin_id":452,"origin_slot":0,"target_id":453,"target_slot":1,"type":"AUDIO"},{"id":713,"origin_id":443,"origin_slot":0,"target_id":453,"target_slot":2,"type":"FLOAT"},{"id":714,"origin_id":453,"origin_slot":0,"target_id":-20,"target_slot":0,"type":"VIDEO"},{"id":763,"origin_id":-10,"origin_slot":0,"target_id":351,"target_slot":0,"type":"IMAGE,MASK"},{"id":765,"origin_id":-10,"origin_slot":1,"target_id":420,"target_slot":0,"type":"STRING"},{"id":767,"origin_id":-10,"origin_slot":3,"target_id":422,"target_slot":0,"type":"INT"},{"id":768,"origin_id":-10,"origin_slot":4,"target_id":426,"target_slot":0,"type":"INT"},{"id":769,"origin_id":-10,"origin_slot":5,"target_id":429,"target_slot":0,"type":"INT"},{"id":770,"origin_id":-10,"origin_slot":6,"target_id":431,"target_slot":0,"type":"INT"},{"id":771,"origin_id":421,"origin_slot":0,"target_id":434,"target_slot":0,"type":"MODEL"},{"id":772,"origin_id":421,"origin_slot":0,"target_id":447,"target_slot":0,"type":"MODEL"},{"id":773,"origin_id":424,"origin_slot":0,"target_id":442,"target_slot":2,"type":"VAE"},{"id":774,"origin_id":424,"origin_slot":0,"target_id":349,"target_slot":0,"type":"VAE"},{"id":775,"origin_id":424,"origin_slot":0,"target_id":451,"target_slot":1,"type":"VAE"},{"id":776,"origin_id":-10,"origin_slot":7,"target_id":432,"target_slot":0,"type":"INT"},{"id":777,"origin_id":-10,"origin_slot":8,"target_id":421,"target_slot":0,"type":"COMBO"},{"id":778,"origin_id":-10,"origin_slot":9,"target_id":424,"target_slot":0,"type":"COMBO"},{"id":779,"origin_id":-10,"origin_slot":10,"target_id":425,"target_slot":0,"type":"COMBO"},{"id":780,"origin_id":-10,"origin_slot":11,"target_id":428,"target_slot":0,"type":"COMBO"},{"id":781,"origin_id":-10,"origin_slot":12,"target_id":433,"target_slot":0,"type":"COMBO"},{"id":813,"origin_id":420,"origin_slot":0,"target_id":419,"target_slot":1,"type":"STRING"},{"id":888,"origin_id":421,"origin_slot":0,"target_id":508,"target_slot":0,"type":"MODEL"},{"id":896,"origin_id":397,"origin_slot":0,"target_id":435,"target_slot":3,"type":"SIGMAS"},{"id":861,"origin_id":-10,"origin_slot":14,"target_id":427,"target_slot":1,"type":"STRING"}],"extra":{}}]},"config":{},"extra":{"frontendVersion":"1.47.12","VHS_latentpreview":false,"VHS_latentpreviewrate":0,"VHS_MetadataImage":true,"VHS_KeepIntermediate":true,"workflow_note":"Side-by-side DiffusionGemma comparison: LTX-2.5 I2V uses Context Hub; MiniMax-H3 Ref2VA uses H3 Reference Context with a one-image manifest and a fail-closed gate.","ds":{"scale":0.6002048668000012,"offset":[498.1630190487116,-42.76984541575996]},"seed_widgets":{"185":3,"418":0,"456":4}},"version":0.4,"seed_widgets":{"185":3,"418":0,"456":4,"515":3,"524":0}} +{"id":"8e24c8f7-c092-4e1d-a78d-9f172b4a55c0","revision":0,"last_node_id":544,"last_link_id":911,"nodes":[{"id":116,"type":"MarkdownNote","pos":[-1845.1552810668936,-976.5838584899902],"size":[1267.65625,255.796875],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[],"title":"START HERE — LTX-2.5 I2V vs MiniMax-H3 Ref2VA comparison","properties":{},"widgets_values":["# DiffusionGemma comparison — LTX-2.5 I2V vs MiniMax-H3 Ref2VA\n\n1. Replace the **shared image** and edit the **shared creative brief**. The image feeds LTX as an exact first-frame anchor, while H3 receives it as ****, a full visual reference.\n2. Keep the two Director branches model-specific: the upper branch uses **LTX Context Hub + LTX target**; the lower branch uses **H3 Reference Context + H3 Ref2VA target**. Do not cross-wire these contexts.\n3. The same image is connected directly to both native model paths. H3 needs both the Director reference manifest and its native **ref_image_0** connection.\n4. Each splitter controls its own raster. This stable baseline uses LTX at **1.0 MP / 16:9** and H3 at **0.4 MP / 16:9**. The shared **10-second** duration maps H3 to **243 frames**, and H3 Sage Attention is set to **auto** for a compatible GPU-specific backend.\n5. The two Branch Generation Gates isolate validation failures: a blocked branch skips only its own native render, while the other branch can continue. A branch gate status means that model-specific packet passed generation validation; the separate Grounding status/report previews show the evidence audit result.\n6. Both Grounding Guards are set to **audit** so grounding diagnostics remain visible without canceling either comparison render. Use strict only for a later compliance run. The H3 Director uses a 2048-token output budget for its longer Ref2VA contract.\n7. H3 `expected_subject_count` is **1**. One connected `` means one reference asset, not one semantic Subject. The count requires exactly one tracked `` definition; ordinary props, environment, lighting, composition, style, actions, and effects remain folded into that hero/whole-scene Subject and its timeline.\n\nImportant: this is a practical visual comparison, not identical conditioning. LTX I2V preserves the supplied opening frame; MiniMax-H3 Ref2VA treats the image as a reference that may be recomposed.\n\nCandidate prompt previews are diagnostic only: they update even when validation blocks a render. Native LTX receives the positive prompt through its Branch Generation Gate and the negative prompt directly from the fail-closed Splitter output; never route a candidate socket directly to the generator. Refresh recomputes but does not randomize a fixed Director seed."],"color":"#222","bgcolor":"#000"},{"id":177,"type":"PrimitiveStringMultiline","pos":[-1310.6767027883088,-248.98693165686993],"size":[618.75,298.125],"flags":{},"order":1,"mode":0,"inputs":[],"outputs":[{"name":"STRING","type":"STRING","links":[1,872]}],"title":"1. Creative brief — describe motion from the supplied frame","properties":{"cnr_id":"comfy-core","ver":"0.24.0","Node name for S&R":"PrimitiveStringMultiline"},"widgets_values":["Create a ten-second continuous live-action shot grounded in the supplied first frame. Keep the officer as the only human and the only independently tracked semantic subject. Preserve his identity, uniform, roadside setting, daylight, and opening composition. Treat vehicles, road, buildings, and other background details as unnumbered scene elements; do not introduce another person, creature, or independently acting subject. He shifts his weight, looks toward the distance, and takes one measured step backward as the camera makes a slow eye-level dolly in; no cuts."],"color":"#232","bgcolor":"#353"},{"id":178,"type":"PrimitiveFloat","pos":[-1151.3738148451273,1346.8611402190197],"size":[338.453125,79.375],"flags":{},"order":2,"mode":0,"inputs":[],"outputs":[{"name":"FLOAT","type":"FLOAT","links":[16,17,873,902]}],"title":"2. Shared duration seconds — Director + LTX","properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"PrimitiveFloat"},"widgets_values":[10],"color":"#322","bgcolor":"#533"},{"id":179,"type":"LoadImage","pos":[-1310.2844629557683,163.21786143836945],"size":[618.75,698.125],"flags":{},"order":3,"mode":0,"inputs":[],"outputs":[{"name":"IMAGE","type":"IMAGE","links":[2,19,871,898]},{"name":"MASK","type":"MASK","links":null}],"title":"3. First-frame image — shared with Context Hub + LTX","properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"LoadImage"},"widgets_values":["ComfyUI_00001_.png","image"]},{"id":182,"type":"DiffusionGemmaModelLoader","pos":[-1242.4214641092578,956.6292192723117],"size":[500,309.828125],"flags":{},"order":4,"mode":0,"inputs":[],"outputs":[{"name":"model_config","type":"DG_MODEL_CONFIG","links":[3,904]},{"name":"runtime_status_json","type":"STRING","links":null}],"title":"4a. Load DiffusionGemma Director — unload before LTX","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaModelLoader"},"widgets_values":["C:\\ComfyUI\\app\\models\\LLM\\diffusiongemma-26B-A4B-it-NVFP4","transformers_inprocess","auto","modelopt_nvfp4",true,"unload_after_run","20.0 GB - safe practical",0.35]},{"id":183,"type":"DiffusionGemmaContextHub","pos":[-20,-560],"size":[500,520],"flags":{},"order":19,"mode":0,"inputs":[{"name":"user_prompt","type":"STRING","link":1},{"name":"image","shape":7,"type":"IMAGE","link":2},{"name":"video","shape":7,"type":"VIDEO","link":null},{"name":"last_frame_image","shape":7,"type":"IMAGE","link":null}],"outputs":[{"name":"gemma_context","type":"DG_CONTEXT","links":[4,8]},{"name":"context_json","type":"STRING","links":null},{"name":"context_preview","type":"STRING","links":null}],"title":"4. LTX first-frame Context Hub","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaContextHub"},"widgets_values":[1,60,60,"trim",false,"","video_recreation"]},{"id":510,"type":"DiffusionGemmaLTX25TargetProfile","pos":[-20,20],"size":[500,429.953125],"flags":{},"order":15,"mode":0,"inputs":[{"name":"target_duration_seconds","type":"FLOAT","widget":{"name":"target_duration_seconds"},"link":16}],"outputs":[{"name":"target_profile_config","type":"DG_TARGET_PROFILE_CONFIG","links":[5,9]},{"name":"target_profile_json","type":"STRING","links":null}],"title":"5. LTX-2.5 target profile — Auto resolves to I2V","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaLTX25TargetProfile"},"widgets_values":["Auto (recommended)",0,"Reality-show","auto_scene_audio","","custom","video game, CGI, cartoon, duplicate people, deformed face, warped hands, subtitles, captions, logos, watermarks","Off"]},{"id":185,"type":"DiffusionGemmaGroundingGuardSettings","pos":[-556.3353380475719,-555.5900344848619],"size":[500,329.953125],"flags":{},"order":5,"mode":0,"showAdvanced":true,"inputs":[{"name":"external_evidence_json","shape":7,"type":"STRING","link":null}],"outputs":[{"name":"grounding_guard_config","type":"DG_GROUNDING_GUARD_CONFIG","links":[6]},{"name":"config_json","type":"STRING","links":null}],"title":"5b. LTX Grounding Guard — audit comparison baseline","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaGroundingGuardSettings"},"widgets_values":["audit",true,"checkpoint_defaults",7,"fixed",false,"diffusiongemma_grounding","auto"]},{"id":418,"type":"SeedNode","pos":[2520,270],"size":[339.953125,84.953125],"flags":{},"order":6,"mode":0,"inputs":[],"outputs":[{"name":"seed","type":"INT","links":[21]}],"title":"LTX seed","properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"SeedNode"},"widgets_values":[347267244880135,"fixed"]},{"id":459,"type":"CM_FloatToInt","pos":[2535.399883319805,428.2324258383219],"size":[273.609375,89.953125],"flags":{},"order":16,"mode":0,"inputs":[{"name":"a","type":"FLOAT","widget":{"name":"a"},"link":17}],"outputs":[{"name":"INT","type":"INT","links":[20]}],"title":"Shared duration → integer seconds","properties":{"cnr_id":"ComfyMath","ver":"c01177221c31b8e5fbc062778fc8254aeb541638","Node name for S&R":"CM_FloatToInt"},"widgets_values":[0]},{"id":186,"type":"DiffusionGemmaCoTGenerator","pos":[540,-560],"size":[450,339.953125],"flags":{},"order":23,"mode":0,"inputs":[{"name":"model_config","type":"DG_MODEL_CONFIG","link":3},{"name":"gemma_context","type":"DG_CONTEXT","link":4},{"name":"target_profile_config","type":"DG_TARGET_PROFILE_CONFIG","link":5},{"name":"grounding_guard_config","shape":7,"type":"DG_GROUNDING_GUARD_CONFIG","link":6}],"outputs":[{"name":"final_json","type":"STRING","links":[7]},{"name":"reasoning_text","type":"STRING","links":null},{"name":"raw_response","type":"STRING","links":null},{"name":"metadata_json","type":"STRING","links":null},{"name":"grounding_status","type":"STRING","links":[14]},{"name":"grounding_report_json","type":"STRING","links":[15]}],"title":"6. Build grounded LTX-2.5 prompt","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaCoTGenerator"},"widgets_values":[0.45,"faithful",0.2,"off",1024,"reuse"]},{"id":187,"type":"DiffusionGemmaJSONSplitter","pos":[540,-150],"size":[450,520],"flags":{},"order":26,"mode":0,"inputs":[{"name":"final_json","type":"STRING","link":7},{"name":"gemma_context","shape":7,"type":"DG_CONTEXT","link":8},{"name":"target_profile_config","shape":7,"type":"DG_TARGET_PROFILE_CONFIG","link":9}],"outputs":[{"name":"ltx_prompt","type":"STRING","links":[10]},{"name":"ideogram_prompt","type":"STRING","links":null},{"name":"negative_prompt","type":"STRING","links":[24]},{"name":"aspect_ratio","type":"STRING","links":null},{"name":"metadata_json","type":"STRING","links":[12]},{"name":"scene_segments_json","type":"STRING","links":null},{"name":"local_prompts","type":"STRING","links":null},{"name":"segment_lengths","type":"STRING","links":null},{"name":"is_valid","type":"BOOLEAN","links":null},{"name":"resolution_selector_preset","type":"STRING","links":null},{"name":"resolution_width","type":"INT","links":[26]},{"name":"resolution_height","type":"INT","links":[27]},{"name":"ready_for_generation","type":"BOOLEAN","links":[11]},{"name":"minimax_h3_prompt","type":"STRING","links":null},{"name":"candidate_ltx_prompt","type":"STRING","links":[911]},{"name":"candidate_negative_prompt","type":"STRING","links":[25]}],"title":"7. Route LTX prompts + select output resolution","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaJSONSplitter"},"widgets_values":["",1,32,"16:9 (Widescreen)"],"shape":2},{"id":188,"type":"DiffusionGemmaBranchGenerationGate","pos":[1050,-560],"size":[539.953125,154.953125],"flags":{},"order":32,"mode":0,"inputs":[{"name":"prompt","type":"STRING","link":10},{"name":"ready_for_generation","type":"BOOLEAN","link":11},{"name":"metadata_json","shape":7,"type":"STRING","link":12}],"outputs":[{"name":"prompt","type":"STRING","links":[18]},{"name":"status","type":"STRING","links":[13]},{"name":"ready","type":"BOOLEAN","links":null}],"title":"8. Isolated LTX-2.5 branch generation gate","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaBranchGenerationGate"},"widgets_values":[],"color":"#5b2222","bgcolor":"#8b3333"},{"id":189,"type":"PreviewAny","pos":[1650,-560],"size":[800,409.953125],"flags":{},"order":34,"mode":0,"inputs":[{"name":"source","type":"*","link":13}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"LTX-2.5 branch gate status","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#244d3b","bgcolor":"#356e55"},{"id":511,"type":"PreviewAny","pos":[1650,-90],"size":[800,220],"flags":{},"order":31,"mode":0,"inputs":[{"name":"source","type":"*","link":25}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"Candidate LTX negative prompt — diagnostic only","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#244d3b","bgcolor":"#356e55"},{"id":190,"type":"PreviewAny","pos":[1050,-330],"size":[539.953125,139.953125],"flags":{},"order":27,"mode":0,"inputs":[{"name":"source","type":"*","link":14}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"Grounding status","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#2a363b","bgcolor":"#3f5159"},{"id":191,"type":"PreviewAny","pos":[1050,-110],"size":[539.953125,499.953125],"flags":{},"order":28,"mode":0,"inputs":[{"name":"source","type":"*","link":15}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"Grounding report","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#2a363b","bgcolor":"#3f5159"},{"id":456,"type":"d9d4c7f2-3c3b-4c2a-9f8b-2a1e3d4c5b6a","pos":[2520,-560],"size":[719.953125,759.953125],"flags":{},"order":35,"mode":0,"inputs":[{"label":"first_frame","name":"input","type":"IMAGE,MASK","link":19},{"label":"prompt","name":"value","type":"STRING","widget":{"name":"value"},"link":18},{"label":"prompt_enhance","name":"value_1","type":"BOOLEAN","link":null},{"label":"duration","name":"value_2","type":"INT","widget":{"name":"value_2"},"link":20},{"label":"width","name":"value_3","type":"INT","widget":{"name":"value_3"},"link":26},{"label":"height","name":"value_4","type":"INT","widget":{"name":"value_4"},"link":27},{"name":"noise_seed","type":"INT","widget":{"name":"noise_seed"},"link":21},{"label":"frame_rate","name":"value_5","type":"INT","widget":{"name":"value_5"},"link":null},{"label":"negative_prompt","name":"negative_prompt","type":"STRING","link":24},{"label":"video_vae","name":"vae_name","type":"COMBO","widget":{"name":"vae_name"},"link":null},{"label":"audio_vae","name":"vae_name_1","type":"COMBO","widget":{"name":"vae_name_1"},"link":null},{"label":"upscale_model","name":"model_name","type":"COMBO","widget":{"name":"model_name"},"link":null},{"label":"prompt_enhance_model","name":"clip_name_1","type":"COMBO","link":null}],"outputs":[{"name":"VIDEO","type":"VIDEO","links":[22]}],"title":"9. Native two-stage LTX-2.5 I2V — prompt enhancer OFF","properties":{"cnr_id":"comfy-core","ver":"0.30.0","previewExposures":[]},"widgets_values":["",5,992,544,347267244880135,24,"","ltx-2.5-22b-distilled-transformer-comfy-int8-convrot.safetensors","ltx-2.5-video-vae-bf16.safetensors","ltx-2.5-audio-vae-bf16.safetensors","gemma4-12b-with-proj-ltx-2.5-comfy-int8-convrot.safetensors","ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors"]},{"id":483,"type":"easy cleanGpuUsed","pos":[3300,-557.7640642438612],"size":[249.9375,64.953125],"flags":{},"order":37,"mode":0,"inputs":[{"name":"anything","type":"*","link":22}],"outputs":[{"name":"output","type":"*","links":[23]}],"title":"Unload LTX models after render","properties":{"cnr_id":"comfyui-easy-use","ver":"1.3.6","Node name for S&R":"easy cleanGpuUsed"},"widgets_values":[]},{"id":481,"type":"SaveVideo","pos":[3303.6025565011164,-410.9316471644813],"size":[1329.59375,910.265625],"flags":{},"order":39,"mode":0,"inputs":[{"name":"video","type":"VIDEO","link":23}],"outputs":[{"name":"video","type":"VIDEO","links":null}],"title":"10. Save DiffusionGemma LTX-2.5 I2V","properties":{"cnr_id":"comfy-core","ver":"0.14.1","Node name for S&R":"SaveVideo","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["video/ltx2.5_diffusiongemma_i2v","auto","auto"]},{"id":513,"type":"DiffusionGemmaH3ReferenceContext","pos":[-29.270162054729614,618.5876835010446],"size":[500,590],"flags":{},"order":20,"mode":0,"inputs":[{"name":"user_prompt","type":"STRING","link":872},{"name":"reference_images","shape":7,"type":"IMAGE","link":871},{"name":"reference_video","shape":7,"type":"VIDEO","link":null}],"outputs":[{"name":"gemma_context","type":"DG_CONTEXT","links":[863,867]},{"name":"context_json","type":"STRING","links":null},{"name":"context_preview","type":"STRING","links":null}],"title":"4. H3 ordered reference context — one shared image","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaH3ReferenceContext"},"widgets_values":[": [dg:identity,appearance,color,environment,lighting,composition] sole visual reference for visible subject and scene attributes.",1,60,60,"trim","","1 image - all visual attributes",1]},{"id":515,"type":"DiffusionGemmaGroundingGuardSettings","pos":[-556.2148941971532,622.8978035358848],"size":[500,329.4375],"flags":{},"order":7,"mode":0,"showAdvanced":true,"inputs":[{"name":"external_evidence_json","shape":7,"type":"STRING","link":null}],"outputs":[{"name":"grounding_guard_config","type":"DG_GROUNDING_GUARD_CONFIG","links":[865]},{"name":"config_json","type":"STRING","links":null}],"title":"5b. H3 Grounding Guard — audit comparison baseline","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaGroundingGuardSettings"},"widgets_values":["audit",true,"checkpoint_defaults",7,"fixed",false,"diffusiongemma_grounding","auto"]},{"id":516,"type":"DiffusionGemmaCoTGenerator","pos":[537.3151138519959,601.4657424243728],"size":[450,349.84375],"flags":{},"order":24,"mode":0,"inputs":[{"name":"model_config","type":"DG_MODEL_CONFIG","link":904},{"name":"gemma_context","type":"DG_CONTEXT","link":863},{"name":"target_profile_config","type":"DG_TARGET_PROFILE_CONFIG","link":870},{"name":"grounding_guard_config","shape":7,"type":"DG_GROUNDING_GUARD_CONFIG","link":865}],"outputs":[{"name":"final_json","type":"STRING","links":[866]},{"name":"reasoning_text","type":"STRING","links":null},{"name":"raw_response","type":"STRING","links":null},{"name":"metadata_json","type":"STRING","links":null},{"name":"grounding_status","type":"STRING","links":[]},{"name":"grounding_report_json","type":"STRING","links":[]}],"title":"6. Build grounded MiniMax-H3 Ref2VA prompt","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaCoTGenerator"},"widgets_values":[0.45,"faithful",0.2,"off",2048,"reuse"]},{"id":517,"type":"DiffusionGemmaJSONSplitter","pos":[530.7298379452703,1028.587683501045],"size":[450,520],"flags":{},"order":29,"mode":0,"inputs":[{"name":"final_json","type":"STRING","link":866},{"name":"gemma_context","shape":7,"type":"DG_CONTEXT","link":867},{"name":"target_profile_config","shape":7,"type":"DG_TARGET_PROFILE_CONFIG","link":869}],"outputs":[{"name":"ltx_prompt","type":"STRING","links":[]},{"name":"ideogram_prompt","type":"STRING","links":null},{"name":"negative_prompt","type":"STRING","links":[]},{"name":"aspect_ratio","type":"STRING","links":null},{"name":"metadata_json","type":"STRING","links":[908]},{"name":"scene_segments_json","type":"STRING","links":null},{"name":"local_prompts","type":"STRING","links":null},{"name":"segment_lengths","type":"STRING","links":null},{"name":"is_valid","type":"BOOLEAN","links":null},{"name":"resolution_selector_preset","type":"STRING","links":null},{"name":"resolution_width","type":"INT","links":[900]},{"name":"resolution_height","type":"INT","links":[901]},{"name":"ready_for_generation","type":"BOOLEAN","links":[907]},{"name":"minimax_h3_prompt","type":"STRING","links":[906]}],"title":"7. Route MiniMax-H3 prompt + select output resolution","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaJSONSplitter"},"widgets_values":["",0.4,32,"16:9 (Widescreen)"],"shape":2},{"id":518,"type":"DiffusionGemmaMiniMaxH3TargetProfile","pos":[-27.219616252359916,1189.9471823525093],"size":[502.25,505.796875],"flags":{"collapsed":false},"order":17,"mode":0,"inputs":[{"name":"target_duration_seconds","type":"FLOAT","widget":{"name":"target_duration_seconds"},"link":873}],"outputs":[{"name":"target_profile_config","type":"DG_TARGET_PROFILE_CONFIG","links":[869,870]},{"name":"target_profile_json","type":"STRING","links":null}],"properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaMiniMaxH3TargetProfile"},"widgets_values":["ref2va",0,"auto_scene_audio","","auto",12,"auto",2,"","empty",""],"title":"5. MiniMax-H3 Ref2VA target profile"},{"id":519,"type":"UNETLoader","pos":[1134.6112589095078,731.0985272955096],"size":[637.5,88.75],"flags":{},"order":8,"mode":0,"inputs":[],"outputs":[{"name":"MODEL","type":"MODEL","links":[905]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"UNETLoader","models":[{"name":"minimax_h3_ref2va_int8_convrot.safetensors","url":"https://huggingface.co/Comfy-Org/MiniMax-H3/resolve/main/diffusion_models/minimax_h3_ref2va_int8_convrot.safetensors","directory":"diffusion_models"}]},"widgets_values":["minimax_h3_ref2va_pruned_fp8_scaled.safetensors","default"]},{"id":520,"type":"CLIPLoader","pos":[1134.6112589095078,881.0985272955088],"size":[637.5,120],"flags":{},"order":9,"mode":0,"inputs":[],"outputs":[{"name":"CLIP","type":"CLIP","links":[875]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"CLIPLoader","models":[{"name":"qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors","url":"https://huggingface.co/Comfy-Org/MiniMax-H3/resolve/main/text_encoders/qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors","directory":"text_encoders"}]},"widgets_values":["qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors","minimax","default"]},{"id":521,"type":"ComfyMathExpression","pos":[1282.2131527489764,1956.3305770876827],"size":[225,0],"flags":{"collapsed":true},"order":18,"mode":0,"inputs":[{"label":"a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":902},{"label":"b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"name":"FLOAT","type":"FLOAT","links":null},{"name":"INT","type":"INT","links":[903]},{"name":"BOOL","type":"BOOLEAN","links":null}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"ComfyMathExpression"},"widgets_values":["max(5, round(a * 24)) + (5 - (max(5, round(a * 24)) % 17)) % 17"]},{"id":522,"type":"VAELoader","pos":[1134.6112589095078,1051.0985272955095],"size":[637.5,70],"flags":{},"order":10,"mode":0,"inputs":[],"outputs":[{"name":"VAE","type":"VAE","links":[876,887]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"VAELoader","models":[{"name":"minimax_h3_video_vae_fp16.safetensors","url":"https://huggingface.co/Comfy-Org/MiniMax-H3/resolve/main/vae/minimax_h3_video_vae_fp16.safetensors","directory":"vae"}]},"widgets_values":["minimax_h3_video_vae_fp16.safetensors"]},{"id":523,"type":"VAELoader","pos":[1134.6112589095078,1181.0985272955104],"size":[650,70],"flags":{},"order":11,"mode":0,"inputs":[],"outputs":[{"name":"VAE","type":"VAE","links":[877,889]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"VAELoader","models":[{"name":"minimax_h3_audio_vae_fp32.safetensors","url":"https://huggingface.co/Comfy-Org/MiniMax-H3/resolve/main/vae/minimax_h3_audio_vae_fp32.safetensors","directory":"vae"}]},"widgets_values":["minimax_h3_audio_vae_fp32.safetensors"]},{"id":524,"type":"RandomNoise","pos":[1807.4959184851828,1585.682072373795],"size":[359.375,88.75],"flags":{},"order":12,"mode":0,"inputs":[],"outputs":[{"name":"NOISE","type":"NOISE","links":[881]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"RandomNoise"},"widgets_values":[1000000101010,"fixed"]},{"id":525,"type":"KSamplerSelect","pos":[1801.791989408122,1742.236950170994],"size":[368.75,70],"flags":{},"order":13,"mode":0,"inputs":[],"outputs":[{"name":"SAMPLER","type":"SAMPLER","links":[883]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"KSamplerSelect"},"widgets_values":["euler_ancestral"]},{"id":526,"type":"BasicScheduler","pos":[1801.7922272886276,1879.1823085009742],"size":[368.75,129.375],"flags":{},"order":30,"mode":0,"inputs":[{"name":"model","type":"MODEL","link":874}],"outputs":[{"name":"SIGMAS","type":"SIGMAS","links":[884]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"BasicScheduler"},"widgets_values":["simple",20,1]},{"id":527,"type":"MiniMaxH3ReferenceToVideo","pos":[1284.8406950235349,1542.0306309661514],"size":[468.75,353.875],"flags":{},"order":33,"mode":0,"inputs":[{"name":"clip","type":"CLIP","link":875},{"name":"vae","type":"VAE","link":876},{"name":"audio_vae","type":"VAE","link":877},{"label":"ref_image_0","name":"ref_images.ref_image_0","shape":7,"type":"IMAGE","link":878},{"label":"ref_video_0","name":"ref_videos.ref_video_0","shape":7,"type":"IMAGE","link":null},{"label":"ref_video_audio_0","name":"ref_video_audios.ref_video_audio_0","shape":7,"type":"AUDIO","link":null},{"label":"ref_audio_0","name":"ref_audios.ref_audio_0","shape":7,"type":"AUDIO","link":null},{"name":"prompt","type":"STRING","widget":{"name":"prompt"},"link":909},{"name":"width","type":"INT","widget":{"name":"width"},"link":900},{"name":"height","type":"INT","widget":{"name":"height"},"link":901},{"name":"length","type":"INT","widget":{"name":"length"},"link":903},{"label":"ref_image_1","name":"ref_images.ref_image_1","shape":7,"type":"IMAGE","link":null}],"outputs":[{"name":"positive","type":"CONDITIONING","links":[880]},{"name":"LATENT","type":"LATENT","links":[885]}],"title":"9. Native MiniMax-H3 Ref2VA conditioning","properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"MiniMaxH3ReferenceToVideo"},"widgets_values":["",864,480,481,"match"]},{"id":528,"type":"BasicGuider","pos":[1812.575469537352,2077.6946270894073],"size":[359.375,57.5],"flags":{},"order":36,"mode":0,"inputs":[{"name":"model","type":"MODEL","link":879},{"name":"conditioning","type":"CONDITIONING","link":880}],"outputs":[{"name":"GUIDER","type":"GUIDER","links":[882]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"BasicGuider"},"widgets_values":[]},{"id":529,"type":"SamplerCustomAdvanced","pos":[2255.626811156978,1598.5311397952596],"size":[228.125,138.75],"flags":{},"order":38,"mode":0,"inputs":[{"name":"noise","type":"NOISE","link":881},{"name":"guider","type":"GUIDER","link":882},{"name":"sampler","type":"SAMPLER","link":883},{"name":"sigmas","type":"SIGMAS","link":884},{"name":"latent_image","type":"LATENT","link":885}],"outputs":[{"name":"output","type":"LATENT","links":[886,888]},{"name":"denoised_output","type":"LATENT","links":null}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"SamplerCustomAdvanced"},"widgets_values":[]},{"id":530,"type":"VAEDecode","pos":[2252.286496011532,1810.873166113142],"size":[228.125,57.5],"flags":{"collapsed":false},"order":40,"mode":0,"inputs":[{"name":"samples","type":"LATENT","link":886},{"name":"vae","type":"VAE","link":887}],"outputs":[{"name":"IMAGE","type":"IMAGE","links":[890]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"VAEDecode"},"widgets_values":[]},{"id":531,"type":"VAEDecodeAudio","pos":[2248.467236029842,1941.9612727874842],"size":[228.125,57.5],"flags":{"collapsed":false},"order":41,"mode":0,"inputs":[{"name":"samples","type":"LATENT","link":888},{"name":"vae","type":"VAE","link":889}],"outputs":[{"name":"AUDIO","type":"AUDIO","links":[891]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"VAEDecodeAudio"},"widgets_values":[]},{"id":532,"type":"CreateVideo","pos":[2561.9426903489993,1862.5224262021243],"size":[268.75,109.921875],"flags":{},"order":42,"mode":0,"inputs":[{"name":"images","type":"IMAGE","link":890},{"name":"audio","shape":7,"type":"AUDIO","link":891}],"outputs":[{"name":"VIDEO","type":"VIDEO","links":[893]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"CreateVideo"},"widgets_values":[24,8]},{"id":533,"type":"SaveVideo","pos":[2924.3572390269305,699.999641676696],"size":[1635.671875,1048.375],"flags":{},"order":44,"mode":0,"inputs":[{"name":"video","type":"VIDEO","link":892}],"outputs":[{"name":"video","type":"VIDEO","links":null}],"title":"10. Save MiniMax-H3 Ref2VA comparison","properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"SaveVideo"},"widgets_values":["video/minimax_h3/diffusiongemma_director_ref2va","mp4","h264","auto"]},{"id":534,"type":"easy cleanGpuUsed","pos":[2585.7365260676925,2046.3043003960834],"size":[225,57.9375],"flags":{},"order":43,"mode":0,"inputs":[{"name":"anything","type":"*","link":893}],"outputs":[{"name":"output","type":"*","links":[892]}],"properties":{"cnr_id":"comfyui-easy-use","ver":"1.3.6","Node name for S&R":"easy cleanGpuUsed"},"widgets_values":[]},{"id":535,"type":"PathchSageAttentionKJ","pos":[1855.4164967630563,732.537790400303],"size":[384.375,113.921875],"flags":{"collapsed":false},"order":22,"mode":0,"inputs":[{"name":"model","type":"MODEL","link":905}],"outputs":[{"name":"MODEL","type":"MODEL","links":[896]}],"properties":{"cnr_id":"comfyui-kjnodes","ver":"1289b52fbb6d64a339a4047b9ea74cf7758ccf1e","Node name for S&R":"PathchSageAttentionKJ","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.8"}},"widgets_values":["auto",false]},{"id":537,"type":"MiniMaxH3SigmaShift","pos":[1458.8989102697196,2078.845774264639],"size":[268.75,89.921875],"flags":{},"order":25,"mode":0,"inputs":[{"name":"model","type":"MODEL","link":896}],"outputs":[{"name":"MODEL","type":"MODEL","links":[874,879]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.0","Node name for S&R":"MiniMaxH3SigmaShift","ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{}}},"widgets_values":[12,6]},{"id":540,"type":"Reroute","pos":[1116.5069026766316,1539.0182086955522],"size":[75,23.125],"flags":{},"order":14,"mode":0,"inputs":[{"name":"","type":"*","link":null}],"outputs":[{"name":"","type":"*","links":null}],"properties":{"showOutputText":false,"horizontal":false}},{"id":541,"type":"Reroute","pos":[1116.8459410493742,1633.1468431220214],"size":[75,25.453125],"flags":{},"order":21,"mode":0,"inputs":[{"name":"","type":"*","link":898}],"outputs":[{"name":"","type":"IMAGE","links":[878]}],"properties":{"showOutputText":false,"horizontal":false}},{"id":542,"type":"DiffusionGemmaBranchGenerationGate","pos":[1025,1320],"size":[360,180],"flags":{},"order":45,"mode":0,"inputs":[{"name":"prompt","type":"STRING","link":906},{"name":"ready_for_generation","type":"BOOLEAN","link":907},{"name":"metadata_json","shape":7,"type":"STRING","link":908}],"outputs":[{"name":"prompt","type":"STRING","links":[909]},{"name":"status","type":"STRING","links":[910]},{"name":"ready","type":"BOOLEAN","links":null}],"title":"8. Isolated MiniMax-H3 branch generation gate","properties":{"cnr_id":"diffusiongemma-prompt-builder","ver":"dfcd642a21fc689ee6454b2848a6fced501ca00a","Node name for S&R":"DiffusionGemmaBranchGenerationGate"},"widgets_values":[],"color":"#5b2222","bgcolor":"#8b3333"},{"id":543,"type":"PreviewAny","pos":[1420,1320],"size":[800,180],"flags":{},"order":46,"mode":0,"inputs":[{"name":"source","type":"*","link":910}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"MiniMax-H3 branch gate status","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#2a363b","bgcolor":"#3f5159"},{"id":544,"type":"PreviewAny","pos":[1660.0,370.0],"size":[800.0,300.0],"flags":{},"order":47,"mode":0,"inputs":[{"name":"source","type":"*","link":911}],"outputs":[{"name":"STRING","type":"STRING","links":null}],"title":"Candidate LTX positive prompt — diagnostic only","properties":{"cnr_id":"comfy-core","ver":"0.15.1","Node name for S&R":"PreviewAny","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[],"color":"#23364d","bgcolor":"#354f6e"}],"links":[[1,177,0,183,0,"STRING"],[2,179,0,183,1,"IMAGE"],[3,182,0,186,0,"DG_MODEL_CONFIG"],[4,183,0,186,1,"DG_CONTEXT"],[5,510,0,186,2,"DG_TARGET_PROFILE_CONFIG"],[6,185,0,186,3,"DG_GROUNDING_GUARD_CONFIG"],[7,186,0,187,0,"STRING"],[8,183,0,187,1,"DG_CONTEXT"],[9,510,0,187,2,"DG_TARGET_PROFILE_CONFIG"],[10,187,0,188,0,"STRING"],[11,187,12,188,1,"BOOLEAN"],[12,187,4,188,2,"STRING"],[13,188,1,189,0,"STRING"],[14,186,4,190,0,"STRING"],[15,186,5,191,0,"STRING"],[16,178,0,510,0,"FLOAT"],[17,178,0,459,0,"FLOAT"],[18,188,0,456,1,"STRING"],[19,179,0,456,0,"IMAGE"],[20,459,0,456,3,"INT"],[21,418,0,456,6,"INT"],[22,456,0,483,0,"VIDEO"],[23,483,0,481,0,"VIDEO"],[24,187,2,456,8,"STRING"],[25,187,15,511,0,"STRING"],[26,187,10,456,4,"INT"],[27,187,11,456,5,"INT"],[863,513,0,516,1,"DG_CONTEXT"],[865,515,0,516,3,"DG_GROUNDING_GUARD_CONFIG"],[866,516,0,517,0,"STRING"],[867,513,0,517,1,"DG_CONTEXT"],[869,518,0,517,2,"DG_TARGET_PROFILE_CONFIG"],[870,518,0,516,2,"DG_TARGET_PROFILE_CONFIG"],[871,179,0,513,1,"IMAGE"],[872,177,0,513,0,"STRING"],[873,178,0,518,0,"FLOAT"],[874,537,0,526,0,"MODEL"],[875,520,0,527,0,"CLIP"],[876,522,0,527,1,"VAE"],[877,523,0,527,2,"VAE"],[878,541,0,527,3,"IMAGE"],[879,537,0,528,0,"MODEL"],[880,527,0,528,1,"CONDITIONING"],[881,524,0,529,0,"NOISE"],[882,528,0,529,1,"GUIDER"],[883,525,0,529,2,"SAMPLER"],[884,526,0,529,3,"SIGMAS"],[885,527,1,529,4,"LATENT"],[886,529,0,530,0,"LATENT"],[887,522,0,530,1,"VAE"],[888,529,0,531,0,"LATENT"],[889,523,0,531,1,"VAE"],[890,530,0,532,0,"IMAGE"],[891,531,0,532,1,"AUDIO"],[892,534,0,533,0,"VIDEO"],[893,532,0,534,0,"VIDEO"],[896,535,0,537,0,"MODEL"],[898,179,0,541,0,"IMAGE"],[900,517,10,527,8,"INT"],[901,517,11,527,9,"INT"],[902,178,0,521,0,"FLOAT"],[903,521,1,527,10,"INT"],[904,182,0,516,0,"DG_MODEL_CONFIG"],[905,519,0,535,0,"MODEL"],[906,517,13,542,0,"STRING"],[907,517,12,542,1,"BOOLEAN"],[908,517,4,542,2,"STRING"],[909,542,0,527,7,"STRING"],[910,542,1,543,0,"STRING"],[911,187,14,544,0,"STRING"]],"groups":[{"id":1,"title":"1. Inputs + first-frame anchor","bounding":[-1372.8535257230408,-430.2395989344056,726.6388884752423,1898.122793520093],"color":"#3f789e","flags":{}},{"id":2,"title":"2. DiffusionGemma LTX-2.5 Director","bounding":[-570,-660,1583.4162074497767,1140.559076581683],"color":"#6b5b95","flags":{}},{"id":3,"title":"3. Verified prompt handoff","bounding":[1020,-660,1460,1100],"color":"#4f7f65","flags":{}},{"id":4,"title":"4. Native LTX-2.5 Image-to-Video","bounding":[2490,-660,2180,1190],"color":"#a86f32","flags":{}},{"id":29,"title":"2B. DiffusionGemma MiniMax-H3 Ref2VA Director","bounding":[-563.652152759948,515.3004237179819,1578.1993342808291,1210.745015825543],"color":"#88A","flags":{}},{"id":30,"title":"4B. Native MiniMax-H3 Ref2VA","bounding":[1073.669321363001,577.0661462184072,3545.049750085717,1702.4317298737458],"color":"#b58b2a","flags":{}},{"id":31,"title":"NATIVE REF2VA CONDITIONING","bounding":[1238.8340223444825,1447.4393598469765,1636.5432372205755,764.2573625168106],"color":"#3f789e","flags":{}},{"id":32,"title":"25-STEP SAMPLING","bounding":[1775.8263994741528,1502.8849279584897,731.8965690286641,671.1869170680311],"color":"#355c4a","flags":{}},{"id":33,"title":"DECODE + SAVE","bounding":[2531.5806096019596,1766.1370478749477,331.32124510848917,374.613419338585],"color":"#75524a","flags":{}}],"definitions":{"subgraphs":[{"id":"d9d4c7f2-3c3b-4c2a-9f8b-2a1e3d4c5b6a","version":1,"state":{"lastGroupId":33,"lastNodeId":541,"lastLinkId":905,"lastRerouteId":0},"revision":0,"config":{},"name":"Image to Video (LTX-2.5, DiffusionGemma prompts)","description":"Native two-stage LTX-2.5 I2V with external DiffusionGemma positive and negative prompts; built-in prompt enhancement remains off.","inputNode":{"id":-10,"bounding":[-640,6460,183.814453125,348]},"outputNode":{"id":-20,"bounding":[5540,6496,128,68]},"inputs":[{"id":"075be400-91e7-40a7-8f4e-d5c907af36e8","name":"input","type":"IMAGE,MASK","linkIds":[763],"label":"first_frame","pos":[-480.185546875,6484]},{"id":"5dab3f68-2044-46e7-b01f-4bf4b8bf4e79","name":"value","type":"STRING","linkIds":[765],"label":"prompt","pos":[-480.185546875,6504]},{"id":"21c9d37e-1f04-47f8-b752-22667180790c","name":"value_1","type":"BOOLEAN","linkIds":[],"label":"prompt_enhance","pos":[-480.185546875,6524]},{"id":"00f26a0c-569d-4aa1-aa8a-281ad2f3c4e0","name":"value_2","type":"INT","linkIds":[767],"label":"duration","pos":[-480.185546875,6544]},{"id":"5d05d885-6c96-43dd-9cdb-f1d0c48045b5","name":"value_3","type":"INT","linkIds":[768],"label":"width","pos":[-480.185546875,6564]},{"id":"c646ee59-a1e0-433e-b2f5-f1d8217fe526","name":"value_4","type":"INT","linkIds":[769],"label":"height","pos":[-480.185546875,6584]},{"id":"7072a79b-5168-42ee-9088-e3f92ac07791","name":"noise_seed","type":"INT","linkIds":[770],"pos":[-480.185546875,6604]},{"id":"85a2fb6d-1b63-40a7-adb6-5acc97a7cc99","name":"value_5","type":"INT","linkIds":[776],"label":"frame_rate","pos":[-480.185546875,6624]},{"id":"8e0b9cf6-f939-4a31-983d-8a76d52dd2d9","name":"negative_prompt","type":"STRING","linkIds":[861],"label":"negative_prompt","pos":[-480.185546875,6644]},{"id":"cbb7ddb9-95d0-4e63-a473-f37c329fbcda","name":"unet_name","type":"COMBO","linkIds":[777],"pos":[-480.185546875,6664]},{"id":"dd0f8943-da6e-4182-8265-efb74da42c33","name":"vae_name","type":"COMBO","linkIds":[778],"label":"video_vae","pos":[-480.185546875,6684]},{"id":"69b9a13b-ee5a-4525-abd9-281d4c257277","name":"vae_name_1","type":"COMBO","linkIds":[779],"label":"audio_vae","pos":[-480.185546875,6704]},{"id":"de6a02d4-1e94-43e7-bf67-2e06f8688943","name":"clip_name","type":"COMBO","linkIds":[780],"pos":[-480.185546875,6724]},{"id":"83db7bd8-4276-4950-8d15-ee1803e29646","name":"model_name","type":"COMBO","linkIds":[781],"label":"upscale_model","pos":[-480.185546875,6744]},{"id":"e5ca018e-1483-44ba-a318-3fc83c7f19ba","name":"clip_name_1","type":"COMBO","linkIds":[],"label":"prompt_enhance_model","pos":[-480.185546875,6764]}],"outputs":[{"id":"b92869b1-7119-47c1-8a9c-c52c131eb1f1","name":"VIDEO","type":"VIDEO","linkIds":[714],"localized_name":"VIDEO","pos":[5564,6520]}],"widgets":[],"nodes":[{"id":419,"type":"CLIPTextEncode","pos":[1160,6040],"size":[550,738.96875],"flags":{},"order":10,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":732},{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":813}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","links":[696]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"CLIPTextEncode","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[""],"color":"#232","bgcolor":"#353"},{"id":420,"type":"PrimitiveStringMultiline","pos":[150,6080],"size":[368.96875,348.96875],"flags":{},"order":11,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"STRING","widget":{"name":"value"},"link":765}],"outputs":[{"localized_name":"STRING","name":"STRING","type":"STRING","links":[813]}],"title":"Prompt","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveStringMultiline","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["Egyptian royal in blue-and-gold headdress and high collar, white dress with golden embroidery and armbands, desert, robot soldiers in formation left and right. She walks steadily forward, head held level and gaze fixed ahead—no dipping or lowering of the head. The camera performs a single, smooth push-in only: starting in a wider shot of her, the robots, and the desert, it moves steadily forward until she is in a medium or medium-close frame, then holds. She stops, posture and head still upright, and says: “The old gods are silent. I am not.” Robot soldiers shift or march in place; sand and fabric move with the wind. No pull-back; the only camera move is the continuous push-in."]},{"id":421,"type":"UNETLoader","pos":[650,6200],"size":[418.96875,129.375],"flags":{},"order":12,"mode":0,"inputs":[{"localized_name":"unet_name","name":"unet_name","type":"COMBO","widget":{"name":"unet_name"},"link":777}],"outputs":[{"localized_name":"MODEL","name":"MODEL","type":"MODEL","links":[771,772,888]}],"properties":{"cnr_id":"comfy-core","ver":"0.29.0","Node name for S&R":"UNETLoader","models":[{"name":"ltx-2.5-22b-distilled-transformer-comfy-int8-convrot.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/diffusion_models/ltx-2.5-22b-distilled-transformer-comfy-int8-convrot.safetensors","directory":"diffusion_models"}]},"widgets_values":["ltx-2.5-22b-distilled-transformer-comfy-int8-convrot.safetensors","default"]},{"id":422,"type":"PrimitiveInt","pos":[150,6630],"size":[368.96875,108.96875],"flags":{},"order":13,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"INT","widget":{"name":"value"},"link":767}],"outputs":[{"localized_name":"INT","name":"INT","type":"INT","links":[715]}],"title":"Duration","properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"PrimitiveInt","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[5,"fixed"]},{"id":363,"type":"PrimitiveBoolean","pos":[160,6480],"size":[368.96875,98.96875],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[{"localized_name":"BOOLEAN","name":"BOOLEAN","type":"BOOLEAN","links":[683,693]}],"title":"Switch to Text to Video?","properties":{"cnr_id":"comfy-core","ver":"0.16.0","Node name for S&R":"PrimitiveBoolean","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[false]},{"id":423,"type":"LTXVConditioning","pos":[1810,6480],"size":[278.96875,129.375],"flags":{},"order":14,"mode":0,"inputs":[{"localized_name":"positive","name":"positive","type":"CONDITIONING","link":696},{"localized_name":"negative","name":"negative","type":"CONDITIONING","link":697},{"localized_name":"frame_rate","name":"frame_rate","type":"FLOAT","widget":{"name":"frame_rate"},"link":698}],"outputs":[{"localized_name":"positive","name":"positive","type":"CONDITIONING","links":[735,755]},{"localized_name":"negative","name":"negative","type":"CONDITIONING","links":[736,756]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"LTXVConditioning","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[24]},{"id":424,"type":"VAELoader","pos":[650,6398.844815215871],"size":[409.375,70],"flags":{},"order":15,"mode":0,"inputs":[{"localized_name":"vae_name","name":"vae_name","type":"COMBO","widget":{"name":"vae_name"},"link":778}],"outputs":[{"localized_name":"VAE","name":"VAE","type":"VAE","links":[727,773,774,775]}],"properties":{"cnr_id":"comfy-core","ver":"0.29.0","Node name for S&R":"VAELoader","models":[{"name":"ltx-2.5-video-vae-bf16.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/vae/ltx-2.5-video-vae-bf16.safetensors","directory":"vae"}]},"widgets_values":["ltx-2.5-video-vae-bf16.safetensors"]},{"id":425,"type":"VAELoader","pos":[650,6560],"size":[400,88.96875],"flags":{},"order":16,"mode":0,"inputs":[{"localized_name":"vae_name","name":"vae_name","type":"COMBO","widget":{"name":"vae_name"},"link":779}],"outputs":[{"localized_name":"VAE","name":"VAE","type":"VAE","links":[729,730]}],"properties":{"cnr_id":"comfy-core","ver":"0.29.0","Node name for S&R":"VAELoader","models":[{"name":"ltx-2.5-audio-vae-bf16.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/vae/ltx-2.5-audio-vae-bf16.safetensors","directory":"vae"}]},"widgets_values":["ltx-2.5-audio-vae-bf16.safetensors"]},{"id":426,"type":"PrimitiveInt","pos":[150,6780],"size":[368.96875,108.96875],"flags":{},"order":17,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"INT","widget":{"name":"value"},"link":768}],"outputs":[{"localized_name":"INT","name":"INT","type":"INT","links":[687]}],"title":"Width","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveInt","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[1280,"fixed"]},{"id":427,"type":"CLIPTextEncode","pos":[1170,6880],"size":[528.96875,238.96875],"flags":{},"order":18,"mode":0,"inputs":[{"localized_name":"clip","name":"clip","type":"CLIP","link":731},{"localized_name":"text","name":"text","type":"STRING","widget":{"name":"text"},"link":897}],"outputs":[{"localized_name":"CONDITIONING","name":"CONDITIONING","type":"CONDITIONING","links":[697]}],"title":"Negative prompt — from DiffusionGemma","properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"CLIPTextEncode","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[""],"color":"#323","bgcolor":"#535"},{"id":428,"type":"CLIPLoader","pos":[650,6730],"size":[400,141.921875],"flags":{},"order":19,"mode":0,"showAdvanced":true,"inputs":[{"localized_name":"clip_name","name":"clip_name","type":"COMBO","widget":{"name":"clip_name"},"link":780}],"outputs":[{"localized_name":"CLIP","name":"CLIP","type":"CLIP","links":[731,732]}],"properties":{"cnr_id":"comfy-core","ver":"0.29.0","Node name for S&R":"CLIPLoader","models":[{"name":"gemma4-12b-with-proj-ltx-2.5-comfy-int8-convrot.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/text_encoders/gemma4-12b-with-proj-ltx-2.5-comfy-int8-convrot.safetensors","directory":"text_encoders"}]},"widgets_values":["gemma4-12b-with-proj-ltx-2.5-comfy-int8-convrot.safetensors","ltxv","default"]},{"id":429,"type":"PrimitiveInt","pos":[150,6930],"size":[368.96875,108.96875],"flags":{},"order":20,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"INT","widget":{"name":"value"},"link":769}],"outputs":[{"localized_name":"INT","name":"INT","type":"INT","links":[688]}],"title":"Height","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveInt","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[720,"fixed"]},{"id":430,"type":"KSamplerSelect","pos":[2224.3008005573674,6709.40359723377],"size":[278.96875,108.96875],"flags":{},"order":1,"mode":0,"inputs":[],"outputs":[{"localized_name":"SAMPLER","name":"SAMPLER","type":"SAMPLER","links":[671]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"KSamplerSelect","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["euler_ancestral"]},{"id":431,"type":"RandomNoise","pos":[2190,6300],"size":[278.96875,108.96875],"flags":{},"order":21,"mode":0,"inputs":[{"localized_name":"noise_seed","name":"noise_seed","type":"INT","widget":{"name":"noise_seed"},"link":770}],"outputs":[{"localized_name":"NOISE","name":"NOISE","type":"NOISE","links":[670]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.56","Node name for S&R":"RandomNoise","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[900359092894726,"randomize"]},{"id":397,"type":"ManualSigmas","pos":[2195.0564044977027,6895.64484593597],"size":[500,98.96875],"flags":{},"order":2,"mode":0,"inputs":[],"outputs":[{"localized_name":"SIGMAS","name":"SIGMAS","type":"SIGMAS","links":[896]}],"properties":{"cnr_id":"comfy-core","ver":"0.14.1","Node name for S&R":"ManualSigmas"},"widgets_values":["1.0, 0.99375, 0.9875, 0.98125, 0.975, 0.909375, 0.725, 0.421875, 0.0"]},{"id":432,"type":"PrimitiveInt","pos":[150,7080],"size":[368.96875,108.96875],"flags":{},"order":22,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"INT","widget":{"name":"value"},"link":776}],"outputs":[{"localized_name":"INT","name":"INT","type":"INT","links":[695,716]}],"title":"Frame Rate","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveInt","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[24,"fixed"]},{"id":433,"type":"LatentUpscaleModelLoader","pos":[640.6800332933674,6971.0077671585605],"size":[409.375,138.96875],"flags":{},"order":23,"mode":0,"inputs":[{"localized_name":"model_name","name":"model_name","type":"COMBO","widget":{"name":"model_name"},"link":781}],"outputs":[{"localized_name":"LATENT_UPSCALE_MODEL","name":"LATENT_UPSCALE_MODEL","type":"LATENT_UPSCALE_MODEL","links":[678]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LatentUpscaleModelLoader","models":[{"name":"ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors","url":"https://huggingface.co/Lightricks/LTX-2.5/resolve/main/latent_upscale_models/ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors","directory":"latent_upscale_models"}],"enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["ltx-2.5-latent-spatial-upscaler-x2-bf16-1.0.safetensors"]},{"id":434,"type":"LTXVDualCFGGuider","pos":[2215.9956793671613,6502.287759672367],"size":[269.046875,159.046875],"flags":{},"order":24,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":771},{"localized_name":"positive","name":"positive","type":"CONDITIONING","link":735},{"localized_name":"negative","name":"negative","type":"CONDITIONING","link":736}],"outputs":[{"localized_name":"GUIDER","name":"GUIDER","type":"GUIDER","links":[733]}],"properties":{"Node name for S&R":"LTXVDualCFGGuider","cnr_id":"comfy-core","ver":"0.28.0","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[0.5,1]},{"id":435,"type":"SamplerCustomAdvanced","pos":[2610,6510],"size":[228.96875,170],"flags":{},"order":25,"mode":0,"inputs":[{"localized_name":"noise","name":"noise","type":"NOISE","link":670},{"localized_name":"guider","name":"guider","type":"GUIDER","link":733},{"localized_name":"sampler","name":"sampler","type":"SAMPLER","link":671},{"localized_name":"sigmas","name":"sigmas","type":"SIGMAS","link":896},{"localized_name":"latent_image","name":"latent_image","type":"LATENT","link":672}],"outputs":[{"localized_name":"output","name":"output","type":"LATENT","links":[702]},{"localized_name":"denoised_output","name":"denoised_output","type":"LATENT","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.60","Node name for S&R":"SamplerCustomAdvanced","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":357,"type":"LTXVImgToVideoInplace","pos":[2070,7390],"size":[278.96875,179.375],"flags":{},"order":9,"mode":0,"inputs":[{"localized_name":"vae","name":"vae","type":"VAE","link":727},{"localized_name":"image","name":"image","type":"IMAGE","link":691},{"localized_name":"latent","name":"latent","type":"LATENT","link":692},{"localized_name":"bypass","name":"bypass","type":"BOOLEAN","widget":{"name":"bypass"},"link":693}],"outputs":[{"localized_name":"latent","name":"latent","type":"LATENT","links":[699]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVImgToVideoInplace","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[0.7,false]},{"id":436,"type":"LTXVEmptyLatentAudio","pos":[1620,7370],"size":[278.96875,170],"flags":{},"order":26,"mode":0,"inputs":[{"localized_name":"audio_vae","name":"audio_vae","type":"VAE","link":729},{"localized_name":"frames_number","name":"frames_number","type":"INT","widget":{"name":"frames_number"},"link":717},{"localized_name":"frame_rate","name":"frame_rate","type":"FLOAT,INT","widget":{"name":"frame_rate"},"link":701}],"outputs":[{"localized_name":"Latent","name":"Latent","type":"LATENT","links":[700]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.68","Node name for S&R":"LTXVEmptyLatentAudio","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[97,25,1]},{"id":437,"type":"LTXVSeparateAVLatent","pos":[2890,6520],"size":[250,98.96875],"flags":{},"order":27,"mode":0,"inputs":[{"localized_name":"av_latent","name":"av_latent","type":"LATENT","link":702}],"outputs":[{"localized_name":"video_latent","name":"video_latent","type":"LATENT","links":[677]},{"localized_name":"audio_latent","name":"audio_latent","type":"LATENT","links":[666]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"LTXVSeparateAVLatent","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":438,"type":"LTXVConcatAVLatent","pos":[2470,7390],"size":[238.96875,98.96875],"flags":{},"order":28,"mode":0,"inputs":[{"localized_name":"video_latent","name":"video_latent","type":"LATENT","link":699},{"localized_name":"audio_latent","name":"audio_latent","type":"LATENT","link":700}],"outputs":[{"localized_name":"latent","name":"latent","type":"LATENT","links":[672]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVConcatAVLatent","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":351,"type":"ResizeImageMaskNode","pos":[190,7480],"size":[300,106],"flags":{},"order":8,"mode":0,"inputs":[{"localized_name":"input","name":"input","type":"IMAGE,MASK","link":763}],"outputs":[{"localized_name":"resized","name":"resized","type":"IMAGE,MASK","links":[752]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"ResizeImageMaskNode","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["scale longer dimension",1536,"lanczos"]},{"id":439,"type":"ComfyMathExpression","pos":[1170,7470],"size":[225,74],"flags":{"collapsed":true},"order":29,"mode":0,"inputs":[{"label":"a","localized_name":"values.a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":687},{"label":"b","localized_name":"values.b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"localized_name":"FLOAT","name":"FLOAT","type":"FLOAT","links":[]},{"localized_name":"INT","name":"INT","type":"INT","links":[689]},{"localized_name":"BOOL","name":"BOOL","type":"BOOLEAN","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"ComfyMathExpression","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["a/2"]},{"id":440,"type":"ComfyMathExpression","pos":[1170,7530],"size":[225,74],"flags":{"collapsed":true},"order":30,"mode":0,"inputs":[{"label":"a","localized_name":"values.a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":688},{"label":"b","localized_name":"values.b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"localized_name":"FLOAT","name":"FLOAT","type":"FLOAT","links":[]},{"localized_name":"INT","name":"INT","type":"INT","links":[690]},{"localized_name":"BOOL","name":"BOOL","type":"BOOLEAN","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"ComfyMathExpression","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["a/2"]},{"id":350,"type":"LTXVPreprocess","pos":[620,7480],"size":[288.96875,108.96875],"flags":{},"order":7,"mode":0,"inputs":[{"localized_name":"image","name":"image","type":"IMAGE","link":752}],"outputs":[{"localized_name":"output_image","name":"output_image","type":"IMAGE","links":[681,691]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVPreprocess","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[18]},{"id":441,"type":"EmptyLTXVLatentVideo","pos":[1630,7600],"size":[278.96875,198.96875],"flags":{},"order":31,"mode":0,"inputs":[{"localized_name":"width","name":"width","type":"INT","widget":{"name":"width"},"link":689},{"localized_name":"height","name":"height","type":"INT","widget":{"name":"height"},"link":690},{"localized_name":"length","name":"length","type":"INT","widget":{"name":"length"},"link":718}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","links":[692]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.60","Node name for S&R":"EmptyLTXVLatentVideo","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[768,512,97,1]},{"id":442,"type":"LTXVLatentUpsampler","pos":[3260,6410],"size":[328.96875,120],"flags":{},"order":32,"mode":0,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":677},{"localized_name":"upscale_model","name":"upscale_model","type":"LATENT_UPSCALE_MODEL","link":678},{"localized_name":"vae","name":"vae","type":"VAE","link":773}],"outputs":[{"localized_name":"LATENT","name":"LATENT","type":"LATENT","links":[682]}],"properties":{"cnr_id":"comfy-core","ver":"0.14.1","Node name for S&R":"LTXVLatentUpsampler","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":349,"type":"LTXVImgToVideoInplace","pos":[3270,6620],"size":[300,179.375],"flags":{},"order":6,"mode":0,"inputs":[{"localized_name":"vae","name":"vae","type":"VAE","link":774},{"localized_name":"image","name":"image","type":"IMAGE","link":681},{"localized_name":"latent","name":"latent","type":"LATENT","link":682},{"localized_name":"bypass","name":"bypass","type":"BOOLEAN","widget":{"name":"bypass"},"link":683}],"outputs":[{"localized_name":"latent","name":"latent","type":"LATENT","links":[665]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVImgToVideoInplace","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[1,false]},{"id":443,"type":"ComfyMathExpression","pos":[1170,7670],"size":[225,74],"flags":{"collapsed":true},"order":33,"mode":0,"inputs":[{"label":"a","localized_name":"values.a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":695},{"label":"b","localized_name":"values.b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"localized_name":"FLOAT","name":"FLOAT","type":"FLOAT","links":[698,713]},{"localized_name":"INT","name":"INT","type":"INT","links":[701]},{"localized_name":"BOOL","name":"BOOL","type":"BOOLEAN","links":[]}],"title":"Math Expression (fps)","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"ComfyMathExpression","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["a"]},{"id":444,"type":"ComfyMathExpression","pos":[1180,7770],"size":[225,94],"flags":{"collapsed":true},"order":34,"mode":0,"inputs":[{"label":"a","localized_name":"values.a","name":"values.a","type":"FLOAT,INT,BOOLEAN","link":715},{"label":"b","localized_name":"values.b","name":"values.b","shape":7,"type":"FLOAT,INT,BOOLEAN","link":716},{"label":"c","localized_name":"values.c","name":"values.c","shape":7,"type":"FLOAT,INT,BOOLEAN","link":null}],"outputs":[{"localized_name":"FLOAT","name":"FLOAT","type":"FLOAT","links":[]},{"localized_name":"INT","name":"INT","type":"INT","links":[717,718]},{"localized_name":"BOOL","name":"BOOL","type":"BOOLEAN","links":[]}],"title":"Math Expression (length)","properties":{"cnr_id":"comfy-core","ver":"0.18.1","Node name for S&R":"ComfyMathExpression","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"input_ue_unconnectable":{},"version":"7.7"}},"widgets_values":["a * b + 1"]},{"id":445,"type":"RandomNoise","pos":[3710,6150],"size":[278.96875,108.96875],"flags":{},"order":3,"mode":0,"inputs":[],"outputs":[{"localized_name":"NOISE","name":"NOISE","type":"NOISE","links":[703]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.75","Node name for S&R":"RandomNoise","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[42,"fixed"]},{"id":446,"type":"LTXVConcatAVLatent","pos":[3710,6760],"size":[278.96875,98.96875],"flags":{},"order":35,"mode":0,"inputs":[{"localized_name":"video_latent","name":"video_latent","type":"LATENT","link":665},{"localized_name":"audio_latent","name":"audio_latent","type":"LATENT","link":666}],"outputs":[{"localized_name":"latent","name":"latent","type":"LATENT","links":[707]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"LTXVConcatAVLatent","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":396,"type":"ManualSigmas","pos":[3710,6980],"size":[288.96875,108.96875],"flags":{},"order":4,"mode":0,"inputs":[],"outputs":[{"localized_name":"SIGMAS","name":"SIGMAS","type":"SIGMAS","links":[751]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"ManualSigmas","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["0.85, 0.7250, 0.4219, 0.0"]},{"id":447,"type":"LTXVDualCFGGuider","pos":[3711.811554084113,6320.869184637932],"size":[269.046875,159.046875],"flags":{},"order":36,"mode":0,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":772},{"localized_name":"positive","name":"positive","type":"CONDITIONING","link":755},{"localized_name":"negative","name":"negative","type":"CONDITIONING","link":756}],"outputs":[{"localized_name":"GUIDER","name":"GUIDER","type":"GUIDER","links":[744]}],"properties":{"Node name for S&R":"LTXVDualCFGGuider","cnr_id":"comfy-core","ver":"0.28.0","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65},"widgets_values":[1,1]},{"id":448,"type":"KSamplerSelect","pos":[3710,6560],"size":[278.96875,108.96875],"flags":{},"order":5,"mode":0,"inputs":[],"outputs":[{"localized_name":"SAMPLER","name":"SAMPLER","type":"SAMPLER","links":[705]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.75","Node name for S&R":"KSamplerSelect","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":["res_2s"]},{"id":449,"type":"SamplerCustomAdvanced","pos":[4070,6500],"size":[228.96875,170],"flags":{},"order":37,"mode":0,"inputs":[{"localized_name":"noise","name":"noise","type":"NOISE","link":703},{"localized_name":"guider","name":"guider","type":"GUIDER","link":744},{"localized_name":"sampler","name":"sampler","type":"SAMPLER","link":705},{"localized_name":"sigmas","name":"sigmas","type":"SIGMAS","link":751},{"localized_name":"latent_image","name":"latent_image","type":"LATENT","link":707}],"outputs":[{"localized_name":"output","name":"output","type":"LATENT","links":[708]},{"localized_name":"denoised_output","name":"denoised_output","type":"LATENT","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.3.75","Node name for S&R":"SamplerCustomAdvanced","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":450,"type":"LTXVSeparateAVLatent","pos":[4370,6500],"size":[228.96875,98.96875],"flags":{},"order":38,"mode":0,"inputs":[{"localized_name":"av_latent","name":"av_latent","type":"LATENT","link":708}],"outputs":[{"localized_name":"video_latent","name":"video_latent","type":"LATENT","links":[709]},{"localized_name":"audio_latent","name":"audio_latent","type":"LATENT","links":[694]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"LTXVSeparateAVLatent","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":451,"type":"VAEDecodeTiled","pos":[4760,6360],"size":[278.96875,198.96875],"flags":{},"order":39,"mode":0,"showAdvanced":true,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":709},{"localized_name":"vae","name":"vae","type":"VAE","link":775}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"IMAGE","links":[711]}],"properties":{"cnr_id":"comfy-core","ver":"0.14.1","Node name for S&R":"VAEDecodeTiled","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[512,64,64,16]},{"id":452,"type":"LTXVAudioVAEDecode","pos":[4760,6650],"size":[268.96875,98.96875],"flags":{},"order":40,"mode":0,"inputs":[{"localized_name":"samples","name":"samples","type":"LATENT","link":694},{"label":"Audio VAE","localized_name":"audio_vae","name":"audio_vae","type":"VAE","link":730}],"outputs":[{"localized_name":"Audio","name":"Audio","type":"AUDIO","links":[712]}],"properties":{"cnr_id":"comfy-core","ver":"0.7.0","Node name for S&R":"LTXVAudioVAEDecode","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[]},{"id":453,"type":"CreateVideo","pos":[5200,6460],"size":[278.96875,129.375],"flags":{},"order":41,"mode":0,"inputs":[{"localized_name":"images","name":"images","type":"IMAGE","link":711},{"localized_name":"audio","name":"audio","shape":7,"type":"AUDIO","link":712},{"localized_name":"fps","name":"fps","type":"FLOAT","widget":{"name":"fps"},"link":713}],"outputs":[{"localized_name":"VIDEO","name":"VIDEO","type":"VIDEO","links":[714]}],"properties":{"cnr_id":"comfy-core","ver":"0.5.1","Node name for S&R":"CreateVideo","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[24,8]},{"id":508,"type":"BasicScheduler","pos":[1836.2732329122807,6878.830222687924],"size":[268.75,117.921875],"flags":{},"order":42,"mode":4,"inputs":[{"localized_name":"model","name":"model","type":"MODEL","link":888}],"outputs":[{"localized_name":"SIGMAS","name":"SIGMAS","type":"SIGMAS","links":[]}],"properties":{"cnr_id":"comfy-core","ver":"0.30.1","Node name for S&R":"BasicScheduler"},"widgets_values":["linear_quadratic",25,1]},{"id":509,"type":"PrimitiveStringMultiline","pos":[150,6740],"size":[368.96875,198.96875],"flags":{},"order":43,"mode":0,"inputs":[{"localized_name":"value","name":"value","type":"STRING","widget":{"name":"value"},"link":861}],"outputs":[{"localized_name":"STRING","name":"STRING","type":"STRING","links":[897]}],"title":"Negative Prompt","properties":{"cnr_id":"comfy-core","ver":"0.16.3","Node name for S&R":"PrimitiveStringMultiline","enableTabs":false,"tabWidth":65,"tabXOffset":10,"hasSecondTab":false,"secondTabText":"Send Back","secondTabOffset":80,"secondTabWidth":65,"ue_properties":{"widget_ue_connectable":{},"version":"7.7","input_ue_unconnectable":{}}},"widgets_values":[""],"color":"#323","bgcolor":"#535"}],"groups":[{"id":1,"title":"Model","bounding":[620,5950,480,1270],"color":"#3f789e","flags":{}},{"id":3,"title":"Prompt","bounding":[1130,5950,980,1270],"color":"#3f789e","flags":{}},{"id":19,"title":"Video Settings","bounding":[100,5950,490,1270],"color":"#3f789e","flags":{}},{"id":2,"title":"Generate Low Resolution","bounding":[2140,5950,1020,1270],"color":"#3f789e","flags":{}},{"id":7,"title":"Latent Upscale","bounding":[3190,5950,460,1270],"color":"#3f789e","flags":{}},{"id":20,"title":"Image Preprocessing","bounding":[100,7250,1000,610],"color":"#3f789e","flags":{}},{"id":21,"title":"Empty Latent","bounding":[1480,7250,1680,610],"color":"#3f789e","flags":{}},{"id":22,"title":"Number conversion","bounding":[1130,7250,320,610],"color":"#3f789e","flags":{}},{"id":6,"title":"Generate High Resolution","bounding":[3680,5950,960,1270],"color":"#3f789e","flags":{}}],"links":[{"id":732,"origin_id":428,"origin_slot":0,"target_id":419,"target_slot":0,"type":"CLIP"},{"id":696,"origin_id":419,"origin_slot":0,"target_id":423,"target_slot":0,"type":"CONDITIONING"},{"id":697,"origin_id":427,"origin_slot":0,"target_id":423,"target_slot":1,"type":"CONDITIONING"},{"id":698,"origin_id":443,"origin_slot":0,"target_id":423,"target_slot":2,"type":"FLOAT"},{"id":731,"origin_id":428,"origin_slot":0,"target_id":427,"target_slot":0,"type":"CLIP"},{"id":735,"origin_id":423,"origin_slot":0,"target_id":434,"target_slot":1,"type":"CONDITIONING"},{"id":736,"origin_id":423,"origin_slot":1,"target_id":434,"target_slot":2,"type":"CONDITIONING"},{"id":670,"origin_id":431,"origin_slot":0,"target_id":435,"target_slot":0,"type":"NOISE"},{"id":733,"origin_id":434,"origin_slot":0,"target_id":435,"target_slot":1,"type":"GUIDER"},{"id":671,"origin_id":430,"origin_slot":0,"target_id":435,"target_slot":2,"type":"SAMPLER"},{"id":672,"origin_id":438,"origin_slot":0,"target_id":435,"target_slot":4,"type":"LATENT"},{"id":727,"origin_id":424,"origin_slot":0,"target_id":357,"target_slot":0,"type":"VAE"},{"id":691,"origin_id":350,"origin_slot":0,"target_id":357,"target_slot":1,"type":"IMAGE"},{"id":692,"origin_id":441,"origin_slot":0,"target_id":357,"target_slot":2,"type":"LATENT"},{"id":693,"origin_id":363,"origin_slot":0,"target_id":357,"target_slot":3,"type":"BOOLEAN"},{"id":729,"origin_id":425,"origin_slot":0,"target_id":436,"target_slot":0,"type":"VAE"},{"id":717,"origin_id":444,"origin_slot":1,"target_id":436,"target_slot":1,"type":"INT"},{"id":701,"origin_id":443,"origin_slot":1,"target_id":436,"target_slot":2,"type":"INT"},{"id":702,"origin_id":435,"origin_slot":0,"target_id":437,"target_slot":0,"type":"LATENT"},{"id":699,"origin_id":357,"origin_slot":0,"target_id":438,"target_slot":0,"type":"LATENT"},{"id":700,"origin_id":436,"origin_slot":0,"target_id":438,"target_slot":1,"type":"LATENT"},{"id":687,"origin_id":426,"origin_slot":0,"target_id":439,"target_slot":0,"type":"INT"},{"id":688,"origin_id":429,"origin_slot":0,"target_id":440,"target_slot":0,"type":"INT"},{"id":752,"origin_id":351,"origin_slot":0,"target_id":350,"target_slot":0,"type":"IMAGE"},{"id":689,"origin_id":439,"origin_slot":1,"target_id":441,"target_slot":0,"type":"INT"},{"id":690,"origin_id":440,"origin_slot":1,"target_id":441,"target_slot":1,"type":"INT"},{"id":718,"origin_id":444,"origin_slot":1,"target_id":441,"target_slot":2,"type":"INT"},{"id":677,"origin_id":437,"origin_slot":0,"target_id":442,"target_slot":0,"type":"LATENT"},{"id":678,"origin_id":433,"origin_slot":0,"target_id":442,"target_slot":1,"type":"LATENT_UPSCALE_MODEL"},{"id":681,"origin_id":350,"origin_slot":0,"target_id":349,"target_slot":1,"type":"IMAGE"},{"id":682,"origin_id":442,"origin_slot":0,"target_id":349,"target_slot":2,"type":"LATENT"},{"id":683,"origin_id":363,"origin_slot":0,"target_id":349,"target_slot":3,"type":"BOOLEAN"},{"id":695,"origin_id":432,"origin_slot":0,"target_id":443,"target_slot":0,"type":"INT"},{"id":715,"origin_id":422,"origin_slot":0,"target_id":444,"target_slot":0,"type":"INT"},{"id":716,"origin_id":432,"origin_slot":0,"target_id":444,"target_slot":1,"type":"INT"},{"id":665,"origin_id":349,"origin_slot":0,"target_id":446,"target_slot":0,"type":"LATENT"},{"id":666,"origin_id":437,"origin_slot":1,"target_id":446,"target_slot":1,"type":"LATENT"},{"id":755,"origin_id":423,"origin_slot":0,"target_id":447,"target_slot":1,"type":"CONDITIONING"},{"id":756,"origin_id":423,"origin_slot":1,"target_id":447,"target_slot":2,"type":"CONDITIONING"},{"id":703,"origin_id":445,"origin_slot":0,"target_id":449,"target_slot":0,"type":"NOISE"},{"id":744,"origin_id":447,"origin_slot":0,"target_id":449,"target_slot":1,"type":"GUIDER"},{"id":705,"origin_id":448,"origin_slot":0,"target_id":449,"target_slot":2,"type":"SAMPLER"},{"id":751,"origin_id":396,"origin_slot":0,"target_id":449,"target_slot":3,"type":"SIGMAS"},{"id":707,"origin_id":446,"origin_slot":0,"target_id":449,"target_slot":4,"type":"LATENT"},{"id":708,"origin_id":449,"origin_slot":0,"target_id":450,"target_slot":0,"type":"LATENT"},{"id":709,"origin_id":450,"origin_slot":0,"target_id":451,"target_slot":0,"type":"LATENT"},{"id":694,"origin_id":450,"origin_slot":1,"target_id":452,"target_slot":0,"type":"LATENT"},{"id":730,"origin_id":425,"origin_slot":0,"target_id":452,"target_slot":1,"type":"VAE"},{"id":711,"origin_id":451,"origin_slot":0,"target_id":453,"target_slot":0,"type":"IMAGE"},{"id":712,"origin_id":452,"origin_slot":0,"target_id":453,"target_slot":1,"type":"AUDIO"},{"id":713,"origin_id":443,"origin_slot":0,"target_id":453,"target_slot":2,"type":"FLOAT"},{"id":714,"origin_id":453,"origin_slot":0,"target_id":-20,"target_slot":0,"type":"VIDEO"},{"id":763,"origin_id":-10,"origin_slot":0,"target_id":351,"target_slot":0,"type":"IMAGE,MASK"},{"id":765,"origin_id":-10,"origin_slot":1,"target_id":420,"target_slot":0,"type":"STRING"},{"id":767,"origin_id":-10,"origin_slot":3,"target_id":422,"target_slot":0,"type":"INT"},{"id":768,"origin_id":-10,"origin_slot":4,"target_id":426,"target_slot":0,"type":"INT"},{"id":769,"origin_id":-10,"origin_slot":5,"target_id":429,"target_slot":0,"type":"INT"},{"id":770,"origin_id":-10,"origin_slot":6,"target_id":431,"target_slot":0,"type":"INT"},{"id":771,"origin_id":421,"origin_slot":0,"target_id":434,"target_slot":0,"type":"MODEL"},{"id":772,"origin_id":421,"origin_slot":0,"target_id":447,"target_slot":0,"type":"MODEL"},{"id":773,"origin_id":424,"origin_slot":0,"target_id":442,"target_slot":2,"type":"VAE"},{"id":774,"origin_id":424,"origin_slot":0,"target_id":349,"target_slot":0,"type":"VAE"},{"id":775,"origin_id":424,"origin_slot":0,"target_id":451,"target_slot":1,"type":"VAE"},{"id":776,"origin_id":-10,"origin_slot":7,"target_id":432,"target_slot":0,"type":"INT"},{"id":777,"origin_id":-10,"origin_slot":9,"target_id":421,"target_slot":0,"type":"COMBO"},{"id":778,"origin_id":-10,"origin_slot":10,"target_id":424,"target_slot":0,"type":"COMBO"},{"id":779,"origin_id":-10,"origin_slot":11,"target_id":425,"target_slot":0,"type":"COMBO"},{"id":780,"origin_id":-10,"origin_slot":12,"target_id":428,"target_slot":0,"type":"COMBO"},{"id":781,"origin_id":-10,"origin_slot":13,"target_id":433,"target_slot":0,"type":"COMBO"},{"id":813,"origin_id":420,"origin_slot":0,"target_id":419,"target_slot":1,"type":"STRING"},{"id":888,"origin_id":421,"origin_slot":0,"target_id":508,"target_slot":0,"type":"MODEL"},{"id":896,"origin_id":397,"origin_slot":0,"target_id":435,"target_slot":3,"type":"SIGMAS"},{"id":861,"origin_id":-10,"origin_slot":8,"target_id":509,"target_slot":0,"type":"STRING"},{"id":897,"origin_id":509,"origin_slot":0,"target_id":427,"target_slot":1,"type":"STRING"}],"extra":{}}]},"config":{},"extra":{"frontendVersion":"1.47.12","VHS_latentpreview":false,"VHS_latentpreviewrate":0,"VHS_MetadataImage":true,"VHS_KeepIntermediate":true,"workflow_note":"Side-by-side DiffusionGemma comparison: LTX-2.5 I2V uses Context Hub; MiniMax-H3 Ref2VA uses H3 Reference Context with a one-image manifest and a fail-closed gate.","ds":{"scale":0.6002048668000012,"offset":[498.1630190487116,-42.76984541575996]},"seed_widgets":{"185":3,"418":0,"456":4}},"version":0.4,"seed_widgets":{"185":3,"418":0,"456":4,"515":3,"524":0}} diff --git a/examples/15_minimax_h3_ref2va_music_video_v6.json b/examples/15_minimax_h3_ref2va_music_video_v6.json new file mode 100644 index 0000000..5872a5b --- /dev/null +++ b/examples/15_minimax_h3_ref2va_music_video_v6.json @@ -0,0 +1,14021 @@ +{ + "id": "0b7e6336-45b3-5db9-a933-489a63c88f52", + "revision": 16, + "last_node_id": 737, + "last_link_id": 1482, + "nodes": [ + { + "id": 116, + "type": "MarkdownNote", + "pos": [ + -1685.4558313894945, + 876.3856918339638 + ], + "size": [ + 1325, + 463.671875 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [], + "title": "START HERE — upload or ACE song / dual identity / Natural audio-led default", + "properties": {}, + "widgets_values": [ + "# DiffusionGemma + ACE-Step + MiniMax-H3 — dual identity / guarded relay\n\n1. **Picture 1** is the primary full-body/wardrobe reference. **Picture 2** is the generated multi-view identity sheet for that same sole performer. If either input is replaced, keep Picture 2 as a same-person multi-panel sheet rather than a second character. The two pictures jointly define one semantic Subject; they are not two people.\n2. **Identity picture count** is fixed to 2 for this sibling. The shared manifest is the single contract source for both Director validation and generation-lane planning.\n3. **Continuity relay** defaults to **Off (identity-first)**. Every lane therefore starts from the same two clean identity anchors and may execute independently. Select **Previous lane tail** only when boundary pose/spatial continuity matters more than the risk of propagating a degraded face.\n4. When relay is enabled, the immediately previous retained tail is routed lazily as **Picture 3** for lanes 2–4. Picture 1 and Picture 2 remain the identity authorities; Picture 3 is opening continuity evidence only.\n5. The two clean references share one downscale-only reference-pixel budget: Picture 1 receives 40% and the multi-panel Picture 2 receives 60%. When enabled, Picture 3 is capped near 0.068 megapixels (roughly 192×352 for a 544×960 source) before entering H3. Native H3 stays on `ref_image_size=match`; every model, LoRA-strength, sampler, scheduler, sigma-shift, Sage, audio-slice, latent, assembly, and pristine ACE-mux setting from the successful b430 execution remains unchanged.\n6. One H3 generation lane remains one model invocation of at most 15 seconds. Native `[Shot N]` blocks remain inside the planned lanes, and the Project Master remains authoritative for duration and lane ceiling.\n7. Leave Director cache on **reuse**. **refresh** is a one-run diagnostic and must immediately return to **reuse**.\n\nThe dependable path is: two clean identity anchors → shared strict manifest → measured-audio Director → dual-identity lane plan → optional lazy Picture 3 relay → unchanged FAST H3 samplers → exact-frame assembly → pristine-song mux.\n\n## Music-performance choice (V5)\n\n- **Natural / audio-led sync** is the default. The soundtrack alone decides whether the subject naturally articulates; no lyric text is used as a mouth-motion schedule.\n- **Dance / music sync** deliberately suppresses singing/lip-sync and concentrates on whole-body choreography, expressive and physically coherent H3 camera work, and beat/dynamic synchronization.\n- **Lyrics + lip sync** first separates the vocal stem and aligns the audible vocal intervals to the authored lyrics. Only verified, hash-locked timing events reach the H3 lane prompts. Instrumental gaps remain explicitly non-vocal. Missing, stale, weak, or failed analysis safely becomes Natural/audio-led behavior instead of forcing singing.\n\nThe lyric-window node below remains an internal lexical-candidate helper. Its old local dropdown is informational only; the single authoritative control is **H3 PERFORMANCE MODE**.\n\n## Music audition + QC (policy revision 4)\n\nA canonically aligned double-time subdivision is advisory when canonical error is within 5%, excerpt onset pressure is at most 4.0/s, vocal activity is present, and at least two of visual-recovery coverage, excerpt score, tonal-family consistency, or transition stability pass their strict thresholds; weakly supported, dense, or misaligned double-time remains blocking.\n\n## H3 generation-lane boundary policy (revision 2)\n\nGeneration-lane seams prefer native shot boundaries with measured recovery, then native-only or mixed evidence. If those grids cannot satisfy the hard duration limits, deterministic balanced seams are used. A non-native seam carries the active source shot into the next lane so later timestamps remain truthful. The plan records why each seam was selected separately from the evidence present there. Missing ideal cut evidence never blocks generation; invalid clocks, malformed shot blocks, timestamps, identity references, stale audio locks, and impossible lane capacity remain hard failures.\n\n## Custom soundtrack upload (V6)\n\n- **Source passthrough** is an ACE planning choice: it still generates one ACE song and does not load an audio file.\n- Set **SONG SOURCE** to **Upload song**, choose a file in **UPLOAD SONG**, and optionally enter its known BPM and matching lyrics. BPM `0` uses signal-derived tempo analysis.\n- Upload mode requests only the uploaded waveform and its measured metadata. ACE candidates remain lazy. Generate mode requests only the existing ACE branch, so an unselected upload never affects Compose or Cover.\n- An uploaded song is source-locked: malformed, too-short, silent, clipped, or artifact-like audio still blocks, while tempo aliases, vocal presence, onset density, tonal movement, and generated-candidate score are reported as advisories instead of rejecting your chosen music. The existing selector remains the authority for waveform SHA-256, excerpt start, sync-safe guide construction, and the pristine soundtrack mux.\n- Matching uploaded lyrics are needed only for **Lyrics + lip sync**. Natural/audio-led and Dance/music-sync modes do not require lyric text.\n" + ], + "color": "#222", + "bgcolor": "#000" + }, + { + "id": 177, + "type": "PrimitiveStringMultiline", + "pos": [ + -1662.1103662362345, + -1515.4760120647911 + ], + "size": [ + 805.03125, + 166.453125 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 1, + 1219, + 1223 + ] + } + ], + "title": "1b. Creative brief — describe motion from the supplied frame", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.24.0", + "Node name for S&R": "PrimitiveStringMultiline" + }, + "widgets_values": [ + "Create a rap music video; keep the black-and-white high-fashion photography aesthetic." + ], + "color": "#232", + "bgcolor": "#353" + }, + { + "id": 178, + "type": "PrimitiveFloat", + "pos": [ + -94.57285207015195, + -983.799058176751 + ], + "size": [ + 512.3125, + 76.25 + ], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "FLOAT", + "type": "FLOAT", + "links": [ + 1083, + 1090, + 1113, + 1213, + 1224, + 1228, + 1235, + 1354, + 1452 + ] + } + ], + "title": "2. FAST TEST VIDEO duration — 5s default; configurable for production", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.30.1", + "Node name for S&R": "PrimitiveFloat" + }, + "widgets_values": [ + 60 + ], + "color": "#322", + "bgcolor": "#533" + }, + { + "id": 179, + "type": "LoadImage", + "pos": [ + -3585.2091636820287, + -2848.607381577966 + ], + "size": [ + 1780.421875, + 2680.265625 + ], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 2, + 1417, + 1419 + ] + }, + { + "name": "MASK", + "type": "MASK", + "links": null + } + ], + "title": "3a. Picture 1 — primary full-body / wardrobe identity authority", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.30.1", + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "img_221.png", + "image" + ] + }, + { + "id": 182, + "type": "DiffusionGemmaModelLoader", + "pos": [ + -1652.1379051444658, + -2199.7164521735895 + ], + "size": [ + 797.453125, + 309.828125 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "model_config", + "type": "DG_MODEL_CONFIG", + "links": [ + 3, + 972 + ] + }, + { + "name": "runtime_status_json", + "type": "STRING", + "links": null + } + ], + "title": "4a. Load DiffusionGemma Director — unload before native H3", + "properties": { + "cnr_id": "diffusiongemma-prompt-builder", + "ver": "dfcd642a21fc689ee6454b2848a6fced501ca00a", + "Node name for S&R": "DiffusionGemmaModelLoader" + }, + "widgets_values": [ + "C:\\ComfyUI\\app\\models\\LLM\\diffusiongemma-26B-A4B-it-NVFP4", + "transformers_inprocess", + "auto", + "modelopt_nvfp4", + true, + "unload_after_run", + "20.0 GB - safe practical", + 0.35 + ] + }, + { + "id": 183, + "type": "DiffusionGemmaContextHub", + "pos": [ + -714.4488746521363, + -1627.459152640017 + ], + "size": [ + 500, + 520 + ], + "flags": {}, + "order": 25, + "mode": 0, + "inputs": [ + { + "name": "user_prompt", + "type": "STRING", + "link": 1 + }, + { + "name": "image", + "shape": 7, + "type": "IMAGE", + "link": 2 + }, + { + "name": "video", + "shape": 7, + "type": "VIDEO", + "link": null + }, + { + "name": "last_frame_image", + "shape": 7, + "type": "IMAGE", + "link": null + } + ], + "outputs": [ + { + "name": "gemma_context", + "type": "DG_CONTEXT", + "links": [ + 973 + ] + }, + { + "name": "context_json", + "type": "STRING", + "links": null + }, + { + "name": "context_preview", + "type": "STRING", + "links": null + } + ], + "title": "4. Song-planning Context Hub — source image context", + "properties": { + "cnr_id": "diffusiongemma-prompt-builder", + "ver": "dfcd642a21fc689ee6454b2848a6fced501ca00a", + "Node name for S&R": "DiffusionGemmaContextHub" + }, + "widgets_values": [ + 1, + 60, + 60, + "trim", + false, + "", + "video_recreation" + ] + }, + { + "id": 185, + "type": "DiffusionGemmaGroundingGuardSettings", + "pos": [ + -711.1883419864932, + -2034.1195900088192 + ], + "size": [ + 500, + 329.375 + ], + "flags": {}, + "order": 5, + "mode": 0, + "showAdvanced": true, + "inputs": [ + { + "name": "external_evidence_json", + "shape": 7, + "type": "STRING", + "link": null + } + ], + "outputs": [ + { + "name": "grounding_guard_config", + "type": "DG_GROUNDING_GUARD_CONFIG", + "links": [ + 6 + ] + }, + { + "name": "config_json", + "type": "STRING", + "links": null + } + ], + "title": "5b. H3 Grounding Guard — audit comparison baseline", + "properties": { + "cnr_id": "diffusiongemma-prompt-builder", + "ver": "dfcd642a21fc689ee6454b2848a6fced501ca00a", + "Node name for S&R": "DiffusionGemmaGroundingGuardSettings" + }, + "widgets_values": [ + "off", + true, + "checkpoint_defaults", + 7, + "fixed", + false, + "diffusiongemma_grounding", + "auto" + ] + }, + { + "id": 418, + "type": "SeedNode", + "pos": [ + 505.92289246050996, + -985.5276950622383 + ], + "size": [ + 466.96875, + 81.984375 + ], + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "seed", + "type": "INT", + "links": [ + 1242 + ] + } + ], + "title": "H3 root seed — video only; does not regenerate the locked song", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.30.1", + "Node name for S&R": "SeedNode" + }, + "widgets_values": [ + 347267244880141, + "fixed" + ] + }, + { + "id": 186, + "type": "DiffusionGemmaCoTGenerator", + "pos": [ + 516.578073457484, + -1488.4939899687745 + ], + "size": [ + 450, + 348.125 + ], + "flags": {}, + "order": 53, + "mode": 0, + "inputs": [ + { + "name": "model_config", + "type": "DG_MODEL_CONFIG", + "link": 3 + }, + { + "name": "gemma_context", + "type": "DG_CONTEXT", + "link": 1221 + }, + { + "name": "target_profile_config", + "type": "DG_TARGET_PROFILE_CONFIG", + "link": 1216 + }, + { + "name": "grounding_guard_config", + "shape": 7, + "type": "DG_GROUNDING_GUARD_CONFIG", + "link": 6 + }, + { + "name": "measured_audio_report_json", + "shape": 7, + "type": "STRING", + "link": 1095 + } + ], + "outputs": [ + { + "name": "final_json", + "type": "STRING", + "links": [ + 7 + ] + }, + { + "name": "reasoning_text", + "type": "STRING", + "links": null + }, + { + "name": "raw_response", + "type": "STRING", + "links": null + }, + { + "name": "metadata_json", + "type": "STRING", + "links": null + }, + { + "name": "grounding_status", + "type": "STRING", + "links": [ + 14 + ] + }, + { + "name": "grounding_report_json", + "type": "STRING", + "links": [ + 15 + ] + } + ], + "title": "6. Build grounded MiniMax-H3 Ref2VA production prompt", + "properties": { + "cnr_id": "diffusiongemma-prompt-builder", + "ver": "dfcd642a21fc689ee6454b2848a6fced501ca00a", + "Node name for S&R": "DiffusionGemmaCoTGenerator" + }, + "widgets_values": [ + 0.45, + "wild", + 1, + "on", + 2048, + "reuse" + ] + }, + { + "id": 187, + "type": "DiffusionGemmaJSONSplitter", + "pos": [ + 509.9817599588055, + -2241.114403567913 + ], + "size": [ + 469.703125, + 520 + ], + "flags": {}, + "order": 56, + "mode": 0, + "inputs": [ + { + "name": "final_json", + "type": "STRING", + "link": 7 + }, + { + "name": "gemma_context", + "shape": 7, + "type": "DG_CONTEXT", + "link": 1222 + }, + { + "name": "target_profile_config", + "shape": 7, + "type": "DG_TARGET_PROFILE_CONFIG", + "link": 1215 + }, + { + "name": "resolution_aspect_ratio_override", + "shape": 7, + "type": "STRING", + "link": 1230 + } + ], + "outputs": [ + { + "name": "ltx_prompt", + "type": "STRING", + "links": [] + }, + { + "name": "ideogram_prompt", + "type": "STRING", + "links": null + }, + { + "name": "negative_prompt", + "type": "STRING", + "links": [] + }, + { + "name": "aspect_ratio", + "type": "STRING", + "links": null + }, + { + "name": "metadata_json", + "type": "STRING", + "links": [ + 12 + ] + }, + { + "name": "scene_segments_json", + "type": "STRING", + "links": null + }, + { + "name": "local_prompts", + "type": "STRING", + "links": null + }, + { + "name": "segment_lengths", + "type": "STRING", + "links": null + }, + { + "name": "is_valid", + "type": "BOOLEAN", + "links": null + }, + { + "name": "resolution_selector_preset", + "type": "STRING", + "links": null + }, + { + "name": "resolution_width", + "type": "INT", + "links": [ + 1373, + 1421 + ] + }, + { + "name": "resolution_height", + "type": "INT", + "links": [ + 1374, + 1422 + ] + }, + { + "name": "ready_for_generation", + "type": "BOOLEAN", + "links": [ + 11 + ] + }, + { + "name": "minimax_h3_prompt", + "type": "STRING", + "links": [ + 1218 + ] + }, + { + "name": "candidate_ltx_prompt", + "type": "STRING", + "links": [] + }, + { + "name": "candidate_negative_prompt", + "type": "STRING", + "links": [] + } + ], + "title": "7. Route H3 prompt + resolution — FAST TEST defaults to 0.4 MP", + "properties": { + "cnr_id": "diffusiongemma-prompt-builder", + "ver": "dfcd642a21fc689ee6454b2848a6fced501ca00a", + "Node name for S&R": "DiffusionGemmaJSONSplitter" + }, + "widgets_values": [ + "", + 0.5, + 32, + "9:16 (Portrait Widescreen)" + ], + "shape": 2 + }, + { + "id": 188, + "type": "DiffusionGemmaBranchGenerationGate", + "pos": [ + 1059.8930791628077, + -2188.6832260261026 + ], + "size": [ + 537.5, + 154.375 + ], + "flags": {}, + "order": 62, + "mode": 0, + "inputs": [ + { + "name": "prompt", + "type": "STRING", + "link": 1218 + }, + { + "name": "ready_for_generation", + "type": "BOOLEAN", + "link": 11 + }, + { + "name": "metadata_json", + "shape": 7, + "type": "STRING", + "link": 12 + } + ], + "outputs": [ + { + "name": "prompt", + "type": "STRING", + "links": [ + 1109, + 1232 + ] + }, + { + "name": "status", + "type": "STRING", + "links": [ + 13 + ] + }, + { + "name": "ready", + "type": "BOOLEAN", + "links": null + } + ], + "title": "8. Isolated MiniMax-H3 prompt generation gate", + "properties": { + "cnr_id": "diffusiongemma-prompt-builder", + "ver": "dfcd642a21fc689ee6454b2848a6fced501ca00a", + "Node name for S&R": "DiffusionGemmaBranchGenerationGate" + }, + "widgets_values": [], + "color": "#5b2222", + "bgcolor": "#8b3333" + }, + { + "id": 189, + "type": "PreviewAny", + "pos": [ + 1067.7615745241126, + -1158.9690664148386 + ], + "size": [ + 531.96875, + 215.59375 + ], + "flags": {}, + "order": 65, + "mode": 0, + "inputs": [ + { + "name": "source", + "type": "*", + "link": 13 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": null + } + ], + "title": "MiniMax-H3 branch gate status", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.15.1", + "Node name for S&R": "PreviewAny", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10 + }, + "widgets_values": [], + "color": "#323", + "bgcolor": "#535" + }, + { + "id": 190, + "type": "PreviewAny", + "pos": [ + 1062.4597173752256, + -1964.0499240918869 + ], + "size": [ + 537.5, + 138.75 + ], + "flags": {}, + "order": 57, + "mode": 0, + "inputs": [ + { + "name": "source", + "type": "*", + "link": 14 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": null + } + ], + "title": "Grounding status", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.15.1", + "Node name for S&R": "PreviewAny", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10 + }, + "widgets_values": [], + "color": "#2a363b", + "bgcolor": "#3f5159" + }, + { + "id": 191, + "type": "PreviewAny", + "pos": [ + 1061.2440562220572, + -1750.3515300356487 + ], + "size": [ + 537.5, + 498.125 + ], + "flags": {}, + "order": 58, + "mode": 0, + "inputs": [ + { + "name": "source", + "type": "*", + "link": 15 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": null + } + ], + "title": "Grounding report", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.15.1", + "Node name for S&R": "PreviewAny", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10 + }, + "widgets_values": [], + "color": "#2a363b", + "bgcolor": "#3f5159" + }, + { + "id": 556, + "type": "SplatStageBlueprintRouter", + "pos": [ + -1677.6579195389002, + 258.8373600709349 + ], + "size": [ + 618.75, + 469.859375 + ], + "flags": {}, + "order": 35, + "mode": 0, + "inputs": [ + { + "name": "blueprint_json", + "type": "STRING", + "link": 971 + }, + { + "name": "song_duration_seconds", + "shape": 7, + "type": "FLOAT", + "link": 992 + }, + { + "name": "root_seed", + "type": "INT", + "widget": { + "name": "root_seed" + }, + "link": 994 + }, + { + "name": "rhythm_mode", + "shape": 7, + "type": "COMBO", + "widget": { + "name": "rhythm_mode" + }, + "link": 997 + }, + { + "name": "candidate_count", + "shape": 7, + "type": "INT", + "widget": { + "name": "candidate_count" + }, + "link": 999 + } + ], + "outputs": [ + { + "name": "validated_blueprint", + "type": "STRING", + "links": [] + }, + { + "name": "project_title", + "type": "STRING", + "links": [] + }, + { + "name": "creative_summary", + "type": "STRING", + "links": [] + }, + { + "name": "ace_tags", + "type": "STRING", + "links": [ + 1117 + ] + }, + { + "name": "lyrics", + "type": "STRING", + "links": [ + 984, + 1118, + 1460 + ] + }, + { + "name": "music_seed", + "type": "INT", + "links": [] + }, + { + "name": "bpm", + "type": "INT", + "links": [ + 1081, + 1120 + ] + }, + { + "name": "duration_seconds", + "type": "FLOAT", + "links": [] + }, + { + "name": "time_signature", + "type": "COMBO", + "links": [ + 1122 + ] + }, + { + "name": "language", + "type": "COMBO", + "links": [ + 1123 + ] + }, + { + "name": "key", + "type": "COMBO", + "links": [ + 1124 + ] + }, + { + "name": "finish_preset", + "type": "COMBO", + "links": [] + }, + { + "name": "blueprint_report", + "type": "STRING", + "links": [ + 930 + ] + }, + { + "name": "fx_blend_mode", + "type": "COMBO", + "links": [] + }, + { + "name": "fx_key_mode", + "type": "COMBO", + "links": [] + }, + { + "name": "fx_opacity", + "type": "FLOAT", + "links": [] + } + ], + "title": "SONG BLUEPRINT ROUTER — exact passthrough + audition provenance", + "properties": { + "Node name for S&R": "SplatStageBlueprintRouter", + "splatstage_node_workflow": true + }, + "widgets_values": [ + 26073001, + "Audition and select", + "auto", + 90 + ] + }, + { + "id": 557, + "type": "PreviewAny", + "pos": [ + -948.8255749052402, + -86.7315379654119 + ], + "size": [ + 547.25, + 451.265625 + ], + "flags": {}, + "order": 40, + "mode": 0, + "inputs": [ + { + "name": "source", + "type": "*", + "link": 930 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [] + } + ], + "title": "LEGACY SPLATSTAGE REPORT — full-song clock does not drive H3 duration", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.30.1", + "Node name for S&R": "PreviewAny", + "splatstage_node_workflow": true + }, + "widgets_values": [] + }, + { + "id": 558, + "type": "UNETLoader", + "pos": [ + -328.6920633252003, + -424.22302783156533 + ], + "size": [ + 456.25, + 85.9375 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 1126 + ] + } + ], + "title": "ACE-Step 1.5 Turbo Model", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.11.1", + "Node name for S&R": "UNETLoader", + "models": [ + { + "directory": "diffusion_models", + "name": "acestep_v1.5_turbo.safetensors", + "url": "https://huggingface.co/Comfy-Org/ace_step_1.5_ComfyUI_files/resolve/main/split_files/diffusion_models/acestep_v1.5_turbo.safetensors" + } + ] + }, + "widgets_values": [ + "acestep_v1.5_turbo.safetensors", + "default" + ] + }, + { + "id": 559, + "type": "DualCLIPLoader", + "pos": [ + -328.6920633252003, + -637.5471822315958 + ], + "size": [ + 453.125, + 141.921875 + ], + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "CLIP", + "type": "CLIP", + "links": [ + 1116 + ] + } + ], + "title": "ACE-Step Text Encoders", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.11.1", + "Node name for S&R": "DualCLIPLoader", + "models": [ + { + "directory": "text_encoders", + "name": "qwen_0.6b_ace15.safetensors", + "url": "https://huggingface.co/Comfy-Org/ace_step_1.5_ComfyUI_files/resolve/main/split_files/text_encoders/qwen_0.6b_ace15.safetensors" + }, + { + "directory": "text_encoders", + "name": "qwen_4b_ace15.safetensors", + "url": "https://huggingface.co/Comfy-Org/ace_step_1.5_ComfyUI_files/resolve/main/split_files/text_encoders/qwen_4b_ace15.safetensors" + } + ] + }, + "widgets_values": [ + "qwen_0.6b_ace15.safetensors", + "qwen_4b_ace15.safetensors", + "ace", + "default" + ] + }, + { + "id": 560, + "type": "VAELoader", + "pos": [ + -331.0253789797162, + -267.88498443850517 + ], + "size": [ + 462.5, + 82.5 + ], + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VAE", + "type": "VAE", + "links": [ + 1128 + ] + } + ], + "title": "ACE-Step VAE", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.11.1", + "Node name for S&R": "VAELoader", + "models": [ + { + "directory": "vae", + "name": "ace_1.5_vae.safetensors", + "url": "https://huggingface.co/Comfy-Org/ace_step_1.5_ComfyUI_files/resolve/main/split_files/vae/ace_1.5_vae.safetensors" + } + ] + }, + "widgets_values": [ + "ace_1.5_vae.safetensors" + ] + }, + { + "id": 562, + "type": "PrimitiveFloat", + "pos": [ + -1690.957075794149, + -628.8322733315554 + ], + "size": [ + 628.125, + 95 + ], + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "FLOAT", + "type": "FLOAT", + "links": [ + 942, + 992, + 1108, + 1121, + 1461 + ] + } + ], + "title": "ACE FULL SONG DURATION — independent from video duration", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.30.1", + "Node name for S&R": "PrimitiveFloat", + "splatstage_node_workflow": true + }, + "widgets_values": [ + 90 + ] + }, + { + "id": 565, + "type": "EmptyAceStep1.5LatentAudio", + "pos": [ + -325.4212797383398, + -31.098351742291698 + ], + "size": [ + 467.625, + 89.921875 + ], + "flags": {}, + "order": 26, + "mode": 0, + "inputs": [ + { + "name": "seconds", + "type": "FLOAT", + "widget": { + "name": "seconds" + }, + "link": 942 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 1127 + ] + } + ], + "title": "Shared full-song ACE latent — candidates are seed-independent", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.11.1", + "Node name for S&R": "EmptyAceStep1.5LatentAudio" + }, + "widgets_values": [ + 90, + 1 + ] + }, + { + "id": 568, + "type": "PreviewAudio", + "pos": [ + 810.3209245544249, + 498.2977606818119 + ], + "size": [ + 778.953125, + 126.25 + ], + "flags": {}, + "order": 42, + "mode": 0, + "inputs": [ + { + "name": "audio", + "type": "AUDIO", + "link": 1091 + } + ], + "outputs": [ + { + "name": "audio", + "type": "AUDIO", + "links": null + } + ], + "title": "SELECTED FULL SONG — decoded QC winner", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.30.1", + "Node name for S&R": "PreviewAudio", + "splatstage_node_workflow": true + }, + "widgets_values": [], + "color": "#223", + "bgcolor": "#335" + }, + { + "id": 569, + "type": "TrimAudioDuration", + "pos": [ + 2874.4513626574226, + -911.1840756672034 + ], + "size": [ + 546.875, + 110.625 + ], + "flags": {}, + "order": 43, + "mode": 4, + "inputs": [ + { + "name": "audio", + "type": "AUDIO", + "link": 1088 + }, + { + "name": "start_index", + "type": "FLOAT", + "widget": { + "name": "start_index" + }, + "link": 1089 + }, + { + "name": "duration", + "type": "FLOAT", + "widget": { + "name": "duration" + }, + "link": 1090 + } + ], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 1092 + ] + } + ], + "title": "QC-SELECTED EXCERPT — suggested start + master video duration", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.30.1", + "Node name for S&R": "TrimAudioDuration", + "splatstage_node_workflow": true + }, + "widgets_values": [ + 30, + 20 + ] + }, + { + "id": 577, + "type": "easy cleanGpuUsed", + "pos": [ + 2871.478596932921, + -733.9829535405103 + ], + "size": [ + 553.125, + 57.9375 + ], + "flags": {}, + "order": 49, + "mode": 4, + "inputs": [ + { + "name": "anything", + "type": "*", + "link": 1092 + } + ], + "outputs": [ + { + "name": "output", + "type": "*", + "links": [ + 1093 + ] + } + ], + "title": "Unload ACE models before Director and H3 conditioning", + "properties": { + "cnr_id": "comfyui-easy-use", + "ver": "1.3.6", + "Node name for S&R": "easy cleanGpuUsed" + }, + "widgets_values": [] + }, + { + "id": 578, + "type": "DiffusionGemmaSplatStagePlanner", + "pos": [ + -1687.8987218524064, + -470.01299799978113 + ], + "size": [ + 634.375, + 293.84375 + ], + "flags": {}, + "order": 31, + "mode": 0, + "inputs": [ + { + "name": "model_config", + "type": "DG_MODEL_CONFIG", + "link": 972 + }, + { + "name": "gemma_context", + "type": "DG_CONTEXT", + "link": 973 + }, + { + "name": "root_seed", + "type": "INT", + "widget": { + "name": "root_seed" + }, + "link": 993 + }, + { + "name": "duration_seconds", + "type": "FLOAT", + "widget": { + "name": "duration_seconds" + }, + "link": 1108 + }, + { + "name": "production_mode", + "type": "COMBO", + "widget": { + "name": "production_mode" + }, + "link": 996 + } + ], + "outputs": [ + { + "name": "blueprint_json", + "type": "STRING", + "links": [ + 971 + ] + }, + { + "name": "is_valid", + "type": "BOOLEAN", + "links": [] + }, + { + "name": "validation_errors_json", + "type": "STRING", + "links": [] + }, + { + "name": "raw_response", + "type": "STRING", + "links": [] + } + ], + "title": "SONG + VIDEO BLUEPRINT — shared production concept / fixed full-song clock", + "properties": { + "cnr_id": "diffusiongemma-prompt-builder", + "ver": "07f3dc254f187b1b1cb6b8f9fc51a7684cb65f20", + "Node name for S&R": "DiffusionGemmaSplatStagePlanner", + "splatstage_node_workflow": true + }, + "widgets_values": [ + 26073001, + 90, + "9:16", + 0.35, + 2048, + "Audition and select" + ] + }, + { + "id": 585, + "type": "PreviewAny", + "pos": [ + -954.388820631998, + -631.4699936875681 + ], + "size": [ + 534.375, + 466.875 + ], + "flags": {}, + "order": 37, + "mode": 0, + "inputs": [ + { + "name": "source", + "type": "*", + "link": 984 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [] + } + ], + "title": "BLUEPRINT LYRICS", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.30.1", + "Node name for S&R": "PreviewAny", + "splatstage_node_workflow": true + }, + "widgets_values": [] + }, + { + "id": 589, + "type": "DiffusionGemmaMusicProductionConcept", + "pos": [ + -1679.6797020977067, + -110.90673587395833 + ], + "size": [ + 618.75, + 153.90625 + ], + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "planner_mode", + "type": "COMBO", + "links": [ + 996, + 998 + ] + }, + { + "name": "router_mode", + "type": "COMBO", + "links": [ + 997 + ] + }, + { + "name": "candidate_count", + "type": "INT", + "links": [ + 999, + 1458 + ] + } + ], + "title": "PRODUCTION CONCEPT — audition 2–4, or one source/joint song", + "properties": { + "cnr_id": "diffusiongemma-prompt-builder", + "ver": "07f3dc254f187b1b1cb6b8f9fc51a7684cb65f20", + "Node name for S&R": "DiffusionGemmaMusicProductionConcept" + }, + "widgets_values": [ + "Source passthrough", + 2 + ] + }, + { + "id": 590, + "type": "SeedNode", + "pos": [ + -1678.159315009466, + 99.0222321811286 + ], + "size": [ + 618.75, + 95 + ], + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "seed", + "type": "INT", + "links": [ + 993, + 994, + 995 + ] + } + ], + "title": "Song plan / audition root — independent from LTX seed", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.30.1", + "Node name for S&R": "SeedNode" + }, + "widgets_values": [ + 26073002, + "fixed" + ] + }, + { + "id": 591, + "type": "DiffusionGemmaSongSeedFanout", + "pos": [ + -322.6292960847051, + 357.22896811030574 + ], + "size": [ + 518.75, + 207.90625 + ], + "flags": {}, + "order": 27, + "mode": 0, + "inputs": [ + { + "name": "root_seed", + "type": "INT", + "widget": { + "name": "root_seed" + }, + "link": 995 + }, + { + "name": "production_concept", + "type": "COMBO", + "widget": { + "name": "production_concept" + }, + "link": 998 + } + ], + "outputs": [ + { + "name": "candidate_1_seed", + "type": "INT", + "links": [ + 1119 + ] + }, + { + "name": "candidate_2_seed", + "type": "INT", + "links": [ + 1130 + ] + }, + { + "name": "candidate_3_seed", + "type": "INT", + "links": [ + 1131 + ] + }, + { + "name": "candidate_4_seed", + "type": "INT", + "links": [ + 1132 + ] + }, + { + "name": "seed_report_json", + "type": "STRING", + "links": [] + } + ], + "title": "ACE candidate seeds — deterministic / concept-aware", + "properties": { + "cnr_id": "diffusiongemma-prompt-builder", + "ver": "07f3dc254f187b1b1cb6b8f9fc51a7684cb65f20", + "Node name for S&R": "DiffusionGemmaSongSeedFanout" + }, + "widgets_values": [ + 26073001, + "Audition and select" + ] + }, + { + "id": 592, + "type": "DiffusionGemmaACEReferenceMode", + "pos": [ + -333.0959145072821, + 138.11120467854948 + ], + "size": [ + 468.859375, + 107.59375 + ], + "flags": {}, + "order": 13, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "generate_audio_codes", + "type": "BOOLEAN", + "links": [ + 1125 + ] + }, + { + "name": "mode_token", + "type": "STRING", + "links": [ + 1129 + ] + } + ], + "title": "ACE SOURCE MODE — Compose new / optional Cover reference", + "properties": { + "cnr_id": "diffusiongemma-prompt-builder", + "ver": "07f3dc254f187b1b1cb6b8f9fc51a7684cb65f20", + "Node name for S&R": "DiffusionGemmaACEReferenceMode" + }, + "widgets_values": [ + "Compose new" + ] + }, + { + "id": 609, + "type": "CM_IntToFloat", + "pos": [ + 262.77509882393565, + 6.2424908454713375 + ], + "size": [ + 428.125, + 85.921875 + ], + "flags": {}, + "order": 38, + "mode": 0, + "inputs": [ + { + "name": "a", + "type": "INT", + "widget": { + "name": "a" + }, + "link": 1081 + } + ], + "outputs": [ + { + "name": "FLOAT", + "type": "FLOAT", + "links": [ + 1459 + ] + } + ], + "title": "Requested BPM → numeric QC expectation", + "properties": { + "cnr_id": "ComfyMath", + "ver": "c01177221c31b8e5fbc062778fc8254aeb541638", + "Node name for S&R": "CM_IntToFloat" + }, + "widgets_values": [ + 120 + ] + }, + { + "id": 610, + "type": "DiffusionGemmaAudioCandidateSelector", + "pos": [ + 806.2624266417795, + 22.440010134628892 + ], + "size": [ + 784.375, + 398.40625 + ], + "flags": {}, + "order": 41, + "mode": 0, + "inputs": [ + { + "name": "candidate_1", + "shape": 7, + "type": "AUDIO", + "link": 1471 + }, + { + "name": "candidate_2", + "shape": 7, + "type": "AUDIO", + "link": 1472 + }, + { + "name": "candidate_3", + "shape": 7, + "type": "AUDIO", + "link": 1473 + }, + { + "name": "candidate_4", + "shape": 7, + "type": "AUDIO", + "link": 1474 + }, + { + "name": "candidate_count", + "type": "INT", + "widget": { + "name": "candidate_count" + }, + "link": 1475 + }, + { + "name": "expected_bpm", + "type": "FLOAT", + "widget": { + "name": "expected_bpm" + }, + "link": 1476 + }, + { + "name": "excerpt_duration_seconds", + "type": "FLOAT", + "widget": { + "name": "excerpt_duration_seconds" + }, + "link": 1083 + }, + { + "name": "source_policy", + "type": "STRING", + "link": 1477, + "shape": 7 + } + ], + "outputs": [ + { + "name": "selected_audio", + "type": "AUDIO", + "links": [ + 1088, + 1091 + ] + }, + { + "name": "suggested_start_seconds", + "type": "FLOAT", + "links": [ + 1089, + 1112, + 1227, + 1234, + 1451 + ] + }, + { + "name": "waveform_sha256", + "type": "STRING", + "links": [ + 1099, + 1225, + 1449 + ] + }, + { + "name": "director_report_json", + "type": "STRING", + "links": [ + 1094 + ] + }, + { + "name": "audit_report_json", + "type": "STRING", + "links": [ + 1097 + ] + }, + { + "name": "status", + "type": "STRING", + "links": [ + 1098 + ] + }, + { + "name": "ready", + "type": "BOOLEAN", + "links": [] + } + ], + "title": "MUSIC INPUT + QC — ACE candidates or uploaded-song verification", + "properties": { + "cnr_id": "diffusiongemma-prompt-builder", + "ver": "07f3dc254f187b1b1cb6b8f9fc51a7684cb65f20", + "Node name for S&R": "DiffusionGemmaAudioCandidateSelector" + }, + "widgets_values": [ + 2, + "auto_select", + 0, + 25, + 0.52, + "", + -1 + ] + }, + { + "id": 611, + "type": "DiffusionGemmaLTXAudioGuide", + "pos": [ + 2879.8432038470582, + -606.8448817205947 + ], + "size": [ + 553.125, + 0 + ], + "flags": {}, + "order": 54, + "mode": 4, + "inputs": [ + { + "name": "final_audio", + "type": "AUDIO", + "link": 1093 + }, + { + "name": "vocal_stem", + "shape": 7, + "type": "AUDIO", + "link": null + } + ], + "outputs": [ + { + "name": "conditioning_audio", + "type": "AUDIO", + "links": [ + 1254, + 1282, + 1310, + 1338 + ] + }, + { + "name": "final_audio", + "type": "AUDIO", + "links": [ + 1096, + 1353, + 1445, + 1446 + ] + }, + { + "name": "conditioning_sha256", + "type": "STRING", + "links": [] + }, + { + "name": "guide_report_json", + "type": "STRING", + "links": [] + }, + { + "name": "status", + "type": "STRING", + "links": [] + }, + { + "name": "ready", + "type": "BOOLEAN", + "links": [] + } + ], + "title": "H3 AUDIO GUIDE — sync-safe conditioning / pristine final master", + "properties": { + "cnr_id": "diffusiongemma-prompt-builder", + "ver": "07f3dc254f187b1b1cb6b8f9fc51a7684cb65f20", + "Node name for S&R": "DiffusionGemmaLTXAudioGuide" + }, + "widgets_values": [ + "sync_safe" + ] + }, + { + "id": 612, + "type": "easy cleanGpuUsed", + "pos": [ + 486.95464529385794, + -1644.7211114940758 + ], + "size": [ + 500, + 82.5 + ], + "flags": {}, + "order": 46, + "mode": 0, + "inputs": [ + { + "name": "anything", + "type": "*", + "link": 1094 + } + ], + "outputs": [ + { + "name": "output", + "type": "*", + "links": [ + 1095, + 1231 + ] + } + ], + "title": "Unload ACE after QC — pass compact measurements to H3 Director", + "properties": { + "cnr_id": "comfyui-easy-use", + "ver": "1.3.6", + "Node name for S&R": "easy cleanGpuUsed" + }, + "widgets_values": [] + }, + { + "id": 613, + "type": "PreviewAudio", + "pos": [ + 4606.2702970257105, + -1994.8188322956607 + ], + "size": [ + 559.375, + 101.9375 + ], + "flags": {}, + "order": 59, + "mode": 4, + "inputs": [ + { + "name": "audio", + "type": "AUDIO", + "link": 1096 + } + ], + "outputs": [ + { + "name": "audio", + "type": "AUDIO", + "links": [] + } + ], + "title": "FINAL SOUNDTRACK EXCERPT — pristine assembly audio", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.30.1", + "Node name for S&R": "PreviewAudio", + "splatstage_node_workflow": true + }, + "widgets_values": [], + "color": "#223", + "bgcolor": "#335" + }, + { + "id": 614, + "type": "PreviewAny", + "pos": [ + 811.1362843922215, + -682.1558516136769 + ], + "size": [ + 775, + 166.875 + ], + "flags": {}, + "order": 47, + "mode": 0, + "inputs": [ + { + "name": "source", + "type": "*", + "link": 1097 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [] + } + ], + "title": "FULL MUSIC QC AUDIT — candidate measurements, rejection reasons + advisories", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.15.1", + "Node name for S&R": "PreviewAny", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10 + }, + "widgets_values": [], + "color": "#223", + "bgcolor": "#335" + }, + { + "id": 615, + "type": "PreviewAny", + "pos": [ + 817.399411460542, + -436.26462567732233 + ], + "size": [ + 769.0625, + 160.625 + ], + "flags": {}, + "order": 48, + "mode": 0, + "inputs": [ + { + "name": "source", + "type": "*", + "link": 1098 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [] + } + ], + "title": "MUSIC QC STATUS — must pass before Director + LTX", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.15.1", + "Node name for S&R": "PreviewAny", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10 + }, + "widgets_values": [], + "color": "#223", + "bgcolor": "#335" + }, + { + "id": 616, + "type": "PreviewAny", + "pos": [ + 820.429526207185, + -203.56100025797696 + ], + "size": [ + 763.421875, + 145.8125 + ], + "flags": {}, + "order": 44, + "mode": 0, + "inputs": [ + { + "name": "source", + "type": "*", + "link": 1099 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [] + } + ], + "title": "SELECTED SONG SHA-256 — copy when using lock-by-hash", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.15.1", + "Node name for S&R": "PreviewAny", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10 + }, + "widgets_values": [], + "color": "#223", + "bgcolor": "#335" + }, + { + "id": 621, + "type": "DiffusionGemmaLTXPerformancePrompt", + "pos": [ + 1822.661992988191, + -1172.6939711687203 + ], + "size": [ + 563.65625, + 0 + ], + "flags": { + "collapsed": true + }, + "order": 64, + "mode": 0, + "inputs": [ + { + "name": "ltx_prompt", + "type": "STRING", + "link": 1109 + }, + { + "name": "lyrics", + "shape": 7, + "type": "STRING", + "link": 1478 + }, + { + "name": "performance_mode_override", + "shape": 7, + "type": "STRING", + "link": 1241 + }, + { + "name": "song_duration_seconds", + "type": "FLOAT", + "widget": { + "name": "song_duration_seconds" + }, + "link": 1481 + }, + { + "name": "excerpt_start_seconds", + "type": "FLOAT", + "widget": { + "name": "excerpt_start_seconds" + }, + "link": 1112 + }, + { + "name": "excerpt_duration_seconds", + "type": "FLOAT", + "widget": { + "name": "excerpt_duration_seconds" + }, + "link": 1113 + } + ], + "outputs": [ + { + "name": "ltx_prompt", + "type": "STRING", + "links": [] + }, + { + "name": "selected_lyrics", + "type": "STRING", + "links": [ + 1115, + 1237 + ] + }, + { + "name": "status", + "type": "STRING", + "links": [] + }, + { + "name": "performance_report_json", + "type": "STRING", + "links": [] + }, + { + "name": "performance_mode", + "type": "STRING", + "links": [] + } + ], + "title": "INTERNAL LYRIC CANDIDATE WINDOW — mode comes only from H3 PERFORMANCE MODE", + "properties": { + "cnr_id": "diffusiongemma-prompt-builder", + "ver": "07f3dc254f187b1b1cb6b8f9fc51a7684cb65f20", + "Node name for S&R": "DiffusionGemmaLTXPerformancePrompt" + }, + "widgets_values": [ + "Natural / audio-led sync", + 90, + 0, + 20 + ], + "color": "#223", + "bgcolor": "#335" + }, + { + "id": 622, + "type": "PreviewAny", + "pos": [ + 1781.8491399306688, + -1086.0461874334508 + ], + "size": [ + 756.25, + 190.34375 + ], + "flags": {}, + "order": 68, + "mode": 0, + "inputs": [ + { + "name": "source", + "type": "*", + "link": 1115 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [] + } + ], + "title": "H3 PERFORMANCE LYRIC WINDOW — empty in dance/music-sync mode", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.15.1", + "Node name for S&R": "PreviewAny", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10 + }, + "widgets_values": [], + "color": "#223", + "bgcolor": "#335" + }, + { + "id": 623, + "type": "9b7da01b-94d2-4514-ac96-ffd5609fdd54", + "pos": [ + 258.1106671000332, + -652.8231862440005 + ], + "size": [ + 431.25, + 585.625 + ], + "flags": {}, + "order": 39, + "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 1116 + }, + { + "name": "tags", + "type": "STRING", + "widget": { + "name": "tags" + }, + "link": 1117 + }, + { + "name": "lyrics", + "type": "STRING", + "widget": { + "name": "lyrics" + }, + "link": 1118 + }, + { + "name": "seed", + "type": "INT", + "widget": { + "name": "seed" + }, + "link": 1119 + }, + { + "name": "bpm", + "type": "INT", + "widget": { + "name": "bpm" + }, + "link": 1120 + }, + { + "name": "duration", + "type": "FLOAT", + "widget": { + "name": "duration" + }, + "link": 1121 + }, + { + "name": "timesignature", + "type": "COMBO", + "widget": { + "name": "timesignature" + }, + "link": 1122 + }, + { + "name": "language", + "type": "COMBO", + "widget": { + "name": "language" + }, + "link": 1123 + }, + { + "name": "keyscale", + "type": "COMBO", + "widget": { + "name": "keyscale" + }, + "link": 1124 + }, + { + "name": "generate_audio_codes", + "type": "BOOLEAN", + "widget": { + "name": "generate_audio_codes" + }, + "link": 1125 + }, + { + "name": "model", + "type": "MODEL", + "link": 1126 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 1127 + }, + { + "name": "vae", + "type": "VAE", + "link": 1128 + }, + { + "name": "mode_token", + "type": "STRING", + "link": 1129 + }, + { + "name": "seed_1", + "type": "INT", + "widget": { + "name": "seed_1" + }, + "link": 1130 + }, + { + "name": "seed_2", + "type": "INT", + "widget": { + "name": "seed_2" + }, + "link": 1131 + }, + { + "name": "seed_3", + "type": "INT", + "widget": { + "name": "seed_3" + }, + "link": 1132 + } + ], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 1462 + ] + }, + { + "name": "AUDIO_1", + "type": "AUDIO", + "links": [ + 1463 + ] + }, + { + "name": "AUDIO_2", + "type": "AUDIO", + "links": [ + 1464 + ] + }, + { + "name": "AUDIO_3", + "type": "AUDIO", + "links": [ + 1465 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.30.1", + "previewExposures": [ + { + "name": "$$canvas-image-preview", + "sourceNodeId": "566", + "sourcePreviewName": "$$canvas-image-preview" + }, + { + "name": "$$canvas-image-preview_1", + "sourceNodeId": "596", + "sourcePreviewName": "$$canvas-image-preview" + }, + { + "name": "$$canvas-image-preview_2", + "sourceNodeId": "601", + "sourcePreviewName": "$$canvas-image-preview" + }, + { + "name": "$$canvas-image-preview_3", + "sourceNodeId": "606", + "sourcePreviewName": "$$canvas-image-preview" + } + ] + }, + "widgets_values": [ + "bright pop", + "[Verse 1]\\nLight it up tonight\\n[Chorus]\\nWe are shining bright\\n[Verse 2]\\nCarry the rhythm on\\n[Bridge]\\nHearts in the neon glow\\n[Chorus]\\nWe are shining bright", + 26073001, + 120, + 90, + "4", + "en", + "C major", + true, + 26073001, + 26073001, + 26073001 + ] + }, + { + "id": 624, + "type": "PrimitiveStringMultiline", + "pos": [ + -1662.7216002542407, + -1794.8840439196615 + ], + "size": [ + 807.453125, + 184.4375 + ], + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 1239 + ] + } + ], + "title": "1a. Creative brief — H3 audio/performance guidance", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.24.0", + "Node name for S&R": "PrimitiveStringMultiline" + }, + "widgets_values": [ + "Use the selected song as the exact soundtrack and timing authority. Synchronize body motion, scene changes, cuts, and expressive, physically coherent H3 camera choreography to measured rhythm, phrasing, dynamics, and recovery intervals. Preserve explicitly requested orbiting, swirling, sweeping or whip movement, pronounced parallax, and coherent compound paths rather than downgrading them. When camera direction is unspecified, let the active Director creativity mode choose camera energy proportional to creative strength. The audio-aware H3 generation-lane planner applies the selected dance or lyric/lip-sync performance contract after validation." + ], + "color": "#2a363b", + "bgcolor": "#3f5159" + }, + { + "id": 651, + "type": "SaveVideo", + "pos": [ + 6213.03896509444, + -2339.074043283506 + ], + "size": [ + 2759.90625, + 4883.875 + ], + "flags": {}, + "order": 80, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 1357 + } + ], + "outputs": [ + { + "name": "video", + "type": "VIDEO", + "links": null + } + ], + "title": "FINAL MINIMAX-H3 MUSIC VIDEO — locked ACE master", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.30.1", + "Node name for S&R": "SaveVideo" + }, + "widgets_values": [ + "minimax_h3/ref2va_image_audio", + "mp4", + "h264", + "auto" + ] + }, + { + "id": 653, + "type": "VAELoader", + "pos": [ + 2826.174814443676, + -1264.309930691746 + ], + "size": [ + 626.015625, + 69.875 + ], + "flags": {}, + "order": 15, + "mode": 4, + "inputs": [], + "outputs": [ + { + "name": "VAE", + "type": "VAE", + "links": [ + 1363 + ] + } + ], + "title": "MiniMax-H3 video VAE", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.30.1", + "Node name for S&R": "VAELoader", + "models": [ + { + "directory": "vae", + "name": "minimax_h3_video_vae_fp16.safetensors", + "url": "https://huggingface.co/Comfy-Org/MiniMax-H3/resolve/main/vae/minimax_h3_video_vae_fp16.safetensors" + } + ] + }, + "widgets_values": [ + "minimax_h3_video_vae_fp16.safetensors" + ] + }, + { + "id": 654, + "type": "VAELoader", + "pos": [ + 2826.174814443676, + -1134.3099306917459 + ], + "size": [ + 629.875, + 75.609375 + ], + "flags": {}, + "order": 16, + "mode": 4, + "inputs": [], + "outputs": [ + { + "name": "VAE", + "type": "VAE", + "links": [ + 1369 + ] + } + ], + "title": "MiniMax-H3 audio VAE — conditioning encoder only", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.30.1", + "Node name for S&R": "VAELoader", + "models": [ + { + "directory": "vae", + "name": "minimax_h3_audio_vae_fp32.safetensors", + "url": "https://huggingface.co/Comfy-Org/MiniMax-H3/resolve/main/vae/minimax_h3_audio_vae_fp32.safetensors" + } + ] + }, + "widgets_values": [ + "minimax_h3_audio_vae_fp32.safetensors" + ] + }, + { + "id": 661, + "type": "UNETLoader", + "pos": [ + 2832.163323388969, + -2158.8666265267266 + ], + "size": [ + 607.09375, + 88.625 + ], + "flags": {}, + "order": 17, + "mode": 4, + "inputs": [], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 1398 + ] + } + ], + "title": "MiniMax-H3 Ref2VA — pruned INT8 fast-test model", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.30.1", + "Node name for S&R": "UNETLoader", + "models": [ + { + "directory": "diffusion_models", + "name": "minimax_h3_ref2va_int8_convrot.safetensors", + "url": "https://huggingface.co/Comfy-Org/MiniMax-H3/resolve/main/diffusion_models/minimax_h3_ref2va_int8_convrot.safetensors" + } + ] + }, + "widgets_values": [ + "minimax_h3_ref2va_pruned_int8_convrot.safetensors", + "default" + ] + }, + { + "id": 662, + "type": "CLIPLoader", + "pos": [ + 2826.174814443676, + -1444.3099306917445 + ], + "size": [ + 626.015625, + 117.984375 + ], + "flags": {}, + "order": 18, + "mode": 4, + "inputs": [], + "outputs": [ + { + "name": "CLIP", + "type": "CLIP", + "links": [ + 1368 + ] + } + ], + "title": "MiniMax-H3 Qwen vision-language encoder", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.30.1", + "Node name for S&R": "CLIPLoader", + "models": [ + { + "directory": "text_encoders", + "name": "qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors", + "url": "https://huggingface.co/Comfy-Org/MiniMax-H3/resolve/main/text_encoders/qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors" + } + ] + }, + "widgets_values": [ + "qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors", + "minimax", + "default" + ] + }, + { + "id": 664, + "type": "CreateVideo", + "pos": [ + 5337.102423173775, + -1029.2909108926021 + ], + "size": [ + 646.875, + 141.875 + ], + "flags": {}, + "order": 78, + "mode": 4, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 1355 + }, + { + "name": "audio", + "shape": 7, + "type": "AUDIO", + "link": 1356 + } + ], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 1357 + ] + } + ], + "title": "Mux exact ACE master with exact-length assembled H3 frames", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.30.1", + "Node name for S&R": "CreateVideo" + }, + "widgets_values": [ + 24, + 8 + ] + }, + { + "id": 670, + "type": "RHMiniMaxH3SageAttentionPatch", + "pos": [ + -7476.173372708015, + 1828.1842988409599 + ], + "size": [ + 637.5, + 98.125 + ], + "flags": {}, + "order": 19, + "mode": 4, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": null + } + ], + "outputs": [ + { + "name": "model", + "type": "MODEL", + "links": [] + } + ], + "title": "Bundled H3 SageAttention patch — safe passthrough when unavailable", + "properties": { + "aux_id": "HM-RunningHub/ComfyUI_RH_MinMaxH3", + "ver": "445fccb8f4e2d2a866d446a6e5589dddc5f0ec6a", + "Node name for S&R": "RHMiniMaxH3SageAttentionPatch" + }, + "widgets_values": [ + true + ] + }, + { + "id": 673, + "type": "DiffusionGemmaMiniMaxH3TargetProfile", + "pos": [ + -113.40166908695596, + -1602.329425034348 + ], + "size": [ + 537.609375, + 533.796875 + ], + "flags": {}, + "order": 32, + "mode": 0, + "inputs": [ + { + "name": "target_duration_seconds", + "type": "FLOAT", + "widget": { + "name": "target_duration_seconds" + }, + "link": 1213 + }, + { + "name": "audio_guidance", + "type": "STRING", + "widget": { + "name": "audio_guidance" + }, + "link": 1240 + } + ], + "outputs": [ + { + "name": "target_profile_config", + "type": "DG_TARGET_PROFILE_CONFIG", + "links": [ + 1215, + 1216 + ] + }, + { + "name": "target_profile_json", + "type": "STRING", + "links": null + } + ], + "title": "H3 TARGET PROFILE — native shots inside each generated video", + "properties": { + "cnr_id": "diffusiongemma-prompt-builder", + "ver": "07f3dc254f187b1b1cb6b8f9fc51a7684cb65f20", + "Node name for S&R": "DiffusionGemmaMiniMaxH3TargetProfile" + }, + "widgets_values": [ + "ref2va", + 0, + "auto_scene_audio", + "", + "custom", + 15, + "off", + 2, + "", + "auto", + "", + 0 + ] + }, + { + "id": 674, + "type": "DiffusionGemmaH3ReferenceContext", + "pos": [ + -118.53715236264348, + -2247.2743110960437 + ], + "size": [ + 548.421875, + 566.875 + ], + "flags": {}, + "order": 34, + "mode": 0, + "inputs": [ + { + "name": "user_prompt", + "type": "STRING", + "link": 1219 + }, + { + "name": "reference_images", + "shape": 7, + "type": "IMAGE", + "link": 1424 + }, + { + "name": "reference_video", + "shape": 7, + "type": "VIDEO", + "link": null + }, + { + "name": "reference_manifest", + "type": "STRING", + "widget": { + "name": "reference_manifest" + }, + "link": 1423 + } + ], + "outputs": [ + { + "name": "gemma_context", + "type": "DG_CONTEXT", + "links": [ + 1221, + 1222 + ] + }, + { + "name": "context_json", + "type": "STRING", + "links": [] + }, + { + "name": "context_preview", + "type": "STRING", + "links": [] + } + ], + "title": "5a. MiniMax-H3 ordered reference context — Pictures 1+2 + Audio 1", + "properties": { + "cnr_id": "diffusiongemma-prompt-builder", + "ver": "07f3dc254f187b1b1cb6b8f9fc51a7684cb65f20", + "Node name for S&R": "DiffusionGemmaH3ReferenceContext" + }, + "widgets_values": [ + ": [dg:identity,appearance,object,color,composition] primary identity, body, wardrobe, and target-composition authority for the same woman.\n: [dg:identity,appearance] multi-panel identity evidence for the same woman only; do not transfer its layout, grid, seams, backgrounds, or pose sequence, and its panels are not separate people.\n