From b02905a8e26a087c1d2a013d20f68277707f72c1 Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Tue, 4 Aug 2026 14:09:37 +0300 Subject: [PATCH 01/29] workflows comfy --- docs/serviceTemplates/README.md | 25 + docs/serviceTemplates/ltx-video-ugc.json | 68 + .../workflows/ocean_ugc_product.json | 5064 ++++++++++++++++ .../workflows/ocean_ugc_testimonial.json | 5167 +++++++++++++++++ src/@types/C2D/ServiceOnDemand.ts | 10 + src/@types/commands.ts | 1 + src/components/c2d/compute_engine_base.ts | 3 +- src/components/c2d/compute_engine_docker.ts | 27 +- src/components/core/service/startService.ts | 16 +- src/components/core/service/templateLoader.ts | 35 +- src/components/httpRoutes/compute.ts | 1 + src/test/unit/service/serviceHandlers.test.ts | 34 +- src/test/unit/service/serviceSchemas.test.ts | 7 + src/test/unit/service/templateLoader.test.ts | 47 +- src/utils/config/schemas.ts | 18 +- 15 files changed, 10510 insertions(+), 13 deletions(-) create mode 100644 docs/serviceTemplates/ltx-video-ugc.json create mode 100644 docs/serviceTemplates/workflows/ocean_ugc_product.json create mode 100644 docs/serviceTemplates/workflows/ocean_ugc_testimonial.json diff --git a/docs/serviceTemplates/README.md b/docs/serviceTemplates/README.md index da37c18b8..506dc7be9 100644 --- a/docs/serviceTemplates/README.md +++ b/docs/serviceTemplates/README.md @@ -31,6 +31,7 @@ Templates are validated against `ServiceTemplateSchema` | `envVars` | Fixed operator-set env vars (values never returned to callers) | | `userConfigurableEnvVars` | Env vars the consumer supplies via ECIES-encrypted `userData` (optional regex `validation`, `sensitive` UI hint) | | `requiredResources` / `recommendedResources` | Gate/score environment selection (`min` is enforced at `SERVICE_START`) | +| `workflows` | Selectable graphs for UI-driven templates; each entry is `id` / `name` / `file` (a path to the graph JSON, resolved relative to this directory and inlined into `graph` at load time) | ## Templates in this folder @@ -101,6 +102,30 @@ so no `command` override is needed. Bundles ComfyUI-Manager for installing check custom nodes from the UI; `HF_TOKEN` / `CIVITAI_TOKEN` are optional user env vars for gated downloads. ~10 GB VRAM for SDXL. +### `ltx-video-ugc.json` — ComfyUI, LTX-2.3 UGC video (GPU) + +ComfyUI preloaded with LTX-2.3 for vertical short-form product video, with two ready-made +workflow graphs (`workflows/ocean_ugc_product.json`, `workflows/ocean_ugc_testimonial.json`): +a product photo becomes a 9:16 clip with camera motion and ambient audio, or a creator photo +plus a voice clip becomes a lip-synced testimonial (capped at the graph's 5.8s — trim longer +voiceovers or raise the frame count). `entrypoint`/`command` override to a bootstrap +script (inlined as `command[0]`) that downloads the ~38 GiB weight set (LTX-2.3 22B fp8 +checkpoint, Gemma-3-12B text encoder, two LoRAs, the x2 spatial upscaler) on first launch. +Pick a persistent-storage bucket for this template — weights and generated clips both live +there, so only the first launch pays the download; without a bucket the weights land inside +the container and are lost on stop. When a bucket is mounted, `ComfyUI/models` is a symlink +into it rather than a real directory. + +The consumer selects a workflow via userData: `COMFY_WORKFLOW_ID` (`ocean_ugc_product` or +`ocean_ugc_testimonial`, used only for the `[ocean] installed workflow …` log line) plus +`COMFY_WORKFLOW` (that workflow's graph JSON, gzipped then base64-encoded). The bootstrap +writes it into a minimal custom-node pack at the constant path +`custom_nodes/ocean_ugc/example_workflows/ocean_ugc.json` — exactly one graph is ever +installed per container, so the filename doesn't vary — which ComfyUI serves at +`/api/workflow_templates/ocean_ugc/ocean_ugc.json`. Open the ComfyUI URL with +`?template=ocean_ugc&source=all` to load it directly instead of building the graph by hand. +Needs a CUDA GPU with 48 GB+ VRAM (LTX-2.3 22B fp8 + Gemma-3-12B encoder). + ### `automatic1111.json` — Stable Diffusion WebUI (A1111) (GPU) The classic AUTOMATIC1111 UI (`universonic/stable-diffusion-webui`). The image entrypoint diff --git a/docs/serviceTemplates/ltx-video-ugc.json b/docs/serviceTemplates/ltx-video-ugc.json new file mode 100644 index 000000000..151dddb71 --- /dev/null +++ b/docs/serviceTemplates/ltx-video-ugc.json @@ -0,0 +1,68 @@ +{ + "id": "ltx-video-ugc", + "name": "ComfyUI \u2014 UGC short-form video (LTX-2.3)", + "description": "ComfyUI preloaded with LTX-2.3 for vertical short-form product video. Two workflows: a product photo becomes a 9:16 clip with ambient audio, or a creator photo plus a voice clip becomes a lip-synced testimonial (the clip is capped at the graph's 5.8s, so trim longer voiceovers or raise the frame count). Weights (38 GiB) download on first launch into the selected persistent-storage bucket and are reused after that; generated clips are written to the same bucket. Needs a CUDA GPU with 48 GB+ VRAM.", + "image": "yanwk/comfyui-boot", + "tag": "cu130-megapak-pt211-20260803", + "exposedPorts": [ + 8188 + ], + "entrypoint": [ + "/bin/bash", + "-c" + ], + "command": [ + "#!/bin/bash\n# Bootstrap for the ltx-video-ugc service template. Runs as the container command with\n# entrypoint [\"/bin/bash\",\"-c\"] \u2014 a shell entrypoint is mandatory because ocean-node passes\n# dockerCmd to Docker verbatim and performs no ${VAR} expansion of its own.\nset -euo pipefail\n\nWF_ID=\"${COMFY_WORKFLOW_ID:-}\"\n# COMFY_WORKFLOW_ID is client-supplied and becomes a filename. ServiceStartHandler never\n# loads templates, so userConfigurableEnvVars.validation is NOT enforced node-side \u2014 this\n# check is the only thing standing between userData and a path traversal.\nif [ -n \"$WF_ID\" ] && ! [[ \"$WF_ID\" =~ ^[A-Za-z0-9_.-]{1,64}$ ]]; then\n echo \"[ocean] invalid COMFY_WORKFLOW_ID\" >&2\n exit 1\nfi\n\nmkdir -p /root/ComfyUI\nif [ -d /data/outputs ]; then\n # Bucket is mounted: keep both weights and generated clips in it, so they survive the\n # container. The image's entrypoint rsyncs with --ignore-existing, so the symlink stands.\n mkdir -p /data/outputs/models /data/outputs/comfy-output\n # /root/ComfyUI/models normally does not exist yet: this image empties /root at build and its\n # entrypoint copies ComfyUI in only after we exec it. Handle a real directory anyway, so a\n # future image that does ship one cannot abort the bootstrap under set -e.\n if [ -d /root/ComfyUI/models ] && [ ! -L /root/ComfyUI/models ]; then\n mv /root/ComfyUI/models /root/ComfyUI/models.image-default\n fi\n ln -sfn /data/outputs/models /root/ComfyUI/models\n export CLI_ARGS=\"--output-directory /data/outputs/comfy-output ${CLI_ARGS:-}\"\nelse\n echo \"[ocean] no bucket mounted \u2014 models download to the container and are lost on stop\"\nfi\n\nMODELS=/root/ComfyUI/models\nmkdir -p \"$MODELS/checkpoints\" \"$MODELS/loras\" \"$MODELS/text_encoders\" \"$MODELS/latent_upscale_models\"\n\n# Download to .part then rename: a truncated file in a persistent bucket would be treated as\n# cached by every future launch.\nget() {\n if [ -f \"$2\" ]; then\n echo \"[ocean] cached $(basename \"$2\")\"\n return 0\n fi\n echo \"[ocean] downloading $(basename \"$2\")\"\n # No -f: a complete .part from a container that died between the download landing and the\n # mv makes `curl -C -` ask HuggingFace to resume a finished file, which answers 416. Check the\n # status ourselves so that specific case can recover instead of wedging every future launch.\n http_code=$(curl -L --retry 5 --retry-delay 5 -C - -o \"$2.part\" -w '%{http_code}' \"$1\")\n if [ \"$http_code\" = \"416\" ] && [ -f \"$2.part\" ]; then\n echo \"[ocean] $(basename \"$2\").part already complete\"\n elif [ \"$http_code\" -lt 200 ] || [ \"$http_code\" -ge 300 ]; then\n echo \"[ocean] download failed for $(basename \"$2\") (HTTP $http_code)\" >&2\n return 22\n fi\n mv \"$2.part\" \"$2\"\n}\n\nHF=https://huggingface.co\nget \"$HF/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors\" \\\n \"$MODELS/checkpoints/ltx-2.3-22b-dev-fp8.safetensors\"\nget \"$HF/Comfy-Org/ltx-2/resolve/main/split_files/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors\" \\\n \"$MODELS/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors\"\nget \"$HF/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors\" \\\n \"$MODELS/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors\"\nget \"$HF/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\" \\\n \"$MODELS/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\"\nget \"$HF/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors\" \\\n \"$MODELS/latent_upscale_models/ltx-2.3-spatial-upscaler-x2-1.1.safetensors\"\n\n# Minimal custom-node pack: ComfyUI serves example_workflows at\n# /api/workflow_templates/ocean_ugc/ocean_ugc.json, which is what ?template=ocean_ugc&source=all\n# loads. Exactly one graph is ever installed per container, so the filename is a constant, not\n# keyed by WF_ID \u2014 WF_ID is only used below for the log line, the in-container record of which\n# graph was picked.\nPACK=/root/ComfyUI/custom_nodes/ocean_ugc\nmkdir -p \"$PACK/example_workflows\"\necho 'NODE_CLASS_MAPPINGS = {}' > \"$PACK/__init__.py\"\nif [ -n \"$WF_ID\" ] && [ -n \"${COMFY_WORKFLOW:-}\" ]; then\n # Escrow is already claimed by the time this runs \u2014 a corrupt/undecodable payload must not take\n # the whole container down with it. Degrade to an empty pack and keep going; base64/gunzip's own\n # stderr plus the line below land in the container logs either way.\n if printf '%s' \"$COMFY_WORKFLOW\" | base64 -d | gunzip > \"$PACK/example_workflows/ocean_ugc.json\"; then\n echo \"[ocean] installed workflow $WF_ID\"\n else\n echo \"[ocean] failed to decode COMFY_WORKFLOW \u2014 starting ComfyUI with an empty workflow pack\" >&2\n rm -f \"$PACK/example_workflows/ocean_ugc.json\"\n fi\nfi\n\nexec bash /runner-scripts/entrypoint.sh\n" + ], + "workflows": [ + { + "id": "ocean_ugc_product", + "name": "Product \u2192 vertical clip", + "description": "Upload a product photo, get a 9:16 clip with camera motion and ambient audio.", + "file": "workflows/ocean_ugc_product.json" + }, + { + "id": "ocean_ugc_testimonial", + "name": "Creator testimonial (lip-sync)", + "description": "Upload a person photo and a voice clip, get a lip-synced 9:16 testimonial.", + "file": "workflows/ocean_ugc_testimonial.json" + } + ], + "userConfigurableEnvVars": [ + { + "key": "COMFY_WORKFLOW_ID", + "validation": "^[A-Za-z0-9_.-]+$" + }, + { + "key": "COMFY_WORKFLOW" + } + ], + "requiredResources": [ + { + "id": "cpu", + "min": 8, + "recommended": 16, + "unit": "cores" + }, + { + "id": "ram", + "min": 32, + "recommended": 64, + "unit": "GB" + }, + { + "id": "disk", + "min": 40, + "recommended": 80, + "unit": "GB" + }, + { + "kind": "discrete", + "type": "gpu", + "min": 1, + "recommended": 1, + "unit": "count", + "description": "CUDA GPU, 48 GB+ VRAM recommended (LTX-2.3 22B fp8 + Gemma-3-12B encoder)" + } + ] +} \ No newline at end of file diff --git a/docs/serviceTemplates/workflows/ocean_ugc_product.json b/docs/serviceTemplates/workflows/ocean_ugc_product.json new file mode 100644 index 000000000..13f6d0cbc --- /dev/null +++ b/docs/serviceTemplates/workflows/ocean_ugc_product.json @@ -0,0 +1,5064 @@ +{ + "id": "07824bbb-6672-4bb0-ac36-4313a519e35b", + "revision": 0, + "last_node_id": 329, + "last_link_id": 646, + "nodes": [ + { + "id": 103, + "type": "MarkdownNote", + "pos": [ + -1220, + 3530 + ], + "size": [ + 750, + 1200 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [], + "title": "Model Links", + "properties": { + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } + }, + "widgets_values": [ + "- Huggingface: [Lightricks/LTX-2.3](https://huggingface.co/Lightricks/LTX-2.3/)\n- Github: [LTX-2](https://github.com/Lightricks/LTX-2)\n\n## LTX-2.3 Prompting Tips\n\n1. **Core Actions**: Describe events and actions as they occur over time \n2. **Visual Details**: Describe all visual details you want to appear in the video \n3. **Audio**: Describe sounds and dialogue needed for the scene\n\n## Report LTX-2.3 Issues\nTo report any issues when running this workflow, [go to GitHub](https://github.com/Lightricks/ComfyUI-LTXVideo/issues)\n\n## Model Links (for Local Users)\n\n**checkpoints**\n\n- [ltx-2.3-22b-dev-fp8.safetensors](https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors)\n\n**loras**\n\n- [ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors](https://huggingface.co/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors)\n- [gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors](https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors)\n\n**latent_upscale_models**\n\n- [ltx-2.3-spatial-upscaler-x2-1.1.safetensors](https://huggingface.co/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors)\n\n\n## Model Storage Location\n\n```\n\ud83d\udcc2 ComfyUI/\n\u251c\u2500\u2500 \ud83d\udcc2 models/\n\u2502 \u251c\u2500\u2500 \ud83d\udcc2 checkpoints/\n\u2502 \u2502 \u2514\u2500\u2500 ltx-2.3-22b-dev-fp8.safetensors\n\u2502 \u251c\u2500\u2500 \ud83d\udcc2 loras/\n\u2502 \u2502 \u251c\u2500\u2500 ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors\n\u2502 \u2502 \u2514\u2500\u2500 gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\n\u2502 \u2514\u2500\u2500 \ud83d\udcc2 latent_upscale_models/\n\u2502 \u2514\u2500\u2500 ltx-2.3-spatial-upscaler-x2-1.1.safetensors\n```\n\n## Report Issue\n\nNote: Please update ComfyUI first ([guide](https://docs.comfy.org/installation/update_comfyui)) and prepare required models. Desktop/Cloud updates follow stable releases, so some nightly-supported models may not be available yet.\n\n- Cannot run / runtime errors: [ComfyUI/issues](https://github.com/Comfy-Org/ComfyUI/issues)\n- UI / frontend issues: [ComfyUI_frontend/issues](https://github.com/Comfy-Org/ComfyUI_frontend/issues)\n- Workflow issues: [workflow_templates/issues](https://github.com/Comfy-Org/workflow_templates/issues)\n" + ], + "color": "#222", + "bgcolor": "#000" + }, + { + "id": 269, + "type": "LoadImage", + "pos": [ + -440, + 3530 + ], + "size": [ + 410, + 530 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 633 + ] + }, + { + "name": "MASK", + "type": "MASK", + "links": null + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "LoadImage", + "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_queen.png", + "image" + ] + }, + { + "id": 75, + "type": "SaveVideo", + "pos": [ + 430, + 3530 + ], + "size": [ + 660, + 580 + ], + "flags": { + "collapsed": false + }, + "order": 3, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 632 + } + ], + "outputs": [ + { + "name": "video", + "type": "VIDEO", + "links": null + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.5.1", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "Node name for S&R": "SaveVideo", + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } + }, + "widgets_values": [ + "video/ocean_ugc_product", + "auto", + "auto" + ] + }, + { + "id": 320, + "type": "2454ad83-157c-40dd-9f19-5daaf4041ce0", + "pos": [ + 10, + 3530 + ], + "size": [ + 380, + 650 + ], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [ + { + "label": "first_frame", + "name": "input", + "type": "IMAGE,MASK", + "link": 633 + }, + { + "label": "prompt", + "name": "value", + "type": "STRING", + "widget": { + "name": "value" + }, + "link": null + }, + { + "label": "prompt_enhance", + "name": "value_1", + "type": "BOOLEAN", + "widget": { + "name": "value_1" + }, + "link": null + }, + { + "label": "width", + "name": "value_2", + "type": "INT", + "widget": { + "name": "value_2" + }, + "link": null + }, + { + "label": "height", + "name": "value_3", + "type": "INT", + "widget": { + "name": "value_3" + }, + "link": null + }, + { + "label": "duration", + "name": "value_4", + "type": "INT", + "widget": { + "name": "value_4" + }, + "link": null + }, + { + "label": "fps", + "name": "value_5", + "type": "INT", + "widget": { + "name": "value_5" + }, + "link": null + }, + { + "label": "seed", + "name": "noise_seed", + "type": "INT", + "widget": { + "name": "noise_seed" + }, + "link": null + }, + { + "label": "distilled_lora", + "name": "lora_name", + "type": "COMBO", + "widget": { + "name": "lora_name" + }, + "link": null + }, + { + "label": "text_encoder", + "name": "text_encoder", + "type": "COMBO", + "widget": { + "name": "text_encoder" + }, + "link": null + }, + { + "label": "latent_upscale_model", + "name": "model_name", + "type": "COMBO", + "widget": { + "name": "model_name" + }, + "link": null + }, + { + "label": "lora", + "name": "lora_name_1", + "type": "COMBO", + "widget": { + "name": "lora_name_1" + }, + "link": null + } + ], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 632 + ] + } + ], + "properties": { + "proxyWidgets": [ + [ + "319", + "value" + ], + [ + "328", + "value" + ], + [ + "312", + "value" + ], + [ + "299", + "value" + ], + [ + "301", + "value" + ], + [ + "300", + "value" + ], + [ + "277", + "noise_seed" + ], + [ + "316", + "ckpt_name" + ], + [ + "285", + "lora_name" + ], + [ + "317", + "text_encoder" + ], + [ + "311", + "model_name" + ], + [ + "324", + "lora_name" + ] + ], + "cnr_id": "comfy-core", + "ver": "0.16.3", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "ue_properties": { + "widget_ue_connectable": { + "value_1": true, + "value_2": true, + "value_3": true, + "value_4": true, + "lora_name": true, + "model_name": true, + "value_5": true + }, + "version": "7.7", + "input_ue_unconnectable": {} + } + }, + "widgets_values": [] + } + ], + "links": [ + [ + 632, + 320, + 0, + 75, + 0, + "VIDEO" + ], + [ + 633, + 269, + 0, + 320, + 0, + "IMAGE" + ] + ], + "groups": [], + "definitions": { + "subgraphs": [ + { + "id": "2454ad83-157c-40dd-9f19-5daaf4041ce0", + "version": 1, + "state": { + "lastGroupId": 26, + "lastNodeId": 329, + "lastLinkId": 646, + "lastRerouteId": 0 + }, + "revision": 0, + "config": {}, + "name": "Image to Video (LTX-2.3)", + "inputNode": { + "id": -10, + "bounding": [ + 730, + 4110, + 170.162109375, + 308 + ] + }, + "outputNode": { + "id": -20, + "bounding": [ + 6590, + 4360, + 128, + 68 + ] + }, + "inputs": [ + { + "id": "7afd6ea8-c738-4fd9-97b8-66fa905cd381", + "name": "input", + "type": "IMAGE,MASK", + "linkIds": [ + 535 + ], + "localized_name": "input", + "label": "first_frame", + "pos": [ + 876.162109375, + 4134 + ] + }, + { + "id": "9494c550-4172-49c6-930e-5b508f775e77", + "name": "value", + "type": "STRING", + "linkIds": [ + 595 + ], + "label": "prompt", + "pos": [ + 876.162109375, + 4154 + ] + }, + { + "id": "ec291311-2d21-49f9-aaba-24bb2e544ce0", + "name": "value_1", + "type": "BOOLEAN", + "linkIds": [ + 644 + ], + "label": "prompt_enhance", + "pos": [ + 876.162109375, + 4174 + ] + }, + { + "id": "58dbb3f6-f924-4548-96ef-e0e34610bd4e", + "name": "value_2", + "type": "INT", + "linkIds": [ + 597 + ], + "label": "width", + "pos": [ + 876.162109375, + 4194 + ] + }, + { + "id": "6086d5b8-2586-448c-a641-dd14d76dd102", + "name": "value_3", + "type": "INT", + "linkIds": [ + 598 + ], + "label": "height", + "pos": [ + 876.162109375, + 4214 + ] + }, + { + "id": "feb8c2eb-ae48-4fa8-bc24-929552d656c3", + "name": "value_4", + "type": "INT", + "linkIds": [ + 599 + ], + "label": "duration", + "pos": [ + 876.162109375, + 4234 + ] + }, + { + "id": "3e32ce15-0ae7-4cd0-909f-a354e8e9c4c9", + "name": "value_5", + "type": "INT", + "linkIds": [ + 624 + ], + "label": "fps", + "pos": [ + 876.162109375, + 4254 + ] + }, + { + "id": "dc40eadf-b8a9-421e-88f6-245042dd5424", + "name": "noise_seed", + "type": "INT", + "linkIds": [ + 646 + ], + "label": "seed", + "pos": [ + 876.162109375, + 4274 + ] + }, + { + "id": "d7255058-319a-4880-8f9a-7e542c8f3c3c", + "name": "ckpt_name", + "type": "COMBO", + "linkIds": [ + 601, + 604, + 605 + ], + "pos": [ + 876.162109375, + 4294 + ] + }, + { + "id": "4afce68d-8f65-4342-9d6d-ae0a7688c3e3", + "name": "lora_name", + "type": "COMBO", + "linkIds": [ + 602 + ], + "label": "distilled_lora", + "pos": [ + 876.162109375, + 4314 + ] + }, + { + "id": "ab842b4b-c977-4679-b421-424722785b57", + "name": "text_encoder", + "type": "COMBO", + "linkIds": [ + 606 + ], + "label": "text_encoder", + "pos": [ + 876.162109375, + 4334 + ] + }, + { + "id": "9e47372d-28d9-4311-91e9-e90d03f4eb43", + "name": "model_name", + "type": "COMBO", + "linkIds": [ + 607 + ], + "label": "latent_upscale_model", + "pos": [ + 876.162109375, + 4354 + ] + }, + { + "id": "682e457c-5d94-49b2-bf40-5731696deaf0", + "name": "lora_name_1", + "type": "COMBO", + "linkIds": [ + 645 + ], + "label": "lora", + "pos": [ + 876.162109375, + 4374 + ] + } + ], + "outputs": [ + { + "id": "954ef307-c897-4eea-8b5c-5c6ce15a5357", + "name": "VIDEO", + "type": "VIDEO", + "linkIds": [ + 536 + ], + "localized_name": "VIDEO", + "pos": [ + 6614, + 4384 + ] + } + ], + "widgets": [], + "nodes": [ + { + "id": 276, + "type": "RandomNoise", + "pos": [ + 4700, + 3650 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "NOISE", + "name": "NOISE", + "type": "NOISE", + "links": [ + 490 + ] + } + ], + "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": 277, + "type": "RandomNoise", + "pos": [ + 3160, + 3630 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "localized_name": "noise_seed", + "name": "noise_seed", + "type": "INT", + "widget": { + "name": "noise_seed" + }, + "link": 646 + } + ], + "outputs": [ + { + "localized_name": "NOISE", + "name": "NOISE", + "type": "NOISE", + "links": [ + 483 + ] + } + ], + "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": [ + 60540193790228, + "randomize" + ] + }, + { + "id": 278, + "type": "LTXVConcatAVLatent", + "pos": [ + 4710, + 4490 + ], + "size": [ + 280, + 100 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "link": 512 + }, + { + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", + "link": 513 + } + ], + "outputs": [ + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 494 + ] + } + ], + "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": 279, + "type": "LTXVAudioVAELoader", + "pos": [ + 1660, + 4100 + ], + "size": [ + 430, + 110 + ], + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "localized_name": "ckpt_name", + "name": "ckpt_name", + "type": "COMBO", + "widget": { + "name": "ckpt_name" + }, + "link": 604 + } + ], + "outputs": [ + { + "localized_name": "Audio VAE", + "name": "Audio VAE", + "type": "VAE", + "links": [ + 481, + 496 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.3.68", + "Node name for S&R": "LTXVAudioVAELoader", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "models": [ + { + "name": "ltx-2.3-22b-dev-fp8.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", + "directory": "checkpoints" + } + ], + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } + }, + "widgets_values": [ + "ltx-2.3-22b-dev-fp8.safetensors" + ] + }, + { + "id": 280, + "type": "KSamplerSelect", + "pos": [ + 4700, + 4100 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "SAMPLER", + "name": "SAMPLER", + "type": "SAMPLER", + "links": [ + 492 + ] + } + ], + "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": [ + "euler" + ] + }, + { + "id": 281, + "type": "ManualSigmas", + "pos": [ + 4700, + 4290 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "SIGMAS", + "name": "SIGMAS", + "type": "SIGMAS", + "links": [ + 493 + ] + } + ], + "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": 282, + "type": "CFGGuider", + "pos": [ + 4700, + 3850 + ], + "size": [ + 280, + 160 + ], + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 478 + }, + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 479 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 480 + } + ], + "outputs": [ + { + "localized_name": "GUIDER", + "name": "GUIDER", + "type": "GUIDER", + "links": [ + 491 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.3.71", + "Node name for S&R": "CFGGuider", + "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 + ] + }, + { + "id": 283, + "type": "SamplerCustomAdvanced", + "pos": [ + 3550, + 3630 + ], + "size": [ + 230, + 170 + ], + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ + { + "localized_name": "noise", + "name": "noise", + "type": "NOISE", + "link": 483 + }, + { + "localized_name": "guider", + "name": "guider", + "type": "GUIDER", + "link": 484 + }, + { + "localized_name": "sampler", + "name": "sampler", + "type": "SAMPLER", + "link": 485 + }, + { + "localized_name": "sigmas", + "name": "sigmas", + "type": "SIGMAS", + "link": 544 + }, + { + "localized_name": "latent_image", + "name": "latent_image", + "type": "LATENT", + "link": 487 + } + ], + "outputs": [ + { + "localized_name": "output", + "name": "output", + "type": "LATENT", + "links": [ + 488 + ] + }, + { + "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": 284, + "type": "LTXVCropGuides", + "pos": [ + 3830, + 3810 + ], + "size": [ + 250, + 120 + ], + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 475 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 476 + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "link": 477 + } + ], + "outputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "links": [ + 479 + ] + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "links": [ + 480 + ] + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "slot_index": 2, + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.3.68", + "Node name for S&R": "LTXVCropGuides", + "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": 285, + "type": "LoraLoaderModelOnly", + "pos": [ + 1660, + 3890 + ], + "size": [ + 430, + 140 + ], + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 520 + }, + { + "localized_name": "lora_name", + "name": "lora_name", + "type": "COMBO", + "widget": { + "name": "lora_name" + }, + "link": 602 + } + ], + "outputs": [ + { + "localized_name": "MODEL", + "name": "MODEL", + "type": "MODEL", + "links": [ + 478, + 541, + 641 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.3.75", + "Node name for S&R": "LoraLoaderModelOnly", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "models": [ + { + "name": "ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", + "url": "https://huggingface.co/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", + "directory": "loras" + } + ], + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } + }, + "widgets_values": [ + "ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", + 0.5 + ] + }, + { + "id": 286, + "type": "ResizeImagesByLongerEdge", + "pos": [ + 2070, + 4810 + ], + "size": [ + 348.624609375, + 110 + ], + "flags": { + "collapsed": false + }, + "order": 13, + "mode": 0, + "inputs": [ + { + "localized_name": "images", + "name": "images", + "type": "IMAGE", + "link": 523 + } + ], + "outputs": [ + { + "localized_name": "images", + "name": "images", + "type": "IMAGE", + "links": [ + 505 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.5.1", + "Node name for S&R": "ResizeImagesByLongerEdge", + "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": [ + 1536 + ] + }, + { + "id": 287, + "type": "LTXVLatentUpsampler", + "pos": [ + 4250, + 3760 + ], + "size": [ + 330, + 120 + ], + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [ + { + "localized_name": "samples", + "name": "samples", + "type": "LATENT", + "link": 547 + }, + { + "localized_name": "upscale_model", + "name": "upscale_model", + "type": "LATENT_UPSCALE_MODEL", + "link": 545 + }, + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 554 + } + ], + "outputs": [ + { + "localized_name": "LATENT", + "name": "LATENT", + "type": "LATENT", + "links": [ + 548 + ] + } + ], + "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": 288, + "type": "LTXVImgToVideoInplace", + "pos": [ + 4230, + 4100 + ], + "size": [ + 300, + 180 + ], + "flags": {}, + "order": 15, + "mode": 0, + "inputs": [ + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 552 + }, + { + "localized_name": "image", + "name": "image", + "type": "IMAGE", + "link": 515 + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "link": 548 + }, + { + "localized_name": "bypass", + "name": "bypass", + "type": "BOOLEAN", + "widget": { + "name": "bypass" + }, + "link": 543 + } + ], + "outputs": [ + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 512 + ] + } + ], + "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": 289, + "type": "LTXVPreprocess", + "pos": [ + 2100, + 5010 + ], + "size": [ + 290, + 110 + ], + "flags": {}, + "order": 16, + "mode": 0, + "inputs": [ + { + "localized_name": "image", + "name": "image", + "type": "IMAGE", + "link": 505 + } + ], + "outputs": [ + { + "localized_name": "output_image", + "name": "output_image", + "type": "IMAGE", + "links": [ + 510, + 515 + ] + } + ], + "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": 290, + "type": "ResizeImageMaskNode", + "pos": [ + 1660, + 4810 + ], + "size": [ + 300, + 154 + ], + "flags": {}, + "order": 17, + "mode": 0, + "inputs": [ + { + "localized_name": "input", + "name": "input", + "type": "IMAGE,MASK", + "link": 535 + }, + { + "localized_name": "width", + "name": "resize_type.width", + "type": "INT", + "widget": { + "name": "resize_type.width" + }, + "link": 558 + }, + { + "localized_name": "height", + "name": "resize_type.height", + "type": "INT", + "widget": { + "name": "resize_type.height" + }, + "link": 559 + } + ], + "outputs": [ + { + "localized_name": "resized", + "name": "resized", + "type": "IMAGE,MASK", + "links": [ + 523 + ] + } + ], + "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 dimensions", + 1920, + 1088, + "center", + "lanczos" + ] + }, + { + "id": 291, + "type": "KSamplerSelect", + "pos": [ + 3160, + 4040 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "SAMPLER", + "name": "SAMPLER", + "type": "SAMPLER", + "links": [ + 485 + ] + } + ], + "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" + ] + }, + { + "id": 292, + "type": "ComfyMathExpression", + "pos": [ + 2540, + 4830 + ], + "size": [ + 225, + 74 + ], + "flags": { + "collapsed": true + }, + "order": 18, + "mode": 0, + "inputs": [ + { + "label": "a", + "localized_name": "values.a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 560 + }, + { + "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": null + }, + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 561 + ] + }, + { + "localized_name": "BOOL", + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "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": 293, + "type": "Reroute", + "pos": [ + 3850, + 4050 + ], + "size": [ + 75, + 26 + ], + "flags": {}, + "order": 19, + "mode": 0, + "inputs": [ + { + "name": "", + "type": "*", + "link": 557 + } + ], + "outputs": [ + { + "name": "", + "type": "VAE", + "links": [ + 552, + 553, + 554 + ] + } + ], + "properties": { + "showOutputText": false, + "horizontal": false, + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } + } + }, + { + "id": 294, + "type": "ComfyMathExpression", + "pos": [ + 2550, + 4890 + ], + "size": [ + 225, + 74 + ], + "flags": { + "collapsed": true + }, + "order": 20, + "mode": 0, + "inputs": [ + { + "label": "a", + "localized_name": "values.a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 562 + }, + { + "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": null + }, + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 563 + ] + }, + { + "localized_name": "BOOL", + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "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": 295, + "type": "EmptyLTXVLatentVideo", + "pos": [ + 2870, + 4940 + ], + "size": [ + 280, + 200 + ], + "flags": {}, + "order": 21, + "mode": 0, + "inputs": [ + { + "localized_name": "width", + "name": "width", + "type": "INT", + "widget": { + "name": "width" + }, + "link": 561 + }, + { + "localized_name": "height", + "name": "height", + "type": "INT", + "widget": { + "name": "height" + }, + "link": 563 + }, + { + "localized_name": "length", + "name": "length", + "type": "INT", + "widget": { + "name": "length" + }, + "link": 631 + } + ], + "outputs": [ + { + "localized_name": "LATENT", + "name": "LATENT", + "type": "LATENT", + "links": [ + 511 + ] + } + ], + "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": [ + 576, + 1024, + 145, + 1 + ] + }, + { + "id": 296, + "type": "LTXVImgToVideoInplace", + "pos": [ + 3230, + 4810 + ], + "size": [ + 280, + 180 + ], + "flags": {}, + "order": 22, + "mode": 0, + "inputs": [ + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 556 + }, + { + "localized_name": "image", + "name": "image", + "type": "IMAGE", + "link": 510 + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "link": 511 + }, + { + "localized_name": "bypass", + "name": "bypass", + "type": "BOOLEAN", + "widget": { + "name": "bypass" + }, + "link": 542 + } + ], + "outputs": [ + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 497 + ] + } + ], + "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": 297, + "type": "LTXVAudioVAEDecode", + "pos": [ + 5760, + 3970 + ], + "size": [ + 270, + 100 + ], + "flags": {}, + "order": 23, + "mode": 0, + "inputs": [ + { + "localized_name": "samples", + "name": "samples", + "type": "LATENT", + "link": 495 + }, + { + "label": "Audio VAE", + "localized_name": "audio_vae", + "name": "audio_vae", + "type": "VAE", + "link": 496 + } + ], + "outputs": [ + { + "localized_name": "Audio", + "name": "Audio", + "type": "AUDIO", + "links": [ + 534 + ] + } + ], + "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": 298, + "type": "ComfyMathExpression", + "pos": [ + 2540, + 5030 + ], + "size": [ + 225, + 74 + ], + "flags": { + "collapsed": true + }, + "order": 24, + "mode": 0, + "inputs": [ + { + "label": "a", + "localized_name": "values.a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 564 + }, + { + "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": [ + 566, + 591 + ] + }, + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 565 + ] + }, + { + "localized_name": "BOOL", + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "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": 299, + "type": "PrimitiveInt", + "pos": [ + 1190, + 4650 + ], + "size": [ + 370, + 110 + ], + "flags": {}, + "order": 25, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "INT", + "widget": { + "name": "value" + }, + "link": 598 + } + ], + "outputs": [ + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 559, + 562 + ] + } + ], + "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": 300, + "type": "PrimitiveInt", + "pos": [ + 1190, + 4840 + ], + "size": [ + 370, + 110 + ], + "flags": {}, + "order": 26, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "INT", + "widget": { + "name": "value" + }, + "link": 624 + } + ], + "outputs": [ + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 564, + 629 + ] + } + ], + "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": [ + 25, + "fixed" + ] + }, + { + "id": 301, + "type": "PrimitiveInt", + "pos": [ + 1190, + 4280 + ], + "size": [ + 370, + 110 + ], + "flags": {}, + "order": 27, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "INT", + "widget": { + "name": "value" + }, + "link": 599 + } + ], + "outputs": [ + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 628 + ] + } + ], + "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": 302, + "type": "PrimitiveBoolean", + "pos": [ + 1190, + 4110 + ], + "size": [ + 370, + 100 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "BOOLEAN", + "name": "BOOLEAN", + "type": "BOOLEAN", + "links": [ + 542, + 543 + ] + } + ], + "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": 303, + "type": "CLIPTextEncode", + "pos": [ + 2170, + 3640 + ], + "size": [ + 600, + 390 + ], + "flags": {}, + "order": 28, + "mode": 0, + "inputs": [ + { + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 642 + }, + { + "localized_name": "text", + "name": "text", + "type": "STRING", + "widget": { + "name": "text" + }, + "link": 638 + } + ], + "outputs": [ + { + "localized_name": "CONDITIONING", + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 526 + ] + } + ], + "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": 304, + "type": "LTXVConditioning", + "pos": [ + 2800, + 3810 + ], + "size": [ + 280, + 130 + ], + "flags": {}, + "order": 29, + "mode": 0, + "inputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 526 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 527 + }, + { + "localized_name": "frame_rate", + "name": "frame_rate", + "type": "FLOAT", + "widget": { + "name": "frame_rate" + }, + "link": 566 + } + ], + "outputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "links": [ + 475, + 518 + ] + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "links": [ + 476, + 519 + ] + } + ], + "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": 305, + "type": "LTXVEmptyLatentAudio", + "pos": [ + 3540, + 4960 + ], + "size": [ + 280, + 170 + ], + "flags": {}, + "order": 30, + "mode": 0, + "inputs": [ + { + "localized_name": "audio_vae", + "name": "audio_vae", + "type": "VAE", + "link": 481 + }, + { + "localized_name": "frames_number", + "name": "frames_number", + "type": "INT", + "widget": { + "name": "frames_number" + }, + "link": 630 + }, + { + "localized_name": "frame_rate", + "name": "frame_rate", + "type": "INT", + "widget": { + "name": "frame_rate" + }, + "link": 565 + } + ], + "outputs": [ + { + "localized_name": "Latent", + "name": "Latent", + "type": "LATENT", + "links": [ + 498 + ] + } + ], + "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": [ + 145, + 25, + 1 + ] + }, + { + "id": 306, + "type": "ManualSigmas", + "pos": [ + 3160, + 4220 + ], + "size": [ + 500, + 110 + ], + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "SIGMAS", + "name": "SIGMAS", + "type": "SIGMAS", + "links": [ + 544 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.14.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": [ + "1.0, 0.99375, 0.9875, 0.98125, 0.975, 0.909375, 0.725, 0.421875, 0.0" + ] + }, + { + "id": 307, + "type": "LTXVSeparateAVLatent", + "pos": [ + 3820, + 3630 + ], + "size": [ + 250, + 100 + ], + "flags": {}, + "order": 31, + "mode": 0, + "inputs": [ + { + "localized_name": "av_latent", + "name": "av_latent", + "type": "LATENT", + "link": 488 + } + ], + "outputs": [ + { + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "links": [ + 477, + 547 + ] + }, + { + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", + "links": [ + 513 + ] + } + ], + "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": 308, + "type": "SamplerCustomAdvanced", + "pos": [ + 5050, + 3650 + ], + "size": [ + 230, + 170 + ], + "flags": {}, + "order": 32, + "mode": 0, + "inputs": [ + { + "localized_name": "noise", + "name": "noise", + "type": "NOISE", + "link": 490 + }, + { + "localized_name": "guider", + "name": "guider", + "type": "GUIDER", + "link": 491 + }, + { + "localized_name": "sampler", + "name": "sampler", + "type": "SAMPLER", + "link": 492 + }, + { + "localized_name": "sigmas", + "name": "sigmas", + "type": "SIGMAS", + "link": 493 + }, + { + "localized_name": "latent_image", + "name": "latent_image", + "type": "LATENT", + "link": 494 + } + ], + "outputs": [ + { + "localized_name": "output", + "name": "output", + "type": "LATENT", + "links": [ + 578 + ] + }, + { + "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": 309, + "type": "LTXVSeparateAVLatent", + "pos": [ + 5390, + 3650 + ], + "size": [ + 230, + 100 + ], + "flags": {}, + "order": 33, + "mode": 0, + "inputs": [ + { + "localized_name": "av_latent", + "name": "av_latent", + "type": "LATENT", + "link": 578 + } + ], + "outputs": [ + { + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "links": [ + 539 + ] + }, + { + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", + "links": [ + 495 + ] + } + ], + "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": 310, + "type": "CreateVideo", + "pos": [ + 6050, + 4490 + ], + "size": [ + 280, + 130 + ], + "flags": {}, + "order": 34, + "mode": 0, + "inputs": [ + { + "localized_name": "images", + "name": "images", + "type": "IMAGE", + "link": 538 + }, + { + "localized_name": "audio", + "name": "audio", + "shape": 7, + "type": "AUDIO", + "link": 534 + }, + { + "localized_name": "fps", + "name": "fps", + "type": "FLOAT", + "widget": { + "name": "fps" + }, + "link": 591 + } + ], + "outputs": [ + { + "localized_name": "VIDEO", + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 536 + ] + } + ], + "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": 311, + "type": "LatentUpscaleModelLoader", + "pos": [ + 1670, + 4550 + ], + "size": [ + 400, + 110 + ], + "flags": {}, + "order": 35, + "mode": 0, + "inputs": [ + { + "localized_name": "model_name", + "name": "model_name", + "type": "COMBO", + "widget": { + "name": "model_name" + }, + "link": 607 + } + ], + "outputs": [ + { + "localized_name": "LATENT_UPSCALE_MODEL", + "name": "LATENT_UPSCALE_MODEL", + "type": "LATENT_UPSCALE_MODEL", + "links": [ + 545 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "LatentUpscaleModelLoader", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "models": [ + { + "name": "ltx-2.3-spatial-upscaler-x2-1.1.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors", + "directory": "latent_upscale_models" + } + ], + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } + }, + "widgets_values": [ + "ltx-2.3-spatial-upscaler-x2-1.1.safetensors" + ] + }, + { + "id": 312, + "type": "PrimitiveInt", + "pos": [ + 1190, + 4470 + ], + "size": [ + 370, + 110 + ], + "flags": {}, + "order": 36, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "INT", + "widget": { + "name": "value" + }, + "link": 597 + } + ], + "outputs": [ + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 558, + 560 + ] + } + ], + "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": 313, + "type": "CLIPTextEncode", + "pos": [ + 2180, + 4120 + ], + "size": [ + 600, + 170 + ], + "flags": {}, + "order": 37, + "mode": 0, + "inputs": [ + { + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 627 + } + ], + "outputs": [ + { + "localized_name": "CONDITIONING", + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 527 + ] + } + ], + "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": [ + "pc game, console game, video game, cartoon, childish, ugly" + ], + "color": "#323", + "bgcolor": "#535" + }, + { + "id": 314, + "type": "CFGGuider", + "pos": [ + 3160, + 3810 + ], + "size": [ + 280, + 160 + ], + "flags": {}, + "order": 38, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 541 + }, + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 518 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 519 + } + ], + "outputs": [ + { + "localized_name": "GUIDER", + "name": "GUIDER", + "type": "GUIDER", + "links": [ + 484 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.3.64", + "Node name for S&R": "CFGGuider", + "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 + ] + }, + { + "id": 315, + "type": "VAEDecodeTiled", + "pos": [ + 5750, + 3610 + ], + "size": [ + 280, + 200 + ], + "flags": {}, + "order": 39, + "mode": 0, + "inputs": [ + { + "localized_name": "samples", + "name": "samples", + "type": "LATENT", + "link": 539 + }, + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 553 + } + ], + "outputs": [ + { + "localized_name": "IMAGE", + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 538 + ] + } + ], + "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": [ + 768, + 64, + 4096, + 4 + ] + }, + { + "id": 316, + "type": "CheckpointLoaderSimple", + "pos": [ + 1660, + 3660 + ], + "size": [ + 430, + 160 + ], + "flags": {}, + "order": 40, + "mode": 0, + "inputs": [ + { + "localized_name": "ckpt_name", + "name": "ckpt_name", + "type": "COMBO", + "widget": { + "name": "ckpt_name" + }, + "link": 601 + } + ], + "outputs": [ + { + "localized_name": "MODEL", + "name": "MODEL", + "type": "MODEL", + "links": [ + 520 + ] + }, + { + "localized_name": "CLIP", + "name": "CLIP", + "type": "CLIP", + "links": [] + }, + { + "localized_name": "VAE", + "name": "VAE", + "type": "VAE", + "links": [ + 556, + 557 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.3.56", + "Node name for S&R": "CheckpointLoaderSimple", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "models": [ + { + "name": "ltx-2.3-22b-dev-fp8.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", + "directory": "checkpoints" + } + ], + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } + }, + "widgets_values": [ + "ltx-2.3-22b-dev-fp8.safetensors" + ] + }, + { + "id": 317, + "type": "LTXAVTextEncoderLoader", + "pos": [ + 1660, + 4280 + ], + "size": [ + 430, + 170 + ], + "flags": {}, + "order": 41, + "mode": 0, + "showAdvanced": false, + "inputs": [ + { + "localized_name": "text_encoder", + "name": "text_encoder", + "type": "COMBO", + "widget": { + "name": "text_encoder" + }, + "link": 606 + }, + { + "localized_name": "ckpt_name", + "name": "ckpt_name", + "type": "COMBO", + "widget": { + "name": "ckpt_name" + }, + "link": 605 + } + ], + "outputs": [ + { + "localized_name": "CLIP", + "name": "CLIP", + "type": "CLIP", + "links": [ + 627, + 642, + 643 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "LTXAVTextEncoderLoader", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "models": [ + { + "name": "ltx-2.3-22b-dev-fp8.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", + "directory": "checkpoints" + }, + { + "name": "gemma_3_12B_it_fp4_mixed.safetensors", + "url": "https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors", + "directory": "text_encoders" + } + ], + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } + }, + "widgets_values": [ + "gemma_3_12B_it_fp4_mixed.safetensors", + "ltx-2.3-22b-dev-fp8.safetensors", + "default" + ] + }, + { + "id": 318, + "type": "LTXVConcatAVLatent", + "pos": [ + 3860, + 4830 + ], + "size": [ + 240, + 100 + ], + "flags": {}, + "order": 42, + "mode": 0, + "inputs": [ + { + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "link": 497 + }, + { + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", + "link": 498 + } + ], + "outputs": [ + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 487 + ] + } + ], + "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": 319, + "type": "PrimitiveStringMultiline", + "pos": [ + 1190, + 3680 + ], + "size": [ + 370, + 350 + ], + "flags": {}, + "order": 43, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "STRING", + "widget": { + "name": "value" + }, + "link": 595 + } + ], + "outputs": [ + { + "localized_name": "STRING", + "name": "STRING", + "type": "STRING", + "links": [ + 639, + 640 + ] + } + ], + "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\u2014no 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: \u201cThe old gods are silent. I am not.\u201d 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": 323, + "type": "ComfyMathExpression", + "pos": [ + 1210, + 5040 + ], + "size": [ + 225, + 94 + ], + "flags": { + "collapsed": true + }, + "order": 44, + "mode": 0, + "inputs": [ + { + "label": "a", + "localized_name": "values.a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 628 + }, + { + "label": "b", + "localized_name": "values.b", + "name": "values.b", + "shape": 7, + "type": "FLOAT,INT,BOOLEAN", + "link": 629 + }, + { + "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": null + }, + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 630, + 631 + ] + }, + { + "localized_name": "BOOL", + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "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": 324, + "type": "LoraLoader", + "pos": [ + 1200, + 2870 + ], + "size": [ + 380, + 230 + ], + "flags": {}, + "order": 45, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 641 + }, + { + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 643 + }, + { + "localized_name": "lora_name", + "name": "lora_name", + "type": "COMBO", + "widget": { + "name": "lora_name" + }, + "link": 645 + } + ], + "outputs": [ + { + "localized_name": "MODEL", + "name": "MODEL", + "type": "MODEL", + "links": null + }, + { + "localized_name": "CLIP", + "name": "CLIP", + "type": "CLIP", + "links": [ + 634 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "LoraLoader", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "models": [ + { + "name": "gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", + "url": "https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", + "directory": "loras" + } + ] + }, + "widgets_values": [ + "gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", + 1, + 1 + ] + }, + { + "id": 325, + "type": "TextGenerateLTX2Prompt", + "pos": [ + 1630, + 2870 + ], + "size": [ + 400, + 412 + ], + "flags": { + "collapsed": false + }, + "order": 46, + "mode": 0, + "inputs": [ + { + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 634 + }, + { + "localized_name": "image", + "name": "image", + "shape": 7, + "type": "IMAGE", + "link": null + }, + { + "localized_name": "video", + "name": "video", + "shape": 7, + "type": "IMAGE", + "link": null + }, + { + "localized_name": "audio", + "name": "audio", + "shape": 7, + "type": "AUDIO", + "link": null + }, + { + "localized_name": "prompt", + "name": "prompt", + "type": "STRING", + "widget": { + "name": "prompt" + }, + "link": 639 + } + ], + "outputs": [ + { + "localized_name": "generated_text", + "name": "generated_text", + "type": "STRING", + "links": [ + 636 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "TextGenerateLTX2Prompt", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65 + }, + "widgets_values": [ + "A young woman holds the product up to the camera in a bright modern kitchen, turning it slowly to show the label, then smiles at the camera. Handheld iPhone footage, natural window light, shallow depth of field, authentic UGC style.", + 2048, + "on", + 0.7, + 64, + 0.95, + 0.05, + 1.05, + 0, + 0, + false, + true + ] + }, + { + "id": 326, + "type": "PreviewAny", + "pos": [ + 2470, + 2890 + ], + "size": [ + 510, + 360 + ], + "flags": {}, + "order": 47, + "mode": 0, + "inputs": [ + { + "localized_name": "source", + "name": "source", + "type": "*", + "link": 635 + } + ], + "outputs": [ + { + "localized_name": "STRING", + "name": "STRING", + "type": "STRING", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "PreviewAny", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65 + }, + "widgets_values": [] + }, + { + "id": 327, + "type": "ComfySwitchNode", + "pos": [ + 2160, + 3280 + ], + "size": [ + 270, + 130 + ], + "flags": {}, + "order": 48, + "mode": 0, + "inputs": [ + { + "localized_name": "on_false", + "name": "on_false", + "type": "STRING", + "link": 640 + }, + { + "localized_name": "on_true", + "name": "on_true", + "type": "STRING", + "link": 636 + }, + { + "localized_name": "switch", + "name": "switch", + "type": "BOOLEAN", + "widget": { + "name": "switch" + }, + "link": 637 + } + ], + "outputs": [ + { + "localized_name": "output", + "name": "output", + "type": "STRING", + "links": [ + 635, + 638 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.22.0", + "Node name for S&R": "ComfySwitchNode", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65 + }, + "widgets_values": [ + false + ] + }, + { + "id": 328, + "type": "PrimitiveBoolean", + "pos": [ + 1200, + 3350 + ], + "size": [ + 270, + 100 + ], + "flags": {}, + "order": 49, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "BOOLEAN", + "widget": { + "name": "value" + }, + "link": 644 + } + ], + "outputs": [ + { + "localized_name": "BOOLEAN", + "name": "BOOLEAN", + "type": "BOOLEAN", + "links": [ + 637 + ] + } + ], + "title": "Boolean (Enable Prompt Enhance)", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.22.0", + "Node name for S&R": "PrimitiveBoolean", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65 + }, + "widgets_values": [ + false + ] + } + ], + "groups": [ + { + "id": 1, + "title": "Model", + "bounding": [ + 1630, + 3550, + 480, + 1140 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 2, + "title": "Generate Low Resolution", + "bounding": [ + 3130, + 3550, + 1000, + 1140 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 3, + "title": "Prompt", + "bounding": [ + 2140, + 3550, + 960, + 1140 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 6, + "title": "Generate High Resolution", + "bounding": [ + 4670, + 3550, + 990, + 1130 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 7, + "title": "Latent Upscale", + "bounding": [ + 4160, + 3550, + 480, + 1130 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 19, + "title": "Video Settings", + "bounding": [ + 1150, + 3550, + 460, + 1610 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 20, + "title": "Image Preprocess", + "bounding": [ + 1630, + 4720, + 830, + 440 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 21, + "title": "Empty Latent", + "bounding": [ + 2820, + 4720, + 1310, + 450 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 22, + "title": "Number conversion", + "bounding": [ + 2480, + 4720, + 310, + 440 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 26, + "title": "Prompt Enhancement", + "bounding": [ + 1160, + 2790, + 2010, + 720 + ], + "color": "#3f789e", + "flags": {} + } + ], + "links": [ + { + "id": 512, + "origin_id": 288, + "origin_slot": 0, + "target_id": 278, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 513, + "origin_id": 307, + "origin_slot": 1, + "target_id": 278, + "target_slot": 1, + "type": "LATENT" + }, + { + "id": 478, + "origin_id": 285, + "origin_slot": 0, + "target_id": 282, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 479, + "origin_id": 284, + "origin_slot": 0, + "target_id": 282, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 480, + "origin_id": 284, + "origin_slot": 1, + "target_id": 282, + "target_slot": 2, + "type": "CONDITIONING" + }, + { + "id": 541, + "origin_id": 285, + "origin_slot": 0, + "target_id": 314, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 518, + "origin_id": 304, + "origin_slot": 0, + "target_id": 314, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 519, + "origin_id": 304, + "origin_slot": 1, + "target_id": 314, + "target_slot": 2, + "type": "CONDITIONING" + }, + { + "id": 483, + "origin_id": 277, + "origin_slot": 0, + "target_id": 283, + "target_slot": 0, + "type": "NOISE" + }, + { + "id": 484, + "origin_id": 314, + "origin_slot": 0, + "target_id": 283, + "target_slot": 1, + "type": "GUIDER" + }, + { + "id": 485, + "origin_id": 291, + "origin_slot": 0, + "target_id": 283, + "target_slot": 2, + "type": "SAMPLER" + }, + { + "id": 544, + "origin_id": 306, + "origin_slot": 0, + "target_id": 283, + "target_slot": 3, + "type": "SIGMAS" + }, + { + "id": 487, + "origin_id": 318, + "origin_slot": 0, + "target_id": 283, + "target_slot": 4, + "type": "LATENT" + }, + { + "id": 475, + "origin_id": 304, + "origin_slot": 0, + "target_id": 284, + "target_slot": 0, + "type": "CONDITIONING" + }, + { + "id": 476, + "origin_id": 304, + "origin_slot": 1, + "target_id": 284, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 477, + "origin_id": 307, + "origin_slot": 0, + "target_id": 284, + "target_slot": 2, + "type": "LATENT" + }, + { + "id": 520, + "origin_id": 316, + "origin_slot": 0, + "target_id": 285, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 523, + "origin_id": 290, + "origin_slot": 0, + "target_id": 286, + "target_slot": 0, + "type": "IMAGE" + }, + { + "id": 547, + "origin_id": 307, + "origin_slot": 0, + "target_id": 287, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 545, + "origin_id": 311, + "origin_slot": 0, + "target_id": 287, + "target_slot": 1, + "type": "LATENT_UPSCALE_MODEL" + }, + { + "id": 554, + "origin_id": 293, + "origin_slot": 0, + "target_id": 287, + "target_slot": 2, + "type": "VAE" + }, + { + "id": 552, + "origin_id": 293, + "origin_slot": 0, + "target_id": 288, + "target_slot": 0, + "type": "VAE" + }, + { + "id": 515, + "origin_id": 289, + "origin_slot": 0, + "target_id": 288, + "target_slot": 1, + "type": "IMAGE" + }, + { + "id": 548, + "origin_id": 287, + "origin_slot": 0, + "target_id": 288, + "target_slot": 2, + "type": "LATENT" + }, + { + "id": 543, + "origin_id": 302, + "origin_slot": 0, + "target_id": 288, + "target_slot": 3, + "type": "BOOLEAN" + }, + { + "id": 505, + "origin_id": 286, + "origin_slot": 0, + "target_id": 289, + "target_slot": 0, + "type": "IMAGE" + }, + { + "id": 558, + "origin_id": 312, + "origin_slot": 0, + "target_id": 290, + "target_slot": 1, + "type": "INT" + }, + { + "id": 559, + "origin_id": 299, + "origin_slot": 0, + "target_id": 290, + "target_slot": 2, + "type": "INT" + }, + { + "id": 560, + "origin_id": 312, + "origin_slot": 0, + "target_id": 292, + "target_slot": 0, + "type": "INT" + }, + { + "id": 557, + "origin_id": 316, + "origin_slot": 2, + "target_id": 293, + "target_slot": 0, + "type": "VAE" + }, + { + "id": 562, + "origin_id": 299, + "origin_slot": 0, + "target_id": 294, + "target_slot": 0, + "type": "INT" + }, + { + "id": 561, + "origin_id": 292, + "origin_slot": 1, + "target_id": 295, + "target_slot": 0, + "type": "INT" + }, + { + "id": 563, + "origin_id": 294, + "origin_slot": 1, + "target_id": 295, + "target_slot": 1, + "type": "INT" + }, + { + "id": 556, + "origin_id": 316, + "origin_slot": 2, + "target_id": 296, + "target_slot": 0, + "type": "VAE" + }, + { + "id": 510, + "origin_id": 289, + "origin_slot": 0, + "target_id": 296, + "target_slot": 1, + "type": "IMAGE" + }, + { + "id": 511, + "origin_id": 295, + "origin_slot": 0, + "target_id": 296, + "target_slot": 2, + "type": "LATENT" + }, + { + "id": 542, + "origin_id": 302, + "origin_slot": 0, + "target_id": 296, + "target_slot": 3, + "type": "BOOLEAN" + }, + { + "id": 495, + "origin_id": 309, + "origin_slot": 1, + "target_id": 297, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 496, + "origin_id": 279, + "origin_slot": 0, + "target_id": 297, + "target_slot": 1, + "type": "VAE" + }, + { + "id": 564, + "origin_id": 300, + "origin_slot": 0, + "target_id": 298, + "target_slot": 0, + "type": "INT" + }, + { + "id": 526, + "origin_id": 303, + "origin_slot": 0, + "target_id": 304, + "target_slot": 0, + "type": "CONDITIONING" + }, + { + "id": 527, + "origin_id": 313, + "origin_slot": 0, + "target_id": 304, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 566, + "origin_id": 298, + "origin_slot": 0, + "target_id": 304, + "target_slot": 2, + "type": "FLOAT" + }, + { + "id": 497, + "origin_id": 296, + "origin_slot": 0, + "target_id": 318, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 498, + "origin_id": 305, + "origin_slot": 0, + "target_id": 318, + "target_slot": 1, + "type": "LATENT" + }, + { + "id": 481, + "origin_id": 279, + "origin_slot": 0, + "target_id": 305, + "target_slot": 0, + "type": "VAE" + }, + { + "id": 565, + "origin_id": 298, + "origin_slot": 1, + "target_id": 305, + "target_slot": 2, + "type": "INT" + }, + { + "id": 488, + "origin_id": 283, + "origin_slot": 0, + "target_id": 307, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 490, + "origin_id": 276, + "origin_slot": 0, + "target_id": 308, + "target_slot": 0, + "type": "NOISE" + }, + { + "id": 491, + "origin_id": 282, + "origin_slot": 0, + "target_id": 308, + "target_slot": 1, + "type": "GUIDER" + }, + { + "id": 492, + "origin_id": 280, + "origin_slot": 0, + "target_id": 308, + "target_slot": 2, + "type": "SAMPLER" + }, + { + "id": 493, + "origin_id": 281, + "origin_slot": 0, + "target_id": 308, + "target_slot": 3, + "type": "SIGMAS" + }, + { + "id": 494, + "origin_id": 278, + "origin_slot": 0, + "target_id": 308, + "target_slot": 4, + "type": "LATENT" + }, + { + "id": 578, + "origin_id": 308, + "origin_slot": 0, + "target_id": 309, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 539, + "origin_id": 309, + "origin_slot": 0, + "target_id": 315, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 553, + "origin_id": 293, + "origin_slot": 0, + "target_id": 315, + "target_slot": 1, + "type": "VAE" + }, + { + "id": 538, + "origin_id": 315, + "origin_slot": 0, + "target_id": 310, + "target_slot": 0, + "type": "IMAGE" + }, + { + "id": 534, + "origin_id": 297, + "origin_slot": 0, + "target_id": 310, + "target_slot": 1, + "type": "AUDIO" + }, + { + "id": 591, + "origin_id": 298, + "origin_slot": 0, + "target_id": 310, + "target_slot": 2, + "type": "FLOAT" + }, + { + "id": 535, + "origin_id": -10, + "origin_slot": 0, + "target_id": 290, + "target_slot": 0, + "type": "IMAGE,MASK" + }, + { + "id": 536, + "origin_id": 310, + "origin_slot": 0, + "target_id": -20, + "target_slot": 0, + "type": "VIDEO" + }, + { + "id": 595, + "origin_id": -10, + "origin_slot": 1, + "target_id": 319, + "target_slot": 0, + "type": "STRING" + }, + { + "id": 597, + "origin_id": -10, + "origin_slot": 3, + "target_id": 312, + "target_slot": 0, + "type": "INT" + }, + { + "id": 598, + "origin_id": -10, + "origin_slot": 4, + "target_id": 299, + "target_slot": 0, + "type": "INT" + }, + { + "id": 599, + "origin_id": -10, + "origin_slot": 5, + "target_id": 301, + "target_slot": 0, + "type": "INT" + }, + { + "id": 601, + "origin_id": -10, + "origin_slot": 8, + "target_id": 316, + "target_slot": 0, + "type": "COMBO" + }, + { + "id": 602, + "origin_id": -10, + "origin_slot": 9, + "target_id": 285, + "target_slot": 1, + "type": "COMBO" + }, + { + "id": 604, + "origin_id": -10, + "origin_slot": 8, + "target_id": 279, + "target_slot": 0, + "type": "COMBO" + }, + { + "id": 605, + "origin_id": -10, + "origin_slot": 8, + "target_id": 317, + "target_slot": 1, + "type": "COMBO" + }, + { + "id": 606, + "origin_id": -10, + "origin_slot": 10, + "target_id": 317, + "target_slot": 0, + "type": "COMBO" + }, + { + "id": 607, + "origin_id": -10, + "origin_slot": 11, + "target_id": 311, + "target_slot": 0, + "type": "COMBO" + }, + { + "id": 624, + "origin_id": -10, + "origin_slot": 6, + "target_id": 300, + "target_slot": 0, + "type": "INT" + }, + { + "id": 627, + "origin_id": 317, + "origin_slot": 0, + "target_id": 313, + "target_slot": 0, + "type": "CLIP" + }, + { + "id": 628, + "origin_id": 301, + "origin_slot": 0, + "target_id": 323, + "target_slot": 0, + "type": "INT" + }, + { + "id": 629, + "origin_id": 300, + "origin_slot": 0, + "target_id": 323, + "target_slot": 1, + "type": "INT" + }, + { + "id": 630, + "origin_id": 323, + "origin_slot": 1, + "target_id": 305, + "target_slot": 1, + "type": "INT" + }, + { + "id": 631, + "origin_id": 323, + "origin_slot": 1, + "target_id": 295, + "target_slot": 2, + "type": "INT" + }, + { + "id": 634, + "origin_id": 324, + "origin_slot": 1, + "target_id": 325, + "target_slot": 0, + "type": "CLIP" + }, + { + "id": 635, + "origin_id": 327, + "origin_slot": 0, + "target_id": 326, + "target_slot": 0, + "type": "*" + }, + { + "id": 636, + "origin_id": 325, + "origin_slot": 0, + "target_id": 327, + "target_slot": 1, + "type": "STRING" + }, + { + "id": 637, + "origin_id": 328, + "origin_slot": 0, + "target_id": 327, + "target_slot": 2, + "type": "BOOLEAN" + }, + { + "id": 638, + "origin_id": 327, + "origin_slot": 0, + "target_id": 303, + "target_slot": 1, + "type": "STRING" + }, + { + "id": 639, + "origin_id": 319, + "origin_slot": 0, + "target_id": 325, + "target_slot": 4, + "type": "STRING" + }, + { + "id": 640, + "origin_id": 319, + "origin_slot": 0, + "target_id": 327, + "target_slot": 0, + "type": "STRING" + }, + { + "id": 641, + "origin_id": 285, + "origin_slot": 0, + "target_id": 324, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 642, + "origin_id": 317, + "origin_slot": 0, + "target_id": 303, + "target_slot": 0, + "type": "CLIP" + }, + { + "id": 643, + "origin_id": 317, + "origin_slot": 0, + "target_id": 324, + "target_slot": 1, + "type": "CLIP" + }, + { + "id": 644, + "origin_id": -10, + "origin_slot": 2, + "target_id": 328, + "target_slot": 0, + "type": "BOOLEAN" + }, + { + "id": 645, + "origin_id": -10, + "origin_slot": 12, + "target_id": 324, + "target_slot": 2, + "type": "COMBO" + }, + { + "id": 646, + "origin_id": -10, + "origin_slot": 7, + "target_id": 277, + "target_slot": 0, + "type": "INT" + } + ], + "extra": { + "workflowRendererVersion": "Vue-corrected", + "ue_links": [] + } + } + ] + }, + "config": {}, + "extra": { + "ds": { + "scale": 0.41201716738197425, + "offset": [ + 1618.0394287109375, + -3067.713541666667 + ] + }, + "frontendVersion": "1.45.21", + "workflowRendererVersion": "Vue-corrected", + "prompt": { + "1": { + "inputs": { + "ckpt_name": "ltx-av-step-1751000_vocoder_24K.safetensors" + }, + "class_type": "CheckpointLoaderSimple", + "_meta": { + "title": "Load Checkpoint" + } + }, + "2": { + "inputs": { + "gemma_path": "gemma-3-12b-it-qat-q4_0-unquantized_readout_proj/model/model.safetensors", + "ltxv_path": "ltx-av-step-1751000_vocoder_24K.safetensors", + "max_length": 1024 + }, + "class_type": "LTXVGemmaCLIPModelLoader", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 Gemma 3 Model Loader" + } + }, + "3": { + "inputs": { + "text": "", + "clip": [ + "2", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "4": { + "inputs": { + "text": "blurry, low quality, still frame, frames, watermark, overlay, titles, has blurbox, has subtitles", + "clip": [ + "2", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "8": { + "inputs": { + "sampler_name": "euler" + }, + "class_type": "KSamplerSelect", + "_meta": { + "title": "KSamplerSelect" + } + }, + "9": { + "inputs": { + "steps": 20, + "max_shift": 2.05, + "base_shift": 0.95, + "stretch": true, + "terminal": 0.1, + "latent": [ + "28", + 0 + ] + }, + "class_type": "LTXVScheduler", + "_meta": { + "title": "LTXVScheduler" + } + }, + "11": { + "inputs": { + "noise_seed": 10 + }, + "class_type": "RandomNoise", + "_meta": { + "title": "RandomNoise" + } + }, + "12": { + "inputs": { + "samples": [ + "29", + 0 + ], + "vae": [ + "1", + 2 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } + }, + "13": { + "inputs": { + "ckpt_name": "ltx-av-step-1751000_vocoder_24K.safetensors" + }, + "class_type": "LTXVAudioVAELoader", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Audio VAE Loader" + } + }, + "14": { + "inputs": { + "samples": [ + "29", + 1 + ], + "audio_vae": [ + "13", + 0 + ] + }, + "class_type": "LTXVAudioVAEDecode", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Audio VAE Decode" + } + }, + "15": { + "inputs": { + "frame_rate": [ + "23", + 0 + ], + "loop_count": 0, + "filename_prefix": "AnimateDiff", + "format": "video/h264-mp4", + "pix_fmt": "yuv420p", + "crf": 19, + "save_metadata": true, + "trim_to_audio": false, + "pingpong": false, + "save_output": true, + "images": [ + "12", + 0 + ], + "audio": [ + "14", + 0 + ] + }, + "class_type": "VHS_VideoCombine", + "_meta": { + "title": "Video Combine \ud83c\udfa5\ud83c\udd65\ud83c\udd57\ud83c\udd62" + } + }, + "17": { + "inputs": { + "skip_blocks": "29", + "model": [ + "28", + 1 + ], + "positive": [ + "22", + 0 + ], + "negative": [ + "22", + 1 + ], + "parameters": [ + "18", + 0 + ] + }, + "class_type": "MultimodalGuider", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 Multimodal Guider" + } + }, + "18": { + "inputs": { + "modality": "VIDEO", + "cfg": 3, + "stg": 0, + "rescale": 0, + "modality_scale": 3, + "parameters": [ + "19", + 0 + ] + }, + "class_type": "GuiderParameters", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 Guider Parameters" + } + }, + "19": { + "inputs": { + "modality": "AUDIO", + "cfg": 7, + "stg": 0, + "rescale": 0, + "modality_scale": 3 + }, + "class_type": "GuiderParameters", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 Guider Parameters" + } + }, + "21": { + "inputs": { + "audioUI": "", + "audio": [ + "14", + 0 + ] + }, + "class_type": "PreviewAudio", + "_meta": { + "title": "PreviewAudio" + } + }, + "22": { + "inputs": { + "frame_rate": [ + "23", + 0 + ], + "positive": [ + "3", + 0 + ], + "negative": [ + "4", + 0 + ] + }, + "class_type": "LTXVConditioning", + "_meta": { + "title": "LTXVConditioning" + } + }, + "23": { + "inputs": { + "value": 25 + }, + "class_type": "FloatConstant", + "_meta": { + "title": "Float Constant" + } + }, + "26": { + "inputs": { + "frames_number": [ + "27", + 0 + ], + "frame_rate": [ + "42", + 0 + ], + "batch_size": 1 + }, + "class_type": "LTXVEmptyLatentAudio", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Empty Latent Audio" + } + }, + "27": { + "inputs": { + "value": 105 + }, + "class_type": "INTConstant", + "_meta": { + "title": "INT Constant" + } + }, + "28": { + "inputs": { + "video_latent": [ + "43", + 0 + ], + "audio_latent": [ + "26", + 0 + ], + "model": [ + "44", + 0 + ] + }, + "class_type": "LTXVConcatAVLatent", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Concat AV Latent" + } + }, + "29": { + "inputs": { + "av_latent": [ + "41", + 0 + ], + "model": [ + "28", + 1 + ] + }, + "class_type": "LTXVSeparateAVLatent", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Separate AV Latent" + } + }, + "41": { + "inputs": { + "noise": [ + "11", + 0 + ], + "guider": [ + "17", + 0 + ], + "sampler": [ + "8", + 0 + ], + "sigmas": [ + "9", + 0 + ], + "latent_image": [ + "28", + 0 + ] + }, + "class_type": "SamplerCustomAdvanced", + "_meta": { + "title": "SamplerCustomAdvanced" + } + }, + "42": { + "inputs": { + "a": [ + "23", + 0 + ] + }, + "class_type": "CM_FloatToInt", + "_meta": { + "title": "FloatToInt" + } + }, + "43": { + "inputs": { + "width": 768, + "height": 512, + "length": [ + "27", + 0 + ], + "batch_size": 1 + }, + "class_type": "EmptyLTXVLatentVideo", + "_meta": { + "title": "EmptyLTXVLatentVideo" + } + }, + "44": { + "inputs": { + "torch_compile": true, + "disable_backup": false, + "model": [ + "1", + 0 + ] + }, + "class_type": "LTXVSequenceParallelMultiGPUPatcher", + "_meta": { + "title": "LTXVSequenceParallelMultiGPUPatcher" + } + }, + "45": { + "inputs": { + "frame_idx": 0, + "strength": 1 + }, + "class_type": "LTXVAddGuide", + "_meta": { + "title": "LTXVAddGuide" + } + } + }, + "comfy_fork_version": "feature/av_inference@a6994ed1", + "VHS_latentpreview": false, + "VHS_latentpreviewrate": 0, + "VHS_MetadataImage": true, + "VHS_KeepIntermediate": true, + "ue_links": [] + }, + "version": 0.4 +} \ No newline at end of file diff --git a/docs/serviceTemplates/workflows/ocean_ugc_testimonial.json b/docs/serviceTemplates/workflows/ocean_ugc_testimonial.json new file mode 100644 index 000000000..2fffe3f3b --- /dev/null +++ b/docs/serviceTemplates/workflows/ocean_ugc_testimonial.json @@ -0,0 +1,5167 @@ +{ + "id": "07824bbb-6672-4bb0-ac36-4313a519e35b", + "revision": 0, + "last_node_id": 349, + "last_link_id": 762, + "nodes": [ + { + "id": 103, + "type": "MarkdownNote", + "pos": [ + -1220, + 3530 + ], + "size": [ + 750, + 1191.734375 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [], + "title": "Model Links", + "properties": {}, + "widgets_values": [ + "- Huggingface: [Lightricks/LTX-2.3](https://huggingface.co/Lightricks/LTX-2.3/)\n- Github: [LTX-2](https://github.com/Lightricks/LTX-2)\n\n## LTX-2.3 Prompting Tips\n\n1. **Core Actions**: Describe events and actions as they occur over time \n2. **Visual Details**: Describe all visual details you want to appear in the video \n3. **Audio**: Describe sounds and dialogue needed for the scene\n\n## Report LTX-2.3 Issues\nTo report any issues when running this workflow, [go to GitHub](https://github.com/Lightricks/ComfyUI-LTXVideo/issues)\n\n## Model Links\n\n**checkpoints**\n\n- [ltx-2.3-22b-dev-fp8.safetensors](https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors)\n\n**loras**\n\n- [ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors](https://huggingface.co/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors)\n- [gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors](https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors)\n\n**latent_upscale_models**\n\n- [ltx-2.3-spatial-upscaler-x2-1.1.safetensors](https://huggingface.co/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors)\n\n\n## Model Storage Location\n\n```\n\ud83d\udcc2 ComfyUI/\n\u251c\u2500\u2500 \ud83d\udcc2 models/\n\u2502 \u251c\u2500\u2500 \ud83d\udcc2 checkpoints/\n\u2502 \u2502 \u2514\u2500\u2500 ltx-2.3-22b-dev-fp8.safetensors\n\u2502 \u251c\u2500\u2500 \ud83d\udcc2 loras/\n\u2502 \u2502 \u251c\u2500\u2500 ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors\n\u2502 \u2502 \u2514\u2500\u2500 gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\n\u2502 \u2514\u2500\u2500 \ud83d\udcc2 latent_upscale_models/\n\u2502 \u2514\u2500\u2500 ltx-2.3-spatial-upscaler-x2-1.1.safetensors\n```\n\n## Report Issue\n\nNote: Please update ComfyUI first ([guide](https://docs.comfy.org/installation/update_comfyui)) and prepare required models. Desktop/Cloud updates follow stable releases, so some nightly-supported models may not be available yet.\n\n- Cannot run / runtime errors: [ComfyUI/issues](https://github.com/Comfy-Org/ComfyUI/issues)\n- UI / frontend issues: [ComfyUI_frontend/issues](https://github.com/Comfy-Org/ComfyUI_frontend/issues)\n- Workflow issues: [workflow_templates/issues](https://github.com/Comfy-Org/workflow_templates/issues)\n" + ], + "color": "#222", + "bgcolor": "#000" + }, + { + "id": 269, + "type": "LoadImage", + "pos": [ + -440, + 3530 + ], + "size": [ + 400, + 480 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 726 + ] + }, + { + "name": "MASK", + "type": "MASK", + "links": null + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "cactus_man.png", + "image" + ] + }, + { + "id": 339, + "type": "RecordAudio", + "pos": [ + -440, + 4330 + ], + "size": [ + 400, + 160 + ], + "flags": {}, + "order": 2, + "mode": 4, + "inputs": [], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": null + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "RecordAudio" + }, + "widgets_values": [ + "", + "" + ] + }, + { + "id": 341, + "type": "SaveVideo", + "pos": [ + 430, + 3530 + ], + "size": [ + 580, + 580 + ], + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 741 + } + ], + "outputs": [], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "SaveVideo" + }, + "widgets_values": [ + "video/ocean_ugc_testimonial", + "auto", + "auto" + ] + }, + { + "id": 276, + "type": "LoadAudio", + "pos": [ + -440, + 4070 + ], + "size": [ + 400, + 180 + ], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 727 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "LoadAudio" + }, + "widgets_values": [ + "ltx_23_audio.mp3", + null, + null + ] + }, + { + "id": 340, + "type": "98ee9e5b-467b-40aa-a534-36033f27d0b4", + "pos": [ + 0, + 3530 + ], + "size": [ + 400, + 610 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [ + { + "label": "first_frame", + "name": "input", + "type": "IMAGE,MASK", + "link": 726 + }, + { + "name": "audio", + "type": "AUDIO", + "link": 727 + }, + { + "label": "prompt", + "name": "value", + "type": "STRING", + "widget": { + "name": "value" + }, + "link": null + }, + { + "label": "prompt_enhance", + "name": "value_5", + "type": "BOOLEAN", + "widget": { + "name": "value_5" + }, + "link": null + }, + { + "label": "width", + "name": "value_1", + "type": "INT", + "widget": { + "name": "value_1" + }, + "link": null + }, + { + "label": "height", + "name": "value_2", + "type": "INT", + "widget": { + "name": "value_2" + }, + "link": null + }, + { + "label": "audio_start", + "name": "start_index", + "type": "FLOAT", + "widget": { + "name": "start_index" + }, + "link": null + }, + { + "label": "duration", + "name": "value_4", + "type": "FLOAT", + "widget": { + "name": "value_4" + }, + "link": null + }, + { + "label": "fps", + "name": "value_3", + "type": "INT", + "widget": { + "name": "value_3" + }, + "link": null + }, + { + "label": "seed", + "name": "noise_seed", + "type": "INT", + "widget": { + "name": "noise_seed" + }, + "link": null + }, + { + "label": "distilled_lora", + "name": "lora_name", + "type": "COMBO", + "widget": { + "name": "lora_name" + }, + "link": null + }, + { + "label": "upscale_model", + "name": "model_name", + "type": "COMBO", + "widget": { + "name": "model_name" + }, + "link": null + }, + { + "label": "lora", + "name": "lora_name_1", + "type": "COMBO", + "widget": { + "name": "lora_name_1" + }, + "link": null + } + ], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 741 + ] + } + ], + "properties": { + "proxyWidgets": [ + [ + "319", + "value" + ], + [ + "349", + "value" + ], + [ + "330", + "value" + ], + [ + "324", + "value" + ], + [ + "332", + "start_index" + ], + [ + "331", + "value" + ], + [ + "323", + "value" + ], + [ + "286", + "noise_seed" + ], + [ + "317", + "ckpt_name" + ], + [ + "293", + "lora_name" + ], + [ + "318", + "text_encoder" + ], + [ + "313", + "model_name" + ], + [ + "345", + "lora_name" + ] + ], + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "ue_properties": { + "widget_ue_connectable": { + "value": true, + "value_1": true, + "value_2": true, + "value_3": true, + "value_4": true, + "value_5": true, + "start_index": true, + "lora_name": true, + "model_name": true + } + } + }, + "widgets_values": [] + } + ], + "links": [ + [ + 726, + 269, + 0, + 340, + 0, + "IMAGE" + ], + [ + 727, + 276, + 0, + 340, + 1, + "AUDIO" + ], + [ + 741, + 340, + 0, + 341, + 0, + "VIDEO" + ] + ], + "groups": [], + "definitions": { + "subgraphs": [ + { + "id": "98ee9e5b-467b-40aa-a534-36033f27d0b4", + "version": 1, + "state": { + "lastGroupId": 27, + "lastNodeId": 349, + "lastLinkId": 762, + "lastRerouteId": 0 + }, + "revision": 0, + "config": {}, + "name": "Video Generation (LTX-2.3)", + "inputNode": { + "id": -10, + "bounding": [ + -140, + 3700, + 142.98046875, + 348 + ] + }, + "outputNode": { + "id": -20, + "bounding": [ + 5320, + 4030, + 128, + 68 + ] + }, + "inputs": [ + { + "id": "b16ca2a6-1c07-4c28-bc42-7aae63573f3b", + "name": "input", + "type": "IMAGE,MASK", + "linkIds": [ + 698 + ], + "localized_name": "input", + "label": "first_frame", + "pos": [ + -21.01953125, + 3724 + ] + }, + { + "id": "104b358d-b776-4554-8154-9d235cda41c0", + "name": "audio", + "type": "AUDIO", + "linkIds": [ + 709 + ], + "localized_name": "audio", + "pos": [ + -21.01953125, + 3744 + ] + }, + { + "id": "fa2f98f8-7318-4426-aa1c-27469bbca13f", + "name": "value", + "type": "STRING", + "linkIds": [ + 729 + ], + "label": "prompt", + "pos": [ + -21.01953125, + 3764 + ] + }, + { + "id": "f1aec0c2-3b9a-42ba-b790-cab8602e67a5", + "name": "value_5", + "type": "BOOLEAN", + "linkIds": [ + 759 + ], + "label": "prompt_enhance", + "pos": [ + -21.01953125, + 3784 + ] + }, + { + "id": "f45f5c0f-4d19-42d1-bfb7-740c91c0fdb6", + "name": "value_1", + "type": "INT", + "linkIds": [ + 730 + ], + "label": "width", + "pos": [ + -21.01953125, + 3804 + ] + }, + { + "id": "a0414d84-a2b3-46c1-a4b4-b4729376ccef", + "name": "value_2", + "type": "INT", + "linkIds": [ + 731 + ], + "label": "height", + "pos": [ + -21.01953125, + 3824 + ] + }, + { + "id": "499cc4e8-be6e-4b0e-b599-1d50339916c6", + "name": "start_index", + "type": "FLOAT", + "linkIds": [ + 733 + ], + "label": "audio_start", + "pos": [ + -21.01953125, + 3844 + ] + }, + { + "id": "13c9ac19-d8c7-4a44-9f31-97969f6fa165", + "name": "value_4", + "type": "FLOAT", + "linkIds": [ + 734 + ], + "label": "duration", + "pos": [ + -21.01953125, + 3864 + ] + }, + { + "id": "6c555a9a-2881-448b-92f9-f23c68de4e26", + "name": "value_3", + "type": "INT", + "linkIds": [ + 732 + ], + "label": "fps", + "pos": [ + -21.01953125, + 3884 + ] + }, + { + "id": "cf644152-3b39-4fbb-8946-6484c25a48d5", + "name": "noise_seed", + "type": "INT", + "linkIds": [ + 761 + ], + "label": "seed", + "pos": [ + -21.01953125, + 3904 + ] + }, + { + "id": "2c4a6dcd-8cb9-4058-ba4d-7379641317c7", + "name": "ckpt_name", + "type": "COMBO", + "linkIds": [ + 735, + 736, + 737 + ], + "pos": [ + -21.01953125, + 3924 + ] + }, + { + "id": "50329cb8-e54e-45bf-b7ae-d4fb7919c46e", + "name": "lora_name", + "type": "COMBO", + "linkIds": [ + 738 + ], + "label": "distilled_lora", + "pos": [ + -21.01953125, + 3944 + ] + }, + { + "id": "6032f234-532a-4f8f-b91c-1de13178983b", + "name": "text_encoder", + "type": "COMBO", + "linkIds": [ + 739 + ], + "pos": [ + -21.01953125, + 3964 + ] + }, + { + "id": "9f8f45c4-bf9e-4cfb-a289-72cfc4faea8b", + "name": "model_name", + "type": "COMBO", + "linkIds": [ + 740 + ], + "label": "upscale_model", + "pos": [ + -21.01953125, + 3984 + ] + }, + { + "id": "8745bf6c-2c6c-4e4c-a046-930d27917750", + "name": "lora_name_1", + "type": "COMBO", + "linkIds": [ + 760 + ], + "label": "lora", + "pos": [ + -21.01953125, + 4004 + ] + } + ], + "outputs": [ + { + "id": "05fff727-0167-4215-b9ae-17ac246e5734", + "name": "VIDEO", + "type": "VIDEO", + "linkIds": [ + 699 + ], + "localized_name": "VIDEO", + "pos": [ + 5344, + 4054 + ] + } + ], + "widgets": [], + "nodes": [ + { + "id": 285, + "type": "RandomNoise", + "pos": [ + 3970, + 3430 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "NOISE", + "name": "NOISE", + "type": "NOISE", + "links": [ + 687 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.3.75", + "Node name for S&R": "RandomNoise" + }, + "widgets_values": [ + 42, + "fixed" + ] + }, + { + "id": 286, + "type": "RandomNoise", + "pos": [ + 2330, + 3420 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "localized_name": "noise_seed", + "name": "noise_seed", + "type": "INT", + "widget": { + "name": "noise_seed" + }, + "link": 761 + } + ], + "outputs": [ + { + "localized_name": "NOISE", + "name": "NOISE", + "type": "NOISE", + "links": [ + 650 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.3.56", + "Node name for S&R": "RandomNoise" + }, + "widgets_values": [ + 225158785956033, + "randomize" + ] + }, + { + "id": 287, + "type": "LTXVConcatAVLatent", + "pos": [ + 3970, + 4130 + ], + "size": [ + 280, + 100 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "link": 642 + }, + { + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", + "link": 643 + } + ], + "outputs": [ + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 691 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.5.1", + "Node name for S&R": "LTXVConcatAVLatent" + }, + "widgets_values": [] + }, + { + "id": 288, + "type": "KSamplerSelect", + "pos": [ + 3970, + 3790 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "SAMPLER", + "name": "SAMPLER", + "type": "SAMPLER", + "links": [ + 689 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.3.75", + "Node name for S&R": "KSamplerSelect" + }, + "widgets_values": [ + "euler" + ] + }, + { + "id": 289, + "type": "ManualSigmas", + "pos": [ + 3970, + 3960 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "SIGMAS", + "name": "SIGMAS", + "type": "SIGMAS", + "links": [ + 690 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.5.1", + "Node name for S&R": "ManualSigmas" + }, + "widgets_values": [ + "0.85, 0.7250, 0.4219, 0.0" + ] + }, + { + "id": 290, + "type": "CFGGuider", + "pos": [ + 3970, + 3580 + ], + "size": [ + 280, + 160 + ], + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 644 + }, + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 645 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 646 + } + ], + "outputs": [ + { + "localized_name": "GUIDER", + "name": "GUIDER", + "type": "GUIDER", + "links": [ + 688 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.3.71", + "Node name for S&R": "CFGGuider" + }, + "widgets_values": [ + 1 + ] + }, + { + "id": 291, + "type": "SamplerCustomAdvanced", + "pos": [ + 2730, + 3420 + ], + "size": [ + 230, + 170 + ], + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [ + { + "localized_name": "noise", + "name": "noise", + "type": "NOISE", + "link": 650 + }, + { + "localized_name": "guider", + "name": "guider", + "type": "GUIDER", + "link": 651 + }, + { + "localized_name": "sampler", + "name": "sampler", + "type": "SAMPLER", + "link": 652 + }, + { + "localized_name": "sigmas", + "name": "sigmas", + "type": "SIGMAS", + "link": 653 + }, + { + "localized_name": "latent_image", + "name": "latent_image", + "type": "LATENT", + "link": 654 + } + ], + "outputs": [ + { + "localized_name": "output", + "name": "output", + "type": "LATENT", + "links": [ + 686 + ] + }, + { + "localized_name": "denoised_output", + "name": "denoised_output", + "type": "LATENT", + "links": [] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.3.60", + "Node name for S&R": "SamplerCustomAdvanced" + }, + "widgets_values": [] + }, + { + "id": 292, + "type": "LTXVCropGuides", + "pos": [ + 3070, + 3610 + ], + "size": [ + 250, + 120 + ], + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 655 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 656 + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "link": 657 + } + ], + "outputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "links": [ + 645 + ] + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "links": [ + 646 + ] + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "slot_index": 2, + "links": [] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.3.68", + "Node name for S&R": "LTXVCropGuides" + }, + "widgets_values": [] + }, + { + "id": 295, + "type": "LTXVLatentUpsampler", + "pos": [ + 3500, + 3710 + ], + "size": [ + 330, + 120 + ], + "flags": {}, + "order": 13, + "mode": 0, + "inputs": [ + { + "localized_name": "samples", + "name": "samples", + "type": "LATENT", + "link": 660 + }, + { + "localized_name": "upscale_model", + "name": "upscale_model", + "type": "LATENT_UPSCALE_MODEL", + "link": 661 + }, + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 662 + } + ], + "outputs": [ + { + "localized_name": "LATENT", + "name": "LATENT", + "type": "LATENT", + "links": [ + 665 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.14.1", + "Node name for S&R": "LTXVLatentUpsampler" + }, + "widgets_values": [] + }, + { + "id": 296, + "type": "LTXVImgToVideoInplace", + "pos": [ + 3520, + 3870 + ], + "size": [ + 300, + 180 + ], + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [ + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 663 + }, + { + "localized_name": "image", + "name": "image", + "type": "IMAGE", + "link": 664 + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "link": 665 + }, + { + "localized_name": "bypass", + "name": "bypass", + "type": "BOOLEAN", + "widget": { + "name": "bypass" + }, + "link": 666 + } + ], + "outputs": [ + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 642 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "LTXVImgToVideoInplace" + }, + "widgets_values": [ + 1, + false + ] + }, + { + "id": 298, + "type": "KSamplerSelect", + "pos": [ + 2340, + 3790 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "SAMPLER", + "name": "SAMPLER", + "type": "SAMPLER", + "links": [ + 652 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.3.56", + "Node name for S&R": "KSamplerSelect" + }, + "widgets_values": [ + "euler" + ] + }, + { + "id": 300, + "type": "Reroute", + "pos": [ + 3180, + 3850 + ], + "size": [ + 75, + 26 + ], + "flags": {}, + "order": 17, + "mode": 0, + "inputs": [ + { + "name": "", + "type": "*", + "link": 671 + } + ], + "outputs": [ + { + "name": "", + "type": "VAE", + "links": [ + 662, + 663, + 694 + ] + } + ], + "properties": { + "showOutputText": false, + "horizontal": false + } + }, + { + "id": 303, + "type": "LTXVAudioVAEDecode", + "pos": [ + 4990, + 3660 + ], + "size": [ + 270, + 100 + ], + "flags": {}, + "order": 20, + "mode": 0, + "inputs": [ + { + "localized_name": "samples", + "name": "samples", + "type": "LATENT", + "link": 679 + }, + { + "label": "Audio VAE", + "localized_name": "audio_vae", + "name": "audio_vae", + "type": "VAE", + "link": 680 + } + ], + "outputs": [ + { + "localized_name": "Audio", + "name": "Audio", + "type": "AUDIO", + "links": [ + 696 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "LTXVAudioVAEDecode" + }, + "widgets_values": [] + }, + { + "id": 306, + "type": "CLIPTextEncode", + "pos": [ + 1370, + 3430 + ], + "size": [ + 600, + 390 + ], + "flags": {}, + "order": 22, + "mode": 0, + "inputs": [ + { + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 703 + }, + { + "localized_name": "text", + "name": "text", + "type": "STRING", + "widget": { + "name": "text" + }, + "link": 755 + } + ], + "outputs": [ + { + "localized_name": "CONDITIONING", + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 682 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.3.56", + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "" + ], + "color": "#232", + "bgcolor": "#353" + }, + { + "id": 307, + "type": "LTXVConditioning", + "pos": [ + 2000, + 3600 + ], + "size": [ + 280, + 130 + ], + "flags": {}, + "order": 23, + "mode": 0, + "inputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 682 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 683 + }, + { + "localized_name": "frame_rate", + "name": "frame_rate", + "type": "FLOAT", + "widget": { + "name": "frame_rate" + }, + "link": 684 + } + ], + "outputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "links": [ + 648, + 655 + ] + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "links": [ + 649, + 656 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.3.56", + "Node name for S&R": "LTXVConditioning" + }, + "widgets_values": [ + 24 + ] + }, + { + "id": 308, + "type": "ManualSigmas", + "pos": [ + 2340, + 4000 + ], + "size": [ + 500, + 110 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "SIGMAS", + "name": "SIGMAS", + "type": "SIGMAS", + "links": [ + 653 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "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": 309, + "type": "LTXVSeparateAVLatent", + "pos": [ + 3070, + 3430 + ], + "size": [ + 250, + 100 + ], + "flags": {}, + "order": 24, + "mode": 0, + "inputs": [ + { + "localized_name": "av_latent", + "name": "av_latent", + "type": "LATENT", + "link": 686 + } + ], + "outputs": [ + { + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "links": [ + 657, + 660 + ] + }, + { + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", + "links": [ + 643 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.5.1", + "Node name for S&R": "LTXVSeparateAVLatent" + }, + "widgets_values": [] + }, + { + "id": 310, + "type": "SamplerCustomAdvanced", + "pos": [ + 4310, + 3440 + ], + "size": [ + 230, + 170 + ], + "flags": {}, + "order": 25, + "mode": 0, + "inputs": [ + { + "localized_name": "noise", + "name": "noise", + "type": "NOISE", + "link": 687 + }, + { + "localized_name": "guider", + "name": "guider", + "type": "GUIDER", + "link": 688 + }, + { + "localized_name": "sampler", + "name": "sampler", + "type": "SAMPLER", + "link": 689 + }, + { + "localized_name": "sigmas", + "name": "sigmas", + "type": "SIGMAS", + "link": 690 + }, + { + "localized_name": "latent_image", + "name": "latent_image", + "type": "LATENT", + "link": 691 + } + ], + "outputs": [ + { + "localized_name": "output", + "name": "output", + "type": "LATENT", + "links": [ + 692 + ] + }, + { + "localized_name": "denoised_output", + "name": "denoised_output", + "type": "LATENT", + "links": [] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.3.75", + "Node name for S&R": "SamplerCustomAdvanced" + }, + "widgets_values": [] + }, + { + "id": 311, + "type": "LTXVSeparateAVLatent", + "pos": [ + 4650, + 3440 + ], + "size": [ + 230, + 100 + ], + "flags": {}, + "order": 26, + "mode": 0, + "inputs": [ + { + "localized_name": "av_latent", + "name": "av_latent", + "type": "LATENT", + "link": 692 + } + ], + "outputs": [ + { + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "links": [ + 693 + ] + }, + { + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", + "links": [ + 679 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.5.1", + "Node name for S&R": "LTXVSeparateAVLatent" + }, + "widgets_values": [] + }, + { + "id": 314, + "type": "CLIPTextEncode", + "pos": [ + 1370, + 3910 + ], + "size": [ + 600, + 170 + ], + "flags": {}, + "order": 29, + "mode": 0, + "inputs": [ + { + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 721 + } + ], + "outputs": [ + { + "localized_name": "CONDITIONING", + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 683 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.3.56", + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "pc game, console game, video game, cartoon, childish, ugly" + ], + "color": "#323", + "bgcolor": "#535" + }, + { + "id": 315, + "type": "CFGGuider", + "pos": [ + 2330, + 3580 + ], + "size": [ + 280, + 160 + ], + "flags": {}, + "order": 30, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 647 + }, + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 648 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 649 + } + ], + "outputs": [ + { + "localized_name": "GUIDER", + "name": "GUIDER", + "type": "GUIDER", + "links": [ + 651 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.3.64", + "Node name for S&R": "CFGGuider" + }, + "widgets_values": [ + 1 + ] + }, + { + "id": 316, + "type": "VAEDecodeTiled", + "pos": [ + 4970, + 3440 + ], + "size": [ + 280, + 150 + ], + "flags": {}, + "order": 31, + "mode": 0, + "inputs": [ + { + "localized_name": "samples", + "name": "samples", + "type": "LATENT", + "link": 693 + }, + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 694 + } + ], + "outputs": [ + { + "localized_name": "IMAGE", + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 695 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.14.1", + "Node name for S&R": "VAEDecodeTiled" + }, + "widgets_values": [ + 768, + 64, + 4096, + 4 + ] + }, + { + "id": 325, + "type": "LTXVImgToVideoInplace", + "pos": [ + 2060, + 4410 + ], + "size": [ + 280, + 180 + ], + "flags": {}, + "order": 37, + "mode": 0, + "inputs": [ + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 675 + }, + { + "localized_name": "image", + "name": "image", + "type": "IMAGE", + "link": 676 + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "link": 677 + }, + { + "localized_name": "bypass", + "name": "bypass", + "type": "BOOLEAN", + "widget": { + "name": "bypass" + }, + "link": 678 + } + ], + "outputs": [ + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 685 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "LTXVImgToVideoInplace" + }, + "widgets_values": [ + 0.7, + false + ] + }, + { + "id": 330, + "type": "PrimitiveInt", + "pos": [ + 410, + 4040 + ], + "size": [ + 370, + 110 + ], + "flags": {}, + "order": 42, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "INT", + "widget": { + "name": "value" + }, + "link": 730 + } + ], + "outputs": [ + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 668, + 670, + 716 + ] + } + ], + "title": "Width", + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "PrimitiveInt" + }, + "widgets_values": [ + 1280, + "fixed" + ] + }, + { + "id": 333, + "type": "SolidMask", + "pos": [ + 2390, + 4420 + ], + "size": [ + 260, + 170 + ], + "flags": { + "collapsed": false + }, + "order": 45, + "mode": 0, + "inputs": [ + { + "localized_name": "width", + "name": "width", + "type": "INT", + "widget": { + "name": "width" + }, + "link": 716 + }, + { + "localized_name": "height", + "name": "height", + "type": "INT", + "widget": { + "name": "height" + }, + "link": 717 + } + ], + "outputs": [ + { + "localized_name": "MASK", + "name": "MASK", + "type": "MASK", + "links": [ + 713 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "SolidMask", + "ue_properties": { + "widget_ue_connectable": { + "width": true, + "height": true + }, + "version": "7.5.2", + "input_ue_unconnectable": {} + } + }, + "widgets_values": [ + 0, + 1024, + 1024 + ] + }, + { + "id": 335, + "type": "LTXVAudioVAELoader", + "pos": [ + 870, + 3790 + ], + "size": [ + 430, + 110 + ], + "flags": {}, + "order": 47, + "mode": 0, + "inputs": [ + { + "localized_name": "ckpt_name", + "name": "ckpt_name", + "type": "COMBO", + "widget": { + "name": "ckpt_name" + }, + "link": 737 + } + ], + "outputs": [ + { + "localized_name": "Audio VAE", + "name": "Audio VAE", + "type": "VAE", + "links": [ + 680, + 718 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.3.68", + "Node name for S&R": "LTXVAudioVAELoader", + "models": [ + { + "name": "ltx-2.3-22b-dev-fp8.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", + "directory": "checkpoints" + } + ] + }, + "widgets_values": [ + "ltx-2.3-22b-dev-fp8.safetensors" + ] + }, + { + "id": 305, + "type": "PrimitiveBoolean", + "pos": [ + 420, + 3890 + ], + "size": [ + 370, + 100 + ], + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "BOOLEAN", + "name": "BOOLEAN", + "type": "BOOLEAN", + "links": [ + 666, + 678 + ] + } + ], + "title": "Switch to Text to Video?", + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.0", + "Node name for S&R": "PrimitiveBoolean" + }, + "widgets_values": [ + false + ] + }, + { + "id": 294, + "type": "ResizeImagesByLongerEdge", + "pos": [ + 1330, + 4620 + ], + "size": [ + 310, + 110 + ], + "flags": { + "collapsed": false + }, + "order": 12, + "mode": 0, + "inputs": [ + { + "localized_name": "images", + "name": "images", + "type": "IMAGE", + "link": 659 + } + ], + "outputs": [ + { + "localized_name": "images", + "name": "images", + "type": "IMAGE", + "links": [ + 667 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.5.1", + "Node name for S&R": "ResizeImagesByLongerEdge" + }, + "widgets_values": [ + 1536 + ] + }, + { + "id": 334, + "type": "LTXVPreprocess", + "pos": [ + 1340, + 4460 + ], + "size": [ + 290, + 110 + ], + "flags": {}, + "order": 46, + "mode": 0, + "inputs": [ + { + "localized_name": "image", + "name": "image", + "type": "IMAGE", + "link": 667 + } + ], + "outputs": [ + { + "localized_name": "output_image", + "name": "output_image", + "type": "IMAGE", + "links": [ + 664, + 676 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "LTXVPreprocess" + }, + "widgets_values": [ + 18 + ] + }, + { + "id": 301, + "type": "ComfyMathExpression", + "pos": [ + 1760, + 4670 + ], + "size": [ + 225, + 8 + ], + "flags": { + "collapsed": true + }, + "order": 18, + "mode": 0, + "inputs": [ + { + "label": "a", + "localized_name": "values.a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 672 + }, + { + "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": [ + 674 + ] + }, + { + "localized_name": "BOOL", + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "ComfyMathExpression" + }, + "widgets_values": [ + "a/2" + ] + }, + { + "id": 299, + "type": "ComfyMathExpression", + "pos": [ + 1760, + 4620 + ], + "size": [ + 225, + 8 + ], + "flags": { + "collapsed": true + }, + "order": 16, + "mode": 0, + "inputs": [ + { + "label": "a", + "localized_name": "values.a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 670 + }, + { + "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": [ + 673 + ] + }, + { + "localized_name": "BOOL", + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "ComfyMathExpression" + }, + "widgets_values": [ + "a/2" + ] + }, + { + "id": 304, + "type": "ComfyMathExpression", + "pos": [ + 1760, + 4500 + ], + "size": [ + 225, + 8 + ], + "flags": { + "collapsed": true + }, + "order": 21, + "mode": 0, + "inputs": [ + { + "label": "a", + "localized_name": "values.a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 681 + }, + { + "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": [ + 684, + 697 + ] + }, + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [] + }, + { + "localized_name": "BOOL", + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "ComfyMathExpression" + }, + "widgets_values": [ + "a" + ] + }, + { + "id": 312, + "type": "CreateVideo", + "pos": [ + 4990, + 4310 + ], + "size": [ + 280, + 130 + ], + "flags": {}, + "order": 27, + "mode": 0, + "inputs": [ + { + "localized_name": "images", + "name": "images", + "type": "IMAGE", + "link": 695 + }, + { + "localized_name": "audio", + "name": "audio", + "shape": 7, + "type": "AUDIO", + "link": 696 + }, + { + "localized_name": "fps", + "name": "fps", + "type": "FLOAT", + "widget": { + "name": "fps" + }, + "link": 697 + } + ], + "outputs": [ + { + "localized_name": "VIDEO", + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 699 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.5.1", + "Node name for S&R": "CreateVideo" + }, + "widgets_values": [ + 24 + ] + }, + { + "id": 331, + "type": "PrimitiveFloat", + "pos": [ + 410, + 4520 + ], + "size": [ + 350, + 110 + ], + "flags": {}, + "order": 43, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "FLOAT", + "widget": { + "name": "value" + }, + "link": 734 + } + ], + "outputs": [ + { + "localized_name": "FLOAT", + "name": "FLOAT", + "type": "FLOAT", + "links": [ + 710, + 711 + ] + } + ], + "title": "Duration", + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "PrimitiveFloat" + }, + "widgets_values": [ + 9 + ] + }, + { + "id": 323, + "type": "PrimitiveInt", + "pos": [ + 410, + 4340 + ], + "size": [ + 370, + 110 + ], + "flags": {}, + "order": 35, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "INT", + "widget": { + "name": "value" + }, + "link": 732 + } + ], + "outputs": [ + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 681, + 724 + ] + } + ], + "title": "Frame Rate", + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "PrimitiveInt" + }, + "widgets_values": [ + 24, + "fixed" + ] + }, + { + "id": 302, + "type": "EmptyLTXVLatentVideo", + "pos": [ + 2070, + 4590 + ], + "size": [ + 280, + 200 + ], + "flags": {}, + "order": 19, + "mode": 0, + "inputs": [ + { + "localized_name": "width", + "name": "width", + "type": "INT", + "widget": { + "name": "width" + }, + "link": 673 + }, + { + "localized_name": "height", + "name": "height", + "type": "INT", + "widget": { + "name": "height" + }, + "link": 674 + }, + { + "localized_name": "length", + "name": "length", + "type": "INT", + "widget": { + "name": "length" + }, + "link": 712 + } + ], + "outputs": [ + { + "localized_name": "LATENT", + "name": "LATENT", + "type": "LATENT", + "links": [ + 677 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.3.60", + "Node name for S&R": "EmptyLTXVLatentVideo" + }, + "widgets_values": [ + 576, + 1024, + 145, + 1 + ] + }, + { + "id": 329, + "type": "ComfyMathExpression", + "pos": [ + 1760, + 4720 + ], + "size": [ + 225, + 8 + ], + "flags": { + "collapsed": true + }, + "order": 41, + "mode": 0, + "inputs": [ + { + "label": "a", + "localized_name": "values.a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 711 + }, + { + "label": "b", + "localized_name": "values.b", + "name": "values.b", + "shape": 7, + "type": "FLOAT,INT,BOOLEAN", + "link": 724 + }, + { + "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": [ + 712 + ] + }, + { + "localized_name": "BOOL", + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "ComfyMathExpression" + }, + "widgets_values": [ + "a * b + 1" + ] + }, + { + "id": 324, + "type": "PrimitiveInt", + "pos": [ + 410, + 4190 + ], + "size": [ + 370, + 110 + ], + "flags": {}, + "order": 36, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "INT", + "widget": { + "name": "value" + }, + "link": 731 + } + ], + "outputs": [ + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 669, + 672, + 717 + ] + } + ], + "title": "Height", + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "PrimitiveInt" + }, + "widgets_values": [ + 720, + "fixed" + ] + }, + { + "id": 332, + "type": "TrimAudioDuration", + "pos": [ + 410, + 4810 + ], + "size": [ + 330, + 140 + ], + "flags": {}, + "order": 44, + "mode": 0, + "inputs": [ + { + "localized_name": "audio", + "name": "audio", + "type": "AUDIO", + "link": 709 + }, + { + "localized_name": "start_index", + "name": "start_index", + "type": "FLOAT", + "widget": { + "name": "start_index" + }, + "link": 733 + }, + { + "localized_name": "duration", + "name": "duration", + "type": "FLOAT", + "widget": { + "name": "duration" + }, + "link": 710 + } + ], + "outputs": [ + { + "localized_name": "AUDIO", + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 708 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "TrimAudioDuration" + }, + "widgets_values": [ + 0, + 60 + ] + }, + { + "id": 328, + "type": "LTXVAudioVAEEncode", + "pos": [ + 2400, + 4640 + ], + "size": [ + 250, + 100 + ], + "flags": {}, + "order": 40, + "mode": 0, + "inputs": [ + { + "localized_name": "audio", + "name": "audio", + "type": "AUDIO", + "link": 708 + }, + { + "label": "Audio VAE", + "localized_name": "audio_vae", + "name": "audio_vae", + "type": "VAE", + "link": 718 + } + ], + "outputs": [ + { + "localized_name": "Audio Latent", + "name": "Audio Latent", + "type": "LATENT", + "links": [ + 714 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "LTXVAudioVAEEncode" + }, + "widgets_values": [] + }, + { + "id": 326, + "type": "LTXVConcatAVLatent", + "pos": [ + 3090, + 4420 + ], + "size": [ + 240, + 100 + ], + "flags": {}, + "order": 38, + "mode": 0, + "inputs": [ + { + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "link": 685 + }, + { + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", + "link": 715 + } + ], + "outputs": [ + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 654 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "LTXVConcatAVLatent" + }, + "widgets_values": [] + }, + { + "id": 327, + "type": "SetLatentNoiseMask", + "pos": [ + 2720, + 4640 + ], + "size": [ + 350, + 100 + ], + "flags": {}, + "order": 39, + "mode": 0, + "inputs": [ + { + "localized_name": "samples", + "name": "samples", + "type": "LATENT", + "link": 714 + }, + { + "localized_name": "mask", + "name": "mask", + "type": "MASK", + "link": 713 + } + ], + "outputs": [ + { + "localized_name": "LATENT", + "name": "LATENT", + "type": "LATENT", + "links": [ + 715 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "SetLatentNoiseMask", + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.5.2", + "input_ue_unconnectable": {} + } + }, + "widgets_values": [], + "color": "#323", + "bgcolor": "#535" + }, + { + "id": 313, + "type": "LatentUpscaleModelLoader", + "pos": [ + 880, + 4160 + ], + "size": [ + 400, + 110 + ], + "flags": {}, + "order": 28, + "mode": 0, + "inputs": [ + { + "localized_name": "model_name", + "name": "model_name", + "type": "COMBO", + "widget": { + "name": "model_name" + }, + "link": 740 + } + ], + "outputs": [ + { + "localized_name": "LATENT_UPSCALE_MODEL", + "name": "LATENT_UPSCALE_MODEL", + "type": "LATENT_UPSCALE_MODEL", + "links": [ + 661 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "LatentUpscaleModelLoader", + "models": [ + { + "name": "ltx-2.3-spatial-upscaler-x2-1.1.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors", + "directory": "latent_upscale_models" + } + ] + }, + "widgets_values": [ + "ltx-2.3-spatial-upscaler-x2-1.1.safetensors" + ] + }, + { + "id": 293, + "type": "LoraLoaderModelOnly", + "pos": [ + 870, + 3610 + ], + "size": [ + 430, + 140 + ], + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 658 + }, + { + "localized_name": "lora_name", + "name": "lora_name", + "type": "COMBO", + "widget": { + "name": "lora_name" + }, + "link": 738 + } + ], + "outputs": [ + { + "localized_name": "MODEL", + "name": "MODEL", + "type": "MODEL", + "links": [ + 644, + 647, + 757 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.3.75", + "Node name for S&R": "LoraLoaderModelOnly", + "models": [ + { + "name": "ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", + "url": "https://huggingface.co/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", + "directory": "loras" + } + ] + }, + "widgets_values": [ + "ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", + 0.5 + ] + }, + { + "id": 317, + "type": "CheckpointLoaderSimple", + "pos": [ + 870, + 3410 + ], + "size": [ + 430, + 160 + ], + "flags": {}, + "order": 32, + "mode": 0, + "inputs": [ + { + "localized_name": "ckpt_name", + "name": "ckpt_name", + "type": "COMBO", + "widget": { + "name": "ckpt_name" + }, + "link": 735 + } + ], + "outputs": [ + { + "localized_name": "MODEL", + "name": "MODEL", + "type": "MODEL", + "links": [ + 658 + ] + }, + { + "localized_name": "CLIP", + "name": "CLIP", + "type": "CLIP", + "links": [] + }, + { + "localized_name": "VAE", + "name": "VAE", + "type": "VAE", + "links": [ + 671, + 675 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.3.56", + "Node name for S&R": "CheckpointLoaderSimple", + "models": [ + { + "name": "ltx-2.3-22b-dev-fp8.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", + "directory": "checkpoints" + } + ] + }, + "widgets_values": [ + "ltx-2.3-22b-dev-fp8.safetensors" + ] + }, + { + "id": 318, + "type": "LTXAVTextEncoderLoader", + "pos": [ + 870, + 3950 + ], + "size": [ + 430, + 170 + ], + "flags": {}, + "order": 33, + "mode": 0, + "inputs": [ + { + "localized_name": "text_encoder", + "name": "text_encoder", + "type": "COMBO", + "widget": { + "name": "text_encoder" + }, + "link": 739 + }, + { + "localized_name": "ckpt_name", + "name": "ckpt_name", + "type": "COMBO", + "widget": { + "name": "ckpt_name" + }, + "link": 736 + } + ], + "outputs": [ + { + "localized_name": "CLIP", + "name": "CLIP", + "type": "CLIP", + "links": [ + 703, + 721, + 758 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "LTXAVTextEncoderLoader", + "models": [ + { + "name": "ltx-2.3-22b-dev-fp8.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", + "directory": "checkpoints" + }, + { + "name": "gemma_3_12B_it_fp4_mixed.safetensors", + "url": "https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors", + "directory": "text_encoders" + } + ] + }, + "widgets_values": [ + "gemma_3_12B_it_fp4_mixed.safetensors", + "ltx-2.3-22b-dev-fp8.safetensors", + "default" + ] + }, + { + "id": 319, + "type": "PrimitiveStringMultiline", + "pos": [ + 410, + 3460 + ], + "size": [ + 370, + 350 + ], + "flags": {}, + "order": 34, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "STRING", + "widget": { + "name": "value" + }, + "link": 729 + } + ], + "outputs": [ + { + "localized_name": "STRING", + "name": "STRING", + "type": "STRING", + "links": [ + 756, + 762 + ] + } + ], + "title": "Prompt", + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "PrimitiveStringMultiline" + }, + "widgets_values": [ + "The fuzzy cactus creature is talking to the viewer as it grips the steering wheel with one hand, the other hand gestures naturally as it speaks. The car is moving, revealing the sunlit coastal background, static camera fixed on character, smooth side-tracking shot matching the car speed\n\nscene: Sunlit coastal road trip, clear coastal background\ncharacter: Fuzzy cactus creature with big square sunglasses and a Hawaiian shirt\naction: One hand grips the steering wheel, the other gestures naturally while talking to the camera\ncamera: Fixed on character, smooth side-tracking shot matching car speed" + ] + }, + { + "id": 297, + "type": "ResizeImageMaskNode", + "pos": [ + 890, + 4400 + ], + "size": [ + 300, + 239.984375 + ], + "flags": {}, + "order": 15, + "mode": 0, + "inputs": [ + { + "localized_name": "input", + "name": "input", + "type": "IMAGE,MASK", + "link": 698 + }, + { + "localized_name": "width", + "name": "resize_type.width", + "type": "INT", + "widget": { + "name": "resize_type.width" + }, + "link": 668 + }, + { + "localized_name": "height", + "name": "resize_type.height", + "type": "INT", + "widget": { + "name": "resize_type.height" + }, + "link": 669 + } + ], + "outputs": [ + { + "localized_name": "resized", + "name": "resized", + "type": "IMAGE,MASK", + "links": [ + 659 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "ResizeImageMaskNode" + }, + "widgets_values": [ + "scale dimensions", + 1920, + 1088, + "center", + "lanczos" + ] + }, + { + "id": 345, + "type": "LoraLoader", + "pos": [ + 410, + 2670 + ], + "size": [ + 380, + 230 + ], + "flags": {}, + "order": 48, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 757 + }, + { + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 758 + }, + { + "localized_name": "lora_name", + "name": "lora_name", + "type": "COMBO", + "widget": { + "name": "lora_name" + }, + "link": 760 + } + ], + "outputs": [ + { + "localized_name": "MODEL", + "name": "MODEL", + "type": "MODEL", + "links": null + }, + { + "localized_name": "CLIP", + "name": "CLIP", + "type": "CLIP", + "links": [ + 751 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "LoraLoader", + "models": [ + { + "name": "gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", + "url": "https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", + "directory": "loras" + } + ] + }, + "widgets_values": [ + "gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", + 1, + 1 + ] + }, + { + "id": 346, + "type": "TextGenerateLTX2Prompt", + "pos": [ + 840, + 2670 + ], + "size": [ + 400, + 558.65625 + ], + "flags": { + "collapsed": false + }, + "order": 49, + "mode": 0, + "inputs": [ + { + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 751 + }, + { + "localized_name": "image", + "name": "image", + "shape": 7, + "type": "IMAGE", + "link": null + }, + { + "localized_name": "video", + "name": "video", + "shape": 7, + "type": "IMAGE", + "link": null + }, + { + "localized_name": "audio", + "name": "audio", + "shape": 7, + "type": "AUDIO", + "link": null + }, + { + "localized_name": "prompt", + "name": "prompt", + "type": "STRING", + "widget": { + "name": "prompt" + }, + "link": 756 + } + ], + "outputs": [ + { + "localized_name": "generated_text", + "name": "generated_text", + "type": "STRING", + "links": [ + 753 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "TextGenerateLTX2Prompt" + }, + "widgets_values": [ + "A young woman speaks directly to the camera in her bedroom, holding the product beside her face as she talks about it. Warm natural light, handheld selfie framing, authentic UGC testimonial.", + 2048, + "on", + 0.7, + 64, + 0.95, + 0.05, + 1.05, + 0, + 0, + false, + true + ] + }, + { + "id": 347, + "type": "PreviewAny", + "pos": [ + 1680, + 2690 + ], + "size": [ + 510, + 360 + ], + "flags": {}, + "order": 50, + "mode": 0, + "inputs": [ + { + "localized_name": "source", + "name": "source", + "type": "*", + "link": 752 + } + ], + "outputs": [ + { + "localized_name": "STRING", + "name": "STRING", + "type": "STRING", + "links": [] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "PreviewAny" + }, + "widgets_values": [ + null, + null, + null + ] + }, + { + "id": 348, + "type": "ComfySwitchNode", + "pos": [ + 1370, + 3080 + ], + "size": [ + 270, + 130 + ], + "flags": {}, + "order": 51, + "mode": 0, + "inputs": [ + { + "localized_name": "on_false", + "name": "on_false", + "type": "STRING", + "link": 762 + }, + { + "localized_name": "on_true", + "name": "on_true", + "type": "STRING", + "link": 753 + }, + { + "localized_name": "switch", + "name": "switch", + "type": "BOOLEAN", + "widget": { + "name": "switch" + }, + "link": 754 + } + ], + "outputs": [ + { + "localized_name": "output", + "name": "output", + "type": "STRING", + "links": [ + 752, + 755 + ] + } + ], + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.22.0", + "Node name for S&R": "ComfySwitchNode" + }, + "widgets_values": [ + false + ] + }, + { + "id": 349, + "type": "PrimitiveBoolean", + "pos": [ + 410, + 3150 + ], + "size": [ + 270, + 100 + ], + "flags": {}, + "order": 52, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "BOOLEAN", + "widget": { + "name": "value" + }, + "link": 759 + } + ], + "outputs": [ + { + "localized_name": "BOOLEAN", + "name": "BOOLEAN", + "type": "BOOLEAN", + "links": [ + 754 + ] + } + ], + "title": "Boolean (Enable Prompt Enhance)", + "properties": { + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "cnr_id": "comfy-core", + "ver": "0.22.0", + "Node name for S&R": "PrimitiveBoolean" + }, + "widgets_values": [ + true + ] + } + ], + "groups": [ + { + "id": 1, + "title": "Model", + "bounding": [ + 850, + 3340, + 460, + 960 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 2, + "title": "Generate Low Resolution", + "bounding": [ + 2320, + 3340, + 1050, + 960 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 3, + "title": "Prompt", + "bounding": [ + 1340, + 3340, + 950, + 960 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 6, + "title": "Generate High Resolution", + "bounding": [ + 3930, + 3340, + 1000, + 960 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 7, + "title": "Latent Upscale", + "bounding": [ + 3390, + 3340, + 520, + 960 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 19, + "title": "Video Settings", + "bounding": [ + 370, + 3340, + 450, + 1420 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 20, + "title": "Image Preprocess", + "bounding": [ + 840, + 4330, + 830, + 420 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 21, + "title": "Empty Latent", + "bounding": [ + 2040, + 4330, + 1340, + 420 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 22, + "title": "Number conversion", + "bounding": [ + 1700, + 4330, + 310, + 420 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 27, + "title": "Prompt Enhancement", + "bounding": [ + 370, + 2590, + 2010, + 720 + ], + "color": "#3f789e", + "flags": {} + } + ], + "links": [ + { + "id": 642, + "origin_id": 296, + "origin_slot": 0, + "target_id": 287, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 643, + "origin_id": 309, + "origin_slot": 1, + "target_id": 287, + "target_slot": 1, + "type": "LATENT" + }, + { + "id": 644, + "origin_id": 293, + "origin_slot": 0, + "target_id": 290, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 645, + "origin_id": 292, + "origin_slot": 0, + "target_id": 290, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 646, + "origin_id": 292, + "origin_slot": 1, + "target_id": 290, + "target_slot": 2, + "type": "CONDITIONING" + }, + { + "id": 650, + "origin_id": 286, + "origin_slot": 0, + "target_id": 291, + "target_slot": 0, + "type": "NOISE" + }, + { + "id": 651, + "origin_id": 315, + "origin_slot": 0, + "target_id": 291, + "target_slot": 1, + "type": "GUIDER" + }, + { + "id": 652, + "origin_id": 298, + "origin_slot": 0, + "target_id": 291, + "target_slot": 2, + "type": "SAMPLER" + }, + { + "id": 653, + "origin_id": 308, + "origin_slot": 0, + "target_id": 291, + "target_slot": 3, + "type": "SIGMAS" + }, + { + "id": 654, + "origin_id": 326, + "origin_slot": 0, + "target_id": 291, + "target_slot": 4, + "type": "LATENT" + }, + { + "id": 655, + "origin_id": 307, + "origin_slot": 0, + "target_id": 292, + "target_slot": 0, + "type": "CONDITIONING" + }, + { + "id": 656, + "origin_id": 307, + "origin_slot": 1, + "target_id": 292, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 657, + "origin_id": 309, + "origin_slot": 0, + "target_id": 292, + "target_slot": 2, + "type": "LATENT" + }, + { + "id": 658, + "origin_id": 317, + "origin_slot": 0, + "target_id": 293, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 660, + "origin_id": 309, + "origin_slot": 0, + "target_id": 295, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 661, + "origin_id": 313, + "origin_slot": 0, + "target_id": 295, + "target_slot": 1, + "type": "LATENT_UPSCALE_MODEL" + }, + { + "id": 662, + "origin_id": 300, + "origin_slot": 0, + "target_id": 295, + "target_slot": 2, + "type": "VAE" + }, + { + "id": 663, + "origin_id": 300, + "origin_slot": 0, + "target_id": 296, + "target_slot": 0, + "type": "VAE" + }, + { + "id": 664, + "origin_id": 334, + "origin_slot": 0, + "target_id": 296, + "target_slot": 1, + "type": "IMAGE" + }, + { + "id": 665, + "origin_id": 295, + "origin_slot": 0, + "target_id": 296, + "target_slot": 2, + "type": "LATENT" + }, + { + "id": 666, + "origin_id": 305, + "origin_slot": 0, + "target_id": 296, + "target_slot": 3, + "type": "BOOLEAN" + }, + { + "id": 671, + "origin_id": 317, + "origin_slot": 2, + "target_id": 300, + "target_slot": 0, + "type": "VAE" + }, + { + "id": 679, + "origin_id": 311, + "origin_slot": 1, + "target_id": 303, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 680, + "origin_id": 335, + "origin_slot": 0, + "target_id": 303, + "target_slot": 1, + "type": "VAE" + }, + { + "id": 703, + "origin_id": 318, + "origin_slot": 0, + "target_id": 306, + "target_slot": 0, + "type": "CLIP" + }, + { + "id": 682, + "origin_id": 306, + "origin_slot": 0, + "target_id": 307, + "target_slot": 0, + "type": "CONDITIONING" + }, + { + "id": 683, + "origin_id": 314, + "origin_slot": 0, + "target_id": 307, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 684, + "origin_id": 304, + "origin_slot": 0, + "target_id": 307, + "target_slot": 2, + "type": "FLOAT" + }, + { + "id": 686, + "origin_id": 291, + "origin_slot": 0, + "target_id": 309, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 687, + "origin_id": 285, + "origin_slot": 0, + "target_id": 310, + "target_slot": 0, + "type": "NOISE" + }, + { + "id": 688, + "origin_id": 290, + "origin_slot": 0, + "target_id": 310, + "target_slot": 1, + "type": "GUIDER" + }, + { + "id": 689, + "origin_id": 288, + "origin_slot": 0, + "target_id": 310, + "target_slot": 2, + "type": "SAMPLER" + }, + { + "id": 690, + "origin_id": 289, + "origin_slot": 0, + "target_id": 310, + "target_slot": 3, + "type": "SIGMAS" + }, + { + "id": 691, + "origin_id": 287, + "origin_slot": 0, + "target_id": 310, + "target_slot": 4, + "type": "LATENT" + }, + { + "id": 692, + "origin_id": 310, + "origin_slot": 0, + "target_id": 311, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 721, + "origin_id": 318, + "origin_slot": 0, + "target_id": 314, + "target_slot": 0, + "type": "CLIP" + }, + { + "id": 647, + "origin_id": 293, + "origin_slot": 0, + "target_id": 315, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 648, + "origin_id": 307, + "origin_slot": 0, + "target_id": 315, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 649, + "origin_id": 307, + "origin_slot": 1, + "target_id": 315, + "target_slot": 2, + "type": "CONDITIONING" + }, + { + "id": 693, + "origin_id": 311, + "origin_slot": 0, + "target_id": 316, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 694, + "origin_id": 300, + "origin_slot": 0, + "target_id": 316, + "target_slot": 1, + "type": "VAE" + }, + { + "id": 675, + "origin_id": 317, + "origin_slot": 2, + "target_id": 325, + "target_slot": 0, + "type": "VAE" + }, + { + "id": 676, + "origin_id": 334, + "origin_slot": 0, + "target_id": 325, + "target_slot": 1, + "type": "IMAGE" + }, + { + "id": 677, + "origin_id": 302, + "origin_slot": 0, + "target_id": 325, + "target_slot": 2, + "type": "LATENT" + }, + { + "id": 678, + "origin_id": 305, + "origin_slot": 0, + "target_id": 325, + "target_slot": 3, + "type": "BOOLEAN" + }, + { + "id": 685, + "origin_id": 325, + "origin_slot": 0, + "target_id": 326, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 715, + "origin_id": 327, + "origin_slot": 0, + "target_id": 326, + "target_slot": 1, + "type": "LATENT" + }, + { + "id": 714, + "origin_id": 328, + "origin_slot": 0, + "target_id": 327, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 713, + "origin_id": 333, + "origin_slot": 0, + "target_id": 327, + "target_slot": 1, + "type": "MASK" + }, + { + "id": 708, + "origin_id": 332, + "origin_slot": 0, + "target_id": 328, + "target_slot": 0, + "type": "AUDIO" + }, + { + "id": 718, + "origin_id": 335, + "origin_slot": 0, + "target_id": 328, + "target_slot": 1, + "type": "VAE" + }, + { + "id": 716, + "origin_id": 330, + "origin_slot": 0, + "target_id": 333, + "target_slot": 0, + "type": "INT" + }, + { + "id": 717, + "origin_id": 324, + "origin_slot": 0, + "target_id": 333, + "target_slot": 1, + "type": "INT" + }, + { + "id": 668, + "origin_id": 330, + "origin_slot": 0, + "target_id": 297, + "target_slot": 1, + "type": "INT" + }, + { + "id": 669, + "origin_id": 324, + "origin_slot": 0, + "target_id": 297, + "target_slot": 2, + "type": "INT" + }, + { + "id": 659, + "origin_id": 297, + "origin_slot": 0, + "target_id": 294, + "target_slot": 0, + "type": "IMAGE" + }, + { + "id": 667, + "origin_id": 294, + "origin_slot": 0, + "target_id": 334, + "target_slot": 0, + "type": "IMAGE" + }, + { + "id": 672, + "origin_id": 324, + "origin_slot": 0, + "target_id": 301, + "target_slot": 0, + "type": "INT" + }, + { + "id": 670, + "origin_id": 330, + "origin_slot": 0, + "target_id": 299, + "target_slot": 0, + "type": "INT" + }, + { + "id": 681, + "origin_id": 323, + "origin_slot": 0, + "target_id": 304, + "target_slot": 0, + "type": "INT" + }, + { + "id": 695, + "origin_id": 316, + "origin_slot": 0, + "target_id": 312, + "target_slot": 0, + "type": "IMAGE" + }, + { + "id": 696, + "origin_id": 303, + "origin_slot": 0, + "target_id": 312, + "target_slot": 1, + "type": "AUDIO" + }, + { + "id": 697, + "origin_id": 304, + "origin_slot": 0, + "target_id": 312, + "target_slot": 2, + "type": "FLOAT" + }, + { + "id": 673, + "origin_id": 299, + "origin_slot": 1, + "target_id": 302, + "target_slot": 0, + "type": "INT" + }, + { + "id": 674, + "origin_id": 301, + "origin_slot": 1, + "target_id": 302, + "target_slot": 1, + "type": "INT" + }, + { + "id": 712, + "origin_id": 329, + "origin_slot": 1, + "target_id": 302, + "target_slot": 2, + "type": "INT" + }, + { + "id": 711, + "origin_id": 331, + "origin_slot": 0, + "target_id": 329, + "target_slot": 0, + "type": "FLOAT" + }, + { + "id": 724, + "origin_id": 323, + "origin_slot": 0, + "target_id": 329, + "target_slot": 1, + "type": "INT" + }, + { + "id": 710, + "origin_id": 331, + "origin_slot": 0, + "target_id": 332, + "target_slot": 2, + "type": "FLOAT" + }, + { + "id": 698, + "origin_id": -10, + "origin_slot": 0, + "target_id": 297, + "target_slot": 0, + "type": "IMAGE,MASK" + }, + { + "id": 709, + "origin_id": -10, + "origin_slot": 1, + "target_id": 332, + "target_slot": 0, + "type": "AUDIO" + }, + { + "id": 699, + "origin_id": 312, + "origin_slot": 0, + "target_id": -20, + "target_slot": 0, + "type": "VIDEO" + }, + { + "id": 729, + "origin_id": -10, + "origin_slot": 2, + "target_id": 319, + "target_slot": 0, + "type": "STRING" + }, + { + "id": 730, + "origin_id": -10, + "origin_slot": 4, + "target_id": 330, + "target_slot": 0, + "type": "INT" + }, + { + "id": 731, + "origin_id": -10, + "origin_slot": 5, + "target_id": 324, + "target_slot": 0, + "type": "INT" + }, + { + "id": 732, + "origin_id": -10, + "origin_slot": 8, + "target_id": 323, + "target_slot": 0, + "type": "INT" + }, + { + "id": 733, + "origin_id": -10, + "origin_slot": 6, + "target_id": 332, + "target_slot": 1, + "type": "FLOAT" + }, + { + "id": 734, + "origin_id": -10, + "origin_slot": 7, + "target_id": 331, + "target_slot": 0, + "type": "FLOAT" + }, + { + "id": 735, + "origin_id": -10, + "origin_slot": 10, + "target_id": 317, + "target_slot": 0, + "type": "COMBO" + }, + { + "id": 736, + "origin_id": -10, + "origin_slot": 10, + "target_id": 318, + "target_slot": 1, + "type": "COMBO" + }, + { + "id": 737, + "origin_id": -10, + "origin_slot": 10, + "target_id": 335, + "target_slot": 0, + "type": "COMBO" + }, + { + "id": 738, + "origin_id": -10, + "origin_slot": 11, + "target_id": 293, + "target_slot": 1, + "type": "COMBO" + }, + { + "id": 739, + "origin_id": -10, + "origin_slot": 12, + "target_id": 318, + "target_slot": 0, + "type": "COMBO" + }, + { + "id": 740, + "origin_id": -10, + "origin_slot": 13, + "target_id": 313, + "target_slot": 0, + "type": "COMBO" + }, + { + "id": 751, + "origin_id": 345, + "origin_slot": 1, + "target_id": 346, + "target_slot": 0, + "type": "CLIP" + }, + { + "id": 752, + "origin_id": 348, + "origin_slot": 0, + "target_id": 347, + "target_slot": 0, + "type": "*" + }, + { + "id": 753, + "origin_id": 346, + "origin_slot": 0, + "target_id": 348, + "target_slot": 1, + "type": "STRING" + }, + { + "id": 754, + "origin_id": 349, + "origin_slot": 0, + "target_id": 348, + "target_slot": 2, + "type": "BOOLEAN" + }, + { + "id": 755, + "origin_id": 348, + "origin_slot": 0, + "target_id": 306, + "target_slot": 1, + "type": "STRING" + }, + { + "id": 756, + "origin_id": 319, + "origin_slot": 0, + "target_id": 346, + "target_slot": 4, + "type": "STRING" + }, + { + "id": 757, + "origin_id": 293, + "origin_slot": 0, + "target_id": 345, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 758, + "origin_id": 318, + "origin_slot": 0, + "target_id": 345, + "target_slot": 1, + "type": "CLIP" + }, + { + "id": 759, + "origin_id": -10, + "origin_slot": 3, + "target_id": 349, + "target_slot": 0, + "type": "BOOLEAN" + }, + { + "id": 760, + "origin_id": -10, + "origin_slot": 14, + "target_id": 345, + "target_slot": 2, + "type": "COMBO" + }, + { + "id": 761, + "origin_id": -10, + "origin_slot": 9, + "target_id": 286, + "target_slot": 0, + "type": "INT" + }, + { + "id": 762, + "origin_id": 319, + "origin_slot": 0, + "target_id": 348, + "target_slot": 0, + "type": "STRING" + } + ], + "extra": { + "workflowRendererVersion": "Vue-corrected" + } + } + ] + }, + "config": {}, + "extra": { + "ds": { + "scale": 0.7239609100430904, + "offset": [ + 688.908674348608, + -3229.875453153755 + ] + }, + "frontendVersion": "1.43.18", + "workflowRendererVersion": "Vue-corrected", + "prompt": { + "1": { + "inputs": { + "ckpt_name": "ltx-av-step-1751000_vocoder_24K.safetensors" + }, + "class_type": "CheckpointLoaderSimple", + "_meta": { + "title": "Load Checkpoint" + } + }, + "2": { + "inputs": { + "gemma_path": "gemma-3-12b-it-qat-q4_0-unquantized_readout_proj/model/model.safetensors", + "ltxv_path": "ltx-av-step-1751000_vocoder_24K.safetensors", + "max_length": 1024 + }, + "class_type": "LTXVGemmaCLIPModelLoader", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 Gemma 3 Model Loader" + } + }, + "3": { + "inputs": { + "text": "", + "clip": [ + "2", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "4": { + "inputs": { + "text": "blurry, low quality, still frame, frames, watermark, overlay, titles, has blurbox, has subtitles", + "clip": [ + "2", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "8": { + "inputs": { + "sampler_name": "euler" + }, + "class_type": "KSamplerSelect", + "_meta": { + "title": "KSamplerSelect" + } + }, + "9": { + "inputs": { + "steps": 20, + "max_shift": 2.05, + "base_shift": 0.95, + "stretch": true, + "terminal": 0.1, + "latent": [ + "28", + 0 + ] + }, + "class_type": "LTXVScheduler", + "_meta": { + "title": "LTXVScheduler" + } + }, + "11": { + "inputs": { + "noise_seed": 10 + }, + "class_type": "RandomNoise", + "_meta": { + "title": "RandomNoise" + } + }, + "12": { + "inputs": { + "samples": [ + "29", + 0 + ], + "vae": [ + "1", + 2 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } + }, + "13": { + "inputs": { + "ckpt_name": "ltx-av-step-1751000_vocoder_24K.safetensors" + }, + "class_type": "LTXVAudioVAELoader", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Audio VAE Loader" + } + }, + "14": { + "inputs": { + "samples": [ + "29", + 1 + ], + "audio_vae": [ + "13", + 0 + ] + }, + "class_type": "LTXVAudioVAEDecode", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Audio VAE Decode" + } + }, + "15": { + "inputs": { + "frame_rate": [ + "23", + 0 + ], + "loop_count": 0, + "filename_prefix": "AnimateDiff", + "format": "video/h264-mp4", + "pix_fmt": "yuv420p", + "crf": 19, + "save_metadata": true, + "trim_to_audio": false, + "pingpong": false, + "save_output": true, + "images": [ + "12", + 0 + ], + "audio": [ + "14", + 0 + ] + }, + "class_type": "VHS_VideoCombine", + "_meta": { + "title": "Video Combine \ud83c\udfa5\ud83c\udd65\ud83c\udd57\ud83c\udd62" + } + }, + "17": { + "inputs": { + "skip_blocks": "29", + "model": [ + "28", + 1 + ], + "positive": [ + "22", + 0 + ], + "negative": [ + "22", + 1 + ], + "parameters": [ + "18", + 0 + ] + }, + "class_type": "MultimodalGuider", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 Multimodal Guider" + } + }, + "18": { + "inputs": { + "modality": "VIDEO", + "cfg": 3, + "stg": 0, + "rescale": 0, + "modality_scale": 3, + "parameters": [ + "19", + 0 + ] + }, + "class_type": "GuiderParameters", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 Guider Parameters" + } + }, + "19": { + "inputs": { + "modality": "AUDIO", + "cfg": 7, + "stg": 0, + "rescale": 0, + "modality_scale": 3 + }, + "class_type": "GuiderParameters", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 Guider Parameters" + } + }, + "21": { + "inputs": { + "audioUI": "", + "audio": [ + "14", + 0 + ] + }, + "class_type": "PreviewAudio", + "_meta": { + "title": "PreviewAudio" + } + }, + "22": { + "inputs": { + "frame_rate": [ + "23", + 0 + ], + "positive": [ + "3", + 0 + ], + "negative": [ + "4", + 0 + ] + }, + "class_type": "LTXVConditioning", + "_meta": { + "title": "LTXVConditioning" + } + }, + "23": { + "inputs": { + "value": 25 + }, + "class_type": "FloatConstant", + "_meta": { + "title": "Float Constant" + } + }, + "26": { + "inputs": { + "frames_number": [ + "27", + 0 + ], + "frame_rate": [ + "42", + 0 + ], + "batch_size": 1 + }, + "class_type": "LTXVEmptyLatentAudio", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Empty Latent Audio" + } + }, + "27": { + "inputs": { + "value": 105 + }, + "class_type": "INTConstant", + "_meta": { + "title": "INT Constant" + } + }, + "28": { + "inputs": { + "video_latent": [ + "43", + 0 + ], + "audio_latent": [ + "26", + 0 + ], + "model": [ + "44", + 0 + ] + }, + "class_type": "LTXVConcatAVLatent", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Concat AV Latent" + } + }, + "29": { + "inputs": { + "av_latent": [ + "41", + 0 + ], + "model": [ + "28", + 1 + ] + }, + "class_type": "LTXVSeparateAVLatent", + "_meta": { + "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Separate AV Latent" + } + }, + "41": { + "inputs": { + "noise": [ + "11", + 0 + ], + "guider": [ + "17", + 0 + ], + "sampler": [ + "8", + 0 + ], + "sigmas": [ + "9", + 0 + ], + "latent_image": [ + "28", + 0 + ] + }, + "class_type": "SamplerCustomAdvanced", + "_meta": { + "title": "SamplerCustomAdvanced" + } + }, + "42": { + "inputs": { + "a": [ + "23", + 0 + ] + }, + "class_type": "CM_FloatToInt", + "_meta": { + "title": "FloatToInt" + } + }, + "43": { + "inputs": { + "width": 768, + "height": 512, + "length": [ + "27", + 0 + ], + "batch_size": 1 + }, + "class_type": "EmptyLTXVLatentVideo", + "_meta": { + "title": "EmptyLTXVLatentVideo" + } + }, + "44": { + "inputs": { + "torch_compile": true, + "disable_backup": false, + "model": [ + "1", + 0 + ] + }, + "class_type": "LTXVSequenceParallelMultiGPUPatcher", + "_meta": { + "title": "LTXVSequenceParallelMultiGPUPatcher" + } + }, + "45": { + "inputs": { + "frame_idx": 0, + "strength": 1 + }, + "class_type": "LTXVAddGuide", + "_meta": { + "title": "LTXVAddGuide" + } + } + }, + "comfy_fork_version": "feature/av_inference@a6994ed1", + "VHS_latentpreview": false, + "VHS_latentpreviewrate": 0, + "VHS_MetadataImage": true, + "VHS_KeepIntermediate": true + }, + "version": 0.4 +} \ No newline at end of file diff --git a/src/@types/C2D/ServiceOnDemand.ts b/src/@types/C2D/ServiceOnDemand.ts index f859530b5..5101f5a18 100644 --- a/src/@types/C2D/ServiceOnDemand.ts +++ b/src/@types/C2D/ServiceOnDemand.ts @@ -22,6 +22,14 @@ export interface UserConfigurableEnvVar { sensitive?: boolean // advisory hint for clients/UI (e.g. mask on input). The node receives ALL userData ECIES-encrypted, so this does not change node-side storage. } +export interface ServiceTemplateWorkflow { + id: string // [A-Za-z0-9_.-]+ — becomes a filename and a ?template= value + name: string + description?: string + file?: string // path relative to the templates dir; inlined into `graph` at load time + graph?: unknown // the workflow JSON itself +} + export interface ServiceTemplate { id: string // [a-z0-9][a-z0-9_-]{0,63} name?: string @@ -39,6 +47,7 @@ export interface ServiceTemplate { entrypoint?: string[] // Docker ENTRYPOINT override requiredResources?: TemplateResourceRequirement[] // MUST satisfy — gates SERVICE_START recommendedResources?: TemplateResourceRequirement[] // SHOULD satisfy — used for scoring + UI + workflows?: ServiceTemplateWorkflow[] // client-selectable graphs; no operator secrets, so public } // ── Public / sanitized types ────────────────────────────────────────── @@ -141,6 +150,7 @@ export interface ServiceJob { exposedPorts: number[] endpoints: ServiceEndpoint[] userData?: string // ECIES(node key) string sent by the client; stored as-is, decrypted only at start/restart; never returned + outputBucketId?: string // persistent-storage bucket bind-mounted at /data/outputs resources: ComputeResourceRequestWithPrice[] payment: DBComputeJobPayment // initial start payment extendPayments?: DBComputeJobPayment[] // one entry per successful SERVICE_EXTEND diff --git a/src/@types/commands.ts b/src/@types/commands.ts index 358cab0f0..a8ea49141 100644 --- a/src/@types/commands.ts +++ b/src/@types/commands.ts @@ -422,6 +422,7 @@ export interface ServiceStartCommand extends Command { resources?: ComputeResourceRequest[] duration: number // seconds; capped by serviceOnDemand.maxDurationSeconds userData?: string // ECIES-encrypted (to the node's public key) JSON object → the container's env-var map + outputBucketId?: string // persistent-storage bucket bind-mounted at /data/outputs payment: { chainId: number; token: string } } diff --git a/src/components/c2d/compute_engine_base.ts b/src/components/c2d/compute_engine_base.ts index 977ceb126..714084af8 100644 --- a/src/components/c2d/compute_engine_base.ts +++ b/src/components/c2d/compute_engine_base.ts @@ -100,7 +100,8 @@ export abstract class C2DEngine { owner: string, payment: DBComputeJobPayment, serviceId: string, - userData?: string // ECIES-encrypted; the engine decrypts it transiently into the container env + userData?: string, // ECIES-encrypted; the engine decrypts it transiently into the container env + outputBucketId?: string ): Promise { return null } diff --git a/src/components/c2d/compute_engine_docker.ts b/src/components/c2d/compute_engine_docker.ts index 0c250addb..1e4cae7f5 100755 --- a/src/components/c2d/compute_engine_docker.ts +++ b/src/components/c2d/compute_engine_docker.ts @@ -72,6 +72,7 @@ import { SERVICE_START_PENDING_STATUSES } from '../../@types/C2D/ServiceOnDemand.js' import type { ServiceJob } from '../../@types/C2D/ServiceOnDemand.js' +import type { DockerMountObject } from '../../@types/PersistentStorage.js' import { resolveServiceImage } from './serviceResourceMatching.js' import { allocateHostPort, @@ -3364,7 +3365,8 @@ export class C2DEngineDocker extends C2DEngine { owner: string, payment: DBComputeJobPayment, serviceId: string, - userData?: string + userData?: string, + outputBucketId?: string ): Promise { const containerImage = resolveServiceImage( image, @@ -3396,6 +3398,7 @@ export class C2DEngineDocker extends C2DEngine { exposedPorts, endpoints: [], userData, // stored as received (ECIES-encrypted); decrypted transiently at container start + outputBucketId, resources: resources.map((r) => ({ id: r.id, amount: r.amount })), payment } @@ -3611,6 +3614,14 @@ export class C2DEngineDocker extends C2DEngine { job.environment ) + // Mount failure must fail the start: an unmounted container silently re-downloads its models. + const Mounts: DockerMountObject[] = [] + if (job.outputBucketId) { + const ps = OceanNode.getInstance().getPersistentStorage() + if (!ps) throw new Error('Persistent storage is not configured on this node') + Mounts.push(await ps.getDockerOutputMountObject(job.outputBucketId, job.owner)) + } + container = await this.docker.createContainer({ Image: job.containerImage, Cmd: cmd, @@ -3626,7 +3637,8 @@ export class C2DEngineDocker extends C2DEngine { NetworkMode: network.id, SecurityOpt: ['no-new-privileges'], // security plan #5 CapDrop: ['ALL'], - PidsLimit: 512 + PidsLimit: 512, + Mounts } }) CORE_LOGGER.debug( @@ -4310,6 +4322,14 @@ export class C2DEngineDocker extends C2DEngine { ) // 8. Create and start new container + // Same bind-mount as service start (see above). + const Mounts: DockerMountObject[] = [] + if (job.outputBucketId) { + const ps = OceanNode.getInstance().getPersistentStorage() + if (!ps) throw new Error('Persistent storage is not configured on this node') + Mounts.push(await ps.getDockerOutputMountObject(job.outputBucketId, job.owner)) + } + container = await this.docker.createContainer({ Image: effContainerImage, Cmd: cmd, @@ -4325,7 +4345,8 @@ export class C2DEngineDocker extends C2DEngine { NetworkMode: network.id, SecurityOpt: ['no-new-privileges'], CapDrop: ['ALL'], - PidsLimit: 512 + PidsLimit: 512, + Mounts } }) CORE_LOGGER.debug( diff --git a/src/components/core/service/startService.ts b/src/components/core/service/startService.ts index 585ce69bd..34fc662fe 100644 --- a/src/components/core/service/startService.ts +++ b/src/components/core/service/startService.ts @@ -15,7 +15,7 @@ import type { ComputeEnvironment, DBComputeJobPayment as Payment } from '../../../@types/C2D/C2D.js' -import { generateUniqueID } from '../compute/utils.js' +import { generateUniqueID, validateOutputBucket } from '../compute/utils.js' import { validateAccess } from '../compute/startCompute.js' import { decryptUserData, toPublicServiceJob } from './utils.js' @@ -122,6 +122,17 @@ export class ServiceStartHandler extends CommandHandler { } } + // Must run before createServiceJob claims escrow, or a bad bucket burns the user's payment. + const isValidOutputBucket = await validateOutputBucket( + node, + task.outputBucketId, + '', + task.consumerAddress + ) + if (isValidOutputBucket.status.httpStatus !== 200) { + return isValidOutputBucket + } + // 4. Duration limit const sod = engine.getC2DConfig().connection?.serviceOnDemand const maxDuration = sod?.maxDurationSeconds ?? 86400 @@ -237,7 +248,8 @@ export class ServiceStartHandler extends CommandHandler { task.consumerAddress, payment, serviceId, - task.userData + task.userData, + task.outputBucketId ) return { diff --git a/src/components/core/service/templateLoader.ts b/src/components/core/service/templateLoader.ts index fc3c99abc..e40af9c5c 100644 --- a/src/components/core/service/templateLoader.ts +++ b/src/components/core/service/templateLoader.ts @@ -1,6 +1,9 @@ import { readdir, readFile } from 'fs/promises' -import { join } from 'path' -import type { ServiceTemplate } from '../../../@types/C2D/ServiceOnDemand.js' +import { join, resolve, sep } from 'path' +import type { + ServiceTemplate, + ServiceTemplateWorkflow +} from '../../../@types/C2D/ServiceOnDemand.js' import { ServiceTemplateSchema } from '../../../utils/config/schemas.js' import { CORE_LOGGER } from '../../../utils/logging/common.js' @@ -25,6 +28,7 @@ export async function loadServiceTemplates(dir?: string): Promise() for (const file of files) { let raw: unknown @@ -54,6 +58,33 @@ export async function loadServiceTemplates(dir?: string): Promise resources: (req.body.resources as ComputeResourceRequest[]) || undefined, duration: req.body.duration as number, userData: (req.body.userData as string) || undefined, + outputBucketId: (req.body.outputBucketId as string) || undefined, payment: req.body.payment, authorization: req.headers?.authorization, caller: req.caller diff --git a/src/test/unit/service/serviceHandlers.test.ts b/src/test/unit/service/serviceHandlers.test.ts index 9e0ab3150..6c46a6ad3 100644 --- a/src/test/unit/service/serviceHandlers.test.ts +++ b/src/test/unit/service/serviceHandlers.test.ts @@ -160,6 +160,12 @@ function buildFakes(opts: FakeOpts = {}) { fetchServiceTemplates: sinon.stub().resolves([{ ...TEMPLATE }]) } + // Valid by default; override validateBucket/assertConsumerAllowedForBucket to fail it. + const persistentStorage: any = { + validateBucket: sinon.stub(), + assertConsumerAllowedForBucket: sinon.stub().resolves(undefined) + } + const node: any = { getRequestMap: () => new Map(), getConfig: (): any => ({ @@ -172,10 +178,11 @@ function buildFakes(opts: FakeOpts = {}) { }), getAuth: () => ({ validateAuthenticationOrToken: () => Promise.resolve({ valid: true }) - }) + }), + getPersistentStorage: () => persistentStorage } - return { node, engine, engines, escrow, env } + return { node, engine, engines, escrow, env, persistentStorage } } function body(response: any): Promise { @@ -947,6 +954,29 @@ describe('Service handlers', () => { const out = await body(res) expect(out[0]).to.not.have.property('userData') }) + + it('forwards outputBucketId to createServiceJob', async () => { + const { node, engine } = buildFakes() + const res = await new ServiceStartHandler(node).handle({ + ...baseTask, + outputBucketId: 'bucket-42' + } as any) + expect(res.status.httpStatus).to.equal(200) + expect(engine.createServiceJob.lastCall.args.at(-1)).to.equal('bucket-42') + }) + + it('400 with a clear message when outputBucketId is invalid, and no job record is created (fail fast)', async () => { + const { node, engine, persistentStorage } = buildFakes() + persistentStorage.validateBucket.throws(new Error('bucket not found')) + const res = await new ServiceStartHandler(node).handle({ + ...baseTask, + outputBucketId: 'bad-bucket' + } as any) + expect(res.status.httpStatus).to.equal(400) + expect(String(res.status.error)).to.contain('bucket not found') + // no job record may be created for a start that was refused upfront (see startService.ts) + expect(engine.createServiceJob.called).to.equal(false) + }) }) describe('ServiceGetStreamableLogsHandler', () => { diff --git a/src/test/unit/service/serviceSchemas.test.ts b/src/test/unit/service/serviceSchemas.test.ts index 1377e7f31..41a484ef9 100644 --- a/src/test/unit/service/serviceSchemas.test.ts +++ b/src/test/unit/service/serviceSchemas.test.ts @@ -1,4 +1,6 @@ import { expect } from 'chai' +import { readFileSync } from 'fs' +import { join } from 'path' import { ServiceTemplateSchema, ServiceOnDemandConfigSchema, @@ -84,6 +86,11 @@ describe('ServiceTemplateSchema', () => { }).success ).to.equal(true) }) + it('ltx-video-ugc: template matches ServiceTemplateSchema', () => { + const dir = join(process.cwd(), 'docs', 'serviceTemplates') + const tmpl = JSON.parse(readFileSync(join(dir, 'ltx-video-ugc.json'), 'utf8')) + expect(ServiceTemplateSchema.safeParse(tmpl).success).to.equal(true) + }) }) describe('ServiceOnDemandConfigSchema', () => { diff --git a/src/test/unit/service/templateLoader.test.ts b/src/test/unit/service/templateLoader.test.ts index 791f5275f..1122338c2 100644 --- a/src/test/unit/service/templateLoader.test.ts +++ b/src/test/unit/service/templateLoader.test.ts @@ -1,6 +1,6 @@ import { expect } from 'chai' -import { mkdtempSync, writeFileSync, rmSync } from 'fs' -import { join } from 'path' +import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'fs' +import { join, relative } from 'path' import { tmpdir } from 'os' import { loadServiceTemplates } from '../../../components/core/service/templateLoader.js' @@ -83,4 +83,47 @@ describe('loadServiceTemplates', () => { writeFileSync(join(dir, 'b.json'), JSON.stringify(valid('b'))) expect(await loadServiceTemplates(dir)).to.have.length(2) }) + + it('10. workflows[].file is inlined into graph and file is dropped', async () => { + mkdirSync(join(dir, 'workflows')) + writeFileSync( + join(dir, 'workflows', 'w.json'), + JSON.stringify({ nodes: [{ id: 1 }] }) + ) + writeFileSync( + join(dir, 'a.json'), + JSON.stringify({ + ...valid('tmpl-wf'), + workflows: [ + { id: 'ocean_ugc_product', name: 'Product', file: 'workflows/w.json' } + ] + }) + ) + const [tmpl] = await loadServiceTemplates(dir) + expect(tmpl.workflows[0].graph).to.deep.equal({ nodes: [{ id: 1 }] }) + expect(tmpl.workflows[0]).to.not.have.property('file') + }) + + it('11. workflows[].file escaping the templates dir via ../ is dropped, template survives', async () => { + const outsideDir = mkdtempSync(join(tmpdir(), 'svc-templates-outside-')) + try { + const secretPath = join(outsideDir, 'secret.json') + writeFileSync(secretPath, JSON.stringify({ secret: true })) + writeFileSync( + join(dir, 'a.json'), + JSON.stringify({ + ...valid('tmpl-escape'), + workflows: [ + { id: 'escape', name: 'Escape', file: relative(dir, secretPath) }, + { id: 'inline', name: 'Inline', graph: { nodes: [] } } + ] + }) + ) + const [tmpl] = await loadServiceTemplates(dir) + expect(tmpl.id).to.equal('tmpl-escape') + expect(tmpl.workflows.map((w) => w.id)).to.deep.equal(['inline']) + } finally { + rmSync(outsideDir, { recursive: true, force: true }) + } + }) }) diff --git a/src/utils/config/schemas.ts b/src/utils/config/schemas.ts index 5b4820384..af4f5b7df 100644 --- a/src/utils/config/schemas.ts +++ b/src/utils/config/schemas.ts @@ -343,6 +343,21 @@ const UserConfigurableEnvVarSchema = z }) .strict() +export const ServiceTemplateWorkflowSchema = z + .object({ + id: z.string().regex(/^[A-Za-z0-9_.-]+$/, { + message: 'Workflow id must match [A-Za-z0-9_.-]+' + }), + name: z.string().min(1), + description: z.string().optional(), + file: z.string().min(1).optional(), + graph: z.unknown().optional() + }) + .strict() + .refine((w) => !!w.file !== !!w.graph, { + message: 'A workflow must set exactly one of "file" or "graph"' + }) + export const ServiceTemplateSchema = z .object({ id: z.string().regex(/^[a-z0-9][a-z0-9_-]{0,63}$/, { @@ -364,7 +379,8 @@ export const ServiceTemplateSchema = z command: z.array(z.string()).optional(), entrypoint: z.array(z.string()).optional(), requiredResources: z.array(TemplateResourceRequirementSchema).optional(), - recommendedResources: z.array(TemplateResourceRequirementSchema).optional() + recommendedResources: z.array(TemplateResourceRequirementSchema).optional(), + workflows: z.array(ServiceTemplateWorkflowSchema).optional() }) .strict() .superRefine((tmpl, ctx) => { From 08f1e0d4a4da6051b3ef94fb03e28c3a96c16b99 Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Tue, 4 Aug 2026 15:13:05 +0300 Subject: [PATCH 02/29] fix template --- docs/serviceTemplates/README.md | 11 +++++++++-- docs/serviceTemplates/ltx-video-ugc.json | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/serviceTemplates/README.md b/docs/serviceTemplates/README.md index 506dc7be9..fb5acc392 100644 --- a/docs/serviceTemplates/README.md +++ b/docs/serviceTemplates/README.md @@ -113,8 +113,15 @@ script (inlined as `command[0]`) that downloads the ~38 GiB weight set (LTX-2.3 checkpoint, Gemma-3-12B text encoder, two LoRAs, the x2 spatial upscaler) on first launch. Pick a persistent-storage bucket for this template — weights and generated clips both live there, so only the first launch pays the download; without a bucket the weights land inside -the container and are lost on stop. When a bucket is mounted, `ComfyUI/models` is a symlink -into it rather than a real directory. +the container and are lost on stop (in `/tmp`, not the bucket). + +The bootstrap runs `main.py` directly from the image's read-only bundle with ComfyUI's own +`--base-directory` flag, pointed at the bucket, so models/output/input/user/custom_nodes all +live there and nothing is written under `/root`. This deliberately bypasses the image's +entrypoint, which copies its bundle into `/root/ComfyUI` and therefore fails on hosts where the +service container is not uid 0. Relocating `custom_nodes` also means the image's bundled +ComfyUI-Manager is not loaded — this template ships fixed workflows and installs no nodes at +runtime. The consumer selects a workflow via userData: `COMFY_WORKFLOW_ID` (`ocean_ugc_product` or `ocean_ugc_testimonial`, used only for the `[ocean] installed workflow …` log line) plus diff --git a/docs/serviceTemplates/ltx-video-ugc.json b/docs/serviceTemplates/ltx-video-ugc.json index 151dddb71..7a065234b 100644 --- a/docs/serviceTemplates/ltx-video-ugc.json +++ b/docs/serviceTemplates/ltx-video-ugc.json @@ -1,7 +1,7 @@ { "id": "ltx-video-ugc", "name": "ComfyUI \u2014 UGC short-form video (LTX-2.3)", - "description": "ComfyUI preloaded with LTX-2.3 for vertical short-form product video. Two workflows: a product photo becomes a 9:16 clip with ambient audio, or a creator photo plus a voice clip becomes a lip-synced testimonial (the clip is capped at the graph's 5.8s, so trim longer voiceovers or raise the frame count). Weights (38 GiB) download on first launch into the selected persistent-storage bucket and are reused after that; generated clips are written to the same bucket. Needs a CUDA GPU with 48 GB+ VRAM.", + "description": "ComfyUI preloaded with LTX-2.3 for vertical short-form product video. Two workflows: a product photo becomes a 9:16 clip with ambient audio, or a creator photo plus a voice clip becomes a lip-synced testimonial (the clip is capped at the graph's 5.8s, so trim longer voiceovers or raise the frame count). Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the 38 GiB of weights download once and are reused, and generated clips outlive the container. Needs a CUDA GPU with 48 GB+ VRAM.", "image": "yanwk/comfyui-boot", "tag": "cu130-megapak-pt211-20260803", "exposedPorts": [ @@ -12,7 +12,7 @@ "-c" ], "command": [ - "#!/bin/bash\n# Bootstrap for the ltx-video-ugc service template. Runs as the container command with\n# entrypoint [\"/bin/bash\",\"-c\"] \u2014 a shell entrypoint is mandatory because ocean-node passes\n# dockerCmd to Docker verbatim and performs no ${VAR} expansion of its own.\nset -euo pipefail\n\nWF_ID=\"${COMFY_WORKFLOW_ID:-}\"\n# COMFY_WORKFLOW_ID is client-supplied and becomes a filename. ServiceStartHandler never\n# loads templates, so userConfigurableEnvVars.validation is NOT enforced node-side \u2014 this\n# check is the only thing standing between userData and a path traversal.\nif [ -n \"$WF_ID\" ] && ! [[ \"$WF_ID\" =~ ^[A-Za-z0-9_.-]{1,64}$ ]]; then\n echo \"[ocean] invalid COMFY_WORKFLOW_ID\" >&2\n exit 1\nfi\n\nmkdir -p /root/ComfyUI\nif [ -d /data/outputs ]; then\n # Bucket is mounted: keep both weights and generated clips in it, so they survive the\n # container. The image's entrypoint rsyncs with --ignore-existing, so the symlink stands.\n mkdir -p /data/outputs/models /data/outputs/comfy-output\n # /root/ComfyUI/models normally does not exist yet: this image empties /root at build and its\n # entrypoint copies ComfyUI in only after we exec it. Handle a real directory anyway, so a\n # future image that does ship one cannot abort the bootstrap under set -e.\n if [ -d /root/ComfyUI/models ] && [ ! -L /root/ComfyUI/models ]; then\n mv /root/ComfyUI/models /root/ComfyUI/models.image-default\n fi\n ln -sfn /data/outputs/models /root/ComfyUI/models\n export CLI_ARGS=\"--output-directory /data/outputs/comfy-output ${CLI_ARGS:-}\"\nelse\n echo \"[ocean] no bucket mounted \u2014 models download to the container and are lost on stop\"\nfi\n\nMODELS=/root/ComfyUI/models\nmkdir -p \"$MODELS/checkpoints\" \"$MODELS/loras\" \"$MODELS/text_encoders\" \"$MODELS/latent_upscale_models\"\n\n# Download to .part then rename: a truncated file in a persistent bucket would be treated as\n# cached by every future launch.\nget() {\n if [ -f \"$2\" ]; then\n echo \"[ocean] cached $(basename \"$2\")\"\n return 0\n fi\n echo \"[ocean] downloading $(basename \"$2\")\"\n # No -f: a complete .part from a container that died between the download landing and the\n # mv makes `curl -C -` ask HuggingFace to resume a finished file, which answers 416. Check the\n # status ourselves so that specific case can recover instead of wedging every future launch.\n http_code=$(curl -L --retry 5 --retry-delay 5 -C - -o \"$2.part\" -w '%{http_code}' \"$1\")\n if [ \"$http_code\" = \"416\" ] && [ -f \"$2.part\" ]; then\n echo \"[ocean] $(basename \"$2\").part already complete\"\n elif [ \"$http_code\" -lt 200 ] || [ \"$http_code\" -ge 300 ]; then\n echo \"[ocean] download failed for $(basename \"$2\") (HTTP $http_code)\" >&2\n return 22\n fi\n mv \"$2.part\" \"$2\"\n}\n\nHF=https://huggingface.co\nget \"$HF/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors\" \\\n \"$MODELS/checkpoints/ltx-2.3-22b-dev-fp8.safetensors\"\nget \"$HF/Comfy-Org/ltx-2/resolve/main/split_files/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors\" \\\n \"$MODELS/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors\"\nget \"$HF/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors\" \\\n \"$MODELS/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors\"\nget \"$HF/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\" \\\n \"$MODELS/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\"\nget \"$HF/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors\" \\\n \"$MODELS/latent_upscale_models/ltx-2.3-spatial-upscaler-x2-1.1.safetensors\"\n\n# Minimal custom-node pack: ComfyUI serves example_workflows at\n# /api/workflow_templates/ocean_ugc/ocean_ugc.json, which is what ?template=ocean_ugc&source=all\n# loads. Exactly one graph is ever installed per container, so the filename is a constant, not\n# keyed by WF_ID \u2014 WF_ID is only used below for the log line, the in-container record of which\n# graph was picked.\nPACK=/root/ComfyUI/custom_nodes/ocean_ugc\nmkdir -p \"$PACK/example_workflows\"\necho 'NODE_CLASS_MAPPINGS = {}' > \"$PACK/__init__.py\"\nif [ -n \"$WF_ID\" ] && [ -n \"${COMFY_WORKFLOW:-}\" ]; then\n # Escrow is already claimed by the time this runs \u2014 a corrupt/undecodable payload must not take\n # the whole container down with it. Degrade to an empty pack and keep going; base64/gunzip's own\n # stderr plus the line below land in the container logs either way.\n if printf '%s' \"$COMFY_WORKFLOW\" | base64 -d | gunzip > \"$PACK/example_workflows/ocean_ugc.json\"; then\n echo \"[ocean] installed workflow $WF_ID\"\n else\n echo \"[ocean] failed to decode COMFY_WORKFLOW \u2014 starting ComfyUI with an empty workflow pack\" >&2\n rm -f \"$PACK/example_workflows/ocean_ugc.json\"\n fi\nfi\n\nexec bash /runner-scripts/entrypoint.sh\n" + "#!/bin/bash\n# Bootstrap for the ltx-video-ugc service template. Runs as the container command with\n# entrypoint [\"/bin/bash\",\"-c\"] \u2014 a shell entrypoint is mandatory because ocean-node passes\n# dockerCmd to Docker verbatim and performs no ${VAR} expansion of its own.\n#\n# Nothing is written under /root, and the image's own entrypoint is deliberately bypassed:\n# that entrypoint copies its ComfyUI bundle into /root/ComfyUI, which fails on hosts where the\n# service container is not uid 0. Instead ComfyUI runs straight from the read-only bundle with\n# --base-directory, its native flag for relocating models/output/input/user/custom_nodes.\nset -euo pipefail\n\nWF_ID=\"${COMFY_WORKFLOW_ID:-}\"\n# COMFY_WORKFLOW_ID is client-supplied and becomes a filename. ServiceStartHandler never\n# loads templates, so userConfigurableEnvVars.validation is NOT enforced node-side \u2014 this\n# check is the only thing standing between userData and a path traversal.\nif [ -n \"$WF_ID\" ] && ! [[ \"$WF_ID\" =~ ^[A-Za-z0-9_.-]{1,64}$ ]]; then\n echo \"[ocean] invalid COMFY_WORKFLOW_ID\" >&2\n exit 1\nfi\n\n# The bucket is mounted 0777 by the node, so it is writable whatever uid the container runs as.\n# Without one, everything (including 38 GB of weights) goes to /tmp and dies with the container.\nif [ -d /data/outputs ]; then\n BASE=/data/outputs/comfy\nelse\n BASE=/tmp/comfy\n echo \"[ocean] no bucket mounted \u2014 models download to the container and are lost on stop\"\nfi\n\nMODELS=\"$BASE/models\"\nmkdir -p \"$MODELS/checkpoints\" \"$MODELS/loras\" \"$MODELS/text_encoders\" \\\n \"$MODELS/latent_upscale_models\" \"$BASE/output\" \"$BASE/input\" \"$BASE/temp\" \"$BASE/user\"\n\n# Download to .part then rename: a truncated file in a persistent bucket would be treated as\n# cached by every future launch.\nget() {\n if [ -f \"$2\" ]; then\n echo \"[ocean] cached $(basename \"$2\")\"\n return 0\n fi\n echo \"[ocean] downloading $(basename \"$2\")\"\n # No -f: a complete .part from a container that died between the download landing and the\n # mv makes `curl -C -` ask HuggingFace to resume a finished file, which answers 416. Check the\n # status ourselves so that specific case can recover instead of wedging every future launch.\n http_code=$(curl -L --retry 5 --retry-delay 5 -C - -o \"$2.part\" -w '%{http_code}' \"$1\")\n if [ \"$http_code\" = \"416\" ] && [ -f \"$2.part\" ]; then\n echo \"[ocean] $(basename \"$2\").part already complete\"\n elif [ \"$http_code\" -lt 200 ] || [ \"$http_code\" -ge 300 ]; then\n echo \"[ocean] download failed for $(basename \"$2\") (HTTP $http_code)\" >&2\n return 22\n fi\n mv \"$2.part\" \"$2\"\n}\n\nHF=https://huggingface.co\nget \"$HF/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors\" \\\n \"$MODELS/checkpoints/ltx-2.3-22b-dev-fp8.safetensors\"\nget \"$HF/Comfy-Org/ltx-2/resolve/main/split_files/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors\" \\\n \"$MODELS/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors\"\nget \"$HF/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors\" \\\n \"$MODELS/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors\"\nget \"$HF/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\" \\\n \"$MODELS/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\"\nget \"$HF/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors\" \\\n \"$MODELS/latent_upscale_models/ltx-2.3-spatial-upscaler-x2-1.1.safetensors\"\n\n# Minimal custom-node pack: ComfyUI serves example_workflows at\n# /api/workflow_templates/ocean_ugc/ocean_ugc.json, which is what ?template=ocean_ugc&source=all\n# loads. Exactly one graph is ever installed per container, so the filename is a constant, not\n# keyed by WF_ID \u2014 WF_ID is only used below for the log line, the in-container record of which\n# graph was picked.\nPACK=\"$BASE/custom_nodes/ocean_ugc\"\nmkdir -p \"$PACK/example_workflows\"\necho 'NODE_CLASS_MAPPINGS = {}' > \"$PACK/__init__.py\"\nif [ -n \"$WF_ID\" ] && [ -n \"${COMFY_WORKFLOW:-}\" ]; then\n # Escrow is already claimed by the time this runs \u2014 a corrupt/undecodable payload must not take\n # the whole container down with it. Degrade to an empty pack and keep going; base64/gunzip's own\n # stderr plus the line below land in the container logs either way.\n if printf '%s' \"$COMFY_WORKFLOW\" | base64 -d | gunzip > \"$PACK/example_workflows/ocean_ugc.json\"; then\n echo \"[ocean] installed workflow $WF_ID\"\n else\n echo \"[ocean] failed to decode COMFY_WORKFLOW \u2014 starting ComfyUI with an empty workflow pack\" >&2\n rm -f \"$PACK/example_workflows/ocean_ugc.json\"\n fi\nfi\n\n# Keep every writable path Python and ComfyUI reach for inside $BASE: the bundle is read-only and\n# $HOME (/root) may not be writable at all.\nexport HOME=\"$BASE\"\nexport PYTHONPYCACHEPREFIX=\"$BASE/.cache/pycache\"\nexport XDG_CACHE_HOME=\"$BASE/.cache\"\nexport HF_HOME=\"$BASE/.cache/huggingface\"\n\necho \"[ocean] starting ComfyUI with base directory $BASE\"\nexec python3.13 /default-comfyui-bundle/ComfyUI/main.py \\\n --base-directory \"$BASE\" --listen --port 8188 ${CLI_ARGS:-}\n" ], "workflows": [ { From 248fe1d3f7000f9389f99b87c680a99459ce20f7 Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Tue, 4 Aug 2026 15:29:46 +0300 Subject: [PATCH 03/29] fix download --- docs/serviceTemplates/ltx-video-ugc.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/serviceTemplates/ltx-video-ugc.json b/docs/serviceTemplates/ltx-video-ugc.json index 7a065234b..0472e5324 100644 --- a/docs/serviceTemplates/ltx-video-ugc.json +++ b/docs/serviceTemplates/ltx-video-ugc.json @@ -12,7 +12,7 @@ "-c" ], "command": [ - "#!/bin/bash\n# Bootstrap for the ltx-video-ugc service template. Runs as the container command with\n# entrypoint [\"/bin/bash\",\"-c\"] \u2014 a shell entrypoint is mandatory because ocean-node passes\n# dockerCmd to Docker verbatim and performs no ${VAR} expansion of its own.\n#\n# Nothing is written under /root, and the image's own entrypoint is deliberately bypassed:\n# that entrypoint copies its ComfyUI bundle into /root/ComfyUI, which fails on hosts where the\n# service container is not uid 0. Instead ComfyUI runs straight from the read-only bundle with\n# --base-directory, its native flag for relocating models/output/input/user/custom_nodes.\nset -euo pipefail\n\nWF_ID=\"${COMFY_WORKFLOW_ID:-}\"\n# COMFY_WORKFLOW_ID is client-supplied and becomes a filename. ServiceStartHandler never\n# loads templates, so userConfigurableEnvVars.validation is NOT enforced node-side \u2014 this\n# check is the only thing standing between userData and a path traversal.\nif [ -n \"$WF_ID\" ] && ! [[ \"$WF_ID\" =~ ^[A-Za-z0-9_.-]{1,64}$ ]]; then\n echo \"[ocean] invalid COMFY_WORKFLOW_ID\" >&2\n exit 1\nfi\n\n# The bucket is mounted 0777 by the node, so it is writable whatever uid the container runs as.\n# Without one, everything (including 38 GB of weights) goes to /tmp and dies with the container.\nif [ -d /data/outputs ]; then\n BASE=/data/outputs/comfy\nelse\n BASE=/tmp/comfy\n echo \"[ocean] no bucket mounted \u2014 models download to the container and are lost on stop\"\nfi\n\nMODELS=\"$BASE/models\"\nmkdir -p \"$MODELS/checkpoints\" \"$MODELS/loras\" \"$MODELS/text_encoders\" \\\n \"$MODELS/latent_upscale_models\" \"$BASE/output\" \"$BASE/input\" \"$BASE/temp\" \"$BASE/user\"\n\n# Download to .part then rename: a truncated file in a persistent bucket would be treated as\n# cached by every future launch.\nget() {\n if [ -f \"$2\" ]; then\n echo \"[ocean] cached $(basename \"$2\")\"\n return 0\n fi\n echo \"[ocean] downloading $(basename \"$2\")\"\n # No -f: a complete .part from a container that died between the download landing and the\n # mv makes `curl -C -` ask HuggingFace to resume a finished file, which answers 416. Check the\n # status ourselves so that specific case can recover instead of wedging every future launch.\n http_code=$(curl -L --retry 5 --retry-delay 5 -C - -o \"$2.part\" -w '%{http_code}' \"$1\")\n if [ \"$http_code\" = \"416\" ] && [ -f \"$2.part\" ]; then\n echo \"[ocean] $(basename \"$2\").part already complete\"\n elif [ \"$http_code\" -lt 200 ] || [ \"$http_code\" -ge 300 ]; then\n echo \"[ocean] download failed for $(basename \"$2\") (HTTP $http_code)\" >&2\n return 22\n fi\n mv \"$2.part\" \"$2\"\n}\n\nHF=https://huggingface.co\nget \"$HF/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors\" \\\n \"$MODELS/checkpoints/ltx-2.3-22b-dev-fp8.safetensors\"\nget \"$HF/Comfy-Org/ltx-2/resolve/main/split_files/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors\" \\\n \"$MODELS/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors\"\nget \"$HF/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors\" \\\n \"$MODELS/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors\"\nget \"$HF/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\" \\\n \"$MODELS/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\"\nget \"$HF/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors\" \\\n \"$MODELS/latent_upscale_models/ltx-2.3-spatial-upscaler-x2-1.1.safetensors\"\n\n# Minimal custom-node pack: ComfyUI serves example_workflows at\n# /api/workflow_templates/ocean_ugc/ocean_ugc.json, which is what ?template=ocean_ugc&source=all\n# loads. Exactly one graph is ever installed per container, so the filename is a constant, not\n# keyed by WF_ID \u2014 WF_ID is only used below for the log line, the in-container record of which\n# graph was picked.\nPACK=\"$BASE/custom_nodes/ocean_ugc\"\nmkdir -p \"$PACK/example_workflows\"\necho 'NODE_CLASS_MAPPINGS = {}' > \"$PACK/__init__.py\"\nif [ -n \"$WF_ID\" ] && [ -n \"${COMFY_WORKFLOW:-}\" ]; then\n # Escrow is already claimed by the time this runs \u2014 a corrupt/undecodable payload must not take\n # the whole container down with it. Degrade to an empty pack and keep going; base64/gunzip's own\n # stderr plus the line below land in the container logs either way.\n if printf '%s' \"$COMFY_WORKFLOW\" | base64 -d | gunzip > \"$PACK/example_workflows/ocean_ugc.json\"; then\n echo \"[ocean] installed workflow $WF_ID\"\n else\n echo \"[ocean] failed to decode COMFY_WORKFLOW \u2014 starting ComfyUI with an empty workflow pack\" >&2\n rm -f \"$PACK/example_workflows/ocean_ugc.json\"\n fi\nfi\n\n# Keep every writable path Python and ComfyUI reach for inside $BASE: the bundle is read-only and\n# $HOME (/root) may not be writable at all.\nexport HOME=\"$BASE\"\nexport PYTHONPYCACHEPREFIX=\"$BASE/.cache/pycache\"\nexport XDG_CACHE_HOME=\"$BASE/.cache\"\nexport HF_HOME=\"$BASE/.cache/huggingface\"\n\necho \"[ocean] starting ComfyUI with base directory $BASE\"\nexec python3.13 /default-comfyui-bundle/ComfyUI/main.py \\\n --base-directory \"$BASE\" --listen --port 8188 ${CLI_ARGS:-}\n" + "#!/bin/bash\n# Bootstrap for the ltx-video-ugc service template. Runs as the container command with\n# entrypoint [\"/bin/bash\",\"-c\"] \u2014 a shell entrypoint is mandatory because ocean-node passes\n# dockerCmd to Docker verbatim and performs no ${VAR} expansion of its own.\n#\n# Nothing is written under /root, and the image's own entrypoint is deliberately bypassed:\n# that entrypoint copies its ComfyUI bundle into /root/ComfyUI, which fails on hosts where the\n# service container is not uid 0. Instead ComfyUI runs straight from the read-only bundle with\n# --base-directory, its native flag for relocating models/output/input/user/custom_nodes.\nset -euo pipefail\n\nWF_ID=\"${COMFY_WORKFLOW_ID:-}\"\n# COMFY_WORKFLOW_ID is client-supplied and becomes a filename. ServiceStartHandler never\n# loads templates, so userConfigurableEnvVars.validation is NOT enforced node-side \u2014 this\n# check is the only thing standing between userData and a path traversal.\nif [ -n \"$WF_ID\" ] && ! [[ \"$WF_ID\" =~ ^[A-Za-z0-9_.-]{1,64}$ ]]; then\n echo \"[ocean] invalid COMFY_WORKFLOW_ID\" >&2\n exit 1\nfi\n\n# One line of provenance up front: which uid we got and whether the bucket is really mounted are\n# the two facts every launch failure so far has turned on, and neither is visible after the fact.\necho \"[ocean] $(id) | /data/outputs: $(ls -ld /data/outputs 2>&1 | head -1)\"\n\n# The bucket is mounted 0777 by the node, so it is writable whatever uid the container runs as.\n# Without one, everything (including 38 GB of weights) goes to /tmp and dies with the container.\nif [ -d /data/outputs ]; then\n BASE=/data/outputs/comfy\nelse\n BASE=/tmp/comfy\n echo \"[ocean] no bucket mounted \u2014 models download to the container and are lost on stop.\" \\\n \"If you did select a bucket, the node is not applying outputBucketId: check that it runs\" \\\n \"ocean-node with service bucket-mount support, and that persistentStorage is configured.\" >&2\nfi\n\nMODELS=\"$BASE/models\"\nmkdir -p \"$MODELS/checkpoints\" \"$MODELS/loras\" \"$MODELS/text_encoders\" \\\n \"$MODELS/latent_upscale_models\" \"$BASE/output\" \"$BASE/input\" \"$BASE/temp\" \"$BASE/user\"\n\n# Download to .part then rename: a truncated file in a persistent bucket would be treated as\n# cached by every future launch.\nget() {\n if [ -f \"$2\" ]; then\n echo \"[ocean] cached $(basename \"$2\")\"\n return 0\n fi\n echo \"[ocean] downloading $(basename \"$2\")\"\n # No -f: a complete .part from a container that died between the download landing and the\n # mv makes `curl -C -` ask HuggingFace to resume a finished file, which answers 416. Check the\n # status ourselves so that specific case can recover instead of wedging every future launch.\n http_code=$(curl -L --retry 5 --retry-delay 5 -C - -o \"$2.part\" -w '%{http_code}' \"$1\")\n if [ \"$http_code\" = \"416\" ] && [ -f \"$2.part\" ]; then\n echo \"[ocean] $(basename \"$2\").part already complete\"\n elif [ \"$http_code\" -lt 200 ] || [ \"$http_code\" -ge 300 ]; then\n echo \"[ocean] download failed for $(basename \"$2\") (HTTP $http_code)\" >&2\n return 22\n fi\n # HTTP 200 is not proof of a model file: a proxy or HF error page returns a few hundred bytes\n # with a success status. Without this floor that body gets renamed into place and every later\n # launch treats it as cached. The smallest real file here is ~300 MB, so 10 MB is unambiguous.\n size=$(wc -c < \"$2.part\")\n if [ \"$size\" -lt 10485760 ]; then\n echo \"[ocean] $(basename \"$2\") is only $size bytes \u2014 not a model file. First bytes:\" >&2\n head -c 300 \"$2.part\" >&2 || true\n echo >&2\n rm -f \"$2.part\"\n return 22\n fi\n mv \"$2.part\" \"$2\"\n}\n\nHF=https://huggingface.co\nget \"$HF/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors\" \\\n \"$MODELS/checkpoints/ltx-2.3-22b-dev-fp8.safetensors\"\nget \"$HF/Comfy-Org/ltx-2/resolve/main/split_files/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors\" \\\n \"$MODELS/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors\"\nget \"$HF/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors\" \\\n \"$MODELS/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors\"\nget \"$HF/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\" \\\n \"$MODELS/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\"\nget \"$HF/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors\" \\\n \"$MODELS/latent_upscale_models/ltx-2.3-spatial-upscaler-x2-1.1.safetensors\"\n\n# Minimal custom-node pack: ComfyUI serves example_workflows at\n# /api/workflow_templates/ocean_ugc/ocean_ugc.json, which is what ?template=ocean_ugc&source=all\n# loads. Exactly one graph is ever installed per container, so the filename is a constant, not\n# keyed by WF_ID \u2014 WF_ID is only used below for the log line, the in-container record of which\n# graph was picked.\nPACK=\"$BASE/custom_nodes/ocean_ugc\"\nmkdir -p \"$PACK/example_workflows\"\necho 'NODE_CLASS_MAPPINGS = {}' > \"$PACK/__init__.py\"\nif [ -n \"$WF_ID\" ] && [ -n \"${COMFY_WORKFLOW:-}\" ]; then\n # Escrow is already claimed by the time this runs \u2014 a corrupt/undecodable payload must not take\n # the whole container down with it. Degrade to an empty pack and keep going; base64/gunzip's own\n # stderr plus the line below land in the container logs either way.\n if printf '%s' \"$COMFY_WORKFLOW\" | base64 -d | gunzip > \"$PACK/example_workflows/ocean_ugc.json\"; then\n echo \"[ocean] installed workflow $WF_ID\"\n else\n echo \"[ocean] failed to decode COMFY_WORKFLOW \u2014 starting ComfyUI with an empty workflow pack\" >&2\n rm -f \"$PACK/example_workflows/ocean_ugc.json\"\n fi\nfi\n\n# Keep every writable path Python and ComfyUI reach for inside $BASE: the bundle is read-only and\n# $HOME (/root) may not be writable at all.\nexport HOME=\"$BASE\"\nexport PYTHONPYCACHEPREFIX=\"$BASE/.cache/pycache\"\nexport XDG_CACHE_HOME=\"$BASE/.cache\"\nexport HF_HOME=\"$BASE/.cache/huggingface\"\n\necho \"[ocean] starting ComfyUI with base directory $BASE\"\nexec python3.13 /default-comfyui-bundle/ComfyUI/main.py \\\n --base-directory \"$BASE\" --listen --port 8188 ${CLI_ARGS:-}\n" ], "workflows": [ { From dc783b07d36b74c261a28c6db7c6426ed20c03d0 Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Wed, 5 Aug 2026 10:12:23 +0300 Subject: [PATCH 04/29] split in two bundles --- docs/serviceTemplates/README.md | 61 +++++++----- .../ltx-video-ugc-bootstrap.sh | 98 +++++++++++++++++++ .../ltx-video-ugc-product.json | 60 ++++++++++++ .../ltx-video-ugc-testimonial.json | 60 ++++++++++++ docs/serviceTemplates/ltx-video-ugc.json | 68 ------------- .../workflows/ocean_ugc_product.json | 14 +-- .../workflows/ocean_ugc_testimonial.json | 12 +-- src/@types/C2D/ServiceOnDemand.ts | 2 + src/components/core/service/templateLoader.ts | 34 ++++++- src/test/unit/service/serviceSchemas.test.ts | 8 +- src/test/unit/service/templateLoader.test.ts | 11 +++ src/utils/config/schemas.ts | 9 ++ 12 files changed, 327 insertions(+), 110 deletions(-) create mode 100644 docs/serviceTemplates/ltx-video-ugc-bootstrap.sh create mode 100644 docs/serviceTemplates/ltx-video-ugc-product.json create mode 100644 docs/serviceTemplates/ltx-video-ugc-testimonial.json delete mode 100644 docs/serviceTemplates/ltx-video-ugc.json diff --git a/docs/serviceTemplates/README.md b/docs/serviceTemplates/README.md index fb5acc392..a6768a01f 100644 --- a/docs/serviceTemplates/README.md +++ b/docs/serviceTemplates/README.md @@ -28,6 +28,7 @@ Templates are validated against `ServiceTemplateSchema` | `image` + exactly one of `tag` / `checksum` / `dockerfile` | Image spec (`dockerfile` triggers a build and is gated per daemon by `allowImageBuild`) | | `exposedPorts` | Container ports forwarded to host ports and returned as service endpoints | | `command` / `entrypoint` | Docker CMD / ENTRYPOINT overrides | +| `commandFile` | Path to a script, resolved relative to this directory and inlined as `command[0]` at load time (mutually exclusive with `command`) | | `envVars` | Fixed operator-set env vars (values never returned to callers) | | `userConfigurableEnvVars` | Env vars the consumer supplies via ECIES-encrypted `userData` (optional regex `validation`, `sensitive` UI hint) | | `requiredResources` / `recommendedResources` | Gate/score environment selection (`min` is enforced at `SERVICE_START`) | @@ -102,35 +103,47 @@ so no `command` override is needed. Bundles ComfyUI-Manager for installing check custom nodes from the UI; `HF_TOKEN` / `CIVITAI_TOKEN` are optional user env vars for gated downloads. ~10 GB VRAM for SDXL. -### `ltx-video-ugc.json` — ComfyUI, LTX-2.3 UGC video (GPU) +### `ltx-video-ugc-product.json` — ComfyUI, LTX-2.3 product video (GPU) -ComfyUI preloaded with LTX-2.3 for vertical short-form product video, with two ready-made -workflow graphs (`workflows/ocean_ugc_product.json`, `workflows/ocean_ugc_testimonial.json`): -a product photo becomes a 9:16 clip with camera motion and ambient audio, or a creator photo -plus a voice clip becomes a lip-synced testimonial (capped at the graph's 5.8s — trim longer -voiceovers or raise the frame count). `entrypoint`/`command` override to a bootstrap -script (inlined as `command[0]`) that downloads the ~38 GiB weight set (LTX-2.3 22B fp8 -checkpoint, Gemma-3-12B text encoder, two LoRAs, the x2 spatial upscaler) on first launch. -Pick a persistent-storage bucket for this template — weights and generated clips both live -there, so only the first launch pays the download; without a bucket the weights land inside -the container and are lost on stop (in `/tmp`, not the bucket). +ComfyUI preloaded with LTX-2.3 for one fixed workflow (`workflows/ocean_ugc_product.json`): a +product photo becomes a vertical 9:16 (720×1280) clip with camera motion and ambient audio, +capped at the graph's 5 seconds (126 frames at 25 fps — trim longer voiceovers or raise the +frame count). `entrypoint`/`commandFile` override to a bootstrap script +(`ltx-video-ugc-bootstrap.sh`, inlined as `command[0]` at load time) that downloads the +~38 GiB weight set (LTX-2.3 22B fp8 checkpoint, Gemma-3-12B text encoder, two LoRAs, the x2 +spatial upscaler) on first launch. Pick a persistent-storage bucket for this template: weights +live under the bucket, so only the first launch pays the download, and generated clips are +written to the bucket root (via ComfyUI's `--output-directory`) so the storage API's +`listFiles` — which only lists the bucket's top-level files — can see them. Without a bucket +the weights land inside the container and are lost on stop (in `/tmp`, not the bucket). The bootstrap runs `main.py` directly from the image's read-only bundle with ComfyUI's own -`--base-directory` flag, pointed at the bucket, so models/output/input/user/custom_nodes all -live there and nothing is written under `/root`. This deliberately bypasses the image's -entrypoint, which copies its bundle into `/root/ComfyUI` and therefore fails on hosts where the -service container is not uid 0. Relocating `custom_nodes` also means the image's bundled -ComfyUI-Manager is not loaded — this template ships fixed workflows and installs no nodes at +`--base-directory` flag, pointed at the bucket, so models/input/user/custom_nodes all live +there and nothing is written under `/root`. This deliberately bypasses the image's entrypoint, +which copies its bundle into `/root/ComfyUI` and therefore fails on hosts where the service +container is not uid 0. Relocating `custom_nodes` also means the image's bundled +ComfyUI-Manager is not loaded — this template ships one fixed workflow and installs no nodes at runtime. -The consumer selects a workflow via userData: `COMFY_WORKFLOW_ID` (`ocean_ugc_product` or -`ocean_ugc_testimonial`, used only for the `[ocean] installed workflow …` log line) plus -`COMFY_WORKFLOW` (that workflow's graph JSON, gzipped then base64-encoded). The bootstrap -writes it into a minimal custom-node pack at the constant path -`custom_nodes/ocean_ugc/example_workflows/ocean_ugc.json` — exactly one graph is ever -installed per container, so the filename doesn't vary — which ComfyUI serves at -`/api/workflow_templates/ocean_ugc/ocean_ugc.json`. Open the ComfyUI URL with -`?template=ocean_ugc&source=all` to load it directly instead of building the graph by hand. +The workflow graph is delivered via userData: `COMFY_WORKFLOW_ID` (`ocean_ugc_product`, used +only for the `[ocean] installed workflow …` log line) plus `COMFY_WORKFLOW` (the graph JSON, +gzipped then base64-encoded). The bootstrap writes it into a minimal custom-node pack at the +constant path `custom_nodes/ocean_ugc/example_workflows/ocean_ugc.json`, which ComfyUI serves +at `/api/workflow_templates/ocean_ugc/ocean_ugc.json`. Open the ComfyUI URL with +`?template=ocean_ugc&source=ocean_ugc` to load it directly instead of building the graph by +hand. The same graph is also copied into `user/default/workflows/`, so it appears in ComfyUI's +Workflows sidebar as an ordinary saved workflow — that path needs no template-browser +resolution or URL parameters, and is the fallback when the deep link does not fire. +Needs a CUDA GPU with 48 GB+ VRAM (LTX-2.3 22B fp8 + Gemma-3-12B encoder). + +### `ltx-video-ugc-testimonial.json` — ComfyUI, LTX-2.3 creator testimonial (GPU) + +Same image, bootstrap script, and bucket/weight-download behavior as +`ltx-video-ugc-product.json` above (see that section for details), but with a different fixed +workflow (`workflows/ocean_ugc_testimonial.json`, delivered via `COMFY_WORKFLOW_ID= +ocean_ugc_testimonial` + `COMFY_WORKFLOW`): a creator photo plus a voice clip becomes a +lip-synced vertical 9:16 (720×1280) testimonial, capped at the same 5 seconds (126 frames at +25 fps). Generated clips likewise land in the bucket root so the storage API can list them. Needs a CUDA GPU with 48 GB+ VRAM (LTX-2.3 22B fp8 + Gemma-3-12B encoder). ### `automatic1111.json` — Stable Diffusion WebUI (A1111) (GPU) diff --git a/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh b/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh new file mode 100644 index 000000000..71f65386b --- /dev/null +++ b/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh @@ -0,0 +1,98 @@ +#!/bin/bash +# The image's own entrypoint copies its ComfyUI bundle into /root/ComfyUI, which fails on +# hosts where the service container is not uid 0 — bypassed here in favor of running ComfyUI +# straight from the read-only bundle via --base-directory. +set -euo pipefail + +WF_ID="${COMFY_WORKFLOW_ID:-}" +# COMFY_WORKFLOW_ID is client-supplied and becomes a filename. ServiceStartHandler never +# loads templates, so userConfigurableEnvVars.validation is NOT enforced node-side — this +# check is the only thing standing between userData and a path traversal. +if [ -n "$WF_ID" ] && ! [[ "$WF_ID" =~ ^[A-Za-z0-9_.-]{1,64}$ ]]; then + echo "[ocean] invalid COMFY_WORKFLOW_ID" >&2 + exit 1 +fi + +echo "[ocean] $(id) | /data/outputs: $(ls -ld /data/outputs 2>&1 | head -1)" + +if [ -d /data/outputs ]; then + BASE=/data/outputs/comfy + OUTPUT_DIR_ARGS="--output-directory /data/outputs" +else + BASE=/tmp/comfy + OUTPUT_DIR_ARGS="" + echo "[ocean] no bucket mounted — models download to the container and are lost on stop." \ + "If you did select a bucket, the node is not applying outputBucketId: check that it runs" \ + "ocean-node with service bucket-mount support, and that persistentStorage is configured." >&2 +fi + +MODELS="$BASE/models" +mkdir -p "$MODELS/checkpoints" "$MODELS/loras" "$MODELS/text_encoders" \ + "$MODELS/latent_upscale_models" "$BASE/output" "$BASE/input" "$BASE/temp" "$BASE/user" + +# Download to .part then rename: a truncated file in a persistent bucket would be treated as +# cached by every future launch. +get() { + if [ -f "$2" ]; then + echo "[ocean] cached $(basename "$2")" + return 0 + fi + echo "[ocean] downloading $(basename "$2")" + http_code=$(curl -L --retry 5 --retry-delay 5 -C - -o "$2.part" -w '%{http_code}' "$1") + if [ "$http_code" = "416" ] && [ -f "$2.part" ]; then + echo "[ocean] $(basename "$2").part already complete" + elif [ "$http_code" -lt 200 ] || [ "$http_code" -ge 300 ]; then + echo "[ocean] download failed for $(basename "$2") (HTTP $http_code)" >&2 + return 22 + fi + # HTTP 200 is not proof of a model file: a proxy or HF error page returns a few hundred bytes + # with a success status. Without this floor that body gets renamed into place and every later + # launch treats it as cached. The smallest real file here is ~300 MB, so 10 MB is unambiguous. + size=$(wc -c < "$2.part") + if [ "$size" -lt 10485760 ]; then + echo "[ocean] $(basename "$2") is only $size bytes — not a model file. First bytes:" >&2 + head -c 300 "$2.part" >&2 || true + echo >&2 + rm -f "$2.part" + return 22 + fi + mv "$2.part" "$2" +} + +HF=https://huggingface.co +get "$HF/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors" \ + "$MODELS/checkpoints/ltx-2.3-22b-dev-fp8.safetensors" +get "$HF/Comfy-Org/ltx-2/resolve/main/split_files/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors" \ + "$MODELS/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors" +get "$HF/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors" \ + "$MODELS/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors" +get "$HF/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors" \ + "$MODELS/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors" +get "$HF/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors" \ + "$MODELS/latent_upscale_models/ltx-2.3-spatial-upscaler-x2-1.1.safetensors" + +PACK="$BASE/custom_nodes/ocean_ugc" +SAVED="$BASE/user/default/workflows" +mkdir -p "$PACK/example_workflows" "$SAVED" +echo 'NODE_CLASS_MAPPINGS = {}' > "$PACK/__init__.py" +if [ -n "$WF_ID" ] && [ -n "${COMFY_WORKFLOW:-}" ]; then + # Escrow is already claimed by the time this runs — a corrupt/undecodable payload must not take + # the whole container down with it. Degrade to an empty pack and keep going; base64/gunzip's own + # stderr plus the line below land in the container logs either way. + if printf '%s' "$COMFY_WORKFLOW" | base64 -d | gunzip > "$PACK/example_workflows/ocean_ugc.json"; then + cp "$PACK/example_workflows/ocean_ugc.json" "$SAVED/ocean_ugc.json" + echo "[ocean] installed workflow $WF_ID (template pack + Workflows sidebar)" + else + echo "[ocean] failed to decode COMFY_WORKFLOW — starting ComfyUI with an empty workflow pack" >&2 + rm -f "$PACK/example_workflows/ocean_ugc.json" + fi +fi + +export HOME="$BASE" +export PYTHONPYCACHEPREFIX="$BASE/.cache/pycache" +export XDG_CACHE_HOME="$BASE/.cache" +export HF_HOME="$BASE/.cache/huggingface" + +echo "[ocean] starting ComfyUI with base directory $BASE" +exec python3.13 /default-comfyui-bundle/ComfyUI/main.py \ + --base-directory "$BASE" ${OUTPUT_DIR_ARGS} --listen --port 8188 ${CLI_ARGS:-} diff --git a/docs/serviceTemplates/ltx-video-ugc-product.json b/docs/serviceTemplates/ltx-video-ugc-product.json new file mode 100644 index 000000000..1f68bafa8 --- /dev/null +++ b/docs/serviceTemplates/ltx-video-ugc-product.json @@ -0,0 +1,60 @@ +{ + "id": "ltx-video-ugc-product", + "name": "ComfyUI — UGC product video (LTX-2.3)", + "description": "ComfyUI preloaded with LTX-2.3 for vertical short-form product video: a product photo becomes a 9:16 clip with camera motion and ambient audio, capped at the graph's 5 seconds (126 frames at 25 fps). Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the 38 GiB of weights download once and are reused, and generated clips land in the bucket root. Needs a CUDA GPU with 48 GB+ VRAM.", + "image": "yanwk/comfyui-boot", + "tag": "cu130-megapak-pt211-20260803", + "exposedPorts": [ + 8188 + ], + "entrypoint": [ + "/bin/bash", + "-c" + ], + "commandFile": "ltx-video-ugc-bootstrap.sh", + "workflows": [ + { + "id": "ocean_ugc_product", + "name": "Product → vertical clip", + "description": "Upload a product photo, get a 9:16 clip with camera motion and ambient audio.", + "file": "workflows/ocean_ugc_product.json" + } + ], + "userConfigurableEnvVars": [ + { + "key": "COMFY_WORKFLOW_ID", + "validation": "^[A-Za-z0-9_.-]+$" + }, + { + "key": "COMFY_WORKFLOW" + } + ], + "requiredResources": [ + { + "id": "cpu", + "min": 8, + "recommended": 16, + "unit": "cores" + }, + { + "id": "ram", + "min": 32, + "recommended": 64, + "unit": "GB" + }, + { + "id": "disk", + "min": 40, + "recommended": 80, + "unit": "GB" + }, + { + "kind": "discrete", + "type": "gpu", + "min": 1, + "recommended": 1, + "unit": "count", + "description": "CUDA GPU, 48 GB+ VRAM recommended (LTX-2.3 22B fp8 + Gemma-3-12B encoder)" + } + ] +} diff --git a/docs/serviceTemplates/ltx-video-ugc-testimonial.json b/docs/serviceTemplates/ltx-video-ugc-testimonial.json new file mode 100644 index 000000000..361659682 --- /dev/null +++ b/docs/serviceTemplates/ltx-video-ugc-testimonial.json @@ -0,0 +1,60 @@ +{ + "id": "ltx-video-ugc-testimonial", + "name": "ComfyUI — UGC creator testimonial (LTX-2.3)", + "description": "ComfyUI preloaded with LTX-2.3 for vertical short-form UGC video: a creator photo plus a voice clip becomes a lip-synced 9:16 testimonial, capped at the graph's 5 seconds (126 frames at 25 fps). Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the 38 GiB of weights download once and are reused, and generated clips land in the bucket root. Needs a CUDA GPU with 48 GB+ VRAM.", + "image": "yanwk/comfyui-boot", + "tag": "cu130-megapak-pt211-20260803", + "exposedPorts": [ + 8188 + ], + "entrypoint": [ + "/bin/bash", + "-c" + ], + "commandFile": "ltx-video-ugc-bootstrap.sh", + "workflows": [ + { + "id": "ocean_ugc_testimonial", + "name": "Creator testimonial (lip-sync)", + "description": "Upload a person photo and a voice clip, get a lip-synced 9:16 testimonial.", + "file": "workflows/ocean_ugc_testimonial.json" + } + ], + "userConfigurableEnvVars": [ + { + "key": "COMFY_WORKFLOW_ID", + "validation": "^[A-Za-z0-9_.-]+$" + }, + { + "key": "COMFY_WORKFLOW" + } + ], + "requiredResources": [ + { + "id": "cpu", + "min": 8, + "recommended": 16, + "unit": "cores" + }, + { + "id": "ram", + "min": 32, + "recommended": 64, + "unit": "GB" + }, + { + "id": "disk", + "min": 40, + "recommended": 80, + "unit": "GB" + }, + { + "kind": "discrete", + "type": "gpu", + "min": 1, + "recommended": 1, + "unit": "count", + "description": "CUDA GPU, 48 GB+ VRAM recommended (LTX-2.3 22B fp8 + Gemma-3-12B encoder)" + } + ] +} diff --git a/docs/serviceTemplates/ltx-video-ugc.json b/docs/serviceTemplates/ltx-video-ugc.json deleted file mode 100644 index 0472e5324..000000000 --- a/docs/serviceTemplates/ltx-video-ugc.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "id": "ltx-video-ugc", - "name": "ComfyUI \u2014 UGC short-form video (LTX-2.3)", - "description": "ComfyUI preloaded with LTX-2.3 for vertical short-form product video. Two workflows: a product photo becomes a 9:16 clip with ambient audio, or a creator photo plus a voice clip becomes a lip-synced testimonial (the clip is capped at the graph's 5.8s, so trim longer voiceovers or raise the frame count). Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the 38 GiB of weights download once and are reused, and generated clips outlive the container. Needs a CUDA GPU with 48 GB+ VRAM.", - "image": "yanwk/comfyui-boot", - "tag": "cu130-megapak-pt211-20260803", - "exposedPorts": [ - 8188 - ], - "entrypoint": [ - "/bin/bash", - "-c" - ], - "command": [ - "#!/bin/bash\n# Bootstrap for the ltx-video-ugc service template. Runs as the container command with\n# entrypoint [\"/bin/bash\",\"-c\"] \u2014 a shell entrypoint is mandatory because ocean-node passes\n# dockerCmd to Docker verbatim and performs no ${VAR} expansion of its own.\n#\n# Nothing is written under /root, and the image's own entrypoint is deliberately bypassed:\n# that entrypoint copies its ComfyUI bundle into /root/ComfyUI, which fails on hosts where the\n# service container is not uid 0. Instead ComfyUI runs straight from the read-only bundle with\n# --base-directory, its native flag for relocating models/output/input/user/custom_nodes.\nset -euo pipefail\n\nWF_ID=\"${COMFY_WORKFLOW_ID:-}\"\n# COMFY_WORKFLOW_ID is client-supplied and becomes a filename. ServiceStartHandler never\n# loads templates, so userConfigurableEnvVars.validation is NOT enforced node-side \u2014 this\n# check is the only thing standing between userData and a path traversal.\nif [ -n \"$WF_ID\" ] && ! [[ \"$WF_ID\" =~ ^[A-Za-z0-9_.-]{1,64}$ ]]; then\n echo \"[ocean] invalid COMFY_WORKFLOW_ID\" >&2\n exit 1\nfi\n\n# One line of provenance up front: which uid we got and whether the bucket is really mounted are\n# the two facts every launch failure so far has turned on, and neither is visible after the fact.\necho \"[ocean] $(id) | /data/outputs: $(ls -ld /data/outputs 2>&1 | head -1)\"\n\n# The bucket is mounted 0777 by the node, so it is writable whatever uid the container runs as.\n# Without one, everything (including 38 GB of weights) goes to /tmp and dies with the container.\nif [ -d /data/outputs ]; then\n BASE=/data/outputs/comfy\nelse\n BASE=/tmp/comfy\n echo \"[ocean] no bucket mounted \u2014 models download to the container and are lost on stop.\" \\\n \"If you did select a bucket, the node is not applying outputBucketId: check that it runs\" \\\n \"ocean-node with service bucket-mount support, and that persistentStorage is configured.\" >&2\nfi\n\nMODELS=\"$BASE/models\"\nmkdir -p \"$MODELS/checkpoints\" \"$MODELS/loras\" \"$MODELS/text_encoders\" \\\n \"$MODELS/latent_upscale_models\" \"$BASE/output\" \"$BASE/input\" \"$BASE/temp\" \"$BASE/user\"\n\n# Download to .part then rename: a truncated file in a persistent bucket would be treated as\n# cached by every future launch.\nget() {\n if [ -f \"$2\" ]; then\n echo \"[ocean] cached $(basename \"$2\")\"\n return 0\n fi\n echo \"[ocean] downloading $(basename \"$2\")\"\n # No -f: a complete .part from a container that died between the download landing and the\n # mv makes `curl -C -` ask HuggingFace to resume a finished file, which answers 416. Check the\n # status ourselves so that specific case can recover instead of wedging every future launch.\n http_code=$(curl -L --retry 5 --retry-delay 5 -C - -o \"$2.part\" -w '%{http_code}' \"$1\")\n if [ \"$http_code\" = \"416\" ] && [ -f \"$2.part\" ]; then\n echo \"[ocean] $(basename \"$2\").part already complete\"\n elif [ \"$http_code\" -lt 200 ] || [ \"$http_code\" -ge 300 ]; then\n echo \"[ocean] download failed for $(basename \"$2\") (HTTP $http_code)\" >&2\n return 22\n fi\n # HTTP 200 is not proof of a model file: a proxy or HF error page returns a few hundred bytes\n # with a success status. Without this floor that body gets renamed into place and every later\n # launch treats it as cached. The smallest real file here is ~300 MB, so 10 MB is unambiguous.\n size=$(wc -c < \"$2.part\")\n if [ \"$size\" -lt 10485760 ]; then\n echo \"[ocean] $(basename \"$2\") is only $size bytes \u2014 not a model file. First bytes:\" >&2\n head -c 300 \"$2.part\" >&2 || true\n echo >&2\n rm -f \"$2.part\"\n return 22\n fi\n mv \"$2.part\" \"$2\"\n}\n\nHF=https://huggingface.co\nget \"$HF/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors\" \\\n \"$MODELS/checkpoints/ltx-2.3-22b-dev-fp8.safetensors\"\nget \"$HF/Comfy-Org/ltx-2/resolve/main/split_files/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors\" \\\n \"$MODELS/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors\"\nget \"$HF/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors\" \\\n \"$MODELS/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors\"\nget \"$HF/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\" \\\n \"$MODELS/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\"\nget \"$HF/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors\" \\\n \"$MODELS/latent_upscale_models/ltx-2.3-spatial-upscaler-x2-1.1.safetensors\"\n\n# Minimal custom-node pack: ComfyUI serves example_workflows at\n# /api/workflow_templates/ocean_ugc/ocean_ugc.json, which is what ?template=ocean_ugc&source=all\n# loads. Exactly one graph is ever installed per container, so the filename is a constant, not\n# keyed by WF_ID \u2014 WF_ID is only used below for the log line, the in-container record of which\n# graph was picked.\nPACK=\"$BASE/custom_nodes/ocean_ugc\"\nmkdir -p \"$PACK/example_workflows\"\necho 'NODE_CLASS_MAPPINGS = {}' > \"$PACK/__init__.py\"\nif [ -n \"$WF_ID\" ] && [ -n \"${COMFY_WORKFLOW:-}\" ]; then\n # Escrow is already claimed by the time this runs \u2014 a corrupt/undecodable payload must not take\n # the whole container down with it. Degrade to an empty pack and keep going; base64/gunzip's own\n # stderr plus the line below land in the container logs either way.\n if printf '%s' \"$COMFY_WORKFLOW\" | base64 -d | gunzip > \"$PACK/example_workflows/ocean_ugc.json\"; then\n echo \"[ocean] installed workflow $WF_ID\"\n else\n echo \"[ocean] failed to decode COMFY_WORKFLOW \u2014 starting ComfyUI with an empty workflow pack\" >&2\n rm -f \"$PACK/example_workflows/ocean_ugc.json\"\n fi\nfi\n\n# Keep every writable path Python and ComfyUI reach for inside $BASE: the bundle is read-only and\n# $HOME (/root) may not be writable at all.\nexport HOME=\"$BASE\"\nexport PYTHONPYCACHEPREFIX=\"$BASE/.cache/pycache\"\nexport XDG_CACHE_HOME=\"$BASE/.cache\"\nexport HF_HOME=\"$BASE/.cache/huggingface\"\n\necho \"[ocean] starting ComfyUI with base directory $BASE\"\nexec python3.13 /default-comfyui-bundle/ComfyUI/main.py \\\n --base-directory \"$BASE\" --listen --port 8188 ${CLI_ARGS:-}\n" - ], - "workflows": [ - { - "id": "ocean_ugc_product", - "name": "Product \u2192 vertical clip", - "description": "Upload a product photo, get a 9:16 clip with camera motion and ambient audio.", - "file": "workflows/ocean_ugc_product.json" - }, - { - "id": "ocean_ugc_testimonial", - "name": "Creator testimonial (lip-sync)", - "description": "Upload a person photo and a voice clip, get a lip-synced 9:16 testimonial.", - "file": "workflows/ocean_ugc_testimonial.json" - } - ], - "userConfigurableEnvVars": [ - { - "key": "COMFY_WORKFLOW_ID", - "validation": "^[A-Za-z0-9_.-]+$" - }, - { - "key": "COMFY_WORKFLOW" - } - ], - "requiredResources": [ - { - "id": "cpu", - "min": 8, - "recommended": 16, - "unit": "cores" - }, - { - "id": "ram", - "min": 32, - "recommended": 64, - "unit": "GB" - }, - { - "id": "disk", - "min": 40, - "recommended": 80, - "unit": "GB" - }, - { - "kind": "discrete", - "type": "gpu", - "min": 1, - "recommended": 1, - "unit": "count", - "description": "CUDA GPU, 48 GB+ VRAM recommended (LTX-2.3 22B fp8 + Gemma-3-12B encoder)" - } - ] -} \ No newline at end of file diff --git a/docs/serviceTemplates/workflows/ocean_ugc_product.json b/docs/serviceTemplates/workflows/ocean_ugc_product.json index 13f6d0cbc..eae6b157c 100644 --- a/docs/serviceTemplates/workflows/ocean_ugc_product.json +++ b/docs/serviceTemplates/workflows/ocean_ugc_product.json @@ -133,7 +133,7 @@ } }, "widgets_values": [ - "video/ocean_ugc_product", + "ocean_ugc_product", "auto", "auto" ] @@ -1832,9 +1832,9 @@ } }, "widgets_values": [ - 576, - 1024, - 145, + 768, + 512, + 97, 1 ] }, @@ -2105,7 +2105,7 @@ } }, "widgets_values": [ - 720, + 1280, "fixed" ] }, @@ -2484,7 +2484,7 @@ } }, "widgets_values": [ - 145, + 97, 25, 1 ] @@ -2923,7 +2923,7 @@ } }, "widgets_values": [ - 1280, + 720, "fixed" ] }, diff --git a/docs/serviceTemplates/workflows/ocean_ugc_testimonial.json b/docs/serviceTemplates/workflows/ocean_ugc_testimonial.json index 2fffe3f3b..fdc22939b 100644 --- a/docs/serviceTemplates/workflows/ocean_ugc_testimonial.json +++ b/docs/serviceTemplates/workflows/ocean_ugc_testimonial.json @@ -148,7 +148,7 @@ "Node name for S&R": "SaveVideo" }, "widgets_values": [ - "video/ocean_ugc_testimonial", + "ocean_ugc_testimonial", "auto", "auto" ] @@ -2027,7 +2027,7 @@ "Node name for S&R": "PrimitiveInt" }, "widgets_values": [ - 1280, + 720, "fixed" ] }, @@ -2755,9 +2755,9 @@ "Node name for S&R": "EmptyLTXVLatentVideo" }, "widgets_values": [ - 576, - 1024, - 145, + 768, + 512, + 97, 1 ] }, @@ -2891,7 +2891,7 @@ "Node name for S&R": "PrimitiveInt" }, "widgets_values": [ - 720, + 1280, "fixed" ] }, diff --git a/src/@types/C2D/ServiceOnDemand.ts b/src/@types/C2D/ServiceOnDemand.ts index 5101f5a18..1d866c3de 100644 --- a/src/@types/C2D/ServiceOnDemand.ts +++ b/src/@types/C2D/ServiceOnDemand.ts @@ -44,6 +44,8 @@ export interface ServiceTemplate { envVars?: Record // fixed env vars — operator-set, never returned to callers userConfigurableEnvVars?: UserConfigurableEnvVar[] command?: string[] // Docker CMD override; ${KEY} expanded from userData + commandFile?: string // path relative to the templates dir; inlined into command[0] at load + // time and dropped (mutually exclusive with `command`) entrypoint?: string[] // Docker ENTRYPOINT override requiredResources?: TemplateResourceRequirement[] // MUST satisfy — gates SERVICE_START recommendedResources?: TemplateResourceRequirement[] // SHOULD satisfy — used for scoring + UI diff --git a/src/components/core/service/templateLoader.ts b/src/components/core/service/templateLoader.ts index e40af9c5c..7b9db65bc 100644 --- a/src/components/core/service/templateLoader.ts +++ b/src/components/core/service/templateLoader.ts @@ -7,6 +7,17 @@ import type { import { ServiceTemplateSchema } from '../../../utils/config/schemas.js' import { CORE_LOGGER } from '../../../utils/logging/common.js' +// Resolves `relPath` against `resolvedDir` (an already-resolved absolute dir), rejecting any +// path that escapes it (e.g. via `../`). Returns the resolved absolute path, or null if it +// would land outside `resolvedDir`. +function resolveInTemplatesDir(resolvedDir: string, relPath: string): string | null { + const target = resolve(resolvedDir, relPath) + if (target !== resolvedDir && !target.startsWith(resolvedDir + sep)) { + return null + } + return target +} + // Re-reads on every call so operators can add/edit/remove template files without a restart. // (If profiling ever shows this is hot, add an mtime-keyed cache — semantics stay identical.) export async function loadServiceTemplates(dir?: string): Promise { @@ -58,6 +69,25 @@ export async function loadServiceTemplates(dir?: string): Promise { }).success ).to.equal(true) }) - it('ltx-video-ugc: template matches ServiceTemplateSchema', () => { + it('ltx-video-ugc-product/testimonial: templates match ServiceTemplateSchema', () => { const dir = join(process.cwd(), 'docs', 'serviceTemplates') - const tmpl = JSON.parse(readFileSync(join(dir, 'ltx-video-ugc.json'), 'utf8')) - expect(ServiceTemplateSchema.safeParse(tmpl).success).to.equal(true) + for (const file of ['ltx-video-ugc-product.json', 'ltx-video-ugc-testimonial.json']) { + const tmpl = JSON.parse(readFileSync(join(dir, file), 'utf8')) + expect(ServiceTemplateSchema.safeParse(tmpl).success).to.equal(true) + } }) }) diff --git a/src/test/unit/service/templateLoader.test.ts b/src/test/unit/service/templateLoader.test.ts index 1122338c2..a323df233 100644 --- a/src/test/unit/service/templateLoader.test.ts +++ b/src/test/unit/service/templateLoader.test.ts @@ -126,4 +126,15 @@ describe('loadServiceTemplates', () => { rmSync(outsideDir, { recursive: true, force: true }) } }) + + it('12. commandFile is inlined into command[0] and the key is dropped', async () => { + writeFileSync(join(dir, 'boot.sh'), '#!/bin/bash\necho hi\n') + writeFileSync( + join(dir, 'a.json'), + JSON.stringify({ ...valid('tmpl-cmd'), commandFile: 'boot.sh' }) + ) + const [tmpl] = await loadServiceTemplates(dir) + expect(tmpl.command[0]).to.equal('#!/bin/bash\necho hi\n') + expect(tmpl).to.not.have.property('commandFile') + }) }) diff --git a/src/utils/config/schemas.ts b/src/utils/config/schemas.ts index af4f5b7df..f6df2c071 100644 --- a/src/utils/config/schemas.ts +++ b/src/utils/config/schemas.ts @@ -377,6 +377,7 @@ export const ServiceTemplateSchema = z envVars: z.record(z.string()).optional(), userConfigurableEnvVars: z.array(UserConfigurableEnvVarSchema).optional(), command: z.array(z.string()).optional(), + commandFile: z.string().min(1).optional(), entrypoint: z.array(z.string()).optional(), requiredResources: z.array(TemplateResourceRequirementSchema).optional(), recommendedResources: z.array(TemplateResourceRequirementSchema).optional(), @@ -428,6 +429,14 @@ export const ServiceTemplateSchema = z path: ['additionalDockerFiles'] }) } + + if (tmpl.command && tmpl.commandFile) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: '"command" and "commandFile" are mutually exclusive — set at most one', + path: ['commandFile'] + }) + } }) // ── Per-daemon service config (no templates here) ───────────────────── From 233942cc3d8c5593bde8aa287c8a780737dd32db Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Wed, 5 Aug 2026 10:22:34 +0300 Subject: [PATCH 05/29] workflow id --- docs/serviceTemplates/README.md | 21 +++++++----- .../ltx-video-ugc-bootstrap.sh | 33 ++++++++++--------- .../ltx-video-ugc-product.json | 2 +- .../ltx-video-ugc-testimonial.json | 2 +- 4 files changed, 32 insertions(+), 26 deletions(-) diff --git a/docs/serviceTemplates/README.md b/docs/serviceTemplates/README.md index a6768a01f..5943d5201 100644 --- a/docs/serviceTemplates/README.md +++ b/docs/serviceTemplates/README.md @@ -125,15 +125,18 @@ container is not uid 0. Relocating `custom_nodes` also means the image's bundled ComfyUI-Manager is not loaded — this template ships one fixed workflow and installs no nodes at runtime. -The workflow graph is delivered via userData: `COMFY_WORKFLOW_ID` (`ocean_ugc_product`, used -only for the `[ocean] installed workflow …` log line) plus `COMFY_WORKFLOW` (the graph JSON, -gzipped then base64-encoded). The bootstrap writes it into a minimal custom-node pack at the -constant path `custom_nodes/ocean_ugc/example_workflows/ocean_ugc.json`, which ComfyUI serves -at `/api/workflow_templates/ocean_ugc/ocean_ugc.json`. Open the ComfyUI URL with -`?template=ocean_ugc&source=ocean_ugc` to load it directly instead of building the graph by -hand. The same graph is also copied into `user/default/workflows/`, so it appears in ComfyUI's -Workflows sidebar as an ordinary saved workflow — that path needs no template-browser -resolution or URL parameters, and is the fallback when the deep link does not fire. +The workflow graph is delivered via userData: `COMFY_WORKFLOW_ID` (the workflow's id, e.g. +`ocean_ugc_product`) plus `COMFY_WORKFLOW` (the graph JSON, gzipped then base64-encoded). The +bootstrap writes it into a minimal custom-node pack named after that id — +`custom_nodes//example_workflows/.json` — which ComfyUI serves at +`/api/workflow_templates//.json`, so `?template=&source=` on the ComfyUI URL loads +it directly. Naming the pack after the id is what lets the client build that link from the template +alone, without either side hard-coding a path; `source` must be the module name, since ComfyUI +resolves `source=all` only against its own core templates. The id therefore becomes a directory +name, so its validation excludes dots (it is imported as a Python module). The graph is also copied +into `user/default/workflows/`, where it appears in ComfyUI's Workflows sidebar as an ordinary saved +workflow — no template-browser resolution or URL parameters needed, and the fallback if the deep +link does not fire. Needs a CUDA GPU with 48 GB+ VRAM (LTX-2.3 22B fp8 + Gemma-3-12B encoder). ### `ltx-video-ugc-testimonial.json` — ComfyUI, LTX-2.3 creator testimonial (GPU) diff --git a/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh b/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh index 71f65386b..28f63d5cf 100644 --- a/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh +++ b/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh @@ -5,10 +5,11 @@ set -euo pipefail WF_ID="${COMFY_WORKFLOW_ID:-}" -# COMFY_WORKFLOW_ID is client-supplied and becomes a filename. ServiceStartHandler never -# loads templates, so userConfigurableEnvVars.validation is NOT enforced node-side — this -# check is the only thing standing between userData and a path traversal. -if [ -n "$WF_ID" ] && ! [[ "$WF_ID" =~ ^[A-Za-z0-9_.-]{1,64}$ ]]; then +# COMFY_WORKFLOW_ID is client-supplied and becomes both a directory and a filename. +# ServiceStartHandler never loads templates, so userConfigurableEnvVars.validation is NOT enforced +# node-side — this check is the only thing standing between userData and a path traversal. No dots: +# the directory becomes a Python module name that ComfyUI imports. +if [ -n "$WF_ID" ] && ! [[ "$WF_ID" =~ ^[A-Za-z0-9_-]{1,64}$ ]]; then echo "[ocean] invalid COMFY_WORKFLOW_ID" >&2 exit 1 fi @@ -71,20 +72,22 @@ get "$HF/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterat get "$HF/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors" \ "$MODELS/latent_upscale_models/ltx-2.3-spatial-upscaler-x2-1.1.safetensors" -PACK="$BASE/custom_nodes/ocean_ugc" -SAVED="$BASE/user/default/workflows" -mkdir -p "$PACK/example_workflows" "$SAVED" -echo 'NODE_CLASS_MAPPINGS = {}' > "$PACK/__init__.py" if [ -n "$WF_ID" ] && [ -n "${COMFY_WORKFLOW:-}" ]; then - # Escrow is already claimed by the time this runs — a corrupt/undecodable payload must not take - # the whole container down with it. Degrade to an empty pack and keep going; base64/gunzip's own - # stderr plus the line below land in the container logs either way. - if printf '%s' "$COMFY_WORKFLOW" | base64 -d | gunzip > "$PACK/example_workflows/ocean_ugc.json"; then - cp "$PACK/example_workflows/ocean_ugc.json" "$SAVED/ocean_ugc.json" + # Pack directory and graph filename are both $WF_ID, so the client's deep link + # (?template=&source=) resolves without either side hard-coding a name. + PACK="$BASE/custom_nodes/$WF_ID" + SAVED="$BASE/user/default/workflows" + mkdir -p "$PACK/example_workflows" "$SAVED" + echo 'NODE_CLASS_MAPPINGS = {}' > "$PACK/__init__.py" + # Escrow is already claimed by the time this runs — a corrupt payload must not take the container + # down with it. Degrade to no workflow and keep going; the decode's stderr lands in the logs. + if printf '%s' "$COMFY_WORKFLOW" | base64 -d | gunzip > "$PACK/example_workflows/$WF_ID.json"; then + # Also a saved workflow, so it appears in ComfyUI's sidebar without the template browser. + cp "$PACK/example_workflows/$WF_ID.json" "$SAVED/$WF_ID.json" echo "[ocean] installed workflow $WF_ID (template pack + Workflows sidebar)" else - echo "[ocean] failed to decode COMFY_WORKFLOW — starting ComfyUI with an empty workflow pack" >&2 - rm -f "$PACK/example_workflows/ocean_ugc.json" + echo "[ocean] failed to decode COMFY_WORKFLOW — starting ComfyUI without a workflow" >&2 + rm -f "$PACK/example_workflows/$WF_ID.json" fi fi diff --git a/docs/serviceTemplates/ltx-video-ugc-product.json b/docs/serviceTemplates/ltx-video-ugc-product.json index 1f68bafa8..1b651ef17 100644 --- a/docs/serviceTemplates/ltx-video-ugc-product.json +++ b/docs/serviceTemplates/ltx-video-ugc-product.json @@ -23,7 +23,7 @@ "userConfigurableEnvVars": [ { "key": "COMFY_WORKFLOW_ID", - "validation": "^[A-Za-z0-9_.-]+$" + "validation": "^[A-Za-z0-9_-]+$" }, { "key": "COMFY_WORKFLOW" diff --git a/docs/serviceTemplates/ltx-video-ugc-testimonial.json b/docs/serviceTemplates/ltx-video-ugc-testimonial.json index 361659682..0a82e118e 100644 --- a/docs/serviceTemplates/ltx-video-ugc-testimonial.json +++ b/docs/serviceTemplates/ltx-video-ugc-testimonial.json @@ -23,7 +23,7 @@ "userConfigurableEnvVars": [ { "key": "COMFY_WORKFLOW_ID", - "validation": "^[A-Za-z0-9_.-]+$" + "validation": "^[A-Za-z0-9_-]+$" }, { "key": "COMFY_WORKFLOW" From 613b0171e5c948d94664c8a8a423083cb9f739dd Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Wed, 5 Aug 2026 19:41:00 +0300 Subject: [PATCH 06/29] multiscene test --- docs/serviceTemplates/README.md | 82 +- .../ltx-video-ugc-bootstrap.sh | 84 +- .../ltx-video-ugc-multishot.json | 60 + .../ltx-video-ugc-testimonial.json | 60 - .../workflows/ocean_ugc_multishot.json | 4088 +++++++++++++ .../workflows/ocean_ugc_testimonial.json | 5167 ----------------- src/components/core/service/templateLoader.ts | 4 +- src/test/unit/service/serviceSchemas.test.ts | 4 +- src/test/unit/service/templateLoader.test.ts | 19 + 9 files changed, 4264 insertions(+), 5304 deletions(-) mode change 100644 => 100755 docs/serviceTemplates/ltx-video-ugc-bootstrap.sh create mode 100644 docs/serviceTemplates/ltx-video-ugc-multishot.json delete mode 100644 docs/serviceTemplates/ltx-video-ugc-testimonial.json create mode 100644 docs/serviceTemplates/workflows/ocean_ugc_multishot.json delete mode 100644 docs/serviceTemplates/workflows/ocean_ugc_testimonial.json diff --git a/docs/serviceTemplates/README.md b/docs/serviceTemplates/README.md index 5943d5201..8cfa2c33a 100644 --- a/docs/serviceTemplates/README.md +++ b/docs/serviceTemplates/README.md @@ -105,49 +105,45 @@ downloads. ~10 GB VRAM for SDXL. ### `ltx-video-ugc-product.json` — ComfyUI, LTX-2.3 product video (GPU) -ComfyUI preloaded with LTX-2.3 for one fixed workflow (`workflows/ocean_ugc_product.json`): a -product photo becomes a vertical 9:16 (720×1280) clip with camera motion and ambient audio, -capped at the graph's 5 seconds (126 frames at 25 fps — trim longer voiceovers or raise the -frame count). `entrypoint`/`commandFile` override to a bootstrap script -(`ltx-video-ugc-bootstrap.sh`, inlined as `command[0]` at load time) that downloads the -~38 GiB weight set (LTX-2.3 22B fp8 checkpoint, Gemma-3-12B text encoder, two LoRAs, the x2 -spatial upscaler) on first launch. Pick a persistent-storage bucket for this template: weights -live under the bucket, so only the first launch pays the download, and generated clips are -written to the bucket root (via ComfyUI's `--output-directory`) so the storage API's -`listFiles` — which only lists the bucket's top-level files — can see them. Without a bucket -the weights land inside the container and are lost on stop (in `/tmp`, not the bucket). - -The bootstrap runs `main.py` directly from the image's read-only bundle with ComfyUI's own -`--base-directory` flag, pointed at the bucket, so models/input/user/custom_nodes all live -there and nothing is written under `/root`. This deliberately bypasses the image's entrypoint, -which copies its bundle into `/root/ComfyUI` and therefore fails on hosts where the service -container is not uid 0. Relocating `custom_nodes` also means the image's bundled -ComfyUI-Manager is not loaded — this template ships one fixed workflow and installs no nodes at -runtime. - -The workflow graph is delivered via userData: `COMFY_WORKFLOW_ID` (the workflow's id, e.g. -`ocean_ugc_product`) plus `COMFY_WORKFLOW` (the graph JSON, gzipped then base64-encoded). The -bootstrap writes it into a minimal custom-node pack named after that id — -`custom_nodes//example_workflows/.json` — which ComfyUI serves at -`/api/workflow_templates//.json`, so `?template=&source=` on the ComfyUI URL loads -it directly. Naming the pack after the id is what lets the client build that link from the template -alone, without either side hard-coding a path; `source` must be the module name, since ComfyUI -resolves `source=all` only against its own core templates. The id therefore becomes a directory -name, so its validation excludes dots (it is imported as a Python module). The graph is also copied -into `user/default/workflows/`, where it appears in ComfyUI's Workflows sidebar as an ordinary saved -workflow — no template-browser resolution or URL parameters needed, and the fallback if the deep -link does not fire. -Needs a CUDA GPU with 48 GB+ VRAM (LTX-2.3 22B fp8 + Gemma-3-12B encoder). - -### `ltx-video-ugc-testimonial.json` — ComfyUI, LTX-2.3 creator testimonial (GPU) - -Same image, bootstrap script, and bucket/weight-download behavior as -`ltx-video-ugc-product.json` above (see that section for details), but with a different fixed -workflow (`workflows/ocean_ugc_testimonial.json`, delivered via `COMFY_WORKFLOW_ID= -ocean_ugc_testimonial` + `COMFY_WORKFLOW`): a creator photo plus a voice clip becomes a -lip-synced vertical 9:16 (720×1280) testimonial, capped at the same 5 seconds (126 frames at -25 fps). Generated clips likewise land in the bucket root so the storage API can list them. -Needs a CUDA GPU with 48 GB+ VRAM (LTX-2.3 22B fp8 + Gemma-3-12B encoder). +A product photo becomes a 9:16 vertical clip (720×1280, 5 s) with camera motion and ambient +audio, using the fixed workflow `workflows/ocean_ugc_product.json`. Needs a CUDA GPU with +48 GB+ VRAM. + +Pick a persistent-storage bucket: it holds ComfyUI's whole base directory, so the ~38 GiB +weight set downloads only on the first launch, and clips are written to the bucket root where +the storage API's `listFiles` (top-level files only) can see them. Without a bucket everything +goes to `/tmp` and is lost on stop. + +### `ltx-video-ugc-multishot.json` — ComfyUI, LTX-2.3 multishot UGC reel (GPU) + +Same image and bucket behavior, but builds a 15-shot vertical reel (704×1280, 5 s per shot) +with one consistent character, using `workflows/ocean_ugc_multishot.json`. + +Upload a character reference sheet, type one prompt per line into the shot-list box, then set +ComfyUI's Queue **batch count to 15**. Each shot becomes its own queue item, cancellable +individually from the queue panel. Clips save to the bucket root as `shot_00.mp4` .. +`shot_14.mp4` for assembly in your own editor. + +The shot index wraps at the shot count, so a second batch in the same session starts again at +line 0 rather than running off the end of the list. Update that count if you change the number +of lines. + +## The shared bootstrap (`ltx-video-ugc-bootstrap.sh`) + +Both templates inline this script via `commandFile`. It runs ComfyUI from the image's +read-only bundle with `--base-directory` pointed at the bucket, bypassing the image entrypoint, +which writes to `/root/ComfyUI` and fails wherever the container is not uid 0. + +The workflow arrives as userData (`COMFY_WORKFLOW_ID` + gzipped `COMFY_WORKFLOW`) and is +installed at `custom_nodes//example_workflows/.json`, which ComfyUI serves at +`/api/workflow_templates//.json` — so `?template=&source=` deep-links it. +`source` must name the module; `source=all` only searches ComfyUI's own templates. It is also +copied into `user/default/workflows/` so it appears in the Workflows sidebar. + +Weights are not listed here: the script downloads the HuggingFace URLs carried by the installed +graph itself, so each template fetches only what it loads and a new workflow needs no change +here. A template's `envVars` cannot drive this — nothing merges them into a service container +(`SERVICE_START` has no template id; the container env comes only from `userData`). ### `automatic1111.json` — Stable Diffusion WebUI (A1111) (GPU) diff --git a/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh b/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh old mode 100644 new mode 100755 index 28f63d5cf..17d852f9b --- a/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh +++ b/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh @@ -1,14 +1,12 @@ #!/bin/bash -# The image's own entrypoint copies its ComfyUI bundle into /root/ComfyUI, which fails on -# hosts where the service container is not uid 0 — bypassed here in favor of running ComfyUI -# straight from the read-only bundle via --base-directory. +# Bypasses the image entrypoint, which writes to /root/ComfyUI and fails where the container +# is not uid 0. set -euo pipefail WF_ID="${COMFY_WORKFLOW_ID:-}" -# COMFY_WORKFLOW_ID is client-supplied and becomes both a directory and a filename. -# ServiceStartHandler never loads templates, so userConfigurableEnvVars.validation is NOT enforced -# node-side — this check is the only thing standing between userData and a path traversal. No dots: -# the directory becomes a Python module name that ComfyUI imports. +# Client-supplied, and becomes a directory + filename. userConfigurableEnvVars.validation is not +# enforced node-side, so this is the only guard against traversal. No dots: it becomes a Python +# module name. if [ -n "$WF_ID" ] && ! [[ "$WF_ID" =~ ^[A-Za-z0-9_-]{1,64}$ ]]; then echo "[ocean] invalid COMFY_WORKFLOW_ID" >&2 exit 1 @@ -31,8 +29,7 @@ MODELS="$BASE/models" mkdir -p "$MODELS/checkpoints" "$MODELS/loras" "$MODELS/text_encoders" \ "$MODELS/latent_upscale_models" "$BASE/output" "$BASE/input" "$BASE/temp" "$BASE/user" -# Download to .part then rename: a truncated file in a persistent bucket would be treated as -# cached by every future launch. +# .part then rename: a truncated file in a persistent bucket would look cached forever. get() { if [ -f "$2" ]; then echo "[ocean] cached $(basename "$2")" @@ -46,9 +43,8 @@ get() { echo "[ocean] download failed for $(basename "$2") (HTTP $http_code)" >&2 return 22 fi - # HTTP 200 is not proof of a model file: a proxy or HF error page returns a few hundred bytes - # with a success status. Without this floor that body gets renamed into place and every later - # launch treats it as cached. The smallest real file here is ~300 MB, so 10 MB is unambiguous. + # A proxy or HF error page returns a few hundred bytes with HTTP 200; without this floor that + # body would be cached as a model. Smallest real file is ~300 MB. size=$(wc -c < "$2.part") if [ "$size" -lt 10485760 ]; then echo "[ocean] $(basename "$2") is only $size bytes — not a model file. First bytes:" >&2 @@ -60,30 +56,18 @@ get() { mv "$2.part" "$2" } -HF=https://huggingface.co -get "$HF/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors" \ - "$MODELS/checkpoints/ltx-2.3-22b-dev-fp8.safetensors" -get "$HF/Comfy-Org/ltx-2/resolve/main/split_files/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors" \ - "$MODELS/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors" -get "$HF/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors" \ - "$MODELS/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors" -get "$HF/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors" \ - "$MODELS/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors" -get "$HF/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors" \ - "$MODELS/latent_upscale_models/ltx-2.3-spatial-upscaler-x2-1.1.safetensors" - +WORKFLOW_JSON="" if [ -n "$WF_ID" ] && [ -n "${COMFY_WORKFLOW:-}" ]; then - # Pack directory and graph filename are both $WF_ID, so the client's deep link - # (?template=&source=) resolves without either side hard-coding a name. + # Pack dir and filename are both $WF_ID, so ?template=&source= resolves with no + # hard-coded name on either side. PACK="$BASE/custom_nodes/$WF_ID" SAVED="$BASE/user/default/workflows" mkdir -p "$PACK/example_workflows" "$SAVED" echo 'NODE_CLASS_MAPPINGS = {}' > "$PACK/__init__.py" - # Escrow is already claimed by the time this runs — a corrupt payload must not take the container - # down with it. Degrade to no workflow and keep going; the decode's stderr lands in the logs. + # Escrow is already claimed: a corrupt payload must not kill the container. if printf '%s' "$COMFY_WORKFLOW" | base64 -d | gunzip > "$PACK/example_workflows/$WF_ID.json"; then - # Also a saved workflow, so it appears in ComfyUI's sidebar without the template browser. cp "$PACK/example_workflows/$WF_ID.json" "$SAVED/$WF_ID.json" + WORKFLOW_JSON="$PACK/example_workflows/$WF_ID.json" echo "[ocean] installed workflow $WF_ID (template pack + Workflows sidebar)" else echo "[ocean] failed to decode COMFY_WORKFLOW — starting ComfyUI without a workflow" >&2 @@ -91,6 +75,48 @@ if [ -n "$WF_ID" ] && [ -n "${COMFY_WORKFLOW:-}" ]; then fi fi +# The graph carries the HuggingFace URLs for everything it loads, so each template fetches only +# what it uses and a new workflow needs no edit here. Template envVars can't drive this: nothing +# merges them into a service container. +if [ -n "$WORKFLOW_JSON" ]; then + # `|| true` and the except are both needed: a payload that gunzips but isn't a graph must not + # abort the bootstrap after escrow is claimed. + MODEL_URLS=$(python3.13 - "$WORKFLOW_JSON" <<'PY' || true +import json, re, sys +seen = [] +def walk(o): + if isinstance(o, dict): + for v in o.values(): walk(v) + elif isinstance(o, list): + for v in o: walk(v) + elif isinstance(o, str): + for m in re.findall(r'https://huggingface\.co/[^\s\)\]"]+?\.safetensors', o): + if m not in seen: seen.append(m) +try: + walk(json.load(open(sys.argv[1]))) +except Exception as e: + print(f'[ocean] cannot read model URLs from the workflow: {e}', file=sys.stderr) +print('\n'.join(seen)) +PY +) + if [ -z "$MODEL_URLS" ]; then + echo "[ocean] no model URLs found in the workflow — ComfyUI will start without weights" >&2 + fi + for url in $MODEL_URLS; do + case "$url" in + */text_encoders/*) sub=text_encoders ;; + */loras/*) sub=loras ;; + *upscaler*) sub=latent_upscale_models ;; + *) sub=checkpoints ;; + esac + # One renamed file must not cost the whole paid session. + get "$url" "$MODELS/$sub/$(basename "$url")" || + echo "[ocean] could not fetch $(basename "$url") — ComfyUI will start without it" >&2 + done +else + echo "[ocean] no workflow supplied — skipping model download" >&2 +fi + export HOME="$BASE" export PYTHONPYCACHEPREFIX="$BASE/.cache/pycache" export XDG_CACHE_HOME="$BASE/.cache" diff --git a/docs/serviceTemplates/ltx-video-ugc-multishot.json b/docs/serviceTemplates/ltx-video-ugc-multishot.json new file mode 100644 index 000000000..782bca074 --- /dev/null +++ b/docs/serviceTemplates/ltx-video-ugc-multishot.json @@ -0,0 +1,60 @@ +{ + "id": "ltx-video-ugc-multishot", + "name": "ComfyUI — UGC multishot reel (LTX-2.3)", + "description": "ComfyUI preloaded with LTX-2.3 (IC-LoRA Ingredients) for a 15-shot vertical UGC product reel with one consistent character. Usage: upload a character reference sheet as the workflow's image input, type one prompt per line in its shot-list text box (each line a distinct camera angle/action, e.g. close-up on the product, hands unboxing, walking outdoors), then set ComfyUI's Queue batch count to 15 and hit Queue — each shot runs as its own separate queue item, individually cancellable, and the shot index advances automatically between them. Clips are 9:16 vertical (704×1280, both divisible by 32 as LTX requires) at 5 seconds each (125 frames at 25 fps), saved to the bucket root as shot_00.mp4 .. shot_14.mp4 in order for you to assemble in your own editor — there is no in-container concatenation. Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the ~39 GiB of weights download once and are reused, and the numbered shot clips land in the bucket root where the storage API's listFiles can see them. Needs a CUDA GPU with 48 GB+ VRAM.", + "image": "yanwk/comfyui-boot", + "tag": "cu130-megapak-pt211-20260803", + "exposedPorts": [ + 8188 + ], + "entrypoint": [ + "/bin/bash", + "-c" + ], + "commandFile": "ltx-video-ugc-bootstrap.sh", + "workflows": [ + { + "id": "ocean_ugc_multishot", + "name": "Multishot reel (15 shots)", + "description": "Upload a character reference sheet and a 15-line shot list, set Queue batch count to 15, get 15 numbered 9:16 clips (shot_00..shot_14) with one consistent character.", + "file": "workflows/ocean_ugc_multishot.json" + } + ], + "userConfigurableEnvVars": [ + { + "key": "COMFY_WORKFLOW_ID", + "validation": "^[A-Za-z0-9_-]+$" + }, + { + "key": "COMFY_WORKFLOW" + } + ], + "requiredResources": [ + { + "id": "cpu", + "min": 8, + "recommended": 16, + "unit": "cores" + }, + { + "id": "ram", + "min": 32, + "recommended": 64, + "unit": "GB" + }, + { + "id": "disk", + "min": 45, + "recommended": 85, + "unit": "GB" + }, + { + "kind": "discrete", + "type": "gpu", + "min": 1, + "recommended": 1, + "unit": "count", + "description": "CUDA GPU, 48 GB+ VRAM recommended (LTX-2.3 22B distilled fp8 + Gemma-3-12B encoder)" + } + ] +} diff --git a/docs/serviceTemplates/ltx-video-ugc-testimonial.json b/docs/serviceTemplates/ltx-video-ugc-testimonial.json deleted file mode 100644 index 0a82e118e..000000000 --- a/docs/serviceTemplates/ltx-video-ugc-testimonial.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "id": "ltx-video-ugc-testimonial", - "name": "ComfyUI — UGC creator testimonial (LTX-2.3)", - "description": "ComfyUI preloaded with LTX-2.3 for vertical short-form UGC video: a creator photo plus a voice clip becomes a lip-synced 9:16 testimonial, capped at the graph's 5 seconds (126 frames at 25 fps). Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the 38 GiB of weights download once and are reused, and generated clips land in the bucket root. Needs a CUDA GPU with 48 GB+ VRAM.", - "image": "yanwk/comfyui-boot", - "tag": "cu130-megapak-pt211-20260803", - "exposedPorts": [ - 8188 - ], - "entrypoint": [ - "/bin/bash", - "-c" - ], - "commandFile": "ltx-video-ugc-bootstrap.sh", - "workflows": [ - { - "id": "ocean_ugc_testimonial", - "name": "Creator testimonial (lip-sync)", - "description": "Upload a person photo and a voice clip, get a lip-synced 9:16 testimonial.", - "file": "workflows/ocean_ugc_testimonial.json" - } - ], - "userConfigurableEnvVars": [ - { - "key": "COMFY_WORKFLOW_ID", - "validation": "^[A-Za-z0-9_-]+$" - }, - { - "key": "COMFY_WORKFLOW" - } - ], - "requiredResources": [ - { - "id": "cpu", - "min": 8, - "recommended": 16, - "unit": "cores" - }, - { - "id": "ram", - "min": 32, - "recommended": 64, - "unit": "GB" - }, - { - "id": "disk", - "min": 40, - "recommended": 80, - "unit": "GB" - }, - { - "kind": "discrete", - "type": "gpu", - "min": 1, - "recommended": 1, - "unit": "count", - "description": "CUDA GPU, 48 GB+ VRAM recommended (LTX-2.3 22B fp8 + Gemma-3-12B encoder)" - } - ] -} diff --git a/docs/serviceTemplates/workflows/ocean_ugc_multishot.json b/docs/serviceTemplates/workflows/ocean_ugc_multishot.json new file mode 100644 index 000000000..acdd170a4 --- /dev/null +++ b/docs/serviceTemplates/workflows/ocean_ugc_multishot.json @@ -0,0 +1,4088 @@ +{ + "id": "0112e9af-5129-48ba-af78-92c40ac40b40", + "revision": 0, + "last_node_id": 731, + "last_link_id": 1833, + "nodes": [ + { + "id": 68, + "type": "SaveVideo", + "pos": [ + 1480, + 2270 + ], + "size": [ + 910, + 700 + ], + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 256 + }, + { + "name": "filename_prefix", + "type": "STRING", + "widget": { + "name": "filename_prefix" + }, + "link": 1831 + } + ], + "outputs": [ + { + "name": "video", + "type": "VIDEO", + "links": null + } + ], + "properties": { + "Node name for S&R": "SaveVideo", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.7", + "widget_ue_connectable": {} + }, + "ver": "0.14.1" + }, + "widgets_values": [ + "shot", + "auto", + "auto" + ] + }, + { + "id": 79, + "type": "MarkdownNote", + "pos": [ + -2210, + 2270 + ], + "size": [ + 720, + 1320 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [], + "title": "Model Links", + "properties": { + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.7", + "widget_ue_connectable": {} + } + }, + "widgets_values": [ + "- Hugging Face (base): [Lightricks/LTX-2.3](https://huggingface.co/Lightricks/LTX-2.3/)\n- Hugging Face (Ingredients IC-LoRA): [Lightricks/LTX-2.3-22b-IC-LoRA-Ingredients](https://huggingface.co/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx-2.3-22b-ic-lora-ingredients-0.9.safetensors)\n- [gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors](https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors)\n\n\n## Model Storage Location\n\n```\n📂 ComfyUI/\n├── 📂 models/\n│ ├── 📂 checkpoints/\n│ │ └── ltx-2.3-22b-distilled-fp8.safetensors\n│ ├── 📂 text_encoders/\n│ │ └── gemma_3_12B_it_fp4_mixed.safetensors\n│ └── 📂 loras/\n│ ├── ltx-2.3-22b-ic-lora-ingredients-0.9.safetensors\n│ └── gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\n```\n\n## Report Issue\n\nNote: Please update ComfyUI first ([guide](https://docs.comfy.org/installation/update_comfyui)) and prepare required models. Desktop/Cloud updates follow stable releases, so some nightly-supported models may not be available yet.\n\n- Cannot run / runtime errors: [ComfyUI/issues](https://github.com/comfyanonymous/ComfyUI/issues)\n- UI / frontend issues: [ComfyUI_frontend/issues](https://github.com/Comfy-Org/ComfyUI_frontend/issues)\n- Workflow issues: [workflow_templates/issues](https://github.com/Comfy-Org/workflow_templates/issues)\n" + ], + "color": "#222", + "bgcolor": "#000" + }, + { + "id": 129, + "type": "f9f61b10-b689-4d67-b4fa-0acc1d9b5390", + "pos": [ + 890, + 2270 + ], + "size": [ + 540, + 680 + ], + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [ + { + "label": "first_frame", + "name": "input", + "type": "IMAGE,MASK", + "link": 1805 + }, + { + "label": "control_images", + "name": "input_1", + "type": "IMAGE,MASK", + "link": 1824 + }, + { + "label": "prompt", + "name": "text", + "type": "STRING", + "widget": { + "name": "text" + }, + "link": 1830 + }, + { + "label": "prompt_enhance", + "name": "value_4", + "type": "BOOLEAN", + "widget": { + "name": "value_4" + }, + "link": null + }, + { + "label": "width", + "name": "value", + "type": "INT", + "widget": { + "name": "value" + }, + "link": 1817 + }, + { + "label": "height", + "name": "value_1", + "type": "INT", + "widget": { + "name": "value_1" + }, + "link": 1818 + }, + { + "label": "fps", + "name": "value_3", + "type": "INT", + "widget": { + "name": "value_3" + }, + "link": 1809 + }, + { + "label": "seed", + "name": "noise_seed", + "type": "INT", + "widget": { + "name": "noise_seed" + }, + "link": null + }, + { + "label": "ckpt_name", + "name": "ckpt_name_1", + "type": "COMBO", + "widget": { + "name": "ckpt_name_1" + }, + "link": null + }, + { + "label": "text_encoder", + "name": "text_encoder", + "type": "COMBO", + "widget": { + "name": "text_encoder" + }, + "link": null + }, + { + "label": "lora", + "name": "lora_name", + "type": "COMBO", + "widget": { + "name": "lora_name" + }, + "link": null + }, + { + "label": "ic_lora", + "name": "lora_name_1", + "type": "COMBO", + "widget": { + "name": "lora_name_1" + }, + "link": null + }, + { + "label": "lora_strength", + "name": "strength_model", + "type": "FLOAT", + "widget": { + "name": "strength_model" + }, + "link": null + }, + { + "label": "bypass_first_frame", + "name": "value_2", + "type": "BOOLEAN", + "widget": { + "name": "value_2" + }, + "link": null + } + ], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 256 + ] + } + ], + "properties": { + "proxyWidgets": [ + [ + "209", + "prompt" + ], + [ + "212", + "value" + ], + [ + "113", + "value" + ], + [ + "98", + "value" + ], + [ + "114", + "value" + ], + [ + "704", + "seed" + ], + [ + "126", + "ckpt_name" + ], + [ + "103", + "text_encoder" + ], + [ + "208", + "lora_name" + ], + [ + "195", + "lora_name" + ], + [ + "195", + "strength_model" + ], + [ + "711", + "value" + ] + ], + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.7", + "widget_ue_connectable": {} + }, + "ver": "0.18.1" + }, + "widgets_values": [] + }, + { + "id": 698, + "type": "MarkdownNote", + "pos": [ + -1450, + 2270 + ], + "size": [ + 720, + 2630 + ], + "flags": { + "collapsed": false + }, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [], + "title": "Note: IC-LoRA", + "properties": { + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.7", + "widget_ue_connectable": {} + } + }, + "widgets_values": [ + "## IC-LoRA Ingredients\n\nSources (official only):\n- Model card: [Lightricks/LTX-2.3-22b-IC-LoRA-Ingredients](https://huggingface.co/Lightricks/LTX-2.3-22b-IC-LoRA-Ingredients)\n- IC-LoRA docs: [docs.ltx.video — IC-LoRA usage guide](https://docs.ltx.video/open-source-model/usage-guides/ic-lo-ra)\n\n### What This Model Is\nFrom the model card:\n\n> This is an IC-LoRA trained on top of LTX-2.3-22B, which conditions video generation on a reference sheet — a single composite image inventorying the characters, props, and location of a scene — so that generated videos keep those elements visually consistent.\n\n\n**Model details (model card):**\n- Base Model: LTX-2.3-22B (dev)\n- Training Type: IC-LoRA (in-context LoRA)\n- Control Type: Reference-sheet conditioning — character / prop / location identity carried into the generated video\n- Reference Downscale Factor: `1` (the reference is provided at the same resolution as the output)\n- Pipeline: the reference sheet is supplied as a static video (the still sheet looped to the output's length and frame rate). Trained with a `video_to_video` strategy over reference latents; no extra color/space transforms are applied at inference.\n\n### Intended Use & Out-of-Scope\nFrom the model card:\n\n- **Intended use:** Generating short video clips that stay faithful to a supplied reference sheet — keeping recurring characters (face and costume), handled props, and the set/location consistent with the sheet while following an action described in the prompt.\n- **Out of scope:** This is not a general text-to-video model — it expects a reference sheet as conditioning. It was trained at a single resolution / length bucket (**768×448**, **121 frames**, **24 fps**); other resolutions, much longer clips, or use without a reference sheet are out of distribution. It does not reproduce identities that are absent from the supplied sheet.\n\n### Control Signal Requirements\nFrom the model card:\n\n- **Control signal type:** Reference sheet — a single composite image with one clean panel per distinct visual element (each character as a face close-up + body turnaround, each prop as a product-style render, and one clean location panel), laid out on a **black background with no text**.\n- **Expected input:** A static video built from the reference sheet, looped to match the output clip's length and frame rate, at the output resolution (downscale factor 1).\n- **Preprocessing:** Author the reference sheet, then loop the still into a static video. Frame count must be **≥ 121** so the reference-encoding / 121-frame read bucket is satisfied; all targets in training were ≥ 121 frames.\n- **Alignment:** The reference video should match the output resolution and frame rate; its frame count must be at least the output length (clamped to ≥ 121).\n\n### Prompt Format\nFrom the model card — the prompt is split into two labeled parts, matching how the model was trained:\n\n```text\nReference sheet: \n\nGenerated video: \n```\n\nAt inference, the reference sheet (as a static video) supplies *what things look like*, and the `Generated video:` portion supplies *what happens*. The model reads the reference latents in-context and renders a new clip whose characters, props, and setting match the sheet.\n\nModel-card gallery examples also show prompts labeled as `### Reference Sheet Description` / `### Target Description`.\n\n### ComfyUI Usage\nFrom the model card:\n\n1. Copy the LoRA weights into `models/loras`.\n2. Load the LTX-2.3-22B base model and add the Ingredients LoRA.\n3. Start at strength `1.0` and adjust to taste.\n4. Use an IC-LoRA / reference workflow from the LTX-2 ComfyUI repository, which already wires the reference (control) input. Connect the reference-sheet static video as the control/reference input; a generic LoRA loader that ignores the reference path will not apply the conditioning.\n\n### Recommended Settings\nFrom the model card:\n\n- LoRA strength / weight: **1.4**\n- Inference steps: **30**\n- Guidance scale: **4.0**\n- Resolution & frames: **768×448**, **121 frames**, **24 fps** (the trained bucket — best results here)\n- Prompting: use the two-part `Reference sheet: … / Generated video: …` structure. The `Reference sheet:` text should describe the panels present; the `Generated video:` text drives the action.\n- Suggested negative prompt: `worst quality, inconsistent motion, blurry, jittery, distorted`\n- Validation used spatiotemporal guidance (STG, mode `stg_v`, block 29, scale 1.0), which can help motion stability.\n\n### Tips & Troubleshooting\nFrom the model card only:\n\n- **Bigger panels carry over better:** The more space an element takes up in the reference image, the more faithfully it carries over into the generated video. Give important characters/props larger, more prominent panels rather than small or crowded ones.\n- **Identity drift:** If a character's face or costume drifts, make sure the reference sheet has a clean, front-facing close-up and full turnaround for that character, and that its panel isn't cluttered or text-laden.\n- **Element not appearing:** The model only reproduces elements present on the sheet — add a dedicated panel for any prop/character you need to persist, and describe it in the `Reference sheet:` portion of the prompt.\n- **Reference too short:** The reference static video must be ≥ 121 frames; shorter references break the reference-encoding bucket.\n" + ], + "color": "#222", + "bgcolor": "#000" + }, + { + "id": 709, + "type": "RepeatImageBatch", + "pos": [ + 150, + 2750 + ], + "size": [ + 270, + 110 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": 1825 + }, + { + "name": "amount", + "type": "INT", + "widget": { + "name": "amount" + }, + "link": 1812 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 1821 + ] + } + ], + "properties": { + "Node name for S&R": "RepeatImageBatch" + }, + "widgets_values": [ + 125 + ] + }, + { + "id": 712, + "type": "EmptyImage", + "pos": [ + 550, + 2830 + ], + "size": [ + 225, + 8 + ], + "flags": { + "collapsed": true + }, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 1805 + ] + } + ], + "properties": { + "Node name for S&R": "EmptyImage" + }, + "widgets_values": [ + 512, + 512, + 1, + 0 + ] + }, + { + "id": 715, + "type": "PrimitiveInt", + "pos": [ + 140, + 2310 + ], + "size": [ + 270, + 110 + ], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "INT", + "type": "INT", + "links": [ + 1810 + ] + } + ], + "title": "Int (duration)", + "properties": { + "Node name for S&R": "PrimitiveInt" + }, + "widgets_values": [ + 5, + "fixed" + ] + }, + { + "id": 716, + "type": "PrimitiveInt", + "pos": [ + 150, + 2480 + ], + "size": [ + 270, + 110 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "INT", + "type": "INT", + "links": [ + 1809, + 1811 + ] + } + ], + "title": "Int (fps)", + "properties": { + "Node name for S&R": "PrimitiveInt" + }, + "widgets_values": [ + 25, + "fixed" + ] + }, + { + "id": 717, + "type": "ComfyMathExpression", + "pos": [ + 170, + 2670 + ], + "size": [ + 225, + 8 + ], + "flags": { + "collapsed": true + }, + "order": 6, + "mode": 0, + "inputs": [ + { + "label": "a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 1810 + }, + { + "label": "b", + "name": "values.b", + "shape": 7, + "type": "FLOAT,INT,BOOLEAN", + "link": 1811 + }, + { + "label": "c", + "name": "values.c", + "shape": 7, + "type": "FLOAT,INT,BOOLEAN", + "link": null + } + ], + "outputs": [ + { + "name": "FLOAT", + "type": "FLOAT", + "links": null + }, + { + "name": "INT", + "type": "INT", + "links": [ + 1812 + ] + }, + { + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "properties": { + "Node name for S&R": "ComfyMathExpression" + }, + "widgets_values": [ + "a * b" + ] + }, + { + "id": 721, + "type": "GetImageSize", + "pos": [ + 540, + 2610 + ], + "size": [ + 225, + 8 + ], + "flags": { + "collapsed": true + }, + "order": 9, + "mode": 0, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": 1822 + } + ], + "outputs": [ + { + "name": "width", + "type": "INT", + "links": [ + 1817 + ] + }, + { + "name": "height", + "type": "INT", + "links": [ + 1818 + ] + }, + { + "name": "batch_size", + "type": "INT", + "links": null + } + ], + "properties": { + "Node name for S&R": "GetImageSize" + }, + "widgets_values": [] + }, + { + "id": 722, + "type": "ResizeAndPadImage", + "pos": [ + 530, + 2370 + ], + "size": [ + 280, + 170 + ], + "flags": {}, + "order": 8, + "mode": 0, + "showAdvanced": false, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": 1821 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 1822, + 1823, + 1824 + ] + } + ], + "title": "Resize And Pad Image (Size)", + "properties": { + "Node name for S&R": "ResizeAndPadImage" + }, + "widgets_values": [ + 704, + 1280, + "black", + "lanczos" + ] + }, + { + "id": 723, + "type": "PreviewImage", + "pos": [ + 140, + 2980 + ], + "size": [ + 650, + 110 + ], + "flags": {}, + "order": 10, + "mode": 4, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 1823 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": null + } + ], + "properties": { + "Node name for S&R": "PreviewImage" + }, + "widgets_values": [] + }, + { + "id": 724, + "type": "LoadImage", + "pos": [ + -680, + 2280 + ], + "size": [ + 730, + 660 + ], + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 1825 + ] + }, + { + "name": "MASK", + "type": "MASK", + "links": null + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "german_shepherd_news_anchor_ref.png", + "image" + ] + }, + { + "id": 725, + "type": "PrimitiveStringMultiline", + "pos": [ + -1700, + 2150 + ], + "size": [ + 400, + 360 + ], + "flags": {}, + "order": 13, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 1828 + ] + } + ], + "title": "Shot List (one prompt per line)", + "properties": { + "Node name for S&R": "PrimitiveStringMultiline" + }, + "widgets_values": [ + "Extreme close-up on the product label, slow rotation under soft studio light, shallow depth of field.\nHands unboxing the product from its packaging on a wooden table, top-down angle.\nOver-the-shoulder shot as the person opens the product for the first time, natural window light.\nPerson walking outdoors on a city sidewalk, holding the product up to the camera, casual handheld motion.\nMirror selfie in a bright bathroom, person showing the product at chest height, phone visible in reflection.\nClose-up of hands applying the product, soft focus background, warm indoor lighting.\nPerson sitting on a couch, casually gesturing toward the product on the coffee table, medium shot.\nLow-angle shot looking up as the person raises the product triumphantly outdoors, blue sky background.\nProduct placed on a kitchen counter, slow dolly-in past morning coffee and sunlight through a window.\nPerson talking directly to camera, product held at shoulder height, blurred cafe background.\nOverhead flat-lay shot of the product surrounded by lifestyle props, a hand entering frame to pick it up.\nTracking shot following the person as they carry the product through a sunlit hallway.\nClose-up on the person's face lighting up with a smile as they look at the product, shallow depth of field.\nPerson unboxing the product in a car, phone mounted on the dashboard, natural daylight.\nSlow-motion shot of the product being set down on a marble countertop, logo facing the camera." + ] + }, + { + "id": 726, + "type": "PrimitiveInt", + "pos": [ + -1700, + 2560 + ], + "size": [ + 270, + 110 + ], + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "INT", + "type": "INT", + "links": [ + 1832 + ] + } + ], + "title": "Int (shot index)", + "properties": { + "Node name for S&R": "PrimitiveInt" + }, + "widgets_values": [ + 0, + "increment" + ] + }, + { + "id": 727, + "type": "StringFormat", + "pos": [ + -1300, + 2560 + ], + "size": [ + 320, + 150 + ], + "flags": {}, + "order": 15, + "mode": 0, + "inputs": [ + { + "label": "a", + "name": "values.a", + "type": "*", + "link": 1826 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 1829 + ] + } + ], + "title": "Format Text (line-select regex)", + "properties": { + "Node name for S&R": "StringFormat" + }, + "widgets_values": [ + "(?s)^(?:[^\\n]*\\n){{{a}}}([^\\n]*)" + ] + }, + { + "id": 728, + "type": "RegexExtract", + "pos": [ + -900, + 2150 + ], + "size": [ + 320, + 250 + ], + "flags": {}, + "order": 16, + "mode": 0, + "inputs": [ + { + "name": "string", + "type": "STRING", + "link": 1828 + }, + { + "name": "regex_pattern", + "type": "STRING", + "link": 1829 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 1830 + ] + } + ], + "title": "Extract Text (shot N)", + "properties": { + "Node name for S&R": "RegexExtract" + }, + "widgets_values": [ + "First Group", + true, + false, + false, + 1 + ] + }, + { + "id": 729, + "type": "StringFormat", + "pos": [ + 1050, + 2650 + ], + "size": [ + 320, + 150 + ], + "flags": {}, + "order": 17, + "mode": 0, + "inputs": [ + { + "label": "a", + "name": "values.a", + "type": "*", + "link": 1827 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 1831 + ] + } + ], + "title": "Format Text (filename prefix)", + "properties": { + "Node name for S&R": "StringFormat" + }, + "widgets_values": [ + "shot_{a:02d}" + ] + }, + { + "id": 730, + "type": "PrimitiveInt", + "pos": [ + 150, + 2860 + ], + "size": [ + 270, + 110 + ], + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "INT", + "type": "INT", + "links": [ + 1833 + ] + } + ], + "title": "Int (shots in list)", + "properties": { + "Node name for S&R": "PrimitiveInt" + }, + "widgets_values": [ + 15, + "fixed" + ] + }, + { + "id": 731, + "type": "ComfyMathExpression", + "pos": [ + 470, + 2860 + ], + "size": [ + 225, + 8 + ], + "flags": { + "collapsed": true + }, + "order": 7, + "mode": 0, + "inputs": [ + { + "label": "a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 1832 + }, + { + "label": "b", + "name": "values.b", + "shape": 7, + "type": "FLOAT,INT,BOOLEAN", + "link": 1833 + }, + { + "label": "c", + "name": "values.c", + "shape": 7, + "type": "FLOAT,INT,BOOLEAN", + "link": null + } + ], + "outputs": [ + { + "name": "FLOAT", + "type": "FLOAT", + "links": null + }, + { + "name": "INT", + "type": "INT", + "links": [ + 1826, + 1827 + ] + }, + { + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "title": "Wrap shot index", + "properties": { + "Node name for S&R": "ComfyMathExpression" + }, + "widgets_values": [ + "a % b" + ] + } + ], + "links": [ + [ + 256, + 129, + 0, + 68, + 0, + "VIDEO" + ], + [ + 1805, + 712, + 0, + 129, + 0, + "IMAGE" + ], + [ + 1809, + 716, + 0, + 129, + 6, + "INT" + ], + [ + 1810, + 715, + 0, + 717, + 0, + "INT" + ], + [ + 1811, + 716, + 0, + 717, + 1, + "INT" + ], + [ + 1812, + 717, + 1, + 709, + 1, + "INT" + ], + [ + 1817, + 721, + 0, + 129, + 4, + "INT" + ], + [ + 1818, + 721, + 1, + 129, + 5, + "INT" + ], + [ + 1821, + 709, + 0, + 722, + 0, + "IMAGE" + ], + [ + 1822, + 722, + 0, + 721, + 0, + "IMAGE" + ], + [ + 1823, + 722, + 0, + 723, + 0, + "IMAGE" + ], + [ + 1824, + 722, + 0, + 129, + 1, + "IMAGE" + ], + [ + 1825, + 724, + 0, + 709, + 0, + "IMAGE" + ], + [ + 1826, + 731, + 1, + 727, + 0, + "INT" + ], + [ + 1827, + 731, + 1, + 729, + 0, + "INT" + ], + [ + 1828, + 725, + 0, + 728, + 0, + "STRING" + ], + [ + 1829, + 727, + 0, + 728, + 1, + "STRING" + ], + [ + 1830, + 728, + 0, + 129, + 2, + "STRING" + ], + [ + 1831, + 729, + 0, + 68, + 1, + "STRING" + ], + [ + 1832, + 726, + 0, + 731, + 0, + "INT" + ], + [ + 1833, + 730, + 0, + 731, + 1, + "INT" + ] + ], + "groups": [ + { + "id": 28, + "title": "Video Settings", + "bounding": [ + 100, + 2240, + 740, + 690 + ], + "color": "#3f789e", + "flags": {} + } + ], + "definitions": { + "subgraphs": [ + { + "id": "f9f61b10-b689-4d67-b4fa-0acc1d9b5390", + "version": 1, + "state": { + "lastGroupId": 28, + "lastNodeId": 724, + "lastLinkId": 1825, + "lastRerouteId": 0 + }, + "revision": 0, + "config": {}, + "name": "LTX-2.3 IC-LoRA Video Generation", + "inputNode": { + "id": -10, + "bounding": [ + -160, + 3060, + 155.00390625, + 328 + ] + }, + "outputNode": { + "id": -20, + "bounding": [ + 3620, + 3120, + 128, + 68 + ] + }, + "inputs": [ + { + "id": "6fe179c4-d96f-4383-b202-844f6de4922e", + "name": "input", + "type": "IMAGE,MASK", + "linkIds": [ + 1735, + 1786 + ], + "localized_name": "input", + "label": "first_frame", + "pos": [ + -28.99609375, + 3084 + ] + }, + { + "id": "e80df1ae-5f39-4f86-91bd-0467635e2f2d", + "name": "input_1", + "type": "IMAGE,MASK", + "linkIds": [ + 1777, + 1802 + ], + "localized_name": "input_1", + "label": "control_images", + "pos": [ + -28.99609375, + 3104 + ] + }, + { + "id": "433148fa-bf73-4ab1-81d9-09e2e38ed861", + "name": "text", + "type": "STRING", + "linkIds": [ + 316, + 317 + ], + "label": "prompt", + "pos": [ + -28.99609375, + 3124 + ] + }, + { + "id": "80e8d306-4496-4641-a896-249352d68a33", + "name": "value_4", + "type": "BOOLEAN", + "linkIds": [ + 315 + ], + "label": "prompt_enhance", + "pos": [ + -28.99609375, + 3144 + ] + }, + { + "id": "36915bc8-a6ed-4d48-8619-e0e8723228e9", + "name": "value", + "type": "INT", + "linkIds": [ + 266 + ], + "label": "width", + "pos": [ + -28.99609375, + 3164 + ] + }, + { + "id": "425a36b8-91ab-41b7-81e9-496eba064ec8", + "name": "value_1", + "type": "INT", + "linkIds": [ + 267 + ], + "label": "height", + "pos": [ + -28.99609375, + 3184 + ] + }, + { + "id": "581b52ff-21c5-4774-ac2a-8f69a7e09e2e", + "name": "value_3", + "type": "INT", + "linkIds": [ + 269 + ], + "label": "fps", + "pos": [ + -28.99609375, + 3204 + ] + }, + { + "id": "d03cc171-45da-4658-99aa-77252bbcf522", + "name": "noise_seed", + "type": "INT", + "linkIds": [ + 1793 + ], + "label": "seed", + "pos": [ + -28.99609375, + 3224 + ] + }, + { + "id": "e68e61c8-905e-43ac-8c76-65ac52270a08", + "name": "ckpt_name_1", + "type": "COMBO", + "linkIds": [ + 272, + 275, + 276 + ], + "label": "ckpt_name", + "pos": [ + -28.99609375, + 3244 + ] + }, + { + "id": "5d065f3b-891b-499f-950b-c2df0be24536", + "name": "text_encoder", + "type": "COMBO", + "linkIds": [ + 273 + ], + "label": "text_encoder", + "pos": [ + -28.99609375, + 3264 + ] + }, + { + "id": "e9abdbac-c422-4a1e-bc0d-6b99c0730086", + "name": "lora_name", + "type": "COMBO", + "linkIds": [ + 1768 + ], + "label": "lora", + "pos": [ + -28.99609375, + 3284 + ] + }, + { + "id": "c05ba793-3f43-4594-b7df-3f17fa3f99ba", + "name": "lora_name_1", + "type": "COMBO", + "linkIds": [ + 1769 + ], + "label": "ic_lora", + "pos": [ + -28.99609375, + 3304 + ] + }, + { + "id": "b475372d-89e7-44bb-995b-647f8e29c484", + "name": "strength_model", + "type": "FLOAT", + "linkIds": [ + 1770 + ], + "label": "lora_strength", + "pos": [ + -28.99609375, + 3324 + ] + }, + { + "id": "bfc27fa2-b100-413c-9c64-d38ab1ed5a2d", + "name": "value_2", + "type": "BOOLEAN", + "linkIds": [ + 1804 + ], + "label": "bypass_first_frame", + "pos": [ + -28.99609375, + 3344 + ] + } + ], + "outputs": [ + { + "id": "0c8c2dc0-c67c-4bc2-9e57-6aa00db2e3a9", + "name": "VIDEO", + "type": "VIDEO", + "linkIds": [ + 252 + ], + "localized_name": "VIDEO", + "pos": [ + 3644, + 3144 + ] + } + ], + "widgets": [], + "nodes": [ + { + "id": 101, + "type": "LTXVEmptyLatentAudio", + "pos": [ + 1180, + 3800 + ], + "size": [ + 280, + 170 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [ + { + "localized_name": "audio_vae", + "name": "audio_vae", + "type": "VAE", + "link": 205 + }, + { + "localized_name": "frames_number", + "name": "frames_number", + "type": "INT", + "widget": { + "name": "frames_number" + }, + "link": 1801 + }, + { + "localized_name": "frame_rate", + "name": "frame_rate", + "type": "INT", + "widget": { + "name": "frame_rate" + }, + "link": 207 + } + ], + "outputs": [ + { + "localized_name": "Latent", + "name": "Latent", + "type": "LATENT", + "links": [ + 245 + ] + } + ], + "properties": { + "Node name for S&R": "LTXVEmptyLatentAudio", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.5.2", + "widget_ue_connectable": {} + }, + "ver": "0.3.68" + }, + "widgets_values": [ + 97, + 25, + 1 + ] + }, + { + "id": 106, + "type": "LTXVCropGuides", + "pos": [ + 2430, + 2450 + ], + "size": [ + 280, + 120 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 290 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 292 + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "link": 215 + } + ], + "outputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "links": [] + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "links": [] + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 211 + ] + } + ], + "properties": { + "Node name for S&R": "LTXVCropGuides", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.5.2", + "widget_ue_connectable": {} + }, + "ver": "0.8.2" + }, + "widgets_values": [] + }, + { + "id": 108, + "type": "EmptyLTXVLatentVideo", + "pos": [ + 1180, + 3550 + ], + "size": [ + 280, + 200 + ], + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "localized_name": "width", + "name": "width", + "type": "INT", + "widget": { + "name": "width" + }, + "link": 1778 + }, + { + "localized_name": "height", + "name": "height", + "type": "INT", + "widget": { + "name": "height" + }, + "link": 1779 + }, + { + "localized_name": "length", + "name": "length", + "type": "INT", + "widget": { + "name": "length" + }, + "link": 1800 + } + ], + "outputs": [ + { + "localized_name": "LATENT", + "name": "LATENT", + "type": "LATENT", + "links": [ + 296 + ] + } + ], + "properties": { + "Node name for S&R": "EmptyLTXVLatentVideo", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.5.2", + "widget_ue_connectable": {} + }, + "ver": "0.3.60" + }, + "widgets_values": [ + 768, + 512, + 97, + 1 + ] + }, + { + "id": 109, + "type": "LTXVConditioning", + "pos": [ + 1180, + 3350 + ], + "size": [ + 280, + 130 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 221 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 222 + }, + { + "localized_name": "frame_rate", + "name": "frame_rate", + "type": "FLOAT", + "widget": { + "name": "frame_rate" + }, + "link": 223 + } + ], + "outputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "links": [ + 236 + ] + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "links": [ + 237 + ] + } + ], + "properties": { + "Node name for S&R": "LTXVConditioning", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.5.2", + "widget_ue_connectable": {} + }, + "ver": "0.3.56" + }, + "widgets_values": [ + 25 + ] + }, + { + "id": 114, + "type": "PrimitiveInt", + "pos": [ + 760, + 3840 + ], + "size": [ + 230, + 110 + ], + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "INT", + "widget": { + "name": "value" + }, + "link": 269 + } + ], + "outputs": [ + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 207, + 235 + ] + } + ], + "title": "Frame Rate(int)", + "properties": { + "Node name for S&R": "PrimitiveInt", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.5.2", + "widget_ue_connectable": {} + }, + "ver": "0.7.0" + }, + "widgets_values": [ + 25, + "fixed" + ] + }, + { + "id": 115, + "type": "LTXVAddGuide", + "pos": [ + 2030, + 3360 + ], + "size": [ + 280, + 310 + ], + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 236 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 237 + }, + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 307 + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "link": 289 + }, + { + "localized_name": "image", + "name": "image", + "type": "IMAGE", + "link": 1777 + }, + { + "localized_name": "attention_mask", + "name": "attention_mask", + "shape": 7, + "type": "MASK", + "link": null + }, + { + "localized_name": "iclora_parameters", + "name": "iclora_parameters", + "shape": 7, + "type": "IC_LORA_PARAMETERS", + "link": 288 + } + ], + "outputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "links": [ + 290, + 1791 + ] + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "links": [ + 292, + 1790 + ] + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 287 + ] + } + ], + "properties": { + "Node name for S&R": "LTXVAddGuide", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.7", + "widget_ue_connectable": {} + }, + "ver": "0.12.3" + }, + "widgets_values": [ + 0, + 1 + ] + }, + { + "id": 119, + "type": "LTXVConcatAVLatent", + "pos": [ + 2030, + 2390 + ], + "size": [ + 280, + 100 + ], + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + { + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "link": 287 + }, + { + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", + "link": 245 + } + ], + "outputs": [ + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 1789 + ] + } + ], + "properties": { + "Node name for S&R": "LTXVConcatAVLatent", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.5.2", + "widget_ue_connectable": {} + }, + "ver": "0.7.0" + }, + "widgets_values": [] + }, + { + "id": 123, + "type": "ComfyMathExpression", + "pos": [ + 770, + 4000 + ], + "size": [ + 230, + 80 + ], + "flags": { + "collapsed": true + }, + "order": 15, + "mode": 0, + "inputs": [ + { + "label": "a", + "localized_name": "values.a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 235 + }, + { + "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": [ + 223, + 234 + ] + }, + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [] + }, + { + "localized_name": "BOOL", + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "properties": { + "Node name for S&R": "ComfyMathExpression", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.7", + "widget_ue_connectable": {} + }, + "ver": "0.17.0" + }, + "widgets_values": [ + "a" + ] + }, + { + "id": 113, + "type": "PrimitiveInt", + "pos": [ + 760, + 3340 + ], + "size": [ + 230, + 110 + ], + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "INT", + "widget": { + "name": "value" + }, + "link": 266 + } + ], + "outputs": [ + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 1778 + ] + } + ], + "title": "Width", + "properties": { + "Node name for S&R": "PrimitiveInt", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.5.2", + "widget_ue_connectable": {} + }, + "ver": "0.7.0" + }, + "widgets_values": [ + 704, + "fixed" + ] + }, + { + "id": 98, + "type": "PrimitiveInt", + "pos": [ + 760, + 3490 + ], + "size": [ + 230, + 110 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "INT", + "widget": { + "name": "value" + }, + "link": 267 + } + ], + "outputs": [ + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 1779 + ] + } + ], + "title": "height", + "properties": { + "Node name for S&R": "PrimitiveInt", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.5.2", + "widget_ue_connectable": {} + }, + "ver": "0.7.0" + }, + "widgets_values": [ + 1280, + "fixed" + ] + }, + { + "id": 112, + "type": "CLIPTextEncode", + "pos": [ + 1320, + 2870 + ], + "size": [ + 590, + 200 + ], + "flags": { + "collapsed": false + }, + "order": 8, + "mode": 0, + "inputs": [ + { + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 230 + } + ], + "outputs": [ + { + "localized_name": "CONDITIONING", + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 222 + ] + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.5.2", + "widget_ue_connectable": {} + }, + "ver": "0.3.56" + }, + "widgets_values": [ + "blurry, out of focus, overexposed, underexposed, low contrast, washed out colors, excessive noise, grainy texture, poor lighting, flickering, motion blur, distorted proportions, unnatural skin tones, deformed facial features, asymmetrical face, missing facial features, extra limbs, disfigured hands, wrong hand count, artifacts around text, unreadable text on shirt or hat, incorrect lettering on cap (“PNTR”), incorrect t-shirt slogan (“JUST DO IT”), missing microphone, misplaced microphone, inconsistent perspective, camera shake, incorrect depth of field, background too sharp, background clutter, distracting reflections, harsh shadows, inconsistent lighting direction, color banding, cartoonish rendering, 3D CGI look, unrealistic materials, uncanny valley effect, incorrect ethnicity, wrong gender, exaggerated expressions, smiling, laughing, exaggerated sadness, wrong gaze direction, eyes looking at camera, mismatched lip sync, silent or muted audio, distorted voice, robotic voice, echo, background noise, off-sync audio, missing sniff sounds, incorrect dialogue, added dialogue, repetitive speech, jittery movement, awkward pauses, incorrect timing, unnatural transitions, inconsistent framing, tilted camera, missing door or shelves, missing shallow depth of field, flat lighting, inconsistent tone, cinematic oversaturation, stylized filters, or AI artifacts." + ], + "color": "#223", + "bgcolor": "#335" + }, + { + "id": 122, + "type": "CreateVideo", + "pos": [ + 2890, + 2900 + ], + "size": [ + 280, + 160 + ], + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [ + { + "localized_name": "images", + "name": "images", + "type": "IMAGE", + "link": 232 + }, + { + "localized_name": "audio", + "name": "audio", + "shape": 7, + "type": "AUDIO", + "link": 233 + }, + { + "localized_name": "fps", + "name": "fps", + "type": "FLOAT", + "widget": { + "name": "fps" + }, + "link": 234 + } + ], + "outputs": [ + { + "localized_name": "VIDEO", + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 252 + ] + } + ], + "properties": { + "Node name for S&R": "CreateVideo", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.7", + "widget_ue_connectable": {} + }, + "ver": "0.14.1" + }, + "widgets_values": [ + 24, + 8 + ] + }, + { + "id": 105, + "type": "VAEDecodeTiled", + "pos": [ + 2430, + 2630 + ], + "size": [ + 280, + 200 + ], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [ + { + "localized_name": "samples", + "name": "samples", + "type": "LATENT", + "link": 211 + }, + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 212 + } + ], + "outputs": [ + { + "localized_name": "IMAGE", + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 232 + ] + } + ], + "properties": { + "Node name for S&R": "VAEDecodeTiled", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.5.2", + "widget_ue_connectable": {} + }, + "ver": "0.7.0" + }, + "widgets_values": [ + 768, + 64, + 4096, + 64 + ] + }, + { + "id": 107, + "type": "LTXVAudioVAEDecode", + "pos": [ + 2430, + 2920 + ], + "size": [ + 280, + 100 + ], + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [ + { + "localized_name": "samples", + "name": "samples", + "type": "LATENT", + "link": 216 + }, + { + "label": "Audio VAE", + "localized_name": "audio_vae", + "name": "audio_vae", + "type": "VAE", + "link": 217 + } + ], + "outputs": [ + { + "localized_name": "Audio", + "name": "Audio", + "type": "AUDIO", + "links": [ + 233 + ] + } + ], + "properties": { + "Node name for S&R": "LTXVAudioVAEDecode", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.5.2", + "widget_ue_connectable": {} + }, + "ver": "0.7.0" + }, + "widgets_values": [] + }, + { + "id": 121, + "type": "LTXVSeparateAVLatent", + "pos": [ + 2040, + 3010 + ], + "size": [ + 250, + 100 + ], + "flags": {}, + "order": 13, + "mode": 0, + "inputs": [ + { + "localized_name": "av_latent", + "name": "av_latent", + "type": "LATENT", + "link": 1788 + } + ], + "outputs": [ + { + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "links": [ + 215 + ] + }, + { + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", + "links": [ + 216 + ] + } + ], + "properties": { + "Node name for S&R": "LTXVSeparateAVLatent", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.5.2", + "widget_ue_connectable": {} + }, + "ver": "0.5.1" + }, + "widgets_values": [] + }, + { + "id": 128, + "type": "CLIPTextEncode", + "pos": [ + 1310, + 2380 + ], + "size": [ + 620, + 420 + ], + "flags": {}, + "order": 18, + "mode": 0, + "inputs": [ + { + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 231 + }, + { + "localized_name": "text", + "name": "text", + "type": "STRING", + "widget": { + "name": "text" + }, + "link": 1808 + } + ], + "outputs": [ + { + "localized_name": "CONDITIONING", + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 221 + ] + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.5.2", + "widget_ue_connectable": {} + }, + "ver": "0.3.56" + }, + "widgets_values": [ + "A slow forward dolly shot on a bright, sunlit day in a lush jungle ruin. A lone figure in nature-themed armor stands before a weathered stone arch overgrown with ivy. A textured marble sphere wrapped in twisting vines levitates in the arch’s center, spinning slowly. As the camera glides forward, vines sway softly, leaves flutter in the light breeze. Strong golden sunlight streams through the canopy, illuminating the mossy ruins with bright, clear light. The scene feels vibrant and peaceful, with subtle natural motion." + ], + "color": "#232", + "bgcolor": "#353" + }, + { + "id": 127, + "type": "CheckpointLoaderSimple", + "pos": [ + 770, + 2380 + ], + "size": [ + 420, + 160 + ], + "flags": {}, + "order": 17, + "mode": 0, + "inputs": [ + { + "localized_name": "ckpt_name", + "name": "ckpt_name", + "type": "COMBO", + "widget": { + "name": "ckpt_name" + }, + "link": 276 + } + ], + "outputs": [ + { + "localized_name": "MODEL", + "name": "MODEL", + "type": "MODEL", + "links": [ + 279, + 313 + ] + }, + { + "localized_name": "CLIP", + "name": "CLIP", + "type": "CLIP", + "links": [] + }, + { + "localized_name": "VAE", + "name": "VAE", + "type": "VAE", + "links": [ + 212, + 306, + 307 + ] + } + ], + "properties": { + "Node name for S&R": "CheckpointLoaderSimple", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "models": [ + { + "name": "ltx-2.3-22b-distilled-fp8.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-distilled-fp8.safetensors", + "directory": "checkpoints" + } + ], + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.5.2", + "widget_ue_connectable": {} + }, + "ver": "0.10.0" + }, + "widgets_values": [ + "ltx-2.3-22b-distilled-fp8.safetensors" + ] + }, + { + "id": 126, + "type": "LTXVAudioVAELoader", + "pos": [ + 770, + 2590 + ], + "size": [ + 420, + 110 + ], + "flags": {}, + "order": 16, + "mode": 0, + "inputs": [ + { + "localized_name": "ckpt_name", + "name": "ckpt_name", + "type": "COMBO", + "widget": { + "name": "ckpt_name" + }, + "link": 272 + } + ], + "outputs": [ + { + "localized_name": "Audio VAE", + "name": "Audio VAE", + "type": "VAE", + "links": [ + 205, + 217 + ] + } + ], + "properties": { + "Node name for S&R": "LTXVAudioVAELoader", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "models": [ + { + "name": "ltx-2.3-22b-distilled-fp8.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-distilled-fp8.safetensors", + "directory": "checkpoints" + } + ], + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.5.2", + "widget_ue_connectable": {} + }, + "ver": "0.10.0" + }, + "widgets_values": [ + "ltx-2.3-22b-distilled-fp8.safetensors" + ] + }, + { + "id": 103, + "type": "LTXAVTextEncoderLoader", + "pos": [ + 770, + 2750 + ], + "size": [ + 410, + 170 + ], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [ + { + "localized_name": "text_encoder", + "name": "text_encoder", + "type": "COMBO", + "widget": { + "name": "text_encoder" + }, + "link": 273 + }, + { + "localized_name": "ckpt_name", + "name": "ckpt_name", + "type": "COMBO", + "widget": { + "name": "ckpt_name" + }, + "link": 275 + } + ], + "outputs": [ + { + "localized_name": "CLIP", + "name": "CLIP", + "type": "CLIP", + "links": [ + 230, + 231, + 314 + ] + } + ], + "properties": { + "Node name for S&R": "LTXAVTextEncoderLoader", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "models": [ + { + "name": "gemma_3_12B_it_fp4_mixed.safetensors", + "url": "https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors", + "directory": "text_encoders" + }, + { + "name": "ltx-2.3-22b-distilled-fp8.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-distilled-fp8.safetensors", + "directory": "checkpoints" + } + ], + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.5.2", + "widget_ue_connectable": {} + }, + "ver": "0.10.0" + }, + "widgets_values": [ + "gemma_3_12B_it_fp4_mixed.safetensors", + "ltx-2.3-22b-distilled-fp8.safetensors", + "default" + ] + }, + { + "id": 195, + "type": "LoraLoaderModelOnly", + "pos": [ + 750, + 3020 + ], + "size": [ + 470, + 140 + ], + "flags": {}, + "order": 19, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 279 + }, + { + "localized_name": "lora_name", + "name": "lora_name", + "type": "COMBO", + "widget": { + "name": "lora_name" + }, + "link": 1769 + }, + { + "localized_name": "strength_model", + "name": "strength_model", + "type": "FLOAT", + "widget": { + "name": "strength_model" + }, + "link": 1770 + } + ], + "outputs": [ + { + "localized_name": "MODEL", + "name": "MODEL", + "type": "MODEL", + "links": [ + 277, + 1792 + ] + } + ], + "properties": { + "Node name for S&R": "LoraLoaderModelOnly", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "models": [ + { + "name": "ltx-2.3-22b-ic-lora-ingredients-0.9.safetensors", + "url": "https://huggingface.co/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx-2.3-22b-ic-lora-ingredients-0.9.safetensors", + "directory": "loras" + } + ], + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ver": "0.22.0" + }, + "widgets_values": [ + "ltx-2.3-22b-ic-lora-ingredients-0.9.safetensors", + 1 + ], + "color": "#323", + "bgcolor": "#535" + }, + { + "id": 196, + "type": "GetICLoRAParameters", + "pos": [ + 1590, + 3630 + ], + "size": [ + 300, + 80 + ], + "flags": {}, + "order": 20, + "mode": 0, + "inputs": [ + { + "localized_name": "iclora_model", + "name": "iclora_model", + "type": "MODEL", + "link": 277 + } + ], + "outputs": [ + { + "localized_name": "iclora_parameters", + "name": "iclora_parameters", + "type": "IC_LORA_PARAMETERS", + "links": [ + 288 + ] + } + ], + "properties": { + "Node name for S&R": "GetICLoRAParameters", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ver": "0.22.0" + }, + "widgets_values": [], + "color": "#323", + "bgcolor": "#535" + }, + { + "id": 198, + "type": "LTXVImgToVideoInplace", + "pos": [ + 1580, + 3360 + ], + "size": [ + 270, + 180 + ], + "flags": {}, + "order": 21, + "mode": 0, + "inputs": [ + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 306 + }, + { + "localized_name": "image", + "name": "image", + "type": "IMAGE", + "link": 1786 + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "link": 296 + }, + { + "localized_name": "bypass", + "name": "bypass", + "type": "BOOLEAN", + "widget": { + "name": "bypass" + }, + "link": 1803 + } + ], + "outputs": [ + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 289 + ] + } + ], + "properties": { + "Node name for S&R": "LTXVImgToVideoInplace", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ver": "0.22.0" + }, + "widgets_values": [ + 1, + true + ] + }, + { + "id": 208, + "type": "LoraLoader", + "pos": [ + 770, + 1570 + ], + "size": [ + 380, + 230 + ], + "flags": {}, + "order": 22, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 313 + }, + { + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 314 + }, + { + "localized_name": "lora_name", + "name": "lora_name", + "type": "COMBO", + "widget": { + "name": "lora_name" + }, + "link": 1768 + } + ], + "outputs": [ + { + "localized_name": "MODEL", + "name": "MODEL", + "type": "MODEL", + "links": null + }, + { + "localized_name": "CLIP", + "name": "CLIP", + "type": "CLIP", + "links": [ + 309 + ] + } + ], + "properties": { + "Node name for S&R": "LoraLoader", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "models": [ + { + "name": "gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", + "url": "https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", + "directory": "loras" + } + ], + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ver": "0.16.3" + }, + "widgets_values": [ + "gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", + 1, + 1 + ] + }, + { + "id": 209, + "type": "TextGenerateLTX2Prompt", + "pos": [ + 1200, + 1570 + ], + "size": [ + 400, + 420 + ], + "flags": { + "collapsed": false + }, + "order": 23, + "mode": 0, + "inputs": [ + { + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 309 + }, + { + "localized_name": "image", + "name": "image", + "shape": 7, + "type": "IMAGE", + "link": 1735 + }, + { + "localized_name": "video", + "name": "video", + "shape": 7, + "type": "IMAGE", + "link": null + }, + { + "localized_name": "audio", + "name": "audio", + "shape": 7, + "type": "AUDIO", + "link": null + }, + { + "localized_name": "prompt", + "name": "prompt", + "type": "STRING", + "widget": { + "name": "prompt" + }, + "link": 316 + } + ], + "outputs": [ + { + "localized_name": "generated_text", + "name": "generated_text", + "type": "STRING", + "links": [ + 311 + ] + } + ], + "properties": { + "Node name for S&R": "TextGenerateLTX2Prompt", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ver": "0.16.3" + }, + "widgets_values": [ + "### Reference Sheet Description **Top Row Left (Character):** An anthropomorphic bipedal German Shepherd news anchor with realistic brown, tan, and black fur, a calm professional expression, and thin round copper-bronze framed glasses. He is shown in close-up portraits and full-body front, three-quarter, side, and back views standing upright like a person, with a humanoid torso and limbs and a long bushy German Shepherd tail. He wears a vibrant long-sleeve button-down shirt with an abstract multicolored pink-purple-turquoise-yellow woven pattern, dark charcoal dress pants, and dark leather dress shoes. **Top Row Right (Prop):** A professional black studio condenser microphone on a short circular desk stand shown from multiple angles, plus black over-the-ear wireless earpieces / headsets for broadcast cues. **Middle Row Right (Prop):** A flat product view of the same vibrant long-sleeve multicolored patterned button-down shirt, clearly showing the abstract pink, purple, turquoise, and yellow woven texture. **Bottom Row (Setting):** A wide shot of a high-end professional news studio with a large curved dark teal anchor desk in the foreground, a massive digital backdrop screen displaying bold white \"NEWS\" lettering over soft blue-green abstract graphics, and polished cinematic broadcast lighting with studio fixtures visible around the set.\n\n### Target Description A cozy, cinematic scene inside a high-end professional news studio. The camera begins on a wide establishing shot of the large curved dark teal anchor desk and the soft-focus blue-green \"NEWS\" backdrop, then smoothly pushes in to a steady medium shot of the anthropomorphic bipedal German Shepherd news anchor seated behind the desk. He has realistic brown-tan-black fur, thin round copper-bronze glasses, and a calm professional expression. He wears the vibrant long-sleeve multicolored pink-purple-turquoise-yellow patterned button-down shirt with dark charcoal dress pants. His paw-like hands rest on the desk near the black studio condenser microphone. The studio is bathed in polished cinematic broadcast light from the backdrop and overhead fixtures. His initial expression is focused and composed, then he leans slightly toward the microphone, softens into a confident on-air smile, and speaks clearly to camera: \"Good evening, and welcome to tonight's top stories.\" He pauses briefly, glances down at the desk, then looks back up and continues: \"Here's what you need to know.\" The background \"NEWS\" screen and studio lights remain softly detailed behind him, emphasizing his face, glasses, and colorful shirt under the clean broadcast lighting.", + 2048, + "on", + 0.7, + 64, + 0.95, + 0.05, + 1.05, + 0, + 0, + false, + true + ] + }, + { + "id": 210, + "type": "PreviewAny", + "pos": [ + 2040, + 1590 + ], + "size": [ + 510, + 360 + ], + "flags": {}, + "order": 24, + "mode": 4, + "inputs": [ + { + "localized_name": "source", + "name": "source", + "type": "*", + "link": 310 + } + ], + "outputs": [ + { + "localized_name": "STRING", + "name": "STRING", + "type": "STRING", + "links": [ + 1808 + ] + } + ], + "properties": { + "Node name for S&R": "PreviewAny", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ver": "0.16.3" + }, + "widgets_values": [ + null, + null, + null + ] + }, + { + "id": 211, + "type": "ComfySwitchNode", + "pos": [ + 1730, + 1980 + ], + "size": [ + 270, + 130 + ], + "flags": {}, + "order": 25, + "mode": 0, + "inputs": [ + { + "localized_name": "on_false", + "name": "on_false", + "type": "STRING", + "link": 317 + }, + { + "localized_name": "on_true", + "name": "on_true", + "type": "STRING", + "link": 311 + }, + { + "localized_name": "switch", + "name": "switch", + "type": "BOOLEAN", + "widget": { + "name": "switch" + }, + "link": 312 + } + ], + "outputs": [ + { + "localized_name": "output", + "name": "output", + "type": "STRING", + "links": [ + 310 + ] + } + ], + "properties": { + "Node name for S&R": "ComfySwitchNode", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ver": "0.22.0" + }, + "widgets_values": [ + false + ] + }, + { + "id": 212, + "type": "PrimitiveBoolean", + "pos": [ + 770, + 2050 + ], + "size": [ + 270, + 100 + ], + "flags": {}, + "order": 26, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "BOOLEAN", + "widget": { + "name": "value" + }, + "link": 315 + } + ], + "outputs": [ + { + "localized_name": "BOOLEAN", + "name": "BOOLEAN", + "type": "BOOLEAN", + "links": [ + 312 + ] + } + ], + "title": "Boolean (Enable Prompt Enhance)", + "properties": { + "Node name for S&R": "PrimitiveBoolean", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ver": "0.22.0" + }, + "widgets_values": [ + false + ] + }, + { + "id": 704, + "type": "KSampler", + "pos": [ + 2030, + 2570 + ], + "size": [ + 270, + 350 + ], + "flags": {}, + "order": 27, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 1792 + }, + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 1791 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 1790 + }, + { + "localized_name": "latent_image", + "name": "latent_image", + "type": "LATENT", + "link": 1789 + }, + { + "localized_name": "seed", + "name": "seed", + "type": "INT", + "widget": { + "name": "seed" + }, + "link": 1793 + } + ], + "outputs": [ + { + "localized_name": "LATENT", + "name": "LATENT", + "type": "LATENT", + "links": [ + 1788 + ] + } + ], + "properties": { + "Node name for S&R": "KSampler", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ver": "0.22.0" + }, + "widgets_values": [ + 288370150520961, + "randomize", + 8, + 1, + "euler_ancestral", + "linear_quadratic", + 1 + ] + }, + { + "id": 710, + "type": "GetImageSize", + "pos": [ + 770, + 3650 + ], + "size": [ + 230, + 120 + ], + "flags": {}, + "order": 28, + "mode": 0, + "inputs": [ + { + "localized_name": "image", + "name": "image", + "type": "IMAGE", + "link": 1802 + } + ], + "outputs": [ + { + "localized_name": "width", + "name": "width", + "type": "INT", + "links": null + }, + { + "localized_name": "height", + "name": "height", + "type": "INT", + "links": null + }, + { + "localized_name": "batch_size", + "name": "batch_size", + "type": "INT", + "links": [ + 1800, + 1801 + ] + } + ], + "properties": { + "Node name for S&R": "GetImageSize" + }, + "widgets_values": [] + }, + { + "id": 711, + "type": "PrimitiveBoolean", + "pos": [ + 750, + 4080 + ], + "size": [ + 270, + 100 + ], + "flags": {}, + "order": 29, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "BOOLEAN", + "widget": { + "name": "value" + }, + "link": 1804 + } + ], + "outputs": [ + { + "localized_name": "BOOLEAN", + "name": "BOOLEAN", + "type": "BOOLEAN", + "links": [ + 1803 + ] + } + ], + "properties": { + "Node name for S&R": "PrimitiveBoolean" + }, + "widgets_values": [ + true + ] + } + ], + "groups": [ + { + "id": 1, + "title": "Conditioning", + "bounding": [ + 1050, + 3250, + 1700, + 960 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 2, + "title": "Settings", + "bounding": [ + 730, + 3250, + 300, + 960 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 5, + "title": "Model", + "bounding": [ + 730, + 2240, + 500, + 980 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 6, + "title": "Prompt", + "bounding": [ + 1260, + 2240, + 680, + 980 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 7, + "title": "Sampling", + "bounding": [ + 1970, + 2240, + 380, + 980 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 8, + "title": "Decoding", + "bounding": [ + 2380, + 2240, + 370, + 980 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 24, + "title": "Prompt Enhancement", + "bounding": [ + 730, + 1490, + 2020, + 720 + ], + "color": "#3f789e", + "flags": {} + } + ], + "links": [ + { + "id": 205, + "origin_id": 126, + "origin_slot": 0, + "target_id": 101, + "target_slot": 0, + "type": "VAE" + }, + { + "id": 207, + "origin_id": 114, + "origin_slot": 0, + "target_id": 101, + "target_slot": 2, + "type": "INT" + }, + { + "id": 215, + "origin_id": 121, + "origin_slot": 0, + "target_id": 106, + "target_slot": 2, + "type": "LATENT" + }, + { + "id": 221, + "origin_id": 128, + "origin_slot": 0, + "target_id": 109, + "target_slot": 0, + "type": "CONDITIONING" + }, + { + "id": 222, + "origin_id": 112, + "origin_slot": 0, + "target_id": 109, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 223, + "origin_id": 123, + "origin_slot": 0, + "target_id": 109, + "target_slot": 2, + "type": "FLOAT" + }, + { + "id": 236, + "origin_id": 109, + "origin_slot": 0, + "target_id": 115, + "target_slot": 0, + "type": "CONDITIONING" + }, + { + "id": 237, + "origin_id": 109, + "origin_slot": 1, + "target_id": 115, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 245, + "origin_id": 101, + "origin_slot": 0, + "target_id": 119, + "target_slot": 1, + "type": "LATENT" + }, + { + "id": 235, + "origin_id": 114, + "origin_slot": 0, + "target_id": 123, + "target_slot": 0, + "type": "INT" + }, + { + "id": 230, + "origin_id": 103, + "origin_slot": 0, + "target_id": 112, + "target_slot": 0, + "type": "CLIP" + }, + { + "id": 232, + "origin_id": 105, + "origin_slot": 0, + "target_id": 122, + "target_slot": 0, + "type": "IMAGE" + }, + { + "id": 233, + "origin_id": 107, + "origin_slot": 0, + "target_id": 122, + "target_slot": 1, + "type": "AUDIO" + }, + { + "id": 234, + "origin_id": 123, + "origin_slot": 0, + "target_id": 122, + "target_slot": 2, + "type": "FLOAT" + }, + { + "id": 211, + "origin_id": 106, + "origin_slot": 2, + "target_id": 105, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 212, + "origin_id": 127, + "origin_slot": 2, + "target_id": 105, + "target_slot": 1, + "type": "VAE" + }, + { + "id": 216, + "origin_id": 121, + "origin_slot": 1, + "target_id": 107, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 217, + "origin_id": 126, + "origin_slot": 0, + "target_id": 107, + "target_slot": 1, + "type": "VAE" + }, + { + "id": 231, + "origin_id": 103, + "origin_slot": 0, + "target_id": 128, + "target_slot": 0, + "type": "CLIP" + }, + { + "id": 252, + "origin_id": 122, + "origin_slot": 0, + "target_id": -20, + "target_slot": 0, + "type": "VIDEO" + }, + { + "id": 266, + "origin_id": -10, + "origin_slot": 4, + "target_id": 113, + "target_slot": 0, + "type": "INT" + }, + { + "id": 267, + "origin_id": -10, + "origin_slot": 5, + "target_id": 98, + "target_slot": 0, + "type": "INT" + }, + { + "id": 269, + "origin_id": -10, + "origin_slot": 6, + "target_id": 114, + "target_slot": 0, + "type": "INT" + }, + { + "id": 272, + "origin_id": -10, + "origin_slot": 8, + "target_id": 126, + "target_slot": 0, + "type": "COMBO" + }, + { + "id": 273, + "origin_id": -10, + "origin_slot": 9, + "target_id": 103, + "target_slot": 0, + "type": "COMBO" + }, + { + "id": 275, + "origin_id": -10, + "origin_slot": 8, + "target_id": 103, + "target_slot": 1, + "type": "COMBO" + }, + { + "id": 276, + "origin_id": -10, + "origin_slot": 8, + "target_id": 127, + "target_slot": 0, + "type": "COMBO" + }, + { + "id": 277, + "origin_id": 195, + "origin_slot": 0, + "target_id": 196, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 279, + "origin_id": 127, + "origin_slot": 0, + "target_id": 195, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 287, + "origin_id": 115, + "origin_slot": 2, + "target_id": 119, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 288, + "origin_id": 196, + "origin_slot": 0, + "target_id": 115, + "target_slot": 6, + "type": "IC_LORA_PARAMETERS" + }, + { + "id": 289, + "origin_id": 198, + "origin_slot": 0, + "target_id": 115, + "target_slot": 3, + "type": "LATENT" + }, + { + "id": 290, + "origin_id": 115, + "origin_slot": 0, + "target_id": 106, + "target_slot": 0, + "type": "CONDITIONING" + }, + { + "id": 292, + "origin_id": 115, + "origin_slot": 1, + "target_id": 106, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 296, + "origin_id": 108, + "origin_slot": 0, + "target_id": 198, + "target_slot": 2, + "type": "LATENT" + }, + { + "id": 306, + "origin_id": 127, + "origin_slot": 2, + "target_id": 198, + "target_slot": 0, + "type": "VAE" + }, + { + "id": 307, + "origin_id": 127, + "origin_slot": 2, + "target_id": 115, + "target_slot": 2, + "type": "VAE" + }, + { + "id": 309, + "origin_id": 208, + "origin_slot": 1, + "target_id": 209, + "target_slot": 0, + "type": "CLIP" + }, + { + "id": 310, + "origin_id": 211, + "origin_slot": 0, + "target_id": 210, + "target_slot": 0, + "type": "*" + }, + { + "id": 311, + "origin_id": 209, + "origin_slot": 0, + "target_id": 211, + "target_slot": 1, + "type": "STRING" + }, + { + "id": 312, + "origin_id": 212, + "origin_slot": 0, + "target_id": 211, + "target_slot": 2, + "type": "BOOLEAN" + }, + { + "id": 313, + "origin_id": 127, + "origin_slot": 0, + "target_id": 208, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 314, + "origin_id": 103, + "origin_slot": 0, + "target_id": 208, + "target_slot": 1, + "type": "CLIP" + }, + { + "id": 315, + "origin_id": -10, + "origin_slot": 3, + "target_id": 212, + "target_slot": 0, + "type": "BOOLEAN" + }, + { + "id": 316, + "origin_id": -10, + "origin_slot": 2, + "target_id": 209, + "target_slot": 4, + "type": "STRING" + }, + { + "id": 317, + "origin_id": -10, + "origin_slot": 2, + "target_id": 211, + "target_slot": 0, + "type": "STRING" + }, + { + "id": 1735, + "origin_id": -10, + "origin_slot": 0, + "target_id": 209, + "target_slot": 1, + "type": "IMAGE" + }, + { + "id": 1768, + "origin_id": -10, + "origin_slot": 10, + "target_id": 208, + "target_slot": 2, + "type": "COMBO" + }, + { + "id": 1769, + "origin_id": -10, + "origin_slot": 11, + "target_id": 195, + "target_slot": 1, + "type": "COMBO" + }, + { + "id": 1770, + "origin_id": -10, + "origin_slot": 12, + "target_id": 195, + "target_slot": 2, + "type": "FLOAT" + }, + { + "id": 1777, + "origin_id": -10, + "origin_slot": 1, + "target_id": 115, + "target_slot": 4, + "type": "IMAGE" + }, + { + "id": 1778, + "origin_id": 113, + "origin_slot": 0, + "target_id": 108, + "target_slot": 0, + "type": "INT" + }, + { + "id": 1779, + "origin_id": 98, + "origin_slot": 0, + "target_id": 108, + "target_slot": 1, + "type": "INT" + }, + { + "id": 1786, + "origin_id": -10, + "origin_slot": 0, + "target_id": 198, + "target_slot": 1, + "type": "IMAGE" + }, + { + "id": 1788, + "origin_id": 704, + "origin_slot": 0, + "target_id": 121, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 1789, + "origin_id": 119, + "origin_slot": 0, + "target_id": 704, + "target_slot": 3, + "type": "LATENT" + }, + { + "id": 1790, + "origin_id": 115, + "origin_slot": 1, + "target_id": 704, + "target_slot": 2, + "type": "CONDITIONING" + }, + { + "id": 1791, + "origin_id": 115, + "origin_slot": 0, + "target_id": 704, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 1792, + "origin_id": 195, + "origin_slot": 0, + "target_id": 704, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 1793, + "origin_id": -10, + "origin_slot": 7, + "target_id": 704, + "target_slot": 4, + "type": "INT" + }, + { + "id": 1800, + "origin_id": 710, + "origin_slot": 2, + "target_id": 108, + "target_slot": 2, + "type": "INT" + }, + { + "id": 1801, + "origin_id": 710, + "origin_slot": 2, + "target_id": 101, + "target_slot": 1, + "type": "INT" + }, + { + "id": 1802, + "origin_id": -10, + "origin_slot": 1, + "target_id": 710, + "target_slot": 0, + "type": "IMAGE" + }, + { + "id": 1803, + "origin_id": 711, + "origin_slot": 0, + "target_id": 198, + "target_slot": 3, + "type": "BOOLEAN" + }, + { + "id": 1804, + "origin_id": -10, + "origin_slot": 13, + "target_id": 711, + "target_slot": 0, + "type": "BOOLEAN" + }, + { + "id": 1808, + "origin_id": 210, + "origin_slot": 0, + "target_id": 128, + "target_slot": 1, + "type": "STRING" + } + ], + "extra": { + "ue_links": [] + } + } + ] + }, + "config": {}, + "extra": { + "VHS_KeepIntermediate": true, + "VHS_MetadataImage": true, + "VHS_latentpreview": false, + "VHS_latentpreviewrate": 0, + "frontendVersion": "1.45.15", + "ue_links": [], + "workflowRendererVersion": "Vue-corrected", + "ds": { + "scale": 0.5959744833082783, + "offset": [ + 2409.0282524930844, + -1818.184424107724 + ] + } + }, + "version": 0.4 +} \ No newline at end of file diff --git a/docs/serviceTemplates/workflows/ocean_ugc_testimonial.json b/docs/serviceTemplates/workflows/ocean_ugc_testimonial.json deleted file mode 100644 index fdc22939b..000000000 --- a/docs/serviceTemplates/workflows/ocean_ugc_testimonial.json +++ /dev/null @@ -1,5167 +0,0 @@ -{ - "id": "07824bbb-6672-4bb0-ac36-4313a519e35b", - "revision": 0, - "last_node_id": 349, - "last_link_id": 762, - "nodes": [ - { - "id": 103, - "type": "MarkdownNote", - "pos": [ - -1220, - 3530 - ], - "size": [ - 750, - 1191.734375 - ], - "flags": {}, - "order": 0, - "mode": 0, - "inputs": [], - "outputs": [], - "title": "Model Links", - "properties": {}, - "widgets_values": [ - "- Huggingface: [Lightricks/LTX-2.3](https://huggingface.co/Lightricks/LTX-2.3/)\n- Github: [LTX-2](https://github.com/Lightricks/LTX-2)\n\n## LTX-2.3 Prompting Tips\n\n1. **Core Actions**: Describe events and actions as they occur over time \n2. **Visual Details**: Describe all visual details you want to appear in the video \n3. **Audio**: Describe sounds and dialogue needed for the scene\n\n## Report LTX-2.3 Issues\nTo report any issues when running this workflow, [go to GitHub](https://github.com/Lightricks/ComfyUI-LTXVideo/issues)\n\n## Model Links\n\n**checkpoints**\n\n- [ltx-2.3-22b-dev-fp8.safetensors](https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors)\n\n**loras**\n\n- [ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors](https://huggingface.co/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors)\n- [gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors](https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors)\n\n**latent_upscale_models**\n\n- [ltx-2.3-spatial-upscaler-x2-1.1.safetensors](https://huggingface.co/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors)\n\n\n## Model Storage Location\n\n```\n\ud83d\udcc2 ComfyUI/\n\u251c\u2500\u2500 \ud83d\udcc2 models/\n\u2502 \u251c\u2500\u2500 \ud83d\udcc2 checkpoints/\n\u2502 \u2502 \u2514\u2500\u2500 ltx-2.3-22b-dev-fp8.safetensors\n\u2502 \u251c\u2500\u2500 \ud83d\udcc2 loras/\n\u2502 \u2502 \u251c\u2500\u2500 ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors\n\u2502 \u2502 \u2514\u2500\u2500 gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\n\u2502 \u2514\u2500\u2500 \ud83d\udcc2 latent_upscale_models/\n\u2502 \u2514\u2500\u2500 ltx-2.3-spatial-upscaler-x2-1.1.safetensors\n```\n\n## Report Issue\n\nNote: Please update ComfyUI first ([guide](https://docs.comfy.org/installation/update_comfyui)) and prepare required models. Desktop/Cloud updates follow stable releases, so some nightly-supported models may not be available yet.\n\n- Cannot run / runtime errors: [ComfyUI/issues](https://github.com/Comfy-Org/ComfyUI/issues)\n- UI / frontend issues: [ComfyUI_frontend/issues](https://github.com/Comfy-Org/ComfyUI_frontend/issues)\n- Workflow issues: [workflow_templates/issues](https://github.com/Comfy-Org/workflow_templates/issues)\n" - ], - "color": "#222", - "bgcolor": "#000" - }, - { - "id": 269, - "type": "LoadImage", - "pos": [ - -440, - 3530 - ], - "size": [ - 400, - 480 - ], - "flags": {}, - "order": 1, - "mode": 0, - "inputs": [], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 726 - ] - }, - { - "name": "MASK", - "type": "MASK", - "links": null - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "cactus_man.png", - "image" - ] - }, - { - "id": 339, - "type": "RecordAudio", - "pos": [ - -440, - 4330 - ], - "size": [ - 400, - 160 - ], - "flags": {}, - "order": 2, - "mode": 4, - "inputs": [], - "outputs": [ - { - "name": "AUDIO", - "type": "AUDIO", - "links": null - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "RecordAudio" - }, - "widgets_values": [ - "", - "" - ] - }, - { - "id": 341, - "type": "SaveVideo", - "pos": [ - 430, - 3530 - ], - "size": [ - 580, - 580 - ], - "flags": {}, - "order": 5, - "mode": 0, - "inputs": [ - { - "name": "video", - "type": "VIDEO", - "link": 741 - } - ], - "outputs": [], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "SaveVideo" - }, - "widgets_values": [ - "ocean_ugc_testimonial", - "auto", - "auto" - ] - }, - { - "id": 276, - "type": "LoadAudio", - "pos": [ - -440, - 4070 - ], - "size": [ - 400, - 180 - ], - "flags": {}, - "order": 3, - "mode": 0, - "inputs": [], - "outputs": [ - { - "name": "AUDIO", - "type": "AUDIO", - "links": [ - 727 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "LoadAudio" - }, - "widgets_values": [ - "ltx_23_audio.mp3", - null, - null - ] - }, - { - "id": 340, - "type": "98ee9e5b-467b-40aa-a534-36033f27d0b4", - "pos": [ - 0, - 3530 - ], - "size": [ - 400, - 610 - ], - "flags": {}, - "order": 4, - "mode": 0, - "inputs": [ - { - "label": "first_frame", - "name": "input", - "type": "IMAGE,MASK", - "link": 726 - }, - { - "name": "audio", - "type": "AUDIO", - "link": 727 - }, - { - "label": "prompt", - "name": "value", - "type": "STRING", - "widget": { - "name": "value" - }, - "link": null - }, - { - "label": "prompt_enhance", - "name": "value_5", - "type": "BOOLEAN", - "widget": { - "name": "value_5" - }, - "link": null - }, - { - "label": "width", - "name": "value_1", - "type": "INT", - "widget": { - "name": "value_1" - }, - "link": null - }, - { - "label": "height", - "name": "value_2", - "type": "INT", - "widget": { - "name": "value_2" - }, - "link": null - }, - { - "label": "audio_start", - "name": "start_index", - "type": "FLOAT", - "widget": { - "name": "start_index" - }, - "link": null - }, - { - "label": "duration", - "name": "value_4", - "type": "FLOAT", - "widget": { - "name": "value_4" - }, - "link": null - }, - { - "label": "fps", - "name": "value_3", - "type": "INT", - "widget": { - "name": "value_3" - }, - "link": null - }, - { - "label": "seed", - "name": "noise_seed", - "type": "INT", - "widget": { - "name": "noise_seed" - }, - "link": null - }, - { - "label": "distilled_lora", - "name": "lora_name", - "type": "COMBO", - "widget": { - "name": "lora_name" - }, - "link": null - }, - { - "label": "upscale_model", - "name": "model_name", - "type": "COMBO", - "widget": { - "name": "model_name" - }, - "link": null - }, - { - "label": "lora", - "name": "lora_name_1", - "type": "COMBO", - "widget": { - "name": "lora_name_1" - }, - "link": null - } - ], - "outputs": [ - { - "name": "VIDEO", - "type": "VIDEO", - "links": [ - 741 - ] - } - ], - "properties": { - "proxyWidgets": [ - [ - "319", - "value" - ], - [ - "349", - "value" - ], - [ - "330", - "value" - ], - [ - "324", - "value" - ], - [ - "332", - "start_index" - ], - [ - "331", - "value" - ], - [ - "323", - "value" - ], - [ - "286", - "noise_seed" - ], - [ - "317", - "ckpt_name" - ], - [ - "293", - "lora_name" - ], - [ - "318", - "text_encoder" - ], - [ - "313", - "model_name" - ], - [ - "345", - "lora_name" - ] - ], - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "ue_properties": { - "widget_ue_connectable": { - "value": true, - "value_1": true, - "value_2": true, - "value_3": true, - "value_4": true, - "value_5": true, - "start_index": true, - "lora_name": true, - "model_name": true - } - } - }, - "widgets_values": [] - } - ], - "links": [ - [ - 726, - 269, - 0, - 340, - 0, - "IMAGE" - ], - [ - 727, - 276, - 0, - 340, - 1, - "AUDIO" - ], - [ - 741, - 340, - 0, - 341, - 0, - "VIDEO" - ] - ], - "groups": [], - "definitions": { - "subgraphs": [ - { - "id": "98ee9e5b-467b-40aa-a534-36033f27d0b4", - "version": 1, - "state": { - "lastGroupId": 27, - "lastNodeId": 349, - "lastLinkId": 762, - "lastRerouteId": 0 - }, - "revision": 0, - "config": {}, - "name": "Video Generation (LTX-2.3)", - "inputNode": { - "id": -10, - "bounding": [ - -140, - 3700, - 142.98046875, - 348 - ] - }, - "outputNode": { - "id": -20, - "bounding": [ - 5320, - 4030, - 128, - 68 - ] - }, - "inputs": [ - { - "id": "b16ca2a6-1c07-4c28-bc42-7aae63573f3b", - "name": "input", - "type": "IMAGE,MASK", - "linkIds": [ - 698 - ], - "localized_name": "input", - "label": "first_frame", - "pos": [ - -21.01953125, - 3724 - ] - }, - { - "id": "104b358d-b776-4554-8154-9d235cda41c0", - "name": "audio", - "type": "AUDIO", - "linkIds": [ - 709 - ], - "localized_name": "audio", - "pos": [ - -21.01953125, - 3744 - ] - }, - { - "id": "fa2f98f8-7318-4426-aa1c-27469bbca13f", - "name": "value", - "type": "STRING", - "linkIds": [ - 729 - ], - "label": "prompt", - "pos": [ - -21.01953125, - 3764 - ] - }, - { - "id": "f1aec0c2-3b9a-42ba-b790-cab8602e67a5", - "name": "value_5", - "type": "BOOLEAN", - "linkIds": [ - 759 - ], - "label": "prompt_enhance", - "pos": [ - -21.01953125, - 3784 - ] - }, - { - "id": "f45f5c0f-4d19-42d1-bfb7-740c91c0fdb6", - "name": "value_1", - "type": "INT", - "linkIds": [ - 730 - ], - "label": "width", - "pos": [ - -21.01953125, - 3804 - ] - }, - { - "id": "a0414d84-a2b3-46c1-a4b4-b4729376ccef", - "name": "value_2", - "type": "INT", - "linkIds": [ - 731 - ], - "label": "height", - "pos": [ - -21.01953125, - 3824 - ] - }, - { - "id": "499cc4e8-be6e-4b0e-b599-1d50339916c6", - "name": "start_index", - "type": "FLOAT", - "linkIds": [ - 733 - ], - "label": "audio_start", - "pos": [ - -21.01953125, - 3844 - ] - }, - { - "id": "13c9ac19-d8c7-4a44-9f31-97969f6fa165", - "name": "value_4", - "type": "FLOAT", - "linkIds": [ - 734 - ], - "label": "duration", - "pos": [ - -21.01953125, - 3864 - ] - }, - { - "id": "6c555a9a-2881-448b-92f9-f23c68de4e26", - "name": "value_3", - "type": "INT", - "linkIds": [ - 732 - ], - "label": "fps", - "pos": [ - -21.01953125, - 3884 - ] - }, - { - "id": "cf644152-3b39-4fbb-8946-6484c25a48d5", - "name": "noise_seed", - "type": "INT", - "linkIds": [ - 761 - ], - "label": "seed", - "pos": [ - -21.01953125, - 3904 - ] - }, - { - "id": "2c4a6dcd-8cb9-4058-ba4d-7379641317c7", - "name": "ckpt_name", - "type": "COMBO", - "linkIds": [ - 735, - 736, - 737 - ], - "pos": [ - -21.01953125, - 3924 - ] - }, - { - "id": "50329cb8-e54e-45bf-b7ae-d4fb7919c46e", - "name": "lora_name", - "type": "COMBO", - "linkIds": [ - 738 - ], - "label": "distilled_lora", - "pos": [ - -21.01953125, - 3944 - ] - }, - { - "id": "6032f234-532a-4f8f-b91c-1de13178983b", - "name": "text_encoder", - "type": "COMBO", - "linkIds": [ - 739 - ], - "pos": [ - -21.01953125, - 3964 - ] - }, - { - "id": "9f8f45c4-bf9e-4cfb-a289-72cfc4faea8b", - "name": "model_name", - "type": "COMBO", - "linkIds": [ - 740 - ], - "label": "upscale_model", - "pos": [ - -21.01953125, - 3984 - ] - }, - { - "id": "8745bf6c-2c6c-4e4c-a046-930d27917750", - "name": "lora_name_1", - "type": "COMBO", - "linkIds": [ - 760 - ], - "label": "lora", - "pos": [ - -21.01953125, - 4004 - ] - } - ], - "outputs": [ - { - "id": "05fff727-0167-4215-b9ae-17ac246e5734", - "name": "VIDEO", - "type": "VIDEO", - "linkIds": [ - 699 - ], - "localized_name": "VIDEO", - "pos": [ - 5344, - 4054 - ] - } - ], - "widgets": [], - "nodes": [ - { - "id": 285, - "type": "RandomNoise", - "pos": [ - 3970, - 3430 - ], - "size": [ - 280, - 110 - ], - "flags": {}, - "order": 0, - "mode": 0, - "inputs": [], - "outputs": [ - { - "localized_name": "NOISE", - "name": "NOISE", - "type": "NOISE", - "links": [ - 687 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.3.75", - "Node name for S&R": "RandomNoise" - }, - "widgets_values": [ - 42, - "fixed" - ] - }, - { - "id": 286, - "type": "RandomNoise", - "pos": [ - 2330, - 3420 - ], - "size": [ - 280, - 110 - ], - "flags": {}, - "order": 6, - "mode": 0, - "inputs": [ - { - "localized_name": "noise_seed", - "name": "noise_seed", - "type": "INT", - "widget": { - "name": "noise_seed" - }, - "link": 761 - } - ], - "outputs": [ - { - "localized_name": "NOISE", - "name": "NOISE", - "type": "NOISE", - "links": [ - 650 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.3.56", - "Node name for S&R": "RandomNoise" - }, - "widgets_values": [ - 225158785956033, - "randomize" - ] - }, - { - "id": 287, - "type": "LTXVConcatAVLatent", - "pos": [ - 3970, - 4130 - ], - "size": [ - 280, - 100 - ], - "flags": {}, - "order": 7, - "mode": 0, - "inputs": [ - { - "localized_name": "video_latent", - "name": "video_latent", - "type": "LATENT", - "link": 642 - }, - { - "localized_name": "audio_latent", - "name": "audio_latent", - "type": "LATENT", - "link": 643 - } - ], - "outputs": [ - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "links": [ - 691 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.5.1", - "Node name for S&R": "LTXVConcatAVLatent" - }, - "widgets_values": [] - }, - { - "id": 288, - "type": "KSamplerSelect", - "pos": [ - 3970, - 3790 - ], - "size": [ - 280, - 110 - ], - "flags": {}, - "order": 1, - "mode": 0, - "inputs": [], - "outputs": [ - { - "localized_name": "SAMPLER", - "name": "SAMPLER", - "type": "SAMPLER", - "links": [ - 689 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.3.75", - "Node name for S&R": "KSamplerSelect" - }, - "widgets_values": [ - "euler" - ] - }, - { - "id": 289, - "type": "ManualSigmas", - "pos": [ - 3970, - 3960 - ], - "size": [ - 280, - 110 - ], - "flags": {}, - "order": 2, - "mode": 0, - "inputs": [], - "outputs": [ - { - "localized_name": "SIGMAS", - "name": "SIGMAS", - "type": "SIGMAS", - "links": [ - 690 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.5.1", - "Node name for S&R": "ManualSigmas" - }, - "widgets_values": [ - "0.85, 0.7250, 0.4219, 0.0" - ] - }, - { - "id": 290, - "type": "CFGGuider", - "pos": [ - 3970, - 3580 - ], - "size": [ - 280, - 160 - ], - "flags": {}, - "order": 8, - "mode": 0, - "inputs": [ - { - "localized_name": "model", - "name": "model", - "type": "MODEL", - "link": 644 - }, - { - "localized_name": "positive", - "name": "positive", - "type": "CONDITIONING", - "link": 645 - }, - { - "localized_name": "negative", - "name": "negative", - "type": "CONDITIONING", - "link": 646 - } - ], - "outputs": [ - { - "localized_name": "GUIDER", - "name": "GUIDER", - "type": "GUIDER", - "links": [ - 688 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.3.71", - "Node name for S&R": "CFGGuider" - }, - "widgets_values": [ - 1 - ] - }, - { - "id": 291, - "type": "SamplerCustomAdvanced", - "pos": [ - 2730, - 3420 - ], - "size": [ - 230, - 170 - ], - "flags": {}, - "order": 9, - "mode": 0, - "inputs": [ - { - "localized_name": "noise", - "name": "noise", - "type": "NOISE", - "link": 650 - }, - { - "localized_name": "guider", - "name": "guider", - "type": "GUIDER", - "link": 651 - }, - { - "localized_name": "sampler", - "name": "sampler", - "type": "SAMPLER", - "link": 652 - }, - { - "localized_name": "sigmas", - "name": "sigmas", - "type": "SIGMAS", - "link": 653 - }, - { - "localized_name": "latent_image", - "name": "latent_image", - "type": "LATENT", - "link": 654 - } - ], - "outputs": [ - { - "localized_name": "output", - "name": "output", - "type": "LATENT", - "links": [ - 686 - ] - }, - { - "localized_name": "denoised_output", - "name": "denoised_output", - "type": "LATENT", - "links": [] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.3.60", - "Node name for S&R": "SamplerCustomAdvanced" - }, - "widgets_values": [] - }, - { - "id": 292, - "type": "LTXVCropGuides", - "pos": [ - 3070, - 3610 - ], - "size": [ - 250, - 120 - ], - "flags": {}, - "order": 10, - "mode": 0, - "inputs": [ - { - "localized_name": "positive", - "name": "positive", - "type": "CONDITIONING", - "link": 655 - }, - { - "localized_name": "negative", - "name": "negative", - "type": "CONDITIONING", - "link": 656 - }, - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "link": 657 - } - ], - "outputs": [ - { - "localized_name": "positive", - "name": "positive", - "type": "CONDITIONING", - "links": [ - 645 - ] - }, - { - "localized_name": "negative", - "name": "negative", - "type": "CONDITIONING", - "links": [ - 646 - ] - }, - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "slot_index": 2, - "links": [] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.3.68", - "Node name for S&R": "LTXVCropGuides" - }, - "widgets_values": [] - }, - { - "id": 295, - "type": "LTXVLatentUpsampler", - "pos": [ - 3500, - 3710 - ], - "size": [ - 330, - 120 - ], - "flags": {}, - "order": 13, - "mode": 0, - "inputs": [ - { - "localized_name": "samples", - "name": "samples", - "type": "LATENT", - "link": 660 - }, - { - "localized_name": "upscale_model", - "name": "upscale_model", - "type": "LATENT_UPSCALE_MODEL", - "link": 661 - }, - { - "localized_name": "vae", - "name": "vae", - "type": "VAE", - "link": 662 - } - ], - "outputs": [ - { - "localized_name": "LATENT", - "name": "LATENT", - "type": "LATENT", - "links": [ - 665 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.14.1", - "Node name for S&R": "LTXVLatentUpsampler" - }, - "widgets_values": [] - }, - { - "id": 296, - "type": "LTXVImgToVideoInplace", - "pos": [ - 3520, - 3870 - ], - "size": [ - 300, - 180 - ], - "flags": {}, - "order": 14, - "mode": 0, - "inputs": [ - { - "localized_name": "vae", - "name": "vae", - "type": "VAE", - "link": 663 - }, - { - "localized_name": "image", - "name": "image", - "type": "IMAGE", - "link": 664 - }, - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "link": 665 - }, - { - "localized_name": "bypass", - "name": "bypass", - "type": "BOOLEAN", - "widget": { - "name": "bypass" - }, - "link": 666 - } - ], - "outputs": [ - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "links": [ - 642 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.7.0", - "Node name for S&R": "LTXVImgToVideoInplace" - }, - "widgets_values": [ - 1, - false - ] - }, - { - "id": 298, - "type": "KSamplerSelect", - "pos": [ - 2340, - 3790 - ], - "size": [ - 280, - 110 - ], - "flags": {}, - "order": 3, - "mode": 0, - "inputs": [], - "outputs": [ - { - "localized_name": "SAMPLER", - "name": "SAMPLER", - "type": "SAMPLER", - "links": [ - 652 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.3.56", - "Node name for S&R": "KSamplerSelect" - }, - "widgets_values": [ - "euler" - ] - }, - { - "id": 300, - "type": "Reroute", - "pos": [ - 3180, - 3850 - ], - "size": [ - 75, - 26 - ], - "flags": {}, - "order": 17, - "mode": 0, - "inputs": [ - { - "name": "", - "type": "*", - "link": 671 - } - ], - "outputs": [ - { - "name": "", - "type": "VAE", - "links": [ - 662, - 663, - 694 - ] - } - ], - "properties": { - "showOutputText": false, - "horizontal": false - } - }, - { - "id": 303, - "type": "LTXVAudioVAEDecode", - "pos": [ - 4990, - 3660 - ], - "size": [ - 270, - 100 - ], - "flags": {}, - "order": 20, - "mode": 0, - "inputs": [ - { - "localized_name": "samples", - "name": "samples", - "type": "LATENT", - "link": 679 - }, - { - "label": "Audio VAE", - "localized_name": "audio_vae", - "name": "audio_vae", - "type": "VAE", - "link": 680 - } - ], - "outputs": [ - { - "localized_name": "Audio", - "name": "Audio", - "type": "AUDIO", - "links": [ - 696 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.7.0", - "Node name for S&R": "LTXVAudioVAEDecode" - }, - "widgets_values": [] - }, - { - "id": 306, - "type": "CLIPTextEncode", - "pos": [ - 1370, - 3430 - ], - "size": [ - 600, - 390 - ], - "flags": {}, - "order": 22, - "mode": 0, - "inputs": [ - { - "localized_name": "clip", - "name": "clip", - "type": "CLIP", - "link": 703 - }, - { - "localized_name": "text", - "name": "text", - "type": "STRING", - "widget": { - "name": "text" - }, - "link": 755 - } - ], - "outputs": [ - { - "localized_name": "CONDITIONING", - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 682 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.3.56", - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "" - ], - "color": "#232", - "bgcolor": "#353" - }, - { - "id": 307, - "type": "LTXVConditioning", - "pos": [ - 2000, - 3600 - ], - "size": [ - 280, - 130 - ], - "flags": {}, - "order": 23, - "mode": 0, - "inputs": [ - { - "localized_name": "positive", - "name": "positive", - "type": "CONDITIONING", - "link": 682 - }, - { - "localized_name": "negative", - "name": "negative", - "type": "CONDITIONING", - "link": 683 - }, - { - "localized_name": "frame_rate", - "name": "frame_rate", - "type": "FLOAT", - "widget": { - "name": "frame_rate" - }, - "link": 684 - } - ], - "outputs": [ - { - "localized_name": "positive", - "name": "positive", - "type": "CONDITIONING", - "links": [ - 648, - 655 - ] - }, - { - "localized_name": "negative", - "name": "negative", - "type": "CONDITIONING", - "links": [ - 649, - 656 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.3.56", - "Node name for S&R": "LTXVConditioning" - }, - "widgets_values": [ - 24 - ] - }, - { - "id": 308, - "type": "ManualSigmas", - "pos": [ - 2340, - 4000 - ], - "size": [ - 500, - 110 - ], - "flags": {}, - "order": 4, - "mode": 0, - "inputs": [], - "outputs": [ - { - "localized_name": "SIGMAS", - "name": "SIGMAS", - "type": "SIGMAS", - "links": [ - 653 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "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": 309, - "type": "LTXVSeparateAVLatent", - "pos": [ - 3070, - 3430 - ], - "size": [ - 250, - 100 - ], - "flags": {}, - "order": 24, - "mode": 0, - "inputs": [ - { - "localized_name": "av_latent", - "name": "av_latent", - "type": "LATENT", - "link": 686 - } - ], - "outputs": [ - { - "localized_name": "video_latent", - "name": "video_latent", - "type": "LATENT", - "links": [ - 657, - 660 - ] - }, - { - "localized_name": "audio_latent", - "name": "audio_latent", - "type": "LATENT", - "links": [ - 643 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.5.1", - "Node name for S&R": "LTXVSeparateAVLatent" - }, - "widgets_values": [] - }, - { - "id": 310, - "type": "SamplerCustomAdvanced", - "pos": [ - 4310, - 3440 - ], - "size": [ - 230, - 170 - ], - "flags": {}, - "order": 25, - "mode": 0, - "inputs": [ - { - "localized_name": "noise", - "name": "noise", - "type": "NOISE", - "link": 687 - }, - { - "localized_name": "guider", - "name": "guider", - "type": "GUIDER", - "link": 688 - }, - { - "localized_name": "sampler", - "name": "sampler", - "type": "SAMPLER", - "link": 689 - }, - { - "localized_name": "sigmas", - "name": "sigmas", - "type": "SIGMAS", - "link": 690 - }, - { - "localized_name": "latent_image", - "name": "latent_image", - "type": "LATENT", - "link": 691 - } - ], - "outputs": [ - { - "localized_name": "output", - "name": "output", - "type": "LATENT", - "links": [ - 692 - ] - }, - { - "localized_name": "denoised_output", - "name": "denoised_output", - "type": "LATENT", - "links": [] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.3.75", - "Node name for S&R": "SamplerCustomAdvanced" - }, - "widgets_values": [] - }, - { - "id": 311, - "type": "LTXVSeparateAVLatent", - "pos": [ - 4650, - 3440 - ], - "size": [ - 230, - 100 - ], - "flags": {}, - "order": 26, - "mode": 0, - "inputs": [ - { - "localized_name": "av_latent", - "name": "av_latent", - "type": "LATENT", - "link": 692 - } - ], - "outputs": [ - { - "localized_name": "video_latent", - "name": "video_latent", - "type": "LATENT", - "links": [ - 693 - ] - }, - { - "localized_name": "audio_latent", - "name": "audio_latent", - "type": "LATENT", - "links": [ - 679 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.5.1", - "Node name for S&R": "LTXVSeparateAVLatent" - }, - "widgets_values": [] - }, - { - "id": 314, - "type": "CLIPTextEncode", - "pos": [ - 1370, - 3910 - ], - "size": [ - 600, - 170 - ], - "flags": {}, - "order": 29, - "mode": 0, - "inputs": [ - { - "localized_name": "clip", - "name": "clip", - "type": "CLIP", - "link": 721 - } - ], - "outputs": [ - { - "localized_name": "CONDITIONING", - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 683 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.3.56", - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "pc game, console game, video game, cartoon, childish, ugly" - ], - "color": "#323", - "bgcolor": "#535" - }, - { - "id": 315, - "type": "CFGGuider", - "pos": [ - 2330, - 3580 - ], - "size": [ - 280, - 160 - ], - "flags": {}, - "order": 30, - "mode": 0, - "inputs": [ - { - "localized_name": "model", - "name": "model", - "type": "MODEL", - "link": 647 - }, - { - "localized_name": "positive", - "name": "positive", - "type": "CONDITIONING", - "link": 648 - }, - { - "localized_name": "negative", - "name": "negative", - "type": "CONDITIONING", - "link": 649 - } - ], - "outputs": [ - { - "localized_name": "GUIDER", - "name": "GUIDER", - "type": "GUIDER", - "links": [ - 651 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.3.64", - "Node name for S&R": "CFGGuider" - }, - "widgets_values": [ - 1 - ] - }, - { - "id": 316, - "type": "VAEDecodeTiled", - "pos": [ - 4970, - 3440 - ], - "size": [ - 280, - 150 - ], - "flags": {}, - "order": 31, - "mode": 0, - "inputs": [ - { - "localized_name": "samples", - "name": "samples", - "type": "LATENT", - "link": 693 - }, - { - "localized_name": "vae", - "name": "vae", - "type": "VAE", - "link": 694 - } - ], - "outputs": [ - { - "localized_name": "IMAGE", - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 695 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.14.1", - "Node name for S&R": "VAEDecodeTiled" - }, - "widgets_values": [ - 768, - 64, - 4096, - 4 - ] - }, - { - "id": 325, - "type": "LTXVImgToVideoInplace", - "pos": [ - 2060, - 4410 - ], - "size": [ - 280, - 180 - ], - "flags": {}, - "order": 37, - "mode": 0, - "inputs": [ - { - "localized_name": "vae", - "name": "vae", - "type": "VAE", - "link": 675 - }, - { - "localized_name": "image", - "name": "image", - "type": "IMAGE", - "link": 676 - }, - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "link": 677 - }, - { - "localized_name": "bypass", - "name": "bypass", - "type": "BOOLEAN", - "widget": { - "name": "bypass" - }, - "link": 678 - } - ], - "outputs": [ - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "links": [ - 685 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.7.0", - "Node name for S&R": "LTXVImgToVideoInplace" - }, - "widgets_values": [ - 0.7, - false - ] - }, - { - "id": 330, - "type": "PrimitiveInt", - "pos": [ - 410, - 4040 - ], - "size": [ - 370, - 110 - ], - "flags": {}, - "order": 42, - "mode": 0, - "inputs": [ - { - "localized_name": "value", - "name": "value", - "type": "INT", - "widget": { - "name": "value" - }, - "link": 730 - } - ], - "outputs": [ - { - "localized_name": "INT", - "name": "INT", - "type": "INT", - "links": [ - 668, - 670, - 716 - ] - } - ], - "title": "Width", - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "PrimitiveInt" - }, - "widgets_values": [ - 720, - "fixed" - ] - }, - { - "id": 333, - "type": "SolidMask", - "pos": [ - 2390, - 4420 - ], - "size": [ - 260, - 170 - ], - "flags": { - "collapsed": false - }, - "order": 45, - "mode": 0, - "inputs": [ - { - "localized_name": "width", - "name": "width", - "type": "INT", - "widget": { - "name": "width" - }, - "link": 716 - }, - { - "localized_name": "height", - "name": "height", - "type": "INT", - "widget": { - "name": "height" - }, - "link": 717 - } - ], - "outputs": [ - { - "localized_name": "MASK", - "name": "MASK", - "type": "MASK", - "links": [ - 713 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.7.0", - "Node name for S&R": "SolidMask", - "ue_properties": { - "widget_ue_connectable": { - "width": true, - "height": true - }, - "version": "7.5.2", - "input_ue_unconnectable": {} - } - }, - "widgets_values": [ - 0, - 1024, - 1024 - ] - }, - { - "id": 335, - "type": "LTXVAudioVAELoader", - "pos": [ - 870, - 3790 - ], - "size": [ - 430, - 110 - ], - "flags": {}, - "order": 47, - "mode": 0, - "inputs": [ - { - "localized_name": "ckpt_name", - "name": "ckpt_name", - "type": "COMBO", - "widget": { - "name": "ckpt_name" - }, - "link": 737 - } - ], - "outputs": [ - { - "localized_name": "Audio VAE", - "name": "Audio VAE", - "type": "VAE", - "links": [ - 680, - 718 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.3.68", - "Node name for S&R": "LTXVAudioVAELoader", - "models": [ - { - "name": "ltx-2.3-22b-dev-fp8.safetensors", - "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", - "directory": "checkpoints" - } - ] - }, - "widgets_values": [ - "ltx-2.3-22b-dev-fp8.safetensors" - ] - }, - { - "id": 305, - "type": "PrimitiveBoolean", - "pos": [ - 420, - 3890 - ], - "size": [ - 370, - 100 - ], - "flags": {}, - "order": 5, - "mode": 0, - "inputs": [], - "outputs": [ - { - "localized_name": "BOOLEAN", - "name": "BOOLEAN", - "type": "BOOLEAN", - "links": [ - 666, - 678 - ] - } - ], - "title": "Switch to Text to Video?", - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.0", - "Node name for S&R": "PrimitiveBoolean" - }, - "widgets_values": [ - false - ] - }, - { - "id": 294, - "type": "ResizeImagesByLongerEdge", - "pos": [ - 1330, - 4620 - ], - "size": [ - 310, - 110 - ], - "flags": { - "collapsed": false - }, - "order": 12, - "mode": 0, - "inputs": [ - { - "localized_name": "images", - "name": "images", - "type": "IMAGE", - "link": 659 - } - ], - "outputs": [ - { - "localized_name": "images", - "name": "images", - "type": "IMAGE", - "links": [ - 667 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.5.1", - "Node name for S&R": "ResizeImagesByLongerEdge" - }, - "widgets_values": [ - 1536 - ] - }, - { - "id": 334, - "type": "LTXVPreprocess", - "pos": [ - 1340, - 4460 - ], - "size": [ - 290, - 110 - ], - "flags": {}, - "order": 46, - "mode": 0, - "inputs": [ - { - "localized_name": "image", - "name": "image", - "type": "IMAGE", - "link": 667 - } - ], - "outputs": [ - { - "localized_name": "output_image", - "name": "output_image", - "type": "IMAGE", - "links": [ - 664, - 676 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.7.0", - "Node name for S&R": "LTXVPreprocess" - }, - "widgets_values": [ - 18 - ] - }, - { - "id": 301, - "type": "ComfyMathExpression", - "pos": [ - 1760, - 4670 - ], - "size": [ - 225, - 8 - ], - "flags": { - "collapsed": true - }, - "order": 18, - "mode": 0, - "inputs": [ - { - "label": "a", - "localized_name": "values.a", - "name": "values.a", - "type": "FLOAT,INT,BOOLEAN", - "link": 672 - }, - { - "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": [ - 674 - ] - }, - { - "localized_name": "BOOL", - "name": "BOOL", - "type": "BOOLEAN", - "links": null - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "ComfyMathExpression" - }, - "widgets_values": [ - "a/2" - ] - }, - { - "id": 299, - "type": "ComfyMathExpression", - "pos": [ - 1760, - 4620 - ], - "size": [ - 225, - 8 - ], - "flags": { - "collapsed": true - }, - "order": 16, - "mode": 0, - "inputs": [ - { - "label": "a", - "localized_name": "values.a", - "name": "values.a", - "type": "FLOAT,INT,BOOLEAN", - "link": 670 - }, - { - "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": [ - 673 - ] - }, - { - "localized_name": "BOOL", - "name": "BOOL", - "type": "BOOLEAN", - "links": null - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "ComfyMathExpression" - }, - "widgets_values": [ - "a/2" - ] - }, - { - "id": 304, - "type": "ComfyMathExpression", - "pos": [ - 1760, - 4500 - ], - "size": [ - 225, - 8 - ], - "flags": { - "collapsed": true - }, - "order": 21, - "mode": 0, - "inputs": [ - { - "label": "a", - "localized_name": "values.a", - "name": "values.a", - "type": "FLOAT,INT,BOOLEAN", - "link": 681 - }, - { - "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": [ - 684, - 697 - ] - }, - { - "localized_name": "INT", - "name": "INT", - "type": "INT", - "links": [] - }, - { - "localized_name": "BOOL", - "name": "BOOL", - "type": "BOOLEAN", - "links": null - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "ComfyMathExpression" - }, - "widgets_values": [ - "a" - ] - }, - { - "id": 312, - "type": "CreateVideo", - "pos": [ - 4990, - 4310 - ], - "size": [ - 280, - 130 - ], - "flags": {}, - "order": 27, - "mode": 0, - "inputs": [ - { - "localized_name": "images", - "name": "images", - "type": "IMAGE", - "link": 695 - }, - { - "localized_name": "audio", - "name": "audio", - "shape": 7, - "type": "AUDIO", - "link": 696 - }, - { - "localized_name": "fps", - "name": "fps", - "type": "FLOAT", - "widget": { - "name": "fps" - }, - "link": 697 - } - ], - "outputs": [ - { - "localized_name": "VIDEO", - "name": "VIDEO", - "type": "VIDEO", - "links": [ - 699 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.5.1", - "Node name for S&R": "CreateVideo" - }, - "widgets_values": [ - 24 - ] - }, - { - "id": 331, - "type": "PrimitiveFloat", - "pos": [ - 410, - 4520 - ], - "size": [ - 350, - 110 - ], - "flags": {}, - "order": 43, - "mode": 0, - "inputs": [ - { - "localized_name": "value", - "name": "value", - "type": "FLOAT", - "widget": { - "name": "value" - }, - "link": 734 - } - ], - "outputs": [ - { - "localized_name": "FLOAT", - "name": "FLOAT", - "type": "FLOAT", - "links": [ - 710, - 711 - ] - } - ], - "title": "Duration", - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "PrimitiveFloat" - }, - "widgets_values": [ - 9 - ] - }, - { - "id": 323, - "type": "PrimitiveInt", - "pos": [ - 410, - 4340 - ], - "size": [ - 370, - 110 - ], - "flags": {}, - "order": 35, - "mode": 0, - "inputs": [ - { - "localized_name": "value", - "name": "value", - "type": "INT", - "widget": { - "name": "value" - }, - "link": 732 - } - ], - "outputs": [ - { - "localized_name": "INT", - "name": "INT", - "type": "INT", - "links": [ - 681, - 724 - ] - } - ], - "title": "Frame Rate", - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "PrimitiveInt" - }, - "widgets_values": [ - 24, - "fixed" - ] - }, - { - "id": 302, - "type": "EmptyLTXVLatentVideo", - "pos": [ - 2070, - 4590 - ], - "size": [ - 280, - 200 - ], - "flags": {}, - "order": 19, - "mode": 0, - "inputs": [ - { - "localized_name": "width", - "name": "width", - "type": "INT", - "widget": { - "name": "width" - }, - "link": 673 - }, - { - "localized_name": "height", - "name": "height", - "type": "INT", - "widget": { - "name": "height" - }, - "link": 674 - }, - { - "localized_name": "length", - "name": "length", - "type": "INT", - "widget": { - "name": "length" - }, - "link": 712 - } - ], - "outputs": [ - { - "localized_name": "LATENT", - "name": "LATENT", - "type": "LATENT", - "links": [ - 677 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.3.60", - "Node name for S&R": "EmptyLTXVLatentVideo" - }, - "widgets_values": [ - 768, - 512, - 97, - 1 - ] - }, - { - "id": 329, - "type": "ComfyMathExpression", - "pos": [ - 1760, - 4720 - ], - "size": [ - 225, - 8 - ], - "flags": { - "collapsed": true - }, - "order": 41, - "mode": 0, - "inputs": [ - { - "label": "a", - "localized_name": "values.a", - "name": "values.a", - "type": "FLOAT,INT,BOOLEAN", - "link": 711 - }, - { - "label": "b", - "localized_name": "values.b", - "name": "values.b", - "shape": 7, - "type": "FLOAT,INT,BOOLEAN", - "link": 724 - }, - { - "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": [ - 712 - ] - }, - { - "localized_name": "BOOL", - "name": "BOOL", - "type": "BOOLEAN", - "links": null - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "ComfyMathExpression" - }, - "widgets_values": [ - "a * b + 1" - ] - }, - { - "id": 324, - "type": "PrimitiveInt", - "pos": [ - 410, - 4190 - ], - "size": [ - 370, - 110 - ], - "flags": {}, - "order": 36, - "mode": 0, - "inputs": [ - { - "localized_name": "value", - "name": "value", - "type": "INT", - "widget": { - "name": "value" - }, - "link": 731 - } - ], - "outputs": [ - { - "localized_name": "INT", - "name": "INT", - "type": "INT", - "links": [ - 669, - 672, - 717 - ] - } - ], - "title": "Height", - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "PrimitiveInt" - }, - "widgets_values": [ - 1280, - "fixed" - ] - }, - { - "id": 332, - "type": "TrimAudioDuration", - "pos": [ - 410, - 4810 - ], - "size": [ - 330, - 140 - ], - "flags": {}, - "order": 44, - "mode": 0, - "inputs": [ - { - "localized_name": "audio", - "name": "audio", - "type": "AUDIO", - "link": 709 - }, - { - "localized_name": "start_index", - "name": "start_index", - "type": "FLOAT", - "widget": { - "name": "start_index" - }, - "link": 733 - }, - { - "localized_name": "duration", - "name": "duration", - "type": "FLOAT", - "widget": { - "name": "duration" - }, - "link": 710 - } - ], - "outputs": [ - { - "localized_name": "AUDIO", - "name": "AUDIO", - "type": "AUDIO", - "links": [ - 708 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "TrimAudioDuration" - }, - "widgets_values": [ - 0, - 60 - ] - }, - { - "id": 328, - "type": "LTXVAudioVAEEncode", - "pos": [ - 2400, - 4640 - ], - "size": [ - 250, - 100 - ], - "flags": {}, - "order": 40, - "mode": 0, - "inputs": [ - { - "localized_name": "audio", - "name": "audio", - "type": "AUDIO", - "link": 708 - }, - { - "label": "Audio VAE", - "localized_name": "audio_vae", - "name": "audio_vae", - "type": "VAE", - "link": 718 - } - ], - "outputs": [ - { - "localized_name": "Audio Latent", - "name": "Audio Latent", - "type": "LATENT", - "links": [ - 714 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "LTXVAudioVAEEncode" - }, - "widgets_values": [] - }, - { - "id": 326, - "type": "LTXVConcatAVLatent", - "pos": [ - 3090, - 4420 - ], - "size": [ - 240, - 100 - ], - "flags": {}, - "order": 38, - "mode": 0, - "inputs": [ - { - "localized_name": "video_latent", - "name": "video_latent", - "type": "LATENT", - "link": 685 - }, - { - "localized_name": "audio_latent", - "name": "audio_latent", - "type": "LATENT", - "link": 715 - } - ], - "outputs": [ - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "links": [ - 654 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.7.0", - "Node name for S&R": "LTXVConcatAVLatent" - }, - "widgets_values": [] - }, - { - "id": 327, - "type": "SetLatentNoiseMask", - "pos": [ - 2720, - 4640 - ], - "size": [ - 350, - 100 - ], - "flags": {}, - "order": 39, - "mode": 0, - "inputs": [ - { - "localized_name": "samples", - "name": "samples", - "type": "LATENT", - "link": 714 - }, - { - "localized_name": "mask", - "name": "mask", - "type": "MASK", - "link": 713 - } - ], - "outputs": [ - { - "localized_name": "LATENT", - "name": "LATENT", - "type": "LATENT", - "links": [ - 715 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.7.0", - "Node name for S&R": "SetLatentNoiseMask", - "ue_properties": { - "widget_ue_connectable": {}, - "version": "7.5.2", - "input_ue_unconnectable": {} - } - }, - "widgets_values": [], - "color": "#323", - "bgcolor": "#535" - }, - { - "id": 313, - "type": "LatentUpscaleModelLoader", - "pos": [ - 880, - 4160 - ], - "size": [ - 400, - 110 - ], - "flags": {}, - "order": 28, - "mode": 0, - "inputs": [ - { - "localized_name": "model_name", - "name": "model_name", - "type": "COMBO", - "widget": { - "name": "model_name" - }, - "link": 740 - } - ], - "outputs": [ - { - "localized_name": "LATENT_UPSCALE_MODEL", - "name": "LATENT_UPSCALE_MODEL", - "type": "LATENT_UPSCALE_MODEL", - "links": [ - 661 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.7.0", - "Node name for S&R": "LatentUpscaleModelLoader", - "models": [ - { - "name": "ltx-2.3-spatial-upscaler-x2-1.1.safetensors", - "url": "https://huggingface.co/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors", - "directory": "latent_upscale_models" - } - ] - }, - "widgets_values": [ - "ltx-2.3-spatial-upscaler-x2-1.1.safetensors" - ] - }, - { - "id": 293, - "type": "LoraLoaderModelOnly", - "pos": [ - 870, - 3610 - ], - "size": [ - 430, - 140 - ], - "flags": {}, - "order": 11, - "mode": 0, - "inputs": [ - { - "localized_name": "model", - "name": "model", - "type": "MODEL", - "link": 658 - }, - { - "localized_name": "lora_name", - "name": "lora_name", - "type": "COMBO", - "widget": { - "name": "lora_name" - }, - "link": 738 - } - ], - "outputs": [ - { - "localized_name": "MODEL", - "name": "MODEL", - "type": "MODEL", - "links": [ - 644, - 647, - 757 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.3.75", - "Node name for S&R": "LoraLoaderModelOnly", - "models": [ - { - "name": "ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", - "url": "https://huggingface.co/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", - "directory": "loras" - } - ] - }, - "widgets_values": [ - "ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", - 0.5 - ] - }, - { - "id": 317, - "type": "CheckpointLoaderSimple", - "pos": [ - 870, - 3410 - ], - "size": [ - 430, - 160 - ], - "flags": {}, - "order": 32, - "mode": 0, - "inputs": [ - { - "localized_name": "ckpt_name", - "name": "ckpt_name", - "type": "COMBO", - "widget": { - "name": "ckpt_name" - }, - "link": 735 - } - ], - "outputs": [ - { - "localized_name": "MODEL", - "name": "MODEL", - "type": "MODEL", - "links": [ - 658 - ] - }, - { - "localized_name": "CLIP", - "name": "CLIP", - "type": "CLIP", - "links": [] - }, - { - "localized_name": "VAE", - "name": "VAE", - "type": "VAE", - "links": [ - 671, - 675 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.3.56", - "Node name for S&R": "CheckpointLoaderSimple", - "models": [ - { - "name": "ltx-2.3-22b-dev-fp8.safetensors", - "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", - "directory": "checkpoints" - } - ] - }, - "widgets_values": [ - "ltx-2.3-22b-dev-fp8.safetensors" - ] - }, - { - "id": 318, - "type": "LTXAVTextEncoderLoader", - "pos": [ - 870, - 3950 - ], - "size": [ - 430, - 170 - ], - "flags": {}, - "order": 33, - "mode": 0, - "inputs": [ - { - "localized_name": "text_encoder", - "name": "text_encoder", - "type": "COMBO", - "widget": { - "name": "text_encoder" - }, - "link": 739 - }, - { - "localized_name": "ckpt_name", - "name": "ckpt_name", - "type": "COMBO", - "widget": { - "name": "ckpt_name" - }, - "link": 736 - } - ], - "outputs": [ - { - "localized_name": "CLIP", - "name": "CLIP", - "type": "CLIP", - "links": [ - 703, - 721, - 758 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.7.0", - "Node name for S&R": "LTXAVTextEncoderLoader", - "models": [ - { - "name": "ltx-2.3-22b-dev-fp8.safetensors", - "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", - "directory": "checkpoints" - }, - { - "name": "gemma_3_12B_it_fp4_mixed.safetensors", - "url": "https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors", - "directory": "text_encoders" - } - ] - }, - "widgets_values": [ - "gemma_3_12B_it_fp4_mixed.safetensors", - "ltx-2.3-22b-dev-fp8.safetensors", - "default" - ] - }, - { - "id": 319, - "type": "PrimitiveStringMultiline", - "pos": [ - 410, - 3460 - ], - "size": [ - 370, - 350 - ], - "flags": {}, - "order": 34, - "mode": 0, - "inputs": [ - { - "localized_name": "value", - "name": "value", - "type": "STRING", - "widget": { - "name": "value" - }, - "link": 729 - } - ], - "outputs": [ - { - "localized_name": "STRING", - "name": "STRING", - "type": "STRING", - "links": [ - 756, - 762 - ] - } - ], - "title": "Prompt", - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "PrimitiveStringMultiline" - }, - "widgets_values": [ - "The fuzzy cactus creature is talking to the viewer as it grips the steering wheel with one hand, the other hand gestures naturally as it speaks. The car is moving, revealing the sunlit coastal background, static camera fixed on character, smooth side-tracking shot matching the car speed\n\nscene: Sunlit coastal road trip, clear coastal background\ncharacter: Fuzzy cactus creature with big square sunglasses and a Hawaiian shirt\naction: One hand grips the steering wheel, the other gestures naturally while talking to the camera\ncamera: Fixed on character, smooth side-tracking shot matching car speed" - ] - }, - { - "id": 297, - "type": "ResizeImageMaskNode", - "pos": [ - 890, - 4400 - ], - "size": [ - 300, - 239.984375 - ], - "flags": {}, - "order": 15, - "mode": 0, - "inputs": [ - { - "localized_name": "input", - "name": "input", - "type": "IMAGE,MASK", - "link": 698 - }, - { - "localized_name": "width", - "name": "resize_type.width", - "type": "INT", - "widget": { - "name": "resize_type.width" - }, - "link": 668 - }, - { - "localized_name": "height", - "name": "resize_type.height", - "type": "INT", - "widget": { - "name": "resize_type.height" - }, - "link": 669 - } - ], - "outputs": [ - { - "localized_name": "resized", - "name": "resized", - "type": "IMAGE,MASK", - "links": [ - 659 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.7.0", - "Node name for S&R": "ResizeImageMaskNode" - }, - "widgets_values": [ - "scale dimensions", - 1920, - 1088, - "center", - "lanczos" - ] - }, - { - "id": 345, - "type": "LoraLoader", - "pos": [ - 410, - 2670 - ], - "size": [ - 380, - 230 - ], - "flags": {}, - "order": 48, - "mode": 0, - "inputs": [ - { - "localized_name": "model", - "name": "model", - "type": "MODEL", - "link": 757 - }, - { - "localized_name": "clip", - "name": "clip", - "type": "CLIP", - "link": 758 - }, - { - "localized_name": "lora_name", - "name": "lora_name", - "type": "COMBO", - "widget": { - "name": "lora_name" - }, - "link": 760 - } - ], - "outputs": [ - { - "localized_name": "MODEL", - "name": "MODEL", - "type": "MODEL", - "links": null - }, - { - "localized_name": "CLIP", - "name": "CLIP", - "type": "CLIP", - "links": [ - 751 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "LoraLoader", - "models": [ - { - "name": "gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", - "url": "https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", - "directory": "loras" - } - ] - }, - "widgets_values": [ - "gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", - 1, - 1 - ] - }, - { - "id": 346, - "type": "TextGenerateLTX2Prompt", - "pos": [ - 840, - 2670 - ], - "size": [ - 400, - 558.65625 - ], - "flags": { - "collapsed": false - }, - "order": 49, - "mode": 0, - "inputs": [ - { - "localized_name": "clip", - "name": "clip", - "type": "CLIP", - "link": 751 - }, - { - "localized_name": "image", - "name": "image", - "shape": 7, - "type": "IMAGE", - "link": null - }, - { - "localized_name": "video", - "name": "video", - "shape": 7, - "type": "IMAGE", - "link": null - }, - { - "localized_name": "audio", - "name": "audio", - "shape": 7, - "type": "AUDIO", - "link": null - }, - { - "localized_name": "prompt", - "name": "prompt", - "type": "STRING", - "widget": { - "name": "prompt" - }, - "link": 756 - } - ], - "outputs": [ - { - "localized_name": "generated_text", - "name": "generated_text", - "type": "STRING", - "links": [ - 753 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "TextGenerateLTX2Prompt" - }, - "widgets_values": [ - "A young woman speaks directly to the camera in her bedroom, holding the product beside her face as she talks about it. Warm natural light, handheld selfie framing, authentic UGC testimonial.", - 2048, - "on", - 0.7, - 64, - 0.95, - 0.05, - 1.05, - 0, - 0, - false, - true - ] - }, - { - "id": 347, - "type": "PreviewAny", - "pos": [ - 1680, - 2690 - ], - "size": [ - 510, - 360 - ], - "flags": {}, - "order": 50, - "mode": 0, - "inputs": [ - { - "localized_name": "source", - "name": "source", - "type": "*", - "link": 752 - } - ], - "outputs": [ - { - "localized_name": "STRING", - "name": "STRING", - "type": "STRING", - "links": [] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "PreviewAny" - }, - "widgets_values": [ - null, - null, - null - ] - }, - { - "id": 348, - "type": "ComfySwitchNode", - "pos": [ - 1370, - 3080 - ], - "size": [ - 270, - 130 - ], - "flags": {}, - "order": 51, - "mode": 0, - "inputs": [ - { - "localized_name": "on_false", - "name": "on_false", - "type": "STRING", - "link": 762 - }, - { - "localized_name": "on_true", - "name": "on_true", - "type": "STRING", - "link": 753 - }, - { - "localized_name": "switch", - "name": "switch", - "type": "BOOLEAN", - "widget": { - "name": "switch" - }, - "link": 754 - } - ], - "outputs": [ - { - "localized_name": "output", - "name": "output", - "type": "STRING", - "links": [ - 752, - 755 - ] - } - ], - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.22.0", - "Node name for S&R": "ComfySwitchNode" - }, - "widgets_values": [ - false - ] - }, - { - "id": 349, - "type": "PrimitiveBoolean", - "pos": [ - 410, - 3150 - ], - "size": [ - 270, - 100 - ], - "flags": {}, - "order": 52, - "mode": 0, - "inputs": [ - { - "localized_name": "value", - "name": "value", - "type": "BOOLEAN", - "widget": { - "name": "value" - }, - "link": 759 - } - ], - "outputs": [ - { - "localized_name": "BOOLEAN", - "name": "BOOLEAN", - "type": "BOOLEAN", - "links": [ - 754 - ] - } - ], - "title": "Boolean (Enable Prompt Enhance)", - "properties": { - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "cnr_id": "comfy-core", - "ver": "0.22.0", - "Node name for S&R": "PrimitiveBoolean" - }, - "widgets_values": [ - true - ] - } - ], - "groups": [ - { - "id": 1, - "title": "Model", - "bounding": [ - 850, - 3340, - 460, - 960 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 2, - "title": "Generate Low Resolution", - "bounding": [ - 2320, - 3340, - 1050, - 960 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 3, - "title": "Prompt", - "bounding": [ - 1340, - 3340, - 950, - 960 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 6, - "title": "Generate High Resolution", - "bounding": [ - 3930, - 3340, - 1000, - 960 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 7, - "title": "Latent Upscale", - "bounding": [ - 3390, - 3340, - 520, - 960 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 19, - "title": "Video Settings", - "bounding": [ - 370, - 3340, - 450, - 1420 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 20, - "title": "Image Preprocess", - "bounding": [ - 840, - 4330, - 830, - 420 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 21, - "title": "Empty Latent", - "bounding": [ - 2040, - 4330, - 1340, - 420 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 22, - "title": "Number conversion", - "bounding": [ - 1700, - 4330, - 310, - 420 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 27, - "title": "Prompt Enhancement", - "bounding": [ - 370, - 2590, - 2010, - 720 - ], - "color": "#3f789e", - "flags": {} - } - ], - "links": [ - { - "id": 642, - "origin_id": 296, - "origin_slot": 0, - "target_id": 287, - "target_slot": 0, - "type": "LATENT" - }, - { - "id": 643, - "origin_id": 309, - "origin_slot": 1, - "target_id": 287, - "target_slot": 1, - "type": "LATENT" - }, - { - "id": 644, - "origin_id": 293, - "origin_slot": 0, - "target_id": 290, - "target_slot": 0, - "type": "MODEL" - }, - { - "id": 645, - "origin_id": 292, - "origin_slot": 0, - "target_id": 290, - "target_slot": 1, - "type": "CONDITIONING" - }, - { - "id": 646, - "origin_id": 292, - "origin_slot": 1, - "target_id": 290, - "target_slot": 2, - "type": "CONDITIONING" - }, - { - "id": 650, - "origin_id": 286, - "origin_slot": 0, - "target_id": 291, - "target_slot": 0, - "type": "NOISE" - }, - { - "id": 651, - "origin_id": 315, - "origin_slot": 0, - "target_id": 291, - "target_slot": 1, - "type": "GUIDER" - }, - { - "id": 652, - "origin_id": 298, - "origin_slot": 0, - "target_id": 291, - "target_slot": 2, - "type": "SAMPLER" - }, - { - "id": 653, - "origin_id": 308, - "origin_slot": 0, - "target_id": 291, - "target_slot": 3, - "type": "SIGMAS" - }, - { - "id": 654, - "origin_id": 326, - "origin_slot": 0, - "target_id": 291, - "target_slot": 4, - "type": "LATENT" - }, - { - "id": 655, - "origin_id": 307, - "origin_slot": 0, - "target_id": 292, - "target_slot": 0, - "type": "CONDITIONING" - }, - { - "id": 656, - "origin_id": 307, - "origin_slot": 1, - "target_id": 292, - "target_slot": 1, - "type": "CONDITIONING" - }, - { - "id": 657, - "origin_id": 309, - "origin_slot": 0, - "target_id": 292, - "target_slot": 2, - "type": "LATENT" - }, - { - "id": 658, - "origin_id": 317, - "origin_slot": 0, - "target_id": 293, - "target_slot": 0, - "type": "MODEL" - }, - { - "id": 660, - "origin_id": 309, - "origin_slot": 0, - "target_id": 295, - "target_slot": 0, - "type": "LATENT" - }, - { - "id": 661, - "origin_id": 313, - "origin_slot": 0, - "target_id": 295, - "target_slot": 1, - "type": "LATENT_UPSCALE_MODEL" - }, - { - "id": 662, - "origin_id": 300, - "origin_slot": 0, - "target_id": 295, - "target_slot": 2, - "type": "VAE" - }, - { - "id": 663, - "origin_id": 300, - "origin_slot": 0, - "target_id": 296, - "target_slot": 0, - "type": "VAE" - }, - { - "id": 664, - "origin_id": 334, - "origin_slot": 0, - "target_id": 296, - "target_slot": 1, - "type": "IMAGE" - }, - { - "id": 665, - "origin_id": 295, - "origin_slot": 0, - "target_id": 296, - "target_slot": 2, - "type": "LATENT" - }, - { - "id": 666, - "origin_id": 305, - "origin_slot": 0, - "target_id": 296, - "target_slot": 3, - "type": "BOOLEAN" - }, - { - "id": 671, - "origin_id": 317, - "origin_slot": 2, - "target_id": 300, - "target_slot": 0, - "type": "VAE" - }, - { - "id": 679, - "origin_id": 311, - "origin_slot": 1, - "target_id": 303, - "target_slot": 0, - "type": "LATENT" - }, - { - "id": 680, - "origin_id": 335, - "origin_slot": 0, - "target_id": 303, - "target_slot": 1, - "type": "VAE" - }, - { - "id": 703, - "origin_id": 318, - "origin_slot": 0, - "target_id": 306, - "target_slot": 0, - "type": "CLIP" - }, - { - "id": 682, - "origin_id": 306, - "origin_slot": 0, - "target_id": 307, - "target_slot": 0, - "type": "CONDITIONING" - }, - { - "id": 683, - "origin_id": 314, - "origin_slot": 0, - "target_id": 307, - "target_slot": 1, - "type": "CONDITIONING" - }, - { - "id": 684, - "origin_id": 304, - "origin_slot": 0, - "target_id": 307, - "target_slot": 2, - "type": "FLOAT" - }, - { - "id": 686, - "origin_id": 291, - "origin_slot": 0, - "target_id": 309, - "target_slot": 0, - "type": "LATENT" - }, - { - "id": 687, - "origin_id": 285, - "origin_slot": 0, - "target_id": 310, - "target_slot": 0, - "type": "NOISE" - }, - { - "id": 688, - "origin_id": 290, - "origin_slot": 0, - "target_id": 310, - "target_slot": 1, - "type": "GUIDER" - }, - { - "id": 689, - "origin_id": 288, - "origin_slot": 0, - "target_id": 310, - "target_slot": 2, - "type": "SAMPLER" - }, - { - "id": 690, - "origin_id": 289, - "origin_slot": 0, - "target_id": 310, - "target_slot": 3, - "type": "SIGMAS" - }, - { - "id": 691, - "origin_id": 287, - "origin_slot": 0, - "target_id": 310, - "target_slot": 4, - "type": "LATENT" - }, - { - "id": 692, - "origin_id": 310, - "origin_slot": 0, - "target_id": 311, - "target_slot": 0, - "type": "LATENT" - }, - { - "id": 721, - "origin_id": 318, - "origin_slot": 0, - "target_id": 314, - "target_slot": 0, - "type": "CLIP" - }, - { - "id": 647, - "origin_id": 293, - "origin_slot": 0, - "target_id": 315, - "target_slot": 0, - "type": "MODEL" - }, - { - "id": 648, - "origin_id": 307, - "origin_slot": 0, - "target_id": 315, - "target_slot": 1, - "type": "CONDITIONING" - }, - { - "id": 649, - "origin_id": 307, - "origin_slot": 1, - "target_id": 315, - "target_slot": 2, - "type": "CONDITIONING" - }, - { - "id": 693, - "origin_id": 311, - "origin_slot": 0, - "target_id": 316, - "target_slot": 0, - "type": "LATENT" - }, - { - "id": 694, - "origin_id": 300, - "origin_slot": 0, - "target_id": 316, - "target_slot": 1, - "type": "VAE" - }, - { - "id": 675, - "origin_id": 317, - "origin_slot": 2, - "target_id": 325, - "target_slot": 0, - "type": "VAE" - }, - { - "id": 676, - "origin_id": 334, - "origin_slot": 0, - "target_id": 325, - "target_slot": 1, - "type": "IMAGE" - }, - { - "id": 677, - "origin_id": 302, - "origin_slot": 0, - "target_id": 325, - "target_slot": 2, - "type": "LATENT" - }, - { - "id": 678, - "origin_id": 305, - "origin_slot": 0, - "target_id": 325, - "target_slot": 3, - "type": "BOOLEAN" - }, - { - "id": 685, - "origin_id": 325, - "origin_slot": 0, - "target_id": 326, - "target_slot": 0, - "type": "LATENT" - }, - { - "id": 715, - "origin_id": 327, - "origin_slot": 0, - "target_id": 326, - "target_slot": 1, - "type": "LATENT" - }, - { - "id": 714, - "origin_id": 328, - "origin_slot": 0, - "target_id": 327, - "target_slot": 0, - "type": "LATENT" - }, - { - "id": 713, - "origin_id": 333, - "origin_slot": 0, - "target_id": 327, - "target_slot": 1, - "type": "MASK" - }, - { - "id": 708, - "origin_id": 332, - "origin_slot": 0, - "target_id": 328, - "target_slot": 0, - "type": "AUDIO" - }, - { - "id": 718, - "origin_id": 335, - "origin_slot": 0, - "target_id": 328, - "target_slot": 1, - "type": "VAE" - }, - { - "id": 716, - "origin_id": 330, - "origin_slot": 0, - "target_id": 333, - "target_slot": 0, - "type": "INT" - }, - { - "id": 717, - "origin_id": 324, - "origin_slot": 0, - "target_id": 333, - "target_slot": 1, - "type": "INT" - }, - { - "id": 668, - "origin_id": 330, - "origin_slot": 0, - "target_id": 297, - "target_slot": 1, - "type": "INT" - }, - { - "id": 669, - "origin_id": 324, - "origin_slot": 0, - "target_id": 297, - "target_slot": 2, - "type": "INT" - }, - { - "id": 659, - "origin_id": 297, - "origin_slot": 0, - "target_id": 294, - "target_slot": 0, - "type": "IMAGE" - }, - { - "id": 667, - "origin_id": 294, - "origin_slot": 0, - "target_id": 334, - "target_slot": 0, - "type": "IMAGE" - }, - { - "id": 672, - "origin_id": 324, - "origin_slot": 0, - "target_id": 301, - "target_slot": 0, - "type": "INT" - }, - { - "id": 670, - "origin_id": 330, - "origin_slot": 0, - "target_id": 299, - "target_slot": 0, - "type": "INT" - }, - { - "id": 681, - "origin_id": 323, - "origin_slot": 0, - "target_id": 304, - "target_slot": 0, - "type": "INT" - }, - { - "id": 695, - "origin_id": 316, - "origin_slot": 0, - "target_id": 312, - "target_slot": 0, - "type": "IMAGE" - }, - { - "id": 696, - "origin_id": 303, - "origin_slot": 0, - "target_id": 312, - "target_slot": 1, - "type": "AUDIO" - }, - { - "id": 697, - "origin_id": 304, - "origin_slot": 0, - "target_id": 312, - "target_slot": 2, - "type": "FLOAT" - }, - { - "id": 673, - "origin_id": 299, - "origin_slot": 1, - "target_id": 302, - "target_slot": 0, - "type": "INT" - }, - { - "id": 674, - "origin_id": 301, - "origin_slot": 1, - "target_id": 302, - "target_slot": 1, - "type": "INT" - }, - { - "id": 712, - "origin_id": 329, - "origin_slot": 1, - "target_id": 302, - "target_slot": 2, - "type": "INT" - }, - { - "id": 711, - "origin_id": 331, - "origin_slot": 0, - "target_id": 329, - "target_slot": 0, - "type": "FLOAT" - }, - { - "id": 724, - "origin_id": 323, - "origin_slot": 0, - "target_id": 329, - "target_slot": 1, - "type": "INT" - }, - { - "id": 710, - "origin_id": 331, - "origin_slot": 0, - "target_id": 332, - "target_slot": 2, - "type": "FLOAT" - }, - { - "id": 698, - "origin_id": -10, - "origin_slot": 0, - "target_id": 297, - "target_slot": 0, - "type": "IMAGE,MASK" - }, - { - "id": 709, - "origin_id": -10, - "origin_slot": 1, - "target_id": 332, - "target_slot": 0, - "type": "AUDIO" - }, - { - "id": 699, - "origin_id": 312, - "origin_slot": 0, - "target_id": -20, - "target_slot": 0, - "type": "VIDEO" - }, - { - "id": 729, - "origin_id": -10, - "origin_slot": 2, - "target_id": 319, - "target_slot": 0, - "type": "STRING" - }, - { - "id": 730, - "origin_id": -10, - "origin_slot": 4, - "target_id": 330, - "target_slot": 0, - "type": "INT" - }, - { - "id": 731, - "origin_id": -10, - "origin_slot": 5, - "target_id": 324, - "target_slot": 0, - "type": "INT" - }, - { - "id": 732, - "origin_id": -10, - "origin_slot": 8, - "target_id": 323, - "target_slot": 0, - "type": "INT" - }, - { - "id": 733, - "origin_id": -10, - "origin_slot": 6, - "target_id": 332, - "target_slot": 1, - "type": "FLOAT" - }, - { - "id": 734, - "origin_id": -10, - "origin_slot": 7, - "target_id": 331, - "target_slot": 0, - "type": "FLOAT" - }, - { - "id": 735, - "origin_id": -10, - "origin_slot": 10, - "target_id": 317, - "target_slot": 0, - "type": "COMBO" - }, - { - "id": 736, - "origin_id": -10, - "origin_slot": 10, - "target_id": 318, - "target_slot": 1, - "type": "COMBO" - }, - { - "id": 737, - "origin_id": -10, - "origin_slot": 10, - "target_id": 335, - "target_slot": 0, - "type": "COMBO" - }, - { - "id": 738, - "origin_id": -10, - "origin_slot": 11, - "target_id": 293, - "target_slot": 1, - "type": "COMBO" - }, - { - "id": 739, - "origin_id": -10, - "origin_slot": 12, - "target_id": 318, - "target_slot": 0, - "type": "COMBO" - }, - { - "id": 740, - "origin_id": -10, - "origin_slot": 13, - "target_id": 313, - "target_slot": 0, - "type": "COMBO" - }, - { - "id": 751, - "origin_id": 345, - "origin_slot": 1, - "target_id": 346, - "target_slot": 0, - "type": "CLIP" - }, - { - "id": 752, - "origin_id": 348, - "origin_slot": 0, - "target_id": 347, - "target_slot": 0, - "type": "*" - }, - { - "id": 753, - "origin_id": 346, - "origin_slot": 0, - "target_id": 348, - "target_slot": 1, - "type": "STRING" - }, - { - "id": 754, - "origin_id": 349, - "origin_slot": 0, - "target_id": 348, - "target_slot": 2, - "type": "BOOLEAN" - }, - { - "id": 755, - "origin_id": 348, - "origin_slot": 0, - "target_id": 306, - "target_slot": 1, - "type": "STRING" - }, - { - "id": 756, - "origin_id": 319, - "origin_slot": 0, - "target_id": 346, - "target_slot": 4, - "type": "STRING" - }, - { - "id": 757, - "origin_id": 293, - "origin_slot": 0, - "target_id": 345, - "target_slot": 0, - "type": "MODEL" - }, - { - "id": 758, - "origin_id": 318, - "origin_slot": 0, - "target_id": 345, - "target_slot": 1, - "type": "CLIP" - }, - { - "id": 759, - "origin_id": -10, - "origin_slot": 3, - "target_id": 349, - "target_slot": 0, - "type": "BOOLEAN" - }, - { - "id": 760, - "origin_id": -10, - "origin_slot": 14, - "target_id": 345, - "target_slot": 2, - "type": "COMBO" - }, - { - "id": 761, - "origin_id": -10, - "origin_slot": 9, - "target_id": 286, - "target_slot": 0, - "type": "INT" - }, - { - "id": 762, - "origin_id": 319, - "origin_slot": 0, - "target_id": 348, - "target_slot": 0, - "type": "STRING" - } - ], - "extra": { - "workflowRendererVersion": "Vue-corrected" - } - } - ] - }, - "config": {}, - "extra": { - "ds": { - "scale": 0.7239609100430904, - "offset": [ - 688.908674348608, - -3229.875453153755 - ] - }, - "frontendVersion": "1.43.18", - "workflowRendererVersion": "Vue-corrected", - "prompt": { - "1": { - "inputs": { - "ckpt_name": "ltx-av-step-1751000_vocoder_24K.safetensors" - }, - "class_type": "CheckpointLoaderSimple", - "_meta": { - "title": "Load Checkpoint" - } - }, - "2": { - "inputs": { - "gemma_path": "gemma-3-12b-it-qat-q4_0-unquantized_readout_proj/model/model.safetensors", - "ltxv_path": "ltx-av-step-1751000_vocoder_24K.safetensors", - "max_length": 1024 - }, - "class_type": "LTXVGemmaCLIPModelLoader", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 Gemma 3 Model Loader" - } - }, - "3": { - "inputs": { - "text": "", - "clip": [ - "2", - 0 - ] - }, - "class_type": "CLIPTextEncode", - "_meta": { - "title": "CLIP Text Encode (Prompt)" - } - }, - "4": { - "inputs": { - "text": "blurry, low quality, still frame, frames, watermark, overlay, titles, has blurbox, has subtitles", - "clip": [ - "2", - 0 - ] - }, - "class_type": "CLIPTextEncode", - "_meta": { - "title": "CLIP Text Encode (Prompt)" - } - }, - "8": { - "inputs": { - "sampler_name": "euler" - }, - "class_type": "KSamplerSelect", - "_meta": { - "title": "KSamplerSelect" - } - }, - "9": { - "inputs": { - "steps": 20, - "max_shift": 2.05, - "base_shift": 0.95, - "stretch": true, - "terminal": 0.1, - "latent": [ - "28", - 0 - ] - }, - "class_type": "LTXVScheduler", - "_meta": { - "title": "LTXVScheduler" - } - }, - "11": { - "inputs": { - "noise_seed": 10 - }, - "class_type": "RandomNoise", - "_meta": { - "title": "RandomNoise" - } - }, - "12": { - "inputs": { - "samples": [ - "29", - 0 - ], - "vae": [ - "1", - 2 - ] - }, - "class_type": "VAEDecode", - "_meta": { - "title": "VAE Decode" - } - }, - "13": { - "inputs": { - "ckpt_name": "ltx-av-step-1751000_vocoder_24K.safetensors" - }, - "class_type": "LTXVAudioVAELoader", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Audio VAE Loader" - } - }, - "14": { - "inputs": { - "samples": [ - "29", - 1 - ], - "audio_vae": [ - "13", - 0 - ] - }, - "class_type": "LTXVAudioVAEDecode", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Audio VAE Decode" - } - }, - "15": { - "inputs": { - "frame_rate": [ - "23", - 0 - ], - "loop_count": 0, - "filename_prefix": "AnimateDiff", - "format": "video/h264-mp4", - "pix_fmt": "yuv420p", - "crf": 19, - "save_metadata": true, - "trim_to_audio": false, - "pingpong": false, - "save_output": true, - "images": [ - "12", - 0 - ], - "audio": [ - "14", - 0 - ] - }, - "class_type": "VHS_VideoCombine", - "_meta": { - "title": "Video Combine \ud83c\udfa5\ud83c\udd65\ud83c\udd57\ud83c\udd62" - } - }, - "17": { - "inputs": { - "skip_blocks": "29", - "model": [ - "28", - 1 - ], - "positive": [ - "22", - 0 - ], - "negative": [ - "22", - 1 - ], - "parameters": [ - "18", - 0 - ] - }, - "class_type": "MultimodalGuider", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 Multimodal Guider" - } - }, - "18": { - "inputs": { - "modality": "VIDEO", - "cfg": 3, - "stg": 0, - "rescale": 0, - "modality_scale": 3, - "parameters": [ - "19", - 0 - ] - }, - "class_type": "GuiderParameters", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 Guider Parameters" - } - }, - "19": { - "inputs": { - "modality": "AUDIO", - "cfg": 7, - "stg": 0, - "rescale": 0, - "modality_scale": 3 - }, - "class_type": "GuiderParameters", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 Guider Parameters" - } - }, - "21": { - "inputs": { - "audioUI": "", - "audio": [ - "14", - 0 - ] - }, - "class_type": "PreviewAudio", - "_meta": { - "title": "PreviewAudio" - } - }, - "22": { - "inputs": { - "frame_rate": [ - "23", - 0 - ], - "positive": [ - "3", - 0 - ], - "negative": [ - "4", - 0 - ] - }, - "class_type": "LTXVConditioning", - "_meta": { - "title": "LTXVConditioning" - } - }, - "23": { - "inputs": { - "value": 25 - }, - "class_type": "FloatConstant", - "_meta": { - "title": "Float Constant" - } - }, - "26": { - "inputs": { - "frames_number": [ - "27", - 0 - ], - "frame_rate": [ - "42", - 0 - ], - "batch_size": 1 - }, - "class_type": "LTXVEmptyLatentAudio", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Empty Latent Audio" - } - }, - "27": { - "inputs": { - "value": 105 - }, - "class_type": "INTConstant", - "_meta": { - "title": "INT Constant" - } - }, - "28": { - "inputs": { - "video_latent": [ - "43", - 0 - ], - "audio_latent": [ - "26", - 0 - ], - "model": [ - "44", - 0 - ] - }, - "class_type": "LTXVConcatAVLatent", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Concat AV Latent" - } - }, - "29": { - "inputs": { - "av_latent": [ - "41", - 0 - ], - "model": [ - "28", - 1 - ] - }, - "class_type": "LTXVSeparateAVLatent", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Separate AV Latent" - } - }, - "41": { - "inputs": { - "noise": [ - "11", - 0 - ], - "guider": [ - "17", - 0 - ], - "sampler": [ - "8", - 0 - ], - "sigmas": [ - "9", - 0 - ], - "latent_image": [ - "28", - 0 - ] - }, - "class_type": "SamplerCustomAdvanced", - "_meta": { - "title": "SamplerCustomAdvanced" - } - }, - "42": { - "inputs": { - "a": [ - "23", - 0 - ] - }, - "class_type": "CM_FloatToInt", - "_meta": { - "title": "FloatToInt" - } - }, - "43": { - "inputs": { - "width": 768, - "height": 512, - "length": [ - "27", - 0 - ], - "batch_size": 1 - }, - "class_type": "EmptyLTXVLatentVideo", - "_meta": { - "title": "EmptyLTXVLatentVideo" - } - }, - "44": { - "inputs": { - "torch_compile": true, - "disable_backup": false, - "model": [ - "1", - 0 - ] - }, - "class_type": "LTXVSequenceParallelMultiGPUPatcher", - "_meta": { - "title": "LTXVSequenceParallelMultiGPUPatcher" - } - }, - "45": { - "inputs": { - "frame_idx": 0, - "strength": 1 - }, - "class_type": "LTXVAddGuide", - "_meta": { - "title": "LTXVAddGuide" - } - } - }, - "comfy_fork_version": "feature/av_inference@a6994ed1", - "VHS_latentpreview": false, - "VHS_latentpreviewrate": 0, - "VHS_MetadataImage": true, - "VHS_KeepIntermediate": true - }, - "version": 0.4 -} \ No newline at end of file diff --git a/src/components/core/service/templateLoader.ts b/src/components/core/service/templateLoader.ts index 7b9db65bc..3ad66852a 100644 --- a/src/components/core/service/templateLoader.ts +++ b/src/components/core/service/templateLoader.ts @@ -7,9 +7,7 @@ import type { import { ServiceTemplateSchema } from '../../../utils/config/schemas.js' import { CORE_LOGGER } from '../../../utils/logging/common.js' -// Resolves `relPath` against `resolvedDir` (an already-resolved absolute dir), rejecting any -// path that escapes it (e.g. via `../`). Returns the resolved absolute path, or null if it -// would land outside `resolvedDir`. +// Null when `relPath` escapes `resolvedDir` — template paths are author-controlled. function resolveInTemplatesDir(resolvedDir: string, relPath: string): string | null { const target = resolve(resolvedDir, relPath) if (target !== resolvedDir && !target.startsWith(resolvedDir + sep)) { diff --git a/src/test/unit/service/serviceSchemas.test.ts b/src/test/unit/service/serviceSchemas.test.ts index e26642e63..d361a15ca 100644 --- a/src/test/unit/service/serviceSchemas.test.ts +++ b/src/test/unit/service/serviceSchemas.test.ts @@ -86,9 +86,9 @@ describe('ServiceTemplateSchema', () => { }).success ).to.equal(true) }) - it('ltx-video-ugc-product/testimonial: templates match ServiceTemplateSchema', () => { + it('ltx-video-ugc-product/multishot: templates match ServiceTemplateSchema', () => { const dir = join(process.cwd(), 'docs', 'serviceTemplates') - for (const file of ['ltx-video-ugc-product.json', 'ltx-video-ugc-testimonial.json']) { + for (const file of ['ltx-video-ugc-product.json', 'ltx-video-ugc-multishot.json']) { const tmpl = JSON.parse(readFileSync(join(dir, file), 'utf8')) expect(ServiceTemplateSchema.safeParse(tmpl).success).to.equal(true) } diff --git a/src/test/unit/service/templateLoader.test.ts b/src/test/unit/service/templateLoader.test.ts index a323df233..b6059d3e7 100644 --- a/src/test/unit/service/templateLoader.test.ts +++ b/src/test/unit/service/templateLoader.test.ts @@ -137,4 +137,23 @@ describe('loadServiceTemplates', () => { expect(tmpl.command[0]).to.equal('#!/bin/bash\necho hi\n') expect(tmpl).to.not.have.property('commandFile') }) + + it('13. commandFile escaping the templates dir skips the whole template', async () => { + const outsideDir = mkdtempSync(join(tmpdir(), 'svc-templates-outside-')) + try { + const secret = join(outsideDir, 'secret.sh') + writeFileSync(secret, 'echo pwned\n') + writeFileSync( + join(dir, 'a.json'), + JSON.stringify({ + ...valid('tmpl-escape-cmd'), + commandFile: relative(dir, secret) + }) + ) + // A bad workflow is dropped on its own; a template with no command is not servable. + expect(await loadServiceTemplates(dir)).to.deep.equal([]) + } finally { + rmSync(outsideDir, { recursive: true, force: true }) + } + }) }) From 11fb2ea30a152c7423ea335a5b8163e49b2e1c89 Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Thu, 6 Aug 2026 09:38:16 +0300 Subject: [PATCH 07/29] multishoot v2 --- docs/serviceTemplates/README.md | 24 +- .../ltx-video-ugc-bootstrap.sh | 79 +- .../ltx-video-ugc-multishot.json | 14 +- .../ltx-video-ugc-product.json | 4 +- .../workflows/ocean_ugc_assemble.json | 1759 +++ .../workflows/ocean_ugc_multishot.json | 195 +- .../workflows/ocean_ugc_product.json | 9939 ++++++++--------- 7 files changed, 6908 insertions(+), 5106 deletions(-) create mode 100644 docs/serviceTemplates/workflows/ocean_ugc_assemble.json diff --git a/docs/serviceTemplates/README.md b/docs/serviceTemplates/README.md index 8cfa2c33a..a8a9726ab 100644 --- a/docs/serviceTemplates/README.md +++ b/docs/serviceTemplates/README.md @@ -117,16 +117,24 @@ goes to `/tmp` and is lost on stop. ### `ltx-video-ugc-multishot.json` — ComfyUI, LTX-2.3 multishot UGC reel (GPU) Same image and bucket behavior, but builds a 15-shot vertical reel (704×1280, 5 s per shot) -with one consistent character, using `workflows/ocean_ugc_multishot.json`. +with one consistent character. Ships two workflows: -Upload a character reference sheet, type one prompt per line into the shot-list box, then set -ComfyUI's Queue **batch count to 15**. Each shot becomes its own queue item, cancellable -individually from the queue panel. Clips save to the bucket root as `shot_00.mp4` .. -`shot_14.mp4` for assembly in your own editor. +- `workflows/ocean_ugc_multishot.json` — renders one shot per Run. +- `workflows/ocean_ugc_assemble.json` — concatenates rendered shots into one reel. -The shot index wraps at the shot count, so a second batch in the same session starts again at -line 0 rather than running off the end of the list. Update that count if you change the number -of lines. +Upload a character reference sheet, type one prompt per line into the shot-list box, then click +**Run**. Each Run renders the shot at the current shot index and the index advances +automatically, so review the clip before running the next. Don't like a take? Set the index back +to that shot's number and Run again — SaveVideo appends a counter rather than overwriting, so +both takes land in the bucket and you choose which to use at assembly time. + +Clips save to the bucket root as `shot_00.mp4`, `shot_01.mp4`, etc. Once every shot looks good, +switch to the **Assemble reel** workflow, pick the shots to use in its `LoadVideo` slots, and +Run — it concatenates them (image + audio) into one clip inside ComfyUI, no external editor +needed. + +The shot index wraps at the shot count, so a run past the last line starts again at line 0. +Update *Shots in list* if you change how many lines are in the shot list. ## The shared bootstrap (`ltx-video-ugc-bootstrap.sh`) diff --git a/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh b/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh index 17d852f9b..d9efd97c9 100755 --- a/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh +++ b/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh @@ -16,9 +16,13 @@ echo "[ocean] $(id) | /data/outputs: $(ls -ld /data/outputs 2>&1 | head -1)" if [ -d /data/outputs ]; then BASE=/data/outputs/comfy - OUTPUT_DIR_ARGS="--output-directory /data/outputs" + # Rendered shots land in --output-directory; LoadVideo's dropdown only lists --input-directory. + # Same path for both, so the assemble workflow can pick up clips the generate workflow made. + INPUT_DIR=/data/outputs + OUTPUT_DIR_ARGS="--output-directory /data/outputs --input-directory $INPUT_DIR" else BASE=/tmp/comfy + INPUT_DIR="$BASE/input" OUTPUT_DIR_ARGS="" echo "[ocean] no bucket mounted — models download to the container and are lost on stop." \ "If you did select a bucket, the node is not applying outputBucketId: check that it runs" \ @@ -27,7 +31,7 @@ fi MODELS="$BASE/models" mkdir -p "$MODELS/checkpoints" "$MODELS/loras" "$MODELS/text_encoders" \ - "$MODELS/latent_upscale_models" "$BASE/output" "$BASE/input" "$BASE/temp" "$BASE/user" + "$MODELS/latent_upscale_models" "$BASE/output" "$INPUT_DIR" "$BASE/temp" "$BASE/user" # .part then rename: a truncated file in a persistent bucket would look cached forever. get() { @@ -58,20 +62,54 @@ get() { WORKFLOW_JSON="" if [ -n "$WF_ID" ] && [ -n "${COMFY_WORKFLOW:-}" ]; then - # Pack dir and filename are both $WF_ID, so ?template=&source= resolves with no - # hard-coded name on either side. + # Pack dir is named after $WF_ID (the first workflow), so ?template=&source= resolves + # with no hard-coded name on either side. COMFY_WORKFLOW carries every workflow the template + # ships as {"": , ...} — each entry gets its own file in the pack + sidebar. PACK="$BASE/custom_nodes/$WF_ID" SAVED="$BASE/user/default/workflows" mkdir -p "$PACK/example_workflows" "$SAVED" echo 'NODE_CLASS_MAPPINGS = {}' > "$PACK/__init__.py" + RAW="$PACK/.comfy_workflow_payload.json" # Escrow is already claimed: a corrupt payload must not kill the container. - if printf '%s' "$COMFY_WORKFLOW" | base64 -d | gunzip > "$PACK/example_workflows/$WF_ID.json"; then - cp "$PACK/example_workflows/$WF_ID.json" "$SAVED/$WF_ID.json" - WORKFLOW_JSON="$PACK/example_workflows/$WF_ID.json" - echo "[ocean] installed workflow $WF_ID (template pack + Workflows sidebar)" + if printf '%s' "$COMFY_WORKFLOW" | base64 -d | gunzip > "$RAW"; then + # `|| true`: a decoded-but-malformed payload (wrong shape, bad ids) must not abort either. + INSTALLED=$(python3.13 - "$RAW" "$PACK/example_workflows" "$SAVED" <<'PY' || true +import json, re, sys +raw_path, pack_dir, saved_dir = sys.argv[1:4] +try: + workflows = json.load(open(raw_path, encoding='utf-8')) + if not isinstance(workflows, dict) or not workflows: + raise ValueError('expected a non-empty object of "": ') +except Exception as e: + print(f'[ocean] COMFY_WORKFLOW did not decode to an id -> graph object: {e}', file=sys.stderr) + sys.exit(0) +for wf_id, graph in workflows.items(): + if not re.fullmatch(r'[A-Za-z0-9_.-]{1,64}', wf_id): + print(f'[ocean] skipping workflow with unsafe id {wf_id!r}', file=sys.stderr) + continue + if not isinstance(graph, dict): + print(f'[ocean] skipping workflow {wf_id!r} — graph is not an object', file=sys.stderr) + continue + text = json.dumps(graph, ensure_ascii=False) + open(f'{pack_dir}/{wf_id}.json', 'w', encoding='utf-8').write(text) + open(f'{saved_dir}/{wf_id}.json', 'w', encoding='utf-8').write(text) + print(wf_id) +PY +) + rm -f "$RAW" + if [ -n "$INSTALLED" ]; then + echo "[ocean] installed workflows: $(echo "$INSTALLED" | tr '\n' ' ') (template pack + Workflows sidebar)" + if [ -f "$PACK/example_workflows/$WF_ID.json" ]; then + WORKFLOW_JSON="$PACK/example_workflows/$WF_ID.json" + else + echo "[ocean] COMFY_WORKFLOW_ID ($WF_ID) was not among the installed workflows" >&2 + fi + else + echo "[ocean] no workflows installed from COMFY_WORKFLOW — starting ComfyUI without one" >&2 + fi else echo "[ocean] failed to decode COMFY_WORKFLOW — starting ComfyUI without a workflow" >&2 - rm -f "$PACK/example_workflows/$WF_ID.json" + rm -f "$RAW" fi fi @@ -117,6 +155,29 @@ else echo "[ocean] no workflow supplied — skipping model download" >&2 fi +# The graph's LoadImage/LoadAudio widgets name example assets that ship inside the +# comfyui-workflow-templates package. Copying them into input/ is what makes the first Queue +# work without the user uploading anything. +if [ -n "$WORKFLOW_JSON" ]; then + python3.13 - "$WORKFLOW_JSON" "$INPUT_DIR" <<'PY' || true +import json, shutil, sys +from pathlib import Path +try: + import comfyui_workflow_templates as pkg + src = Path(pkg.__file__).parent / 'templates' + graph = json.load(open(sys.argv[1])) + dest = Path(sys.argv[2]) + for node in graph.get('nodes', []): + if node.get('type') in ('LoadImage', 'LoadAudio'): + name = (node.get('widgets_values') or [None])[0] + if name and (src / name).is_file() and not (dest / name).exists(): + shutil.copy2(src / name, dest / name) + print(f'[ocean] seeded input {name}') +except Exception as e: + print(f'[ocean] could not seed example inputs: {e}', file=sys.stderr) +PY +fi + export HOME="$BASE" export PYTHONPYCACHEPREFIX="$BASE/.cache/pycache" export XDG_CACHE_HOME="$BASE/.cache" diff --git a/docs/serviceTemplates/ltx-video-ugc-multishot.json b/docs/serviceTemplates/ltx-video-ugc-multishot.json index 782bca074..d4a3bcb31 100644 --- a/docs/serviceTemplates/ltx-video-ugc-multishot.json +++ b/docs/serviceTemplates/ltx-video-ugc-multishot.json @@ -1,7 +1,7 @@ { "id": "ltx-video-ugc-multishot", "name": "ComfyUI — UGC multishot reel (LTX-2.3)", - "description": "ComfyUI preloaded with LTX-2.3 (IC-LoRA Ingredients) for a 15-shot vertical UGC product reel with one consistent character. Usage: upload a character reference sheet as the workflow's image input, type one prompt per line in its shot-list text box (each line a distinct camera angle/action, e.g. close-up on the product, hands unboxing, walking outdoors), then set ComfyUI's Queue batch count to 15 and hit Queue — each shot runs as its own separate queue item, individually cancellable, and the shot index advances automatically between them. Clips are 9:16 vertical (704×1280, both divisible by 32 as LTX requires) at 5 seconds each (125 frames at 25 fps), saved to the bucket root as shot_00.mp4 .. shot_14.mp4 in order for you to assemble in your own editor — there is no in-container concatenation. Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the ~39 GiB of weights download once and are reused, and the numbered shot clips land in the bucket root where the storage API's listFiles can see them. Needs a CUDA GPU with 48 GB+ VRAM.", + "description": "ComfyUI preloaded with LTX-2.3 (IC-LoRA Ingredients) for a 15-shot vertical UGC product reel with one consistent character. Usage: upload a character reference sheet as the workflow's image input, type one prompt per line in its shot-list text box (each line a distinct camera angle/action, e.g. close-up on the product, hands unboxing, walking outdoors), then click Run once — it renders the shot at the current shot index and the index advances automatically, so review each clip before running the next; set the index back to a shot number and Run again to redo one you don't like. Clips are 9:16 vertical (704×1280, both divisible by 32 as LTX requires) at 5 seconds each (125 frames at 25 fps), saved to the bucket root as shot_00.mp4, shot_01.mp4, etc. Once every shot is good, switch to the Assemble reel workflow to concatenate them into one clip inside ComfyUI — no external editor needed. Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the ~39 GiB of weights download once and are reused, and the numbered shot clips land in the bucket root where the storage API's listFiles can see them. Needs a CUDA GPU with 48 GB+ VRAM.", "image": "yanwk/comfyui-boot", "tag": "cu130-megapak-pt211-20260803", "exposedPorts": [ @@ -16,8 +16,14 @@ { "id": "ocean_ugc_multishot", "name": "Multishot reel (15 shots)", - "description": "Upload a character reference sheet and a 15-line shot list, set Queue batch count to 15, get 15 numbered 9:16 clips (shot_00..shot_14) with one consistent character.", + "description": "Upload a character reference sheet and a 15-line shot list, then click Run once per shot — the shot index advances automatically and you review each clip before the next. Produces numbered 9:16 clips (shot_00.mp4, shot_01.mp4, …) with one consistent character.", "file": "workflows/ocean_ugc_multishot.json" + }, + { + "id": "ocean_ugc_assemble", + "name": "Assemble reel", + "description": "Concatenates up to 8 rendered shot_NN.mp4 clips (video + audio) into a single reel using core ComfyUI video nodes — pick clips in the LoadVideo dropdowns, bypass any slots you don't need, and Run.", + "file": "workflows/ocean_ugc_assemble.json" } ], "userConfigurableEnvVars": [ @@ -38,8 +44,8 @@ }, { "id": "ram", - "min": 32, - "recommended": 64, + "min": 48, + "recommended": 128, "unit": "GB" }, { diff --git a/docs/serviceTemplates/ltx-video-ugc-product.json b/docs/serviceTemplates/ltx-video-ugc-product.json index 1b651ef17..b8367a324 100644 --- a/docs/serviceTemplates/ltx-video-ugc-product.json +++ b/docs/serviceTemplates/ltx-video-ugc-product.json @@ -38,8 +38,8 @@ }, { "id": "ram", - "min": 32, - "recommended": 64, + "min": 48, + "recommended": 128, "unit": "GB" }, { diff --git a/docs/serviceTemplates/workflows/ocean_ugc_assemble.json b/docs/serviceTemplates/workflows/ocean_ugc_assemble.json new file mode 100644 index 000000000..12539f448 --- /dev/null +++ b/docs/serviceTemplates/workflows/ocean_ugc_assemble.json @@ -0,0 +1,1759 @@ +{ + "id": "f0a7b59b-e37f-4ce2-9564-e772ecd7d9c2", + "revision": 0, + "last_node_id": 51, + "last_link_id": 40, + "nodes": [ + { + "id": 1, + "type": "MarkdownNote", + "pos": [ + 0.0, + -320.0 + ], + "size": [ + 1600, + 260 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": {}, + "widgets_values": [ + "## Assemble reel\n\nPick a rendered `shot_NN.mp4` in each slot's **file** dropdown below (the dropdown lists what's been generated in the bucket — hit ComfyUI's refresh icon if a clip you just rendered isn't listed yet).\n\n**Bypass (Ctrl+B) any slot you don't need.** The chain concatenates whichever slots stay active, in order, so an unused tail slot just needs bypassing — no rewiring.\n\nClick **Run** once. The stitched reel saves as `reel_00001.mp4` in the bucket root.\n\nOnly 8 slots: each 5 s clip is ~125 frames at 704×1280 in float32, about 1.3 GB as a tensor — 15 slots (the multishot template's shot count) would need ~20 GB of RAM just to hold the frames. 8 slots gives a ~40 s reel and stays comfortably inside this template's 128 GB." + ], + "title": "How to use" + }, + { + "id": 10, + "type": "LoadVideo", + "pos": [ + 0.0, + 0.0 + ], + "size": [ + 270, + 100 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 1 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "LoadVideo" + }, + "widgets_values": [ + "shot_00.mp4" + ], + "title": "Shot 1" + }, + { + "id": 20, + "type": "GetVideoComponents", + "pos": [ + 350.0, + 0.0 + ], + "size": [ + 270, + 126 + ], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 1 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 9 + ] + }, + { + "name": "audio", + "type": "AUDIO", + "links": [ + 23 + ] + }, + { + "name": "fps", + "type": "FLOAT", + "links": [ + 38 + ] + }, + { + "name": "bit_depth", + "type": "INT", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "GetVideoComponents" + }, + "title": "Shot 1 components" + }, + { + "id": 11, + "type": "LoadVideo", + "pos": [ + 0.0, + 150.0 + ], + "size": [ + 270, + 100 + ], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 2 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "LoadVideo" + }, + "widgets_values": [ + "shot_01.mp4" + ], + "title": "Shot 2" + }, + { + "id": 21, + "type": "GetVideoComponents", + "pos": [ + 350.0, + 150.0 + ], + "size": [ + 270, + 126 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 2 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 10 + ] + }, + { + "name": "audio", + "type": "AUDIO", + "links": [ + 24 + ] + }, + { + "name": "fps", + "type": "FLOAT", + "links": [] + }, + { + "name": "bit_depth", + "type": "INT", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "GetVideoComponents" + }, + "title": "Shot 2 components" + }, + { + "id": 12, + "type": "LoadVideo", + "pos": [ + 0.0, + 300.0 + ], + "size": [ + 270, + 100 + ], + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 3 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "LoadVideo" + }, + "widgets_values": [ + "shot_02.mp4" + ], + "title": "Shot 3" + }, + { + "id": 22, + "type": "GetVideoComponents", + "pos": [ + 350.0, + 300.0 + ], + "size": [ + 270, + 126 + ], + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 3 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 12 + ] + }, + { + "name": "audio", + "type": "AUDIO", + "links": [ + 26 + ] + }, + { + "name": "fps", + "type": "FLOAT", + "links": [] + }, + { + "name": "bit_depth", + "type": "INT", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "GetVideoComponents" + }, + "title": "Shot 3 components" + }, + { + "id": 13, + "type": "LoadVideo", + "pos": [ + 0.0, + 450.0 + ], + "size": [ + 270, + 100 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 4 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "LoadVideo" + }, + "widgets_values": [ + "shot_03.mp4" + ], + "title": "Shot 4" + }, + { + "id": 23, + "type": "GetVideoComponents", + "pos": [ + 350.0, + 450.0 + ], + "size": [ + 270, + 126 + ], + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 4 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 14 + ] + }, + { + "name": "audio", + "type": "AUDIO", + "links": [ + 28 + ] + }, + { + "name": "fps", + "type": "FLOAT", + "links": [] + }, + { + "name": "bit_depth", + "type": "INT", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "GetVideoComponents" + }, + "title": "Shot 4 components" + }, + { + "id": 14, + "type": "LoadVideo", + "pos": [ + 0.0, + 600.0 + ], + "size": [ + 270, + 100 + ], + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 5 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "LoadVideo" + }, + "widgets_values": [ + "shot_04.mp4" + ], + "title": "Shot 5" + }, + { + "id": 24, + "type": "GetVideoComponents", + "pos": [ + 350.0, + 600.0 + ], + "size": [ + 270, + 126 + ], + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 5 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 16 + ] + }, + { + "name": "audio", + "type": "AUDIO", + "links": [ + 30 + ] + }, + { + "name": "fps", + "type": "FLOAT", + "links": [] + }, + { + "name": "bit_depth", + "type": "INT", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "GetVideoComponents" + }, + "title": "Shot 5 components" + }, + { + "id": 15, + "type": "LoadVideo", + "pos": [ + 0.0, + 750.0 + ], + "size": [ + 270, + 100 + ], + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 6 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "LoadVideo" + }, + "widgets_values": [ + "shot_05.mp4" + ], + "title": "Shot 6" + }, + { + "id": 25, + "type": "GetVideoComponents", + "pos": [ + 350.0, + 750.0 + ], + "size": [ + 270, + 126 + ], + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 6 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 18 + ] + }, + { + "name": "audio", + "type": "AUDIO", + "links": [ + 32 + ] + }, + { + "name": "fps", + "type": "FLOAT", + "links": [] + }, + { + "name": "bit_depth", + "type": "INT", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "GetVideoComponents" + }, + "title": "Shot 6 components" + }, + { + "id": 16, + "type": "LoadVideo", + "pos": [ + 0.0, + 900.0 + ], + "size": [ + 270, + 100 + ], + "flags": {}, + "order": 13, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 7 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "LoadVideo" + }, + "widgets_values": [ + "shot_06.mp4" + ], + "title": "Shot 7" + }, + { + "id": 26, + "type": "GetVideoComponents", + "pos": [ + 350.0, + 900.0 + ], + "size": [ + 270, + 126 + ], + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 7 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 20 + ] + }, + { + "name": "audio", + "type": "AUDIO", + "links": [ + 34 + ] + }, + { + "name": "fps", + "type": "FLOAT", + "links": [] + }, + { + "name": "bit_depth", + "type": "INT", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "GetVideoComponents" + }, + "title": "Shot 7 components" + }, + { + "id": 17, + "type": "LoadVideo", + "pos": [ + 0.0, + 1050.0 + ], + "size": [ + 270, + 100 + ], + "flags": {}, + "order": 15, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 8 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "LoadVideo" + }, + "widgets_values": [ + "shot_07.mp4" + ], + "title": "Shot 8" + }, + { + "id": 27, + "type": "GetVideoComponents", + "pos": [ + 350.0, + 1050.0 + ], + "size": [ + 270, + 126 + ], + "flags": {}, + "order": 16, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 8 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 22 + ] + }, + { + "name": "audio", + "type": "AUDIO", + "links": [ + 36 + ] + }, + { + "name": "fps", + "type": "FLOAT", + "links": [] + }, + { + "name": "bit_depth", + "type": "INT", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "GetVideoComponents" + }, + "title": "Shot 8 components" + }, + { + "id": 30, + "type": "ImageBatch", + "pos": [ + 760.0, + 260.0 + ], + "size": [ + 210, + 60 + ], + "flags": { + "collapsed": true + }, + "order": 17, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 9 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 10 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 11 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 31, + "type": "ImageBatch", + "pos": [ + 950.0, + 260.0 + ], + "size": [ + 210, + 60 + ], + "flags": { + "collapsed": true + }, + "order": 18, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 11 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 12 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 13 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 32, + "type": "ImageBatch", + "pos": [ + 1140.0, + 260.0 + ], + "size": [ + 210, + 60 + ], + "flags": { + "collapsed": true + }, + "order": 19, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 13 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 14 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 15 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 33, + "type": "ImageBatch", + "pos": [ + 1330.0, + 260.0 + ], + "size": [ + 210, + 60 + ], + "flags": { + "collapsed": true + }, + "order": 20, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 15 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 16 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 17 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 34, + "type": "ImageBatch", + "pos": [ + 1520.0, + 260.0 + ], + "size": [ + 210, + 60 + ], + "flags": { + "collapsed": true + }, + "order": 21, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 17 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 18 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 19 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 35, + "type": "ImageBatch", + "pos": [ + 1710.0, + 260.0 + ], + "size": [ + 210, + 60 + ], + "flags": { + "collapsed": true + }, + "order": 22, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 19 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 20 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 21 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 36, + "type": "ImageBatch", + "pos": [ + 1900.0, + 260.0 + ], + "size": [ + 210, + 60 + ], + "flags": { + "collapsed": true + }, + "order": 23, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 21 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 22 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 37 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 40, + "type": "AudioConcat", + "pos": [ + 760.0, + 480.0 + ], + "size": [ + 210, + 78 + ], + "flags": { + "collapsed": true + }, + "order": 24, + "mode": 0, + "inputs": [ + { + "name": "audio1", + "type": "AUDIO", + "link": 23 + }, + { + "name": "audio2", + "type": "AUDIO", + "link": 24 + } + ], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 25 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "AudioConcat" + }, + "widgets_values": [ + "after" + ] + }, + { + "id": 41, + "type": "AudioConcat", + "pos": [ + 950.0, + 480.0 + ], + "size": [ + 210, + 78 + ], + "flags": { + "collapsed": true + }, + "order": 25, + "mode": 0, + "inputs": [ + { + "name": "audio1", + "type": "AUDIO", + "link": 25 + }, + { + "name": "audio2", + "type": "AUDIO", + "link": 26 + } + ], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 27 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "AudioConcat" + }, + "widgets_values": [ + "after" + ] + }, + { + "id": 42, + "type": "AudioConcat", + "pos": [ + 1140.0, + 480.0 + ], + "size": [ + 210, + 78 + ], + "flags": { + "collapsed": true + }, + "order": 26, + "mode": 0, + "inputs": [ + { + "name": "audio1", + "type": "AUDIO", + "link": 27 + }, + { + "name": "audio2", + "type": "AUDIO", + "link": 28 + } + ], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 29 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "AudioConcat" + }, + "widgets_values": [ + "after" + ] + }, + { + "id": 43, + "type": "AudioConcat", + "pos": [ + 1330.0, + 480.0 + ], + "size": [ + 210, + 78 + ], + "flags": { + "collapsed": true + }, + "order": 27, + "mode": 0, + "inputs": [ + { + "name": "audio1", + "type": "AUDIO", + "link": 29 + }, + { + "name": "audio2", + "type": "AUDIO", + "link": 30 + } + ], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 31 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "AudioConcat" + }, + "widgets_values": [ + "after" + ] + }, + { + "id": 44, + "type": "AudioConcat", + "pos": [ + 1520.0, + 480.0 + ], + "size": [ + 210, + 78 + ], + "flags": { + "collapsed": true + }, + "order": 28, + "mode": 0, + "inputs": [ + { + "name": "audio1", + "type": "AUDIO", + "link": 31 + }, + { + "name": "audio2", + "type": "AUDIO", + "link": 32 + } + ], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 33 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "AudioConcat" + }, + "widgets_values": [ + "after" + ] + }, + { + "id": 45, + "type": "AudioConcat", + "pos": [ + 1710.0, + 480.0 + ], + "size": [ + 210, + 78 + ], + "flags": { + "collapsed": true + }, + "order": 29, + "mode": 0, + "inputs": [ + { + "name": "audio1", + "type": "AUDIO", + "link": 33 + }, + { + "name": "audio2", + "type": "AUDIO", + "link": 34 + } + ], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 35 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "AudioConcat" + }, + "widgets_values": [ + "after" + ] + }, + { + "id": 46, + "type": "AudioConcat", + "pos": [ + 1900.0, + 480.0 + ], + "size": [ + 210, + 78 + ], + "flags": { + "collapsed": true + }, + "order": 30, + "mode": 0, + "inputs": [ + { + "name": "audio1", + "type": "AUDIO", + "link": 35 + }, + { + "name": "audio2", + "type": "AUDIO", + "link": 36 + } + ], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 39 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "AudioConcat" + }, + "widgets_values": [ + "after" + ] + }, + { + "id": 50, + "type": "CreateVideo", + "pos": [ + 2180.0, + 350.0 + ], + "size": [ + 270, + 150 + ], + "flags": {}, + "order": 31, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 37 + }, + { + "name": "fps", + "type": "FLOAT", + "widget": { + "name": "fps" + }, + "link": 38 + }, + { + "name": "audio", + "type": "AUDIO", + "shape": 7, + "link": 39 + } + ], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 40 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "CreateVideo" + }, + "widgets_values": [ + 25.0, + 8 + ], + "title": "Create reel" + }, + { + "id": 51, + "type": "SaveVideo", + "pos": [ + 2520.0, + 350.0 + ], + "size": [ + 400, + 300 + ], + "flags": {}, + "order": 32, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 40 + } + ], + "outputs": [ + { + "name": "video", + "type": "VIDEO", + "links": null + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "SaveVideo" + }, + "widgets_values": [ + "reel", + "auto", + "auto" + ], + "title": "Output reel" + } + ], + "links": [ + [ + 1, + 10, + 0, + 20, + 0, + "VIDEO" + ], + [ + 2, + 11, + 0, + 21, + 0, + "VIDEO" + ], + [ + 3, + 12, + 0, + 22, + 0, + "VIDEO" + ], + [ + 4, + 13, + 0, + 23, + 0, + "VIDEO" + ], + [ + 5, + 14, + 0, + 24, + 0, + "VIDEO" + ], + [ + 6, + 15, + 0, + 25, + 0, + "VIDEO" + ], + [ + 7, + 16, + 0, + 26, + 0, + "VIDEO" + ], + [ + 8, + 17, + 0, + 27, + 0, + "VIDEO" + ], + [ + 9, + 20, + 0, + 30, + 0, + "IMAGE" + ], + [ + 10, + 21, + 0, + 30, + 1, + "IMAGE" + ], + [ + 11, + 30, + 0, + 31, + 0, + "IMAGE" + ], + [ + 12, + 22, + 0, + 31, + 1, + "IMAGE" + ], + [ + 13, + 31, + 0, + 32, + 0, + "IMAGE" + ], + [ + 14, + 23, + 0, + 32, + 1, + "IMAGE" + ], + [ + 15, + 32, + 0, + 33, + 0, + "IMAGE" + ], + [ + 16, + 24, + 0, + 33, + 1, + "IMAGE" + ], + [ + 17, + 33, + 0, + 34, + 0, + "IMAGE" + ], + [ + 18, + 25, + 0, + 34, + 1, + "IMAGE" + ], + [ + 19, + 34, + 0, + 35, + 0, + "IMAGE" + ], + [ + 20, + 26, + 0, + 35, + 1, + "IMAGE" + ], + [ + 21, + 35, + 0, + 36, + 0, + "IMAGE" + ], + [ + 22, + 27, + 0, + 36, + 1, + "IMAGE" + ], + [ + 23, + 20, + 1, + 40, + 0, + "AUDIO" + ], + [ + 24, + 21, + 1, + 40, + 1, + "AUDIO" + ], + [ + 25, + 40, + 0, + 41, + 0, + "AUDIO" + ], + [ + 26, + 22, + 1, + 41, + 1, + "AUDIO" + ], + [ + 27, + 41, + 0, + 42, + 0, + "AUDIO" + ], + [ + 28, + 23, + 1, + 42, + 1, + "AUDIO" + ], + [ + 29, + 42, + 0, + 43, + 0, + "AUDIO" + ], + [ + 30, + 24, + 1, + 43, + 1, + "AUDIO" + ], + [ + 31, + 43, + 0, + 44, + 0, + "AUDIO" + ], + [ + 32, + 25, + 1, + 44, + 1, + "AUDIO" + ], + [ + 33, + 44, + 0, + 45, + 0, + "AUDIO" + ], + [ + 34, + 26, + 1, + 45, + 1, + "AUDIO" + ], + [ + 35, + 45, + 0, + 46, + 0, + "AUDIO" + ], + [ + 36, + 27, + 1, + 46, + 1, + "AUDIO" + ], + [ + 37, + 36, + 0, + 50, + 0, + "IMAGE" + ], + [ + 38, + 20, + 2, + 50, + 1, + "FLOAT" + ], + [ + 39, + 46, + 0, + 50, + 2, + "AUDIO" + ], + [ + 40, + 50, + 0, + 51, + 0, + "VIDEO" + ] + ], + "groups": [], + "definitions": { + "subgraphs": [] + }, + "config": {}, + "extra": { + "ds": { + "scale": 1, + "offset": [ + 0, + 0 + ] + } + }, + "version": 0.4 +} \ No newline at end of file diff --git a/docs/serviceTemplates/workflows/ocean_ugc_multishot.json b/docs/serviceTemplates/workflows/ocean_ugc_multishot.json index acdd170a4..94c105ba2 100644 --- a/docs/serviceTemplates/workflows/ocean_ugc_multishot.json +++ b/docs/serviceTemplates/workflows/ocean_ugc_multishot.json @@ -1,15 +1,15 @@ { "id": "0112e9af-5129-48ba-af78-92c40ac40b40", "revision": 0, - "last_node_id": 731, + "last_node_id": 732, "last_link_id": 1833, "nodes": [ { "id": 68, "type": "SaveVideo", "pos": [ - 1480, - 2270 + 2160.0, + 0.0 ], "size": [ 910, @@ -61,44 +61,15 @@ "shot", "auto", "auto" - ] - }, - { - "id": 79, - "type": "MarkdownNote", - "pos": [ - -2210, - 2270 - ], - "size": [ - 720, - 1320 - ], - "flags": {}, - "order": 0, - "mode": 0, - "inputs": [], - "outputs": [], - "title": "Model Links", - "properties": { - "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.7", - "widget_ue_connectable": {} - } - }, - "widgets_values": [ - "- Hugging Face (base): [Lightricks/LTX-2.3](https://huggingface.co/Lightricks/LTX-2.3/)\n- Hugging Face (Ingredients IC-LoRA): [Lightricks/LTX-2.3-22b-IC-LoRA-Ingredients](https://huggingface.co/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx-2.3-22b-ic-lora-ingredients-0.9.safetensors)\n- [gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors](https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors)\n\n\n## Model Storage Location\n\n```\n📂 ComfyUI/\n├── 📂 models/\n│ ├── 📂 checkpoints/\n│ │ └── ltx-2.3-22b-distilled-fp8.safetensors\n│ ├── 📂 text_encoders/\n│ │ └── gemma_3_12B_it_fp4_mixed.safetensors\n│ └── 📂 loras/\n│ ├── ltx-2.3-22b-ic-lora-ingredients-0.9.safetensors\n│ └── gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\n```\n\n## Report Issue\n\nNote: Please update ComfyUI first ([guide](https://docs.comfy.org/installation/update_comfyui)) and prepare required models. Desktop/Cloud updates follow stable releases, so some nightly-supported models may not be available yet.\n\n- Cannot run / runtime errors: [ComfyUI/issues](https://github.com/comfyanonymous/ComfyUI/issues)\n- UI / frontend issues: [ComfyUI_frontend/issues](https://github.com/Comfy-Org/ComfyUI_frontend/issues)\n- Workflow issues: [workflow_templates/issues](https://github.com/Comfy-Org/workflow_templates/issues)\n" ], - "color": "#222", - "bgcolor": "#000" + "title": "Output clips" }, { "id": 129, "type": "f9f61b10-b689-4d67-b4fa-0acc1d9b5390", "pos": [ - 890, - 2270 + 1560.0, + 0.0 ], "size": [ 540, @@ -304,52 +275,23 @@ }, "ver": "0.18.1" }, - "widgets_values": [] - }, - { - "id": 698, - "type": "MarkdownNote", - "pos": [ - -1450, - 2270 - ], - "size": [ - 720, - 2630 - ], - "flags": { - "collapsed": false - }, - "order": 1, - "mode": 0, - "inputs": [], - "outputs": [], - "title": "Note: IC-LoRA", - "properties": { - "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.7", - "widget_ue_connectable": {} - } - }, - "widgets_values": [ - "## IC-LoRA Ingredients\n\nSources (official only):\n- Model card: [Lightricks/LTX-2.3-22b-IC-LoRA-Ingredients](https://huggingface.co/Lightricks/LTX-2.3-22b-IC-LoRA-Ingredients)\n- IC-LoRA docs: [docs.ltx.video — IC-LoRA usage guide](https://docs.ltx.video/open-source-model/usage-guides/ic-lo-ra)\n\n### What This Model Is\nFrom the model card:\n\n> This is an IC-LoRA trained on top of LTX-2.3-22B, which conditions video generation on a reference sheet — a single composite image inventorying the characters, props, and location of a scene — so that generated videos keep those elements visually consistent.\n\n\n**Model details (model card):**\n- Base Model: LTX-2.3-22B (dev)\n- Training Type: IC-LoRA (in-context LoRA)\n- Control Type: Reference-sheet conditioning — character / prop / location identity carried into the generated video\n- Reference Downscale Factor: `1` (the reference is provided at the same resolution as the output)\n- Pipeline: the reference sheet is supplied as a static video (the still sheet looped to the output's length and frame rate). Trained with a `video_to_video` strategy over reference latents; no extra color/space transforms are applied at inference.\n\n### Intended Use & Out-of-Scope\nFrom the model card:\n\n- **Intended use:** Generating short video clips that stay faithful to a supplied reference sheet — keeping recurring characters (face and costume), handled props, and the set/location consistent with the sheet while following an action described in the prompt.\n- **Out of scope:** This is not a general text-to-video model — it expects a reference sheet as conditioning. It was trained at a single resolution / length bucket (**768×448**, **121 frames**, **24 fps**); other resolutions, much longer clips, or use without a reference sheet are out of distribution. It does not reproduce identities that are absent from the supplied sheet.\n\n### Control Signal Requirements\nFrom the model card:\n\n- **Control signal type:** Reference sheet — a single composite image with one clean panel per distinct visual element (each character as a face close-up + body turnaround, each prop as a product-style render, and one clean location panel), laid out on a **black background with no text**.\n- **Expected input:** A static video built from the reference sheet, looped to match the output clip's length and frame rate, at the output resolution (downscale factor 1).\n- **Preprocessing:** Author the reference sheet, then loop the still into a static video. Frame count must be **≥ 121** so the reference-encoding / 121-frame read bucket is satisfied; all targets in training were ≥ 121 frames.\n- **Alignment:** The reference video should match the output resolution and frame rate; its frame count must be at least the output length (clamped to ≥ 121).\n\n### Prompt Format\nFrom the model card — the prompt is split into two labeled parts, matching how the model was trained:\n\n```text\nReference sheet: \n\nGenerated video: \n```\n\nAt inference, the reference sheet (as a static video) supplies *what things look like*, and the `Generated video:` portion supplies *what happens*. The model reads the reference latents in-context and renders a new clip whose characters, props, and setting match the sheet.\n\nModel-card gallery examples also show prompts labeled as `### Reference Sheet Description` / `### Target Description`.\n\n### ComfyUI Usage\nFrom the model card:\n\n1. Copy the LoRA weights into `models/loras`.\n2. Load the LTX-2.3-22B base model and add the Ingredients LoRA.\n3. Start at strength `1.0` and adjust to taste.\n4. Use an IC-LoRA / reference workflow from the LTX-2 ComfyUI repository, which already wires the reference (control) input. Connect the reference-sheet static video as the control/reference input; a generic LoRA loader that ignores the reference path will not apply the conditioning.\n\n### Recommended Settings\nFrom the model card:\n\n- LoRA strength / weight: **1.4**\n- Inference steps: **30**\n- Guidance scale: **4.0**\n- Resolution & frames: **768×448**, **121 frames**, **24 fps** (the trained bucket — best results here)\n- Prompting: use the two-part `Reference sheet: … / Generated video: …` structure. The `Reference sheet:` text should describe the panels present; the `Generated video:` text drives the action.\n- Suggested negative prompt: `worst quality, inconsistent motion, blurry, jittery, distorted`\n- Validation used spatiotemporal guidance (STG, mode `stg_v`, block 29, scale 1.0), which can help motion stability.\n\n### Tips & Troubleshooting\nFrom the model card only:\n\n- **Bigger panels carry over better:** The more space an element takes up in the reference image, the more faithfully it carries over into the generated video. Give important characters/props larger, more prominent panels rather than small or crowded ones.\n- **Identity drift:** If a character's face or costume drifts, make sure the reference sheet has a clean, front-facing close-up and full turnaround for that character, and that its panel isn't cluttered or text-laden.\n- **Element not appearing:** The model only reproduces elements present on the sheet — add a dedicated panel for any prop/character you need to persist, and describe it in the `Reference sheet:` portion of the prompt.\n- **Reference too short:** The reference static video must be ≥ 121 frames; shorter references break the reference-encoding bucket.\n" - ], - "color": "#222", - "bgcolor": "#000" + "widgets_values": [], + "title": "Generate video" }, { "id": 709, "type": "RepeatImageBatch", "pos": [ - 150, - 2750 + 1180.0, + 360.0 ], "size": [ 270, 110 ], - "flags": {}, + "flags": { + "collapsed": true + }, "order": 7, "mode": 0, "inputs": [ @@ -387,8 +329,8 @@ "id": 712, "type": "EmptyImage", "pos": [ - 550, - 2830 + 1180.0, + 290.0 ], "size": [ 225, @@ -423,8 +365,8 @@ "id": 715, "type": "PrimitiveInt", "pos": [ - 140, - 2310 + 820.0, + 300.0 ], "size": [ 270, @@ -443,7 +385,7 @@ ] } ], - "title": "Int (duration)", + "title": "Seconds per shot", "properties": { "Node name for S&R": "PrimitiveInt" }, @@ -456,8 +398,8 @@ "id": 716, "type": "PrimitiveInt", "pos": [ - 150, - 2480 + 820.0, + 450.0 ], "size": [ 270, @@ -477,7 +419,7 @@ ] } ], - "title": "Int (fps)", + "title": "FPS", "properties": { "Node name for S&R": "PrimitiveInt" }, @@ -490,8 +432,8 @@ "id": 717, "type": "ComfyMathExpression", "pos": [ - 170, - 2670 + 820.0, + 920.0 ], "size": [ 225, @@ -554,8 +496,8 @@ "id": 721, "type": "GetImageSize", "pos": [ - 540, - 2610 + 1180.0, + 220.0 ], "size": [ 225, @@ -603,14 +545,16 @@ "id": 722, "type": "ResizeAndPadImage", "pos": [ - 530, - 2370 + 1180.0, + 0.0 ], "size": [ 280, 170 ], - "flags": {}, + "flags": { + "collapsed": true + }, "order": 8, "mode": 0, "showAdvanced": false, @@ -647,8 +591,8 @@ "id": 723, "type": "PreviewImage", "pos": [ - 140, - 2980 + 1180.0, + 500.0 ], "size": [ 650, @@ -680,8 +624,8 @@ "id": 724, "type": "LoadImage", "pos": [ - -680, - 2280 + 0.0, + 0.0 ], "size": [ 730, @@ -711,14 +655,15 @@ "widgets_values": [ "german_shepherd_news_anchor_ref.png", "image" - ] + ], + "title": "Character reference" }, { "id": 725, "type": "PrimitiveStringMultiline", "pos": [ - -1700, - 2150 + 0.0, + 720.0 ], "size": [ 400, @@ -737,7 +682,7 @@ ] } ], - "title": "Shot List (one prompt per line)", + "title": "Shot list (one prompt per line)", "properties": { "Node name for S&R": "PrimitiveStringMultiline" }, @@ -749,8 +694,8 @@ "id": 726, "type": "PrimitiveInt", "pos": [ - -1700, - 2560 + 820.0, + 0.0 ], "size": [ 270, @@ -769,7 +714,7 @@ ] } ], - "title": "Int (shot index)", + "title": "Shot index (auto-increments)", "properties": { "Node name for S&R": "PrimitiveInt" }, @@ -782,14 +727,16 @@ "id": 727, "type": "StringFormat", "pos": [ - -1300, - 2560 + 820.0, + 620.0 ], "size": [ 320, 150 ], - "flags": {}, + "flags": { + "collapsed": true + }, "order": 15, "mode": 0, "inputs": [ @@ -821,14 +768,16 @@ "id": 728, "type": "RegexExtract", "pos": [ - -900, - 2150 + 820.0, + 700.0 ], "size": [ 320, 250 ], - "flags": {}, + "flags": { + "collapsed": true + }, "order": 16, "mode": 0, "inputs": [ @@ -868,14 +817,16 @@ "id": 729, "type": "StringFormat", "pos": [ - 1050, - 2650 + 820.0, + 780.0 ], "size": [ 320, 150 ], - "flags": {}, + "flags": { + "collapsed": true + }, "order": 17, "mode": 0, "inputs": [ @@ -907,8 +858,8 @@ "id": 730, "type": "PrimitiveInt", "pos": [ - 150, - 2860 + 820.0, + 150.0 ], "size": [ 270, @@ -927,7 +878,7 @@ ] } ], - "title": "Int (shots in list)", + "title": "Shots in list", "properties": { "Node name for S&R": "PrimitiveInt" }, @@ -940,8 +891,8 @@ "id": 731, "type": "ComfyMathExpression", "pos": [ - 470, - 2860 + 820.0, + 860.0 ], "size": [ 225, @@ -1001,6 +952,28 @@ "widgets_values": [ "a % b" ] + }, + { + "id": 732, + "type": "MarkdownNote", + "pos": [ + 0.0, + -280.0 + ], + "size": [ + 1180.0, + 220.0 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [], + "title": "How to use", + "properties": {}, + "widgets_values": [ + "## 15-shot vertical reel\n\n**1.** Upload your character reference sheet in *Character reference*.\n\n**2.** Type one prompt per line in *Shot list* — one shot each. If you change how many lines there are, set *Shots in list* to match.\n\n**3.** Click **Run** once. It renders the shot at the current *Shot index*, then the index advances automatically — watch it change in the node.\n\n**4.** Review the clip, then Run again for the next shot.\n\n**5.** Don't like a take? Set *Shot index* back to that shot's number and Run again. SaveVideo appends a counter instead of overwriting, so the earlier take is still there — you pick which one to use when you assemble.\n\n**6.** Once every shot looks good, switch to the **Assemble reel** workflow to stitch them into one clip.\n\nClips save as `shot_00.mp4`, `shot_01.mp4`, … — 704×1280, 5 s each." + ] } ], "links": [ diff --git a/docs/serviceTemplates/workflows/ocean_ugc_product.json b/docs/serviceTemplates/workflows/ocean_ugc_product.json index eae6b157c..5688e3453 100644 --- a/docs/serviceTemplates/workflows/ocean_ugc_product.json +++ b/docs/serviceTemplates/workflows/ocean_ugc_product.json @@ -1,5064 +1,5059 @@ { - "id": "07824bbb-6672-4bb0-ac36-4313a519e35b", - "revision": 0, - "last_node_id": 329, - "last_link_id": 646, - "nodes": [ - { - "id": 103, - "type": "MarkdownNote", - "pos": [ - -1220, - 3530 - ], - "size": [ - 750, - 1200 - ], - "flags": {}, - "order": 0, - "mode": 0, - "inputs": [], - "outputs": [], - "title": "Model Links", - "properties": { - "ue_properties": { - "widget_ue_connectable": {}, - "version": "7.7", - "input_ue_unconnectable": {} - } - }, - "widgets_values": [ - "- Huggingface: [Lightricks/LTX-2.3](https://huggingface.co/Lightricks/LTX-2.3/)\n- Github: [LTX-2](https://github.com/Lightricks/LTX-2)\n\n## LTX-2.3 Prompting Tips\n\n1. **Core Actions**: Describe events and actions as they occur over time \n2. **Visual Details**: Describe all visual details you want to appear in the video \n3. **Audio**: Describe sounds and dialogue needed for the scene\n\n## Report LTX-2.3 Issues\nTo report any issues when running this workflow, [go to GitHub](https://github.com/Lightricks/ComfyUI-LTXVideo/issues)\n\n## Model Links (for Local Users)\n\n**checkpoints**\n\n- [ltx-2.3-22b-dev-fp8.safetensors](https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors)\n\n**loras**\n\n- [ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors](https://huggingface.co/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors)\n- [gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors](https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors)\n\n**latent_upscale_models**\n\n- [ltx-2.3-spatial-upscaler-x2-1.1.safetensors](https://huggingface.co/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors)\n\n\n## Model Storage Location\n\n```\n\ud83d\udcc2 ComfyUI/\n\u251c\u2500\u2500 \ud83d\udcc2 models/\n\u2502 \u251c\u2500\u2500 \ud83d\udcc2 checkpoints/\n\u2502 \u2502 \u2514\u2500\u2500 ltx-2.3-22b-dev-fp8.safetensors\n\u2502 \u251c\u2500\u2500 \ud83d\udcc2 loras/\n\u2502 \u2502 \u251c\u2500\u2500 ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors\n\u2502 \u2502 \u2514\u2500\u2500 gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors\n\u2502 \u2514\u2500\u2500 \ud83d\udcc2 latent_upscale_models/\n\u2502 \u2514\u2500\u2500 ltx-2.3-spatial-upscaler-x2-1.1.safetensors\n```\n\n## Report Issue\n\nNote: Please update ComfyUI first ([guide](https://docs.comfy.org/installation/update_comfyui)) and prepare required models. Desktop/Cloud updates follow stable releases, so some nightly-supported models may not be available yet.\n\n- Cannot run / runtime errors: [ComfyUI/issues](https://github.com/Comfy-Org/ComfyUI/issues)\n- UI / frontend issues: [ComfyUI_frontend/issues](https://github.com/Comfy-Org/ComfyUI_frontend/issues)\n- Workflow issues: [workflow_templates/issues](https://github.com/Comfy-Org/workflow_templates/issues)\n" - ], - "color": "#222", - "bgcolor": "#000" - }, - { - "id": 269, - "type": "LoadImage", - "pos": [ - -440, - 3530 - ], - "size": [ - 410, - 530 - ], - "flags": {}, - "order": 1, - "mode": 0, - "inputs": [], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 633 - ] - }, - { - "name": "MASK", - "type": "MASK", - "links": null - } - ], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "LoadImage", - "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_queen.png", - "image" - ] - }, - { - "id": 75, - "type": "SaveVideo", - "pos": [ - 430, - 3530 - ], - "size": [ - 660, - 580 - ], - "flags": { - "collapsed": false - }, - "order": 3, - "mode": 0, - "inputs": [ - { - "name": "video", - "type": "VIDEO", - "link": 632 - } - ], - "outputs": [ - { - "name": "video", - "type": "VIDEO", - "links": null - } - ], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.5.1", - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "Node name for S&R": "SaveVideo", - "ue_properties": { - "widget_ue_connectable": {}, - "version": "7.7", - "input_ue_unconnectable": {} - } - }, - "widgets_values": [ - "ocean_ugc_product", - "auto", - "auto" - ] - }, - { - "id": 320, - "type": "2454ad83-157c-40dd-9f19-5daaf4041ce0", - "pos": [ - 10, - 3530 - ], - "size": [ - 380, - 650 - ], - "flags": {}, - "order": 2, - "mode": 0, - "inputs": [ - { - "label": "first_frame", - "name": "input", - "type": "IMAGE,MASK", - "link": 633 - }, - { - "label": "prompt", - "name": "value", - "type": "STRING", - "widget": { - "name": "value" - }, - "link": null - }, - { - "label": "prompt_enhance", - "name": "value_1", - "type": "BOOLEAN", - "widget": { - "name": "value_1" - }, - "link": null - }, - { - "label": "width", - "name": "value_2", - "type": "INT", - "widget": { - "name": "value_2" - }, - "link": null - }, - { - "label": "height", - "name": "value_3", - "type": "INT", - "widget": { - "name": "value_3" - }, - "link": null - }, - { - "label": "duration", - "name": "value_4", - "type": "INT", - "widget": { - "name": "value_4" - }, - "link": null - }, - { - "label": "fps", - "name": "value_5", - "type": "INT", - "widget": { - "name": "value_5" - }, - "link": null - }, - { - "label": "seed", - "name": "noise_seed", - "type": "INT", - "widget": { - "name": "noise_seed" - }, - "link": null - }, - { - "label": "distilled_lora", - "name": "lora_name", - "type": "COMBO", - "widget": { - "name": "lora_name" - }, - "link": null - }, + "id": "07824bbb-6672-4bb0-ac36-4313a519e35b", + "revision": 0, + "last_node_id": 400, + "last_link_id": 646, + "nodes": [ { - "label": "text_encoder", - "name": "text_encoder", - "type": "COMBO", - "widget": { - "name": "text_encoder" - }, - "link": null - }, - { - "label": "latent_upscale_model", - "name": "model_name", - "type": "COMBO", - "widget": { - "name": "model_name" - }, - "link": null - }, - { - "label": "lora", - "name": "lora_name_1", - "type": "COMBO", - "widget": { - "name": "lora_name_1" - }, - "link": null - } - ], - "outputs": [ - { - "name": "VIDEO", - "type": "VIDEO", - "links": [ - 632 - ] - } - ], - "properties": { - "proxyWidgets": [ - [ - "319", - "value" - ], - [ - "328", - "value" - ], - [ - "312", - "value" - ], - [ - "299", - "value" - ], - [ - "301", - "value" - ], - [ - "300", - "value" - ], - [ - "277", - "noise_seed" - ], - [ - "316", - "ckpt_name" - ], - [ - "285", - "lora_name" - ], - [ - "317", - "text_encoder" - ], - [ - "311", - "model_name" - ], - [ - "324", - "lora_name" - ] - ], - "cnr_id": "comfy-core", - "ver": "0.16.3", - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "ue_properties": { - "widget_ue_connectable": { - "value_1": true, - "value_2": true, - "value_3": true, - "value_4": true, - "lora_name": true, - "model_name": true, - "value_5": true - }, - "version": "7.7", - "input_ue_unconnectable": {} - } - }, - "widgets_values": [] - } - ], - "links": [ - [ - 632, - 320, - 0, - 75, - 0, - "VIDEO" - ], - [ - 633, - 269, - 0, - 320, - 0, - "IMAGE" - ] - ], - "groups": [], - "definitions": { - "subgraphs": [ - { - "id": "2454ad83-157c-40dd-9f19-5daaf4041ce0", - "version": 1, - "state": { - "lastGroupId": 26, - "lastNodeId": 329, - "lastLinkId": 646, - "lastRerouteId": 0 - }, - "revision": 0, - "config": {}, - "name": "Image to Video (LTX-2.3)", - "inputNode": { - "id": -10, - "bounding": [ - 730, - 4110, - 170.162109375, - 308 - ] - }, - "outputNode": { - "id": -20, - "bounding": [ - 6590, - 4360, - 128, - 68 - ] - }, - "inputs": [ - { - "id": "7afd6ea8-c738-4fd9-97b8-66fa905cd381", - "name": "input", - "type": "IMAGE,MASK", - "linkIds": [ - 535 - ], - "localized_name": "input", - "label": "first_frame", - "pos": [ - 876.162109375, - 4134 - ] - }, - { - "id": "9494c550-4172-49c6-930e-5b508f775e77", - "name": "value", - "type": "STRING", - "linkIds": [ - 595 - ], - "label": "prompt", - "pos": [ - 876.162109375, - 4154 - ] - }, - { - "id": "ec291311-2d21-49f9-aaba-24bb2e544ce0", - "name": "value_1", - "type": "BOOLEAN", - "linkIds": [ - 644 - ], - "label": "prompt_enhance", - "pos": [ - 876.162109375, - 4174 - ] - }, - { - "id": "58dbb3f6-f924-4548-96ef-e0e34610bd4e", - "name": "value_2", - "type": "INT", - "linkIds": [ - 597 - ], - "label": "width", - "pos": [ - 876.162109375, - 4194 - ] - }, - { - "id": "6086d5b8-2586-448c-a641-dd14d76dd102", - "name": "value_3", - "type": "INT", - "linkIds": [ - 598 - ], - "label": "height", - "pos": [ - 876.162109375, - 4214 - ] - }, - { - "id": "feb8c2eb-ae48-4fa8-bc24-929552d656c3", - "name": "value_4", - "type": "INT", - "linkIds": [ - 599 - ], - "label": "duration", - "pos": [ - 876.162109375, - 4234 - ] - }, - { - "id": "3e32ce15-0ae7-4cd0-909f-a354e8e9c4c9", - "name": "value_5", - "type": "INT", - "linkIds": [ - 624 - ], - "label": "fps", + "id": 269, + "type": "LoadImage", "pos": [ - 876.162109375, - 4254 - ] - }, - { - "id": "dc40eadf-b8a9-421e-88f6-245042dd5424", - "name": "noise_seed", - "type": "INT", - "linkIds": [ - 646 - ], - "label": "seed", - "pos": [ - 876.162109375, - 4274 - ] - }, - { - "id": "d7255058-319a-4880-8f9a-7e542c8f3c3c", - "name": "ckpt_name", - "type": "COMBO", - "linkIds": [ - 601, - 604, - 605 - ], - "pos": [ - 876.162109375, - 4294 - ] - }, - { - "id": "4afce68d-8f65-4342-9d6d-ae0a7688c3e3", - "name": "lora_name", - "type": "COMBO", - "linkIds": [ - 602 - ], - "label": "distilled_lora", - "pos": [ - 876.162109375, - 4314 - ] - }, - { - "id": "ab842b4b-c977-4679-b421-424722785b57", - "name": "text_encoder", - "type": "COMBO", - "linkIds": [ - 606 - ], - "label": "text_encoder", - "pos": [ - 876.162109375, - 4334 - ] - }, - { - "id": "9e47372d-28d9-4311-91e9-e90d03f4eb43", - "name": "model_name", - "type": "COMBO", - "linkIds": [ - 607 - ], - "label": "latent_upscale_model", - "pos": [ - 876.162109375, - 4354 - ] - }, - { - "id": "682e457c-5d94-49b2-bf40-5731696deaf0", - "name": "lora_name_1", - "type": "COMBO", - "linkIds": [ - 645 - ], - "label": "lora", - "pos": [ - 876.162109375, - 4374 - ] - } - ], - "outputs": [ - { - "id": "954ef307-c897-4eea-8b5c-5c6ce15a5357", - "name": "VIDEO", - "type": "VIDEO", - "linkIds": [ - 536 - ], - "localized_name": "VIDEO", - "pos": [ - 6614, - 4384 - ] - } - ], - "widgets": [], - "nodes": [ - { - "id": 276, - "type": "RandomNoise", - "pos": [ - 4700, - 3650 + 0.0, + 0.0 ], "size": [ - 280, - 110 + 410, + 530 ], "flags": {}, - "order": 0, + "order": 1, "mode": 0, "inputs": [], "outputs": [ - { - "localized_name": "NOISE", - "name": "NOISE", - "type": "NOISE", - "links": [ - 490 - ] - } + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 633 + ] + }, + { + "name": "MASK", + "type": "MASK", + "links": null + } ], "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": {} - } + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "LoadImage", + "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": 277, - "type": "RandomNoise", + "egyptian_queen.png", + "image" + ], + "title": "Product photo" + }, + { + "id": 75, + "type": "SaveVideo", "pos": [ - 3160, - 3630 + 960.0, + 0.0 ], "size": [ - 280, - 110 + 660, + 580 ], - "flags": {}, - "order": 6, + "flags": { + "collapsed": false + }, + "order": 3, "mode": 0, "inputs": [ - { - "localized_name": "noise_seed", - "name": "noise_seed", - "type": "INT", - "widget": { - "name": "noise_seed" - }, - "link": 646 - } + { + "name": "video", + "type": "VIDEO", + "link": 632 + } ], "outputs": [ - { - "localized_name": "NOISE", - "name": "NOISE", - "type": "NOISE", - "links": [ - 483 - ] - } + { + "name": "video", + "type": "VIDEO", + "links": null + } ], "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": {} - } + "cnr_id": "comfy-core", + "ver": "0.5.1", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "Node name for S&R": "SaveVideo", + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, "widgets_values": [ - 60540193790228, - "randomize" - ] - }, - { - "id": 278, - "type": "LTXVConcatAVLatent", - "pos": [ - 4710, - 4490 - ], - "size": [ - 280, - 100 - ], - "flags": {}, - "order": 7, - "mode": 0, - "inputs": [ - { - "localized_name": "video_latent", - "name": "video_latent", - "type": "LATENT", - "link": 512 - }, - { - "localized_name": "audio_latent", - "name": "audio_latent", - "type": "LATENT", - "link": 513 - } + "ocean_ugc_product", + "auto", + "auto" ], - "outputs": [ - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "links": [ - 494 - ] - } - ], - "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": 279, - "type": "LTXVAudioVAELoader", + "title": "Output clip" + }, + { + "id": 320, + "type": "2454ad83-157c-40dd-9f19-5daaf4041ce0", "pos": [ - 1660, - 4100 + 500.0, + 0.0 ], "size": [ - 430, - 110 + 380, + 650 ], "flags": {}, - "order": 8, + "order": 2, "mode": 0, "inputs": [ - { - "localized_name": "ckpt_name", - "name": "ckpt_name", - "type": "COMBO", - "widget": { - "name": "ckpt_name" + { + "label": "first_frame", + "name": "input", + "type": "IMAGE,MASK", + "link": 633 + }, + { + "label": "prompt", + "name": "value", + "type": "STRING", + "widget": { + "name": "value" + }, + "link": null + }, + { + "label": "prompt_enhance", + "name": "value_1", + "type": "BOOLEAN", + "widget": { + "name": "value_1" + }, + "link": null + }, + { + "label": "width", + "name": "value_2", + "type": "INT", + "widget": { + "name": "value_2" + }, + "link": null + }, + { + "label": "height", + "name": "value_3", + "type": "INT", + "widget": { + "name": "value_3" + }, + "link": null + }, + { + "label": "duration", + "name": "value_4", + "type": "INT", + "widget": { + "name": "value_4" + }, + "link": null }, - "link": 604 - } - ], - "outputs": [ - { - "localized_name": "Audio VAE", - "name": "Audio VAE", - "type": "VAE", - "links": [ - 481, - 496 - ] - } - ], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.68", - "Node name for S&R": "LTXVAudioVAELoader", - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "models": [ { - "name": "ltx-2.3-22b-dev-fp8.safetensors", - "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", - "directory": "checkpoints" + "label": "fps", + "name": "value_5", + "type": "INT", + "widget": { + "name": "value_5" + }, + "link": null + }, + { + "label": "seed", + "name": "noise_seed", + "type": "INT", + "widget": { + "name": "noise_seed" + }, + "link": null + }, + { + "label": "distilled_lora", + "name": "lora_name", + "type": "COMBO", + "widget": { + "name": "lora_name" + }, + "link": null + }, + { + "label": "text_encoder", + "name": "text_encoder", + "type": "COMBO", + "widget": { + "name": "text_encoder" + }, + "link": null + }, + { + "label": "latent_upscale_model", + "name": "model_name", + "type": "COMBO", + "widget": { + "name": "model_name" + }, + "link": null + }, + { + "label": "lora", + "name": "lora_name_1", + "type": "COMBO", + "widget": { + "name": "lora_name_1" + }, + "link": null } - ], - "ue_properties": { - "widget_ue_connectable": {}, - "version": "7.7", - "input_ue_unconnectable": {} - } - }, - "widgets_values": [ - "ltx-2.3-22b-dev-fp8.safetensors" - ] - }, - { - "id": 280, - "type": "KSamplerSelect", - "pos": [ - 4700, - 4100 - ], - "size": [ - 280, - 110 ], - "flags": {}, - "order": 1, - "mode": 0, - "inputs": [], "outputs": [ - { - "localized_name": "SAMPLER", - "name": "SAMPLER", - "type": "SAMPLER", - "links": [ - 492 - ] - } + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 632 + ] + } ], "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": {} - } + "proxyWidgets": [ + [ + "319", + "value" + ], + [ + "328", + "value" + ], + [ + "312", + "value" + ], + [ + "299", + "value" + ], + [ + "301", + "value" + ], + [ + "300", + "value" + ], + [ + "277", + "noise_seed" + ], + [ + "316", + "ckpt_name" + ], + [ + "285", + "lora_name" + ], + [ + "317", + "text_encoder" + ], + [ + "311", + "model_name" + ], + [ + "324", + "lora_name" + ] + ], + "cnr_id": "comfy-core", + "ver": "0.16.3", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "ue_properties": { + "widget_ue_connectable": { + "value_1": true, + "value_2": true, + "value_3": true, + "value_4": true, + "lora_name": true, + "model_name": true, + "value_5": true + }, + "version": "7.7", + "input_ue_unconnectable": {} + } }, - "widgets_values": [ - "euler" - ] - }, - { - "id": 281, - "type": "ManualSigmas", + "widgets_values": [], + "title": "Generate video" + }, + { + "id": 400, + "type": "MarkdownNote", "pos": [ - 4700, - 4290 + 0.0, + -240.0 ], "size": [ - 280, - 110 + 1180.0, + 180.0 ], "flags": {}, - "order": 2, + "order": 0, "mode": 0, "inputs": [], - "outputs": [ - { - "localized_name": "SIGMAS", - "name": "SIGMAS", - "type": "SIGMAS", - "links": [ - 493 - ] - } - ], - "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": {} - } - }, + "outputs": [], + "title": "How to use", + "properties": {}, "widgets_values": [ - "0.85, 0.7250, 0.4219, 0.0" + "## Product → vertical clip\n\n**1.** Upload your product photo in *Product photo*.\n\n**2.** Edit the prompt inside *Generate video* to describe the shot you want.\n\n**3.** Run.\n\nThe clip saves to your bucket — 720×1280, 5 s, with ambient audio." ] - }, - { - "id": 282, - "type": "CFGGuider", - "pos": [ - 4700, - 3850 - ], - "size": [ - 280, - 160 - ], - "flags": {}, - "order": 9, - "mode": 0, - "inputs": [ - { - "localized_name": "model", - "name": "model", - "type": "MODEL", - "link": 478 - }, - { - "localized_name": "positive", - "name": "positive", - "type": "CONDITIONING", - "link": 479 - }, - { - "localized_name": "negative", - "name": "negative", - "type": "CONDITIONING", - "link": 480 - } - ], - "outputs": [ - { - "localized_name": "GUIDER", - "name": "GUIDER", - "type": "GUIDER", + } + ], + "links": [ + [ + 632, + 320, + 0, + 75, + 0, + "VIDEO" + ], + [ + 633, + 269, + 0, + 320, + 0, + "IMAGE" + ] + ], + "groups": [], + "definitions": { + "subgraphs": [ + { + "id": "2454ad83-157c-40dd-9f19-5daaf4041ce0", + "version": 1, + "state": { + "lastGroupId": 26, + "lastNodeId": 329, + "lastLinkId": 646, + "lastRerouteId": 0 + }, + "revision": 0, + "config": {}, + "name": "Image to Video (LTX-2.3)", + "inputNode": { + "id": -10, + "bounding": [ + 730, + 4110, + 170.162109375, + 308 + ] + }, + "outputNode": { + "id": -20, + "bounding": [ + 6590, + 4360, + 128, + 68 + ] + }, + "inputs": [ + { + "id": "7afd6ea8-c738-4fd9-97b8-66fa905cd381", + "name": "input", + "type": "IMAGE,MASK", + "linkIds": [ + 535 + ], + "localized_name": "input", + "label": "first_frame", + "pos": [ + 876.162109375, + 4134 + ] + }, + { + "id": "9494c550-4172-49c6-930e-5b508f775e77", + "name": "value", + "type": "STRING", + "linkIds": [ + 595 + ], + "label": "prompt", + "pos": [ + 876.162109375, + 4154 + ] + }, + { + "id": "ec291311-2d21-49f9-aaba-24bb2e544ce0", + "name": "value_1", + "type": "BOOLEAN", + "linkIds": [ + 644 + ], + "label": "prompt_enhance", + "pos": [ + 876.162109375, + 4174 + ] + }, + { + "id": "58dbb3f6-f924-4548-96ef-e0e34610bd4e", + "name": "value_2", + "type": "INT", + "linkIds": [ + 597 + ], + "label": "width", + "pos": [ + 876.162109375, + 4194 + ] + }, + { + "id": "6086d5b8-2586-448c-a641-dd14d76dd102", + "name": "value_3", + "type": "INT", + "linkIds": [ + 598 + ], + "label": "height", + "pos": [ + 876.162109375, + 4214 + ] + }, + { + "id": "feb8c2eb-ae48-4fa8-bc24-929552d656c3", + "name": "value_4", + "type": "INT", + "linkIds": [ + 599 + ], + "label": "duration", + "pos": [ + 876.162109375, + 4234 + ] + }, + { + "id": "3e32ce15-0ae7-4cd0-909f-a354e8e9c4c9", + "name": "value_5", + "type": "INT", + "linkIds": [ + 624 + ], + "label": "fps", + "pos": [ + 876.162109375, + 4254 + ] + }, + { + "id": "dc40eadf-b8a9-421e-88f6-245042dd5424", + "name": "noise_seed", + "type": "INT", + "linkIds": [ + 646 + ], + "label": "seed", + "pos": [ + 876.162109375, + 4274 + ] + }, + { + "id": "d7255058-319a-4880-8f9a-7e542c8f3c3c", + "name": "ckpt_name", + "type": "COMBO", + "linkIds": [ + 601, + 604, + 605 + ], + "pos": [ + 876.162109375, + 4294 + ] + }, + { + "id": "4afce68d-8f65-4342-9d6d-ae0a7688c3e3", + "name": "lora_name", + "type": "COMBO", + "linkIds": [ + 602 + ], + "label": "distilled_lora", + "pos": [ + 876.162109375, + 4314 + ] + }, + { + "id": "ab842b4b-c977-4679-b421-424722785b57", + "name": "text_encoder", + "type": "COMBO", + "linkIds": [ + 606 + ], + "label": "text_encoder", + "pos": [ + 876.162109375, + 4334 + ] + }, + { + "id": "9e47372d-28d9-4311-91e9-e90d03f4eb43", + "name": "model_name", + "type": "COMBO", + "linkIds": [ + 607 + ], + "label": "latent_upscale_model", + "pos": [ + 876.162109375, + 4354 + ] + }, + { + "id": "682e457c-5d94-49b2-bf40-5731696deaf0", + "name": "lora_name_1", + "type": "COMBO", + "linkIds": [ + 645 + ], + "label": "lora", + "pos": [ + 876.162109375, + 4374 + ] + } + ], + "outputs": [ + { + "id": "954ef307-c897-4eea-8b5c-5c6ce15a5357", + "name": "VIDEO", + "type": "VIDEO", + "linkIds": [ + 536 + ], + "localized_name": "VIDEO", + "pos": [ + 6614, + 4384 + ] + } + ], + "widgets": [], + "nodes": [ + { + "id": 276, + "type": "RandomNoise", + "pos": [ + 4700, + 3650 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "NOISE", + "name": "NOISE", + "type": "NOISE", + "links": [ + 490 + ] + } + ], + "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": 277, + "type": "RandomNoise", + "pos": [ + 3160, + 3630 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "localized_name": "noise_seed", + "name": "noise_seed", + "type": "INT", + "widget": { + "name": "noise_seed" + }, + "link": 646 + } + ], + "outputs": [ + { + "localized_name": "NOISE", + "name": "NOISE", + "type": "NOISE", + "links": [ + 483 + ] + } + ], + "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": [ + 60540193790228, + "randomize" + ] + }, + { + "id": 278, + "type": "LTXVConcatAVLatent", + "pos": [ + 4710, + 4490 + ], + "size": [ + 280, + 100 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "link": 512 + }, + { + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", + "link": 513 + } + ], + "outputs": [ + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 494 + ] + } + ], + "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": 279, + "type": "LTXVAudioVAELoader", + "pos": [ + 1660, + 4100 + ], + "size": [ + 430, + 110 + ], + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "localized_name": "ckpt_name", + "name": "ckpt_name", + "type": "COMBO", + "widget": { + "name": "ckpt_name" + }, + "link": 604 + } + ], + "outputs": [ + { + "localized_name": "Audio VAE", + "name": "Audio VAE", + "type": "VAE", + "links": [ + 481, + 496 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.3.68", + "Node name for S&R": "LTXVAudioVAELoader", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "models": [ + { + "name": "ltx-2.3-22b-dev-fp8.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", + "directory": "checkpoints" + } + ], + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } + }, + "widgets_values": [ + "ltx-2.3-22b-dev-fp8.safetensors" + ] + }, + { + "id": 280, + "type": "KSamplerSelect", + "pos": [ + 4700, + 4100 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "SAMPLER", + "name": "SAMPLER", + "type": "SAMPLER", + "links": [ + 492 + ] + } + ], + "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": [ + "euler" + ] + }, + { + "id": 281, + "type": "ManualSigmas", + "pos": [ + 4700, + 4290 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "SIGMAS", + "name": "SIGMAS", + "type": "SIGMAS", + "links": [ + 493 + ] + } + ], + "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": 282, + "type": "CFGGuider", + "pos": [ + 4700, + 3850 + ], + "size": [ + 280, + 160 + ], + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 478 + }, + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 479 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 480 + } + ], + "outputs": [ + { + "localized_name": "GUIDER", + "name": "GUIDER", + "type": "GUIDER", + "links": [ + 491 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.3.71", + "Node name for S&R": "CFGGuider", + "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 + ] + }, + { + "id": 283, + "type": "SamplerCustomAdvanced", + "pos": [ + 3550, + 3630 + ], + "size": [ + 230, + 170 + ], + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ + { + "localized_name": "noise", + "name": "noise", + "type": "NOISE", + "link": 483 + }, + { + "localized_name": "guider", + "name": "guider", + "type": "GUIDER", + "link": 484 + }, + { + "localized_name": "sampler", + "name": "sampler", + "type": "SAMPLER", + "link": 485 + }, + { + "localized_name": "sigmas", + "name": "sigmas", + "type": "SIGMAS", + "link": 544 + }, + { + "localized_name": "latent_image", + "name": "latent_image", + "type": "LATENT", + "link": 487 + } + ], + "outputs": [ + { + "localized_name": "output", + "name": "output", + "type": "LATENT", + "links": [ + 488 + ] + }, + { + "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": 284, + "type": "LTXVCropGuides", + "pos": [ + 3830, + 3810 + ], + "size": [ + 250, + 120 + ], + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 475 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 476 + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "link": 477 + } + ], + "outputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "links": [ + 479 + ] + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "links": [ + 480 + ] + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "slot_index": 2, + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.3.68", + "Node name for S&R": "LTXVCropGuides", + "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": 285, + "type": "LoraLoaderModelOnly", + "pos": [ + 1660, + 3890 + ], + "size": [ + 430, + 140 + ], + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 520 + }, + { + "localized_name": "lora_name", + "name": "lora_name", + "type": "COMBO", + "widget": { + "name": "lora_name" + }, + "link": 602 + } + ], + "outputs": [ + { + "localized_name": "MODEL", + "name": "MODEL", + "type": "MODEL", + "links": [ + 478, + 541, + 641 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.3.75", + "Node name for S&R": "LoraLoaderModelOnly", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "models": [ + { + "name": "ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", + "url": "https://huggingface.co/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", + "directory": "loras" + } + ], + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } + }, + "widgets_values": [ + "ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", + 0.5 + ] + }, + { + "id": 286, + "type": "ResizeImagesByLongerEdge", + "pos": [ + 2070, + 4810 + ], + "size": [ + 348.624609375, + 110 + ], + "flags": { + "collapsed": false + }, + "order": 13, + "mode": 0, + "inputs": [ + { + "localized_name": "images", + "name": "images", + "type": "IMAGE", + "link": 523 + } + ], + "outputs": [ + { + "localized_name": "images", + "name": "images", + "type": "IMAGE", + "links": [ + 505 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.5.1", + "Node name for S&R": "ResizeImagesByLongerEdge", + "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": [ + 1536 + ] + }, + { + "id": 287, + "type": "LTXVLatentUpsampler", + "pos": [ + 4250, + 3760 + ], + "size": [ + 330, + 120 + ], + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [ + { + "localized_name": "samples", + "name": "samples", + "type": "LATENT", + "link": 547 + }, + { + "localized_name": "upscale_model", + "name": "upscale_model", + "type": "LATENT_UPSCALE_MODEL", + "link": 545 + }, + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 554 + } + ], + "outputs": [ + { + "localized_name": "LATENT", + "name": "LATENT", + "type": "LATENT", + "links": [ + 548 + ] + } + ], + "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": 288, + "type": "LTXVImgToVideoInplace", + "pos": [ + 4230, + 4100 + ], + "size": [ + 300, + 180 + ], + "flags": {}, + "order": 15, + "mode": 0, + "inputs": [ + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 552 + }, + { + "localized_name": "image", + "name": "image", + "type": "IMAGE", + "link": 515 + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "link": 548 + }, + { + "localized_name": "bypass", + "name": "bypass", + "type": "BOOLEAN", + "widget": { + "name": "bypass" + }, + "link": 543 + } + ], + "outputs": [ + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 512 + ] + } + ], + "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": 289, + "type": "LTXVPreprocess", + "pos": [ + 2100, + 5010 + ], + "size": [ + 290, + 110 + ], + "flags": {}, + "order": 16, + "mode": 0, + "inputs": [ + { + "localized_name": "image", + "name": "image", + "type": "IMAGE", + "link": 505 + } + ], + "outputs": [ + { + "localized_name": "output_image", + "name": "output_image", + "type": "IMAGE", + "links": [ + 510, + 515 + ] + } + ], + "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": 290, + "type": "ResizeImageMaskNode", + "pos": [ + 1660, + 4810 + ], + "size": [ + 300, + 154 + ], + "flags": {}, + "order": 17, + "mode": 0, + "inputs": [ + { + "localized_name": "input", + "name": "input", + "type": "IMAGE,MASK", + "link": 535 + }, + { + "localized_name": "width", + "name": "resize_type.width", + "type": "INT", + "widget": { + "name": "resize_type.width" + }, + "link": 558 + }, + { + "localized_name": "height", + "name": "resize_type.height", + "type": "INT", + "widget": { + "name": "resize_type.height" + }, + "link": 559 + } + ], + "outputs": [ + { + "localized_name": "resized", + "name": "resized", + "type": "IMAGE,MASK", + "links": [ + 523 + ] + } + ], + "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 dimensions", + 1920, + 1088, + "center", + "lanczos" + ] + }, + { + "id": 291, + "type": "KSamplerSelect", + "pos": [ + 3160, + 4040 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "SAMPLER", + "name": "SAMPLER", + "type": "SAMPLER", + "links": [ + 485 + ] + } + ], + "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" + ] + }, + { + "id": 292, + "type": "ComfyMathExpression", + "pos": [ + 2540, + 4830 + ], + "size": [ + 225, + 74 + ], + "flags": { + "collapsed": true + }, + "order": 18, + "mode": 0, + "inputs": [ + { + "label": "a", + "localized_name": "values.a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 560 + }, + { + "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": null + }, + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 561 + ] + }, + { + "localized_name": "BOOL", + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "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": 293, + "type": "Reroute", + "pos": [ + 3850, + 4050 + ], + "size": [ + 75, + 26 + ], + "flags": {}, + "order": 19, + "mode": 0, + "inputs": [ + { + "name": "", + "type": "*", + "link": 557 + } + ], + "outputs": [ + { + "name": "", + "type": "VAE", + "links": [ + 552, + 553, + 554 + ] + } + ], + "properties": { + "showOutputText": false, + "horizontal": false, + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } + } + }, + { + "id": 294, + "type": "ComfyMathExpression", + "pos": [ + 2550, + 4890 + ], + "size": [ + 225, + 74 + ], + "flags": { + "collapsed": true + }, + "order": 20, + "mode": 0, + "inputs": [ + { + "label": "a", + "localized_name": "values.a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 562 + }, + { + "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": null + }, + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 563 + ] + }, + { + "localized_name": "BOOL", + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "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": 295, + "type": "EmptyLTXVLatentVideo", + "pos": [ + 2870, + 4940 + ], + "size": [ + 280, + 200 + ], + "flags": {}, + "order": 21, + "mode": 0, + "inputs": [ + { + "localized_name": "width", + "name": "width", + "type": "INT", + "widget": { + "name": "width" + }, + "link": 561 + }, + { + "localized_name": "height", + "name": "height", + "type": "INT", + "widget": { + "name": "height" + }, + "link": 563 + }, + { + "localized_name": "length", + "name": "length", + "type": "INT", + "widget": { + "name": "length" + }, + "link": 631 + } + ], + "outputs": [ + { + "localized_name": "LATENT", + "name": "LATENT", + "type": "LATENT", + "links": [ + 511 + ] + } + ], + "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": 296, + "type": "LTXVImgToVideoInplace", + "pos": [ + 3230, + 4810 + ], + "size": [ + 280, + 180 + ], + "flags": {}, + "order": 22, + "mode": 0, + "inputs": [ + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 556 + }, + { + "localized_name": "image", + "name": "image", + "type": "IMAGE", + "link": 510 + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "link": 511 + }, + { + "localized_name": "bypass", + "name": "bypass", + "type": "BOOLEAN", + "widget": { + "name": "bypass" + }, + "link": 542 + } + ], + "outputs": [ + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 497 + ] + } + ], + "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": 297, + "type": "LTXVAudioVAEDecode", + "pos": [ + 5760, + 3970 + ], + "size": [ + 270, + 100 + ], + "flags": {}, + "order": 23, + "mode": 0, + "inputs": [ + { + "localized_name": "samples", + "name": "samples", + "type": "LATENT", + "link": 495 + }, + { + "label": "Audio VAE", + "localized_name": "audio_vae", + "name": "audio_vae", + "type": "VAE", + "link": 496 + } + ], + "outputs": [ + { + "localized_name": "Audio", + "name": "Audio", + "type": "AUDIO", + "links": [ + 534 + ] + } + ], + "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": 298, + "type": "ComfyMathExpression", + "pos": [ + 2540, + 5030 + ], + "size": [ + 225, + 74 + ], + "flags": { + "collapsed": true + }, + "order": 24, + "mode": 0, + "inputs": [ + { + "label": "a", + "localized_name": "values.a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 564 + }, + { + "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": [ + 566, + 591 + ] + }, + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 565 + ] + }, + { + "localized_name": "BOOL", + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "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": 299, + "type": "PrimitiveInt", + "pos": [ + 1190, + 4650 + ], + "size": [ + 370, + 110 + ], + "flags": {}, + "order": 25, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "INT", + "widget": { + "name": "value" + }, + "link": 598 + } + ], + "outputs": [ + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 559, + 562 + ] + } + ], + "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": [ + 1280, + "fixed" + ] + }, + { + "id": 300, + "type": "PrimitiveInt", + "pos": [ + 1190, + 4840 + ], + "size": [ + 370, + 110 + ], + "flags": {}, + "order": 26, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "INT", + "widget": { + "name": "value" + }, + "link": 624 + } + ], + "outputs": [ + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 564, + 629 + ] + } + ], + "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": [ + 25, + "fixed" + ] + }, + { + "id": 301, + "type": "PrimitiveInt", + "pos": [ + 1190, + 4280 + ], + "size": [ + 370, + 110 + ], + "flags": {}, + "order": 27, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "INT", + "widget": { + "name": "value" + }, + "link": 599 + } + ], + "outputs": [ + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 628 + ] + } + ], + "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": 302, + "type": "PrimitiveBoolean", + "pos": [ + 1190, + 4110 + ], + "size": [ + 370, + 100 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "BOOLEAN", + "name": "BOOLEAN", + "type": "BOOLEAN", + "links": [ + 542, + 543 + ] + } + ], + "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": 303, + "type": "CLIPTextEncode", + "pos": [ + 2170, + 3640 + ], + "size": [ + 600, + 390 + ], + "flags": {}, + "order": 28, + "mode": 0, + "inputs": [ + { + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 642 + }, + { + "localized_name": "text", + "name": "text", + "type": "STRING", + "widget": { + "name": "text" + }, + "link": 638 + } + ], + "outputs": [ + { + "localized_name": "CONDITIONING", + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 526 + ] + } + ], + "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": 304, + "type": "LTXVConditioning", + "pos": [ + 2800, + 3810 + ], + "size": [ + 280, + 130 + ], + "flags": {}, + "order": 29, + "mode": 0, + "inputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 526 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 527 + }, + { + "localized_name": "frame_rate", + "name": "frame_rate", + "type": "FLOAT", + "widget": { + "name": "frame_rate" + }, + "link": 566 + } + ], + "outputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "links": [ + 475, + 518 + ] + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "links": [ + 476, + 519 + ] + } + ], + "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": 305, + "type": "LTXVEmptyLatentAudio", + "pos": [ + 3540, + 4960 + ], + "size": [ + 280, + 170 + ], + "flags": {}, + "order": 30, + "mode": 0, + "inputs": [ + { + "localized_name": "audio_vae", + "name": "audio_vae", + "type": "VAE", + "link": 481 + }, + { + "localized_name": "frames_number", + "name": "frames_number", + "type": "INT", + "widget": { + "name": "frames_number" + }, + "link": 630 + }, + { + "localized_name": "frame_rate", + "name": "frame_rate", + "type": "INT", + "widget": { + "name": "frame_rate" + }, + "link": 565 + } + ], + "outputs": [ + { + "localized_name": "Latent", + "name": "Latent", + "type": "LATENT", + "links": [ + 498 + ] + } + ], + "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": 306, + "type": "ManualSigmas", + "pos": [ + 3160, + 4220 + ], + "size": [ + 500, + 110 + ], + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "SIGMAS", + "name": "SIGMAS", + "type": "SIGMAS", + "links": [ + 544 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.14.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": [ + "1.0, 0.99375, 0.9875, 0.98125, 0.975, 0.909375, 0.725, 0.421875, 0.0" + ] + }, + { + "id": 307, + "type": "LTXVSeparateAVLatent", + "pos": [ + 3820, + 3630 + ], + "size": [ + 250, + 100 + ], + "flags": {}, + "order": 31, + "mode": 0, + "inputs": [ + { + "localized_name": "av_latent", + "name": "av_latent", + "type": "LATENT", + "link": 488 + } + ], + "outputs": [ + { + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "links": [ + 477, + 547 + ] + }, + { + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", + "links": [ + 513 + ] + } + ], + "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": 308, + "type": "SamplerCustomAdvanced", + "pos": [ + 5050, + 3650 + ], + "size": [ + 230, + 170 + ], + "flags": {}, + "order": 32, + "mode": 0, + "inputs": [ + { + "localized_name": "noise", + "name": "noise", + "type": "NOISE", + "link": 490 + }, + { + "localized_name": "guider", + "name": "guider", + "type": "GUIDER", + "link": 491 + }, + { + "localized_name": "sampler", + "name": "sampler", + "type": "SAMPLER", + "link": 492 + }, + { + "localized_name": "sigmas", + "name": "sigmas", + "type": "SIGMAS", + "link": 493 + }, + { + "localized_name": "latent_image", + "name": "latent_image", + "type": "LATENT", + "link": 494 + } + ], + "outputs": [ + { + "localized_name": "output", + "name": "output", + "type": "LATENT", + "links": [ + 578 + ] + }, + { + "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": 309, + "type": "LTXVSeparateAVLatent", + "pos": [ + 5390, + 3650 + ], + "size": [ + 230, + 100 + ], + "flags": {}, + "order": 33, + "mode": 0, + "inputs": [ + { + "localized_name": "av_latent", + "name": "av_latent", + "type": "LATENT", + "link": 578 + } + ], + "outputs": [ + { + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "links": [ + 539 + ] + }, + { + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", + "links": [ + 495 + ] + } + ], + "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": 310, + "type": "CreateVideo", + "pos": [ + 6050, + 4490 + ], + "size": [ + 280, + 130 + ], + "flags": {}, + "order": 34, + "mode": 0, + "inputs": [ + { + "localized_name": "images", + "name": "images", + "type": "IMAGE", + "link": 538 + }, + { + "localized_name": "audio", + "name": "audio", + "shape": 7, + "type": "AUDIO", + "link": 534 + }, + { + "localized_name": "fps", + "name": "fps", + "type": "FLOAT", + "widget": { + "name": "fps" + }, + "link": 591 + } + ], + "outputs": [ + { + "localized_name": "VIDEO", + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 536 + ] + } + ], + "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": 311, + "type": "LatentUpscaleModelLoader", + "pos": [ + 1670, + 4550 + ], + "size": [ + 400, + 110 + ], + "flags": {}, + "order": 35, + "mode": 0, + "inputs": [ + { + "localized_name": "model_name", + "name": "model_name", + "type": "COMBO", + "widget": { + "name": "model_name" + }, + "link": 607 + } + ], + "outputs": [ + { + "localized_name": "LATENT_UPSCALE_MODEL", + "name": "LATENT_UPSCALE_MODEL", + "type": "LATENT_UPSCALE_MODEL", + "links": [ + 545 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "LatentUpscaleModelLoader", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "models": [ + { + "name": "ltx-2.3-spatial-upscaler-x2-1.1.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors", + "directory": "latent_upscale_models" + } + ], + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } + }, + "widgets_values": [ + "ltx-2.3-spatial-upscaler-x2-1.1.safetensors" + ] + }, + { + "id": 312, + "type": "PrimitiveInt", + "pos": [ + 1190, + 4470 + ], + "size": [ + 370, + 110 + ], + "flags": {}, + "order": 36, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "INT", + "widget": { + "name": "value" + }, + "link": 597 + } + ], + "outputs": [ + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 558, + 560 + ] + } + ], + "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": [ + 720, + "fixed" + ] + }, + { + "id": 313, + "type": "CLIPTextEncode", + "pos": [ + 2180, + 4120 + ], + "size": [ + 600, + 170 + ], + "flags": {}, + "order": 37, + "mode": 0, + "inputs": [ + { + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 627 + } + ], + "outputs": [ + { + "localized_name": "CONDITIONING", + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 527 + ] + } + ], + "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": [ + "pc game, console game, video game, cartoon, childish, ugly" + ], + "color": "#323", + "bgcolor": "#535" + }, + { + "id": 314, + "type": "CFGGuider", + "pos": [ + 3160, + 3810 + ], + "size": [ + 280, + 160 + ], + "flags": {}, + "order": 38, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 541 + }, + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 518 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 519 + } + ], + "outputs": [ + { + "localized_name": "GUIDER", + "name": "GUIDER", + "type": "GUIDER", + "links": [ + 484 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.3.64", + "Node name for S&R": "CFGGuider", + "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 + ] + }, + { + "id": 315, + "type": "VAEDecodeTiled", + "pos": [ + 5750, + 3610 + ], + "size": [ + 280, + 200 + ], + "flags": {}, + "order": 39, + "mode": 0, + "inputs": [ + { + "localized_name": "samples", + "name": "samples", + "type": "LATENT", + "link": 539 + }, + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 553 + } + ], + "outputs": [ + { + "localized_name": "IMAGE", + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 538 + ] + } + ], + "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": [ + 768, + 64, + 4096, + 4 + ] + }, + { + "id": 316, + "type": "CheckpointLoaderSimple", + "pos": [ + 1660, + 3660 + ], + "size": [ + 430, + 160 + ], + "flags": {}, + "order": 40, + "mode": 0, + "inputs": [ + { + "localized_name": "ckpt_name", + "name": "ckpt_name", + "type": "COMBO", + "widget": { + "name": "ckpt_name" + }, + "link": 601 + } + ], + "outputs": [ + { + "localized_name": "MODEL", + "name": "MODEL", + "type": "MODEL", + "links": [ + 520 + ] + }, + { + "localized_name": "CLIP", + "name": "CLIP", + "type": "CLIP", + "links": [] + }, + { + "localized_name": "VAE", + "name": "VAE", + "type": "VAE", + "links": [ + 556, + 557 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.3.56", + "Node name for S&R": "CheckpointLoaderSimple", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "models": [ + { + "name": "ltx-2.3-22b-dev-fp8.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", + "directory": "checkpoints" + } + ], + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } + }, + "widgets_values": [ + "ltx-2.3-22b-dev-fp8.safetensors" + ] + }, + { + "id": 317, + "type": "LTXAVTextEncoderLoader", + "pos": [ + 1660, + 4280 + ], + "size": [ + 430, + 170 + ], + "flags": {}, + "order": 41, + "mode": 0, + "showAdvanced": false, + "inputs": [ + { + "localized_name": "text_encoder", + "name": "text_encoder", + "type": "COMBO", + "widget": { + "name": "text_encoder" + }, + "link": 606 + }, + { + "localized_name": "ckpt_name", + "name": "ckpt_name", + "type": "COMBO", + "widget": { + "name": "ckpt_name" + }, + "link": 605 + } + ], + "outputs": [ + { + "localized_name": "CLIP", + "name": "CLIP", + "type": "CLIP", + "links": [ + 627, + 642, + 643 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "LTXAVTextEncoderLoader", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "models": [ + { + "name": "ltx-2.3-22b-dev-fp8.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", + "directory": "checkpoints" + }, + { + "name": "gemma_3_12B_it_fp4_mixed.safetensors", + "url": "https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors", + "directory": "text_encoders" + } + ], + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } + }, + "widgets_values": [ + "gemma_3_12B_it_fp4_mixed.safetensors", + "ltx-2.3-22b-dev-fp8.safetensors", + "default" + ] + }, + { + "id": 318, + "type": "LTXVConcatAVLatent", + "pos": [ + 3860, + 4830 + ], + "size": [ + 240, + 100 + ], + "flags": {}, + "order": 42, + "mode": 0, + "inputs": [ + { + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "link": 497 + }, + { + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", + "link": 498 + } + ], + "outputs": [ + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 487 + ] + } + ], + "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": 319, + "type": "PrimitiveStringMultiline", + "pos": [ + 1190, + 3680 + ], + "size": [ + 370, + 350 + ], + "flags": {}, + "order": 43, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "STRING", + "widget": { + "name": "value" + }, + "link": 595 + } + ], + "outputs": [ + { + "localized_name": "STRING", + "name": "STRING", + "type": "STRING", + "links": [ + 639, + 640 + ] + } + ], + "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": 323, + "type": "ComfyMathExpression", + "pos": [ + 1210, + 5040 + ], + "size": [ + 225, + 94 + ], + "flags": { + "collapsed": true + }, + "order": 44, + "mode": 0, + "inputs": [ + { + "label": "a", + "localized_name": "values.a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 628 + }, + { + "label": "b", + "localized_name": "values.b", + "name": "values.b", + "shape": 7, + "type": "FLOAT,INT,BOOLEAN", + "link": 629 + }, + { + "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": null + }, + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 630, + 631 + ] + }, + { + "localized_name": "BOOL", + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "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": 324, + "type": "LoraLoader", + "pos": [ + 1200, + 2870 + ], + "size": [ + 380, + 230 + ], + "flags": {}, + "order": 45, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 641 + }, + { + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 643 + }, + { + "localized_name": "lora_name", + "name": "lora_name", + "type": "COMBO", + "widget": { + "name": "lora_name" + }, + "link": 645 + } + ], + "outputs": [ + { + "localized_name": "MODEL", + "name": "MODEL", + "type": "MODEL", + "links": null + }, + { + "localized_name": "CLIP", + "name": "CLIP", + "type": "CLIP", + "links": [ + 634 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "LoraLoader", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "models": [ + { + "name": "gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", + "url": "https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", + "directory": "loras" + } + ] + }, + "widgets_values": [ + "gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", + 1, + 1 + ] + }, + { + "id": 325, + "type": "TextGenerateLTX2Prompt", + "pos": [ + 1630, + 2870 + ], + "size": [ + 400, + 412 + ], + "flags": { + "collapsed": false + }, + "order": 46, + "mode": 0, + "inputs": [ + { + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 634 + }, + { + "localized_name": "image", + "name": "image", + "shape": 7, + "type": "IMAGE", + "link": null + }, + { + "localized_name": "video", + "name": "video", + "shape": 7, + "type": "IMAGE", + "link": null + }, + { + "localized_name": "audio", + "name": "audio", + "shape": 7, + "type": "AUDIO", + "link": null + }, + { + "localized_name": "prompt", + "name": "prompt", + "type": "STRING", + "widget": { + "name": "prompt" + }, + "link": 639 + } + ], + "outputs": [ + { + "localized_name": "generated_text", + "name": "generated_text", + "type": "STRING", + "links": [ + 636 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "TextGenerateLTX2Prompt", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65 + }, + "widgets_values": [ + "A young woman holds the product up to the camera in a bright modern kitchen, turning it slowly to show the label, then smiles at the camera. Handheld iPhone footage, natural window light, shallow depth of field, authentic UGC style.", + 2048, + "on", + 0.7, + 64, + 0.95, + 0.05, + 1.05, + 0, + 0, + false, + true + ] + }, + { + "id": 326, + "type": "PreviewAny", + "pos": [ + 2470, + 2890 + ], + "size": [ + 510, + 360 + ], + "flags": {}, + "order": 47, + "mode": 0, + "inputs": [ + { + "localized_name": "source", + "name": "source", + "type": "*", + "link": 635 + } + ], + "outputs": [ + { + "localized_name": "STRING", + "name": "STRING", + "type": "STRING", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "PreviewAny", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65 + }, + "widgets_values": [] + }, + { + "id": 327, + "type": "ComfySwitchNode", + "pos": [ + 2160, + 3280 + ], + "size": [ + 270, + 130 + ], + "flags": {}, + "order": 48, + "mode": 0, + "inputs": [ + { + "localized_name": "on_false", + "name": "on_false", + "type": "STRING", + "link": 640 + }, + { + "localized_name": "on_true", + "name": "on_true", + "type": "STRING", + "link": 636 + }, + { + "localized_name": "switch", + "name": "switch", + "type": "BOOLEAN", + "widget": { + "name": "switch" + }, + "link": 637 + } + ], + "outputs": [ + { + "localized_name": "output", + "name": "output", + "type": "STRING", + "links": [ + 635, + 638 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.22.0", + "Node name for S&R": "ComfySwitchNode", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65 + }, + "widgets_values": [ + false + ] + }, + { + "id": 328, + "type": "PrimitiveBoolean", + "pos": [ + 1200, + 3350 + ], + "size": [ + 270, + 100 + ], + "flags": {}, + "order": 49, + "mode": 0, + "inputs": [ + { + "localized_name": "value", + "name": "value", + "type": "BOOLEAN", + "widget": { + "name": "value" + }, + "link": 644 + } + ], + "outputs": [ + { + "localized_name": "BOOLEAN", + "name": "BOOLEAN", + "type": "BOOLEAN", + "links": [ + 637 + ] + } + ], + "title": "Boolean (Enable Prompt Enhance)", + "properties": { + "cnr_id": "comfy-core", + "ver": "0.22.0", + "Node name for S&R": "PrimitiveBoolean", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65 + }, + "widgets_values": [ + false + ] + } + ], + "groups": [ + { + "id": 1, + "title": "Model", + "bounding": [ + 1630, + 3550, + 480, + 1140 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 2, + "title": "Generate Low Resolution", + "bounding": [ + 3130, + 3550, + 1000, + 1140 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 3, + "title": "Prompt", + "bounding": [ + 2140, + 3550, + 960, + 1140 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 6, + "title": "Generate High Resolution", + "bounding": [ + 4670, + 3550, + 990, + 1130 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 7, + "title": "Latent Upscale", + "bounding": [ + 4160, + 3550, + 480, + 1130 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 19, + "title": "Video Settings", + "bounding": [ + 1150, + 3550, + 460, + 1610 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 20, + "title": "Image Preprocess", + "bounding": [ + 1630, + 4720, + 830, + 440 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 21, + "title": "Empty Latent", + "bounding": [ + 2820, + 4720, + 1310, + 450 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 22, + "title": "Number conversion", + "bounding": [ + 2480, + 4720, + 310, + 440 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 26, + "title": "Prompt Enhancement", + "bounding": [ + 1160, + 2790, + 2010, + 720 + ], + "color": "#3f789e", + "flags": {} + } + ], "links": [ - 491 - ] - } - ], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.71", - "Node name for S&R": "CFGGuider", - "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 + { + "id": 512, + "origin_id": 288, + "origin_slot": 0, + "target_id": 278, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 513, + "origin_id": 307, + "origin_slot": 1, + "target_id": 278, + "target_slot": 1, + "type": "LATENT" + }, + { + "id": 478, + "origin_id": 285, + "origin_slot": 0, + "target_id": 282, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 479, + "origin_id": 284, + "origin_slot": 0, + "target_id": 282, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 480, + "origin_id": 284, + "origin_slot": 1, + "target_id": 282, + "target_slot": 2, + "type": "CONDITIONING" + }, + { + "id": 541, + "origin_id": 285, + "origin_slot": 0, + "target_id": 314, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 518, + "origin_id": 304, + "origin_slot": 0, + "target_id": 314, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 519, + "origin_id": 304, + "origin_slot": 1, + "target_id": 314, + "target_slot": 2, + "type": "CONDITIONING" + }, + { + "id": 483, + "origin_id": 277, + "origin_slot": 0, + "target_id": 283, + "target_slot": 0, + "type": "NOISE" + }, + { + "id": 484, + "origin_id": 314, + "origin_slot": 0, + "target_id": 283, + "target_slot": 1, + "type": "GUIDER" + }, + { + "id": 485, + "origin_id": 291, + "origin_slot": 0, + "target_id": 283, + "target_slot": 2, + "type": "SAMPLER" + }, + { + "id": 544, + "origin_id": 306, + "origin_slot": 0, + "target_id": 283, + "target_slot": 3, + "type": "SIGMAS" + }, + { + "id": 487, + "origin_id": 318, + "origin_slot": 0, + "target_id": 283, + "target_slot": 4, + "type": "LATENT" + }, + { + "id": 475, + "origin_id": 304, + "origin_slot": 0, + "target_id": 284, + "target_slot": 0, + "type": "CONDITIONING" + }, + { + "id": 476, + "origin_id": 304, + "origin_slot": 1, + "target_id": 284, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 477, + "origin_id": 307, + "origin_slot": 0, + "target_id": 284, + "target_slot": 2, + "type": "LATENT" + }, + { + "id": 520, + "origin_id": 316, + "origin_slot": 0, + "target_id": 285, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 523, + "origin_id": 290, + "origin_slot": 0, + "target_id": 286, + "target_slot": 0, + "type": "IMAGE" + }, + { + "id": 547, + "origin_id": 307, + "origin_slot": 0, + "target_id": 287, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 545, + "origin_id": 311, + "origin_slot": 0, + "target_id": 287, + "target_slot": 1, + "type": "LATENT_UPSCALE_MODEL" + }, + { + "id": 554, + "origin_id": 293, + "origin_slot": 0, + "target_id": 287, + "target_slot": 2, + "type": "VAE" + }, + { + "id": 552, + "origin_id": 293, + "origin_slot": 0, + "target_id": 288, + "target_slot": 0, + "type": "VAE" + }, + { + "id": 515, + "origin_id": 289, + "origin_slot": 0, + "target_id": 288, + "target_slot": 1, + "type": "IMAGE" + }, + { + "id": 548, + "origin_id": 287, + "origin_slot": 0, + "target_id": 288, + "target_slot": 2, + "type": "LATENT" + }, + { + "id": 543, + "origin_id": 302, + "origin_slot": 0, + "target_id": 288, + "target_slot": 3, + "type": "BOOLEAN" + }, + { + "id": 505, + "origin_id": 286, + "origin_slot": 0, + "target_id": 289, + "target_slot": 0, + "type": "IMAGE" + }, + { + "id": 558, + "origin_id": 312, + "origin_slot": 0, + "target_id": 290, + "target_slot": 1, + "type": "INT" + }, + { + "id": 559, + "origin_id": 299, + "origin_slot": 0, + "target_id": 290, + "target_slot": 2, + "type": "INT" + }, + { + "id": 560, + "origin_id": 312, + "origin_slot": 0, + "target_id": 292, + "target_slot": 0, + "type": "INT" + }, + { + "id": 557, + "origin_id": 316, + "origin_slot": 2, + "target_id": 293, + "target_slot": 0, + "type": "VAE" + }, + { + "id": 562, + "origin_id": 299, + "origin_slot": 0, + "target_id": 294, + "target_slot": 0, + "type": "INT" + }, + { + "id": 561, + "origin_id": 292, + "origin_slot": 1, + "target_id": 295, + "target_slot": 0, + "type": "INT" + }, + { + "id": 563, + "origin_id": 294, + "origin_slot": 1, + "target_id": 295, + "target_slot": 1, + "type": "INT" + }, + { + "id": 556, + "origin_id": 316, + "origin_slot": 2, + "target_id": 296, + "target_slot": 0, + "type": "VAE" + }, + { + "id": 510, + "origin_id": 289, + "origin_slot": 0, + "target_id": 296, + "target_slot": 1, + "type": "IMAGE" + }, + { + "id": 511, + "origin_id": 295, + "origin_slot": 0, + "target_id": 296, + "target_slot": 2, + "type": "LATENT" + }, + { + "id": 542, + "origin_id": 302, + "origin_slot": 0, + "target_id": 296, + "target_slot": 3, + "type": "BOOLEAN" + }, + { + "id": 495, + "origin_id": 309, + "origin_slot": 1, + "target_id": 297, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 496, + "origin_id": 279, + "origin_slot": 0, + "target_id": 297, + "target_slot": 1, + "type": "VAE" + }, + { + "id": 564, + "origin_id": 300, + "origin_slot": 0, + "target_id": 298, + "target_slot": 0, + "type": "INT" + }, + { + "id": 526, + "origin_id": 303, + "origin_slot": 0, + "target_id": 304, + "target_slot": 0, + "type": "CONDITIONING" + }, + { + "id": 527, + "origin_id": 313, + "origin_slot": 0, + "target_id": 304, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 566, + "origin_id": 298, + "origin_slot": 0, + "target_id": 304, + "target_slot": 2, + "type": "FLOAT" + }, + { + "id": 497, + "origin_id": 296, + "origin_slot": 0, + "target_id": 318, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 498, + "origin_id": 305, + "origin_slot": 0, + "target_id": 318, + "target_slot": 1, + "type": "LATENT" + }, + { + "id": 481, + "origin_id": 279, + "origin_slot": 0, + "target_id": 305, + "target_slot": 0, + "type": "VAE" + }, + { + "id": 565, + "origin_id": 298, + "origin_slot": 1, + "target_id": 305, + "target_slot": 2, + "type": "INT" + }, + { + "id": 488, + "origin_id": 283, + "origin_slot": 0, + "target_id": 307, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 490, + "origin_id": 276, + "origin_slot": 0, + "target_id": 308, + "target_slot": 0, + "type": "NOISE" + }, + { + "id": 491, + "origin_id": 282, + "origin_slot": 0, + "target_id": 308, + "target_slot": 1, + "type": "GUIDER" + }, + { + "id": 492, + "origin_id": 280, + "origin_slot": 0, + "target_id": 308, + "target_slot": 2, + "type": "SAMPLER" + }, + { + "id": 493, + "origin_id": 281, + "origin_slot": 0, + "target_id": 308, + "target_slot": 3, + "type": "SIGMAS" + }, + { + "id": 494, + "origin_id": 278, + "origin_slot": 0, + "target_id": 308, + "target_slot": 4, + "type": "LATENT" + }, + { + "id": 578, + "origin_id": 308, + "origin_slot": 0, + "target_id": 309, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 539, + "origin_id": 309, + "origin_slot": 0, + "target_id": 315, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 553, + "origin_id": 293, + "origin_slot": 0, + "target_id": 315, + "target_slot": 1, + "type": "VAE" + }, + { + "id": 538, + "origin_id": 315, + "origin_slot": 0, + "target_id": 310, + "target_slot": 0, + "type": "IMAGE" + }, + { + "id": 534, + "origin_id": 297, + "origin_slot": 0, + "target_id": 310, + "target_slot": 1, + "type": "AUDIO" + }, + { + "id": 591, + "origin_id": 298, + "origin_slot": 0, + "target_id": 310, + "target_slot": 2, + "type": "FLOAT" + }, + { + "id": 535, + "origin_id": -10, + "origin_slot": 0, + "target_id": 290, + "target_slot": 0, + "type": "IMAGE,MASK" + }, + { + "id": 536, + "origin_id": 310, + "origin_slot": 0, + "target_id": -20, + "target_slot": 0, + "type": "VIDEO" + }, + { + "id": 595, + "origin_id": -10, + "origin_slot": 1, + "target_id": 319, + "target_slot": 0, + "type": "STRING" + }, + { + "id": 597, + "origin_id": -10, + "origin_slot": 3, + "target_id": 312, + "target_slot": 0, + "type": "INT" + }, + { + "id": 598, + "origin_id": -10, + "origin_slot": 4, + "target_id": 299, + "target_slot": 0, + "type": "INT" + }, + { + "id": 599, + "origin_id": -10, + "origin_slot": 5, + "target_id": 301, + "target_slot": 0, + "type": "INT" + }, + { + "id": 601, + "origin_id": -10, + "origin_slot": 8, + "target_id": 316, + "target_slot": 0, + "type": "COMBO" + }, + { + "id": 602, + "origin_id": -10, + "origin_slot": 9, + "target_id": 285, + "target_slot": 1, + "type": "COMBO" + }, + { + "id": 604, + "origin_id": -10, + "origin_slot": 8, + "target_id": 279, + "target_slot": 0, + "type": "COMBO" + }, + { + "id": 605, + "origin_id": -10, + "origin_slot": 8, + "target_id": 317, + "target_slot": 1, + "type": "COMBO" + }, + { + "id": 606, + "origin_id": -10, + "origin_slot": 10, + "target_id": 317, + "target_slot": 0, + "type": "COMBO" + }, + { + "id": 607, + "origin_id": -10, + "origin_slot": 11, + "target_id": 311, + "target_slot": 0, + "type": "COMBO" + }, + { + "id": 624, + "origin_id": -10, + "origin_slot": 6, + "target_id": 300, + "target_slot": 0, + "type": "INT" + }, + { + "id": 627, + "origin_id": 317, + "origin_slot": 0, + "target_id": 313, + "target_slot": 0, + "type": "CLIP" + }, + { + "id": 628, + "origin_id": 301, + "origin_slot": 0, + "target_id": 323, + "target_slot": 0, + "type": "INT" + }, + { + "id": 629, + "origin_id": 300, + "origin_slot": 0, + "target_id": 323, + "target_slot": 1, + "type": "INT" + }, + { + "id": 630, + "origin_id": 323, + "origin_slot": 1, + "target_id": 305, + "target_slot": 1, + "type": "INT" + }, + { + "id": 631, + "origin_id": 323, + "origin_slot": 1, + "target_id": 295, + "target_slot": 2, + "type": "INT" + }, + { + "id": 634, + "origin_id": 324, + "origin_slot": 1, + "target_id": 325, + "target_slot": 0, + "type": "CLIP" + }, + { + "id": 635, + "origin_id": 327, + "origin_slot": 0, + "target_id": 326, + "target_slot": 0, + "type": "*" + }, + { + "id": 636, + "origin_id": 325, + "origin_slot": 0, + "target_id": 327, + "target_slot": 1, + "type": "STRING" + }, + { + "id": 637, + "origin_id": 328, + "origin_slot": 0, + "target_id": 327, + "target_slot": 2, + "type": "BOOLEAN" + }, + { + "id": 638, + "origin_id": 327, + "origin_slot": 0, + "target_id": 303, + "target_slot": 1, + "type": "STRING" + }, + { + "id": 639, + "origin_id": 319, + "origin_slot": 0, + "target_id": 325, + "target_slot": 4, + "type": "STRING" + }, + { + "id": 640, + "origin_id": 319, + "origin_slot": 0, + "target_id": 327, + "target_slot": 0, + "type": "STRING" + }, + { + "id": 641, + "origin_id": 285, + "origin_slot": 0, + "target_id": 324, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 642, + "origin_id": 317, + "origin_slot": 0, + "target_id": 303, + "target_slot": 0, + "type": "CLIP" + }, + { + "id": 643, + "origin_id": 317, + "origin_slot": 0, + "target_id": 324, + "target_slot": 1, + "type": "CLIP" + }, + { + "id": 644, + "origin_id": -10, + "origin_slot": 2, + "target_id": 328, + "target_slot": 0, + "type": "BOOLEAN" + }, + { + "id": 645, + "origin_id": -10, + "origin_slot": 12, + "target_id": 324, + "target_slot": 2, + "type": "COMBO" + }, + { + "id": 646, + "origin_id": -10, + "origin_slot": 7, + "target_id": 277, + "target_slot": 0, + "type": "INT" + } + ], + "extra": { + "workflowRendererVersion": "Vue-corrected", + "ue_links": [] + } + } + ] + }, + "config": {}, + "extra": { + "ds": { + "scale": 0.41201716738197425, + "offset": [ + 1618.0394287109375, + -3067.713541666667 ] - }, - { - "id": 283, - "type": "SamplerCustomAdvanced", - "pos": [ - 3550, - 3630 - ], - "size": [ - 230, - 170 - ], - "flags": {}, - "order": 10, - "mode": 0, - "inputs": [ - { - "localized_name": "noise", - "name": "noise", - "type": "NOISE", - "link": 483 - }, - { - "localized_name": "guider", - "name": "guider", - "type": "GUIDER", - "link": 484 - }, - { - "localized_name": "sampler", - "name": "sampler", - "type": "SAMPLER", - "link": 485 - }, - { - "localized_name": "sigmas", - "name": "sigmas", - "type": "SIGMAS", - "link": 544 - }, - { - "localized_name": "latent_image", - "name": "latent_image", - "type": "LATENT", - "link": 487 - } - ], - "outputs": [ - { - "localized_name": "output", - "name": "output", - "type": "LATENT", - "links": [ - 488 - ] - }, - { - "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": {} - } + }, + "frontendVersion": "1.45.21", + "workflowRendererVersion": "Vue-corrected", + "prompt": { + "1": { + "inputs": { + "ckpt_name": "ltx-av-step-1751000_vocoder_24K.safetensors" + }, + "class_type": "CheckpointLoaderSimple", + "_meta": { + "title": "Load Checkpoint" + } }, - "widgets_values": [] - }, - { - "id": 284, - "type": "LTXVCropGuides", - "pos": [ - 3830, - 3810 - ], - "size": [ - 250, - 120 - ], - "flags": {}, - "order": 11, - "mode": 0, - "inputs": [ - { - "localized_name": "positive", - "name": "positive", - "type": "CONDITIONING", - "link": 475 - }, - { - "localized_name": "negative", - "name": "negative", - "type": "CONDITIONING", - "link": 476 - }, - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "link": 477 - } - ], - "outputs": [ - { - "localized_name": "positive", - "name": "positive", - "type": "CONDITIONING", - "links": [ - 479 - ] - }, - { - "localized_name": "negative", - "name": "negative", - "type": "CONDITIONING", - "links": [ - 480 - ] - }, - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "slot_index": 2, - "links": [] - } - ], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.68", - "Node name for S&R": "LTXVCropGuides", - "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": {} - } + "2": { + "inputs": { + "gemma_path": "gemma-3-12b-it-qat-q4_0-unquantized_readout_proj/model/model.safetensors", + "ltxv_path": "ltx-av-step-1751000_vocoder_24K.safetensors", + "max_length": 1024 + }, + "class_type": "LTXVGemmaCLIPModelLoader", + "_meta": { + "title": "🅛🅣🅧 Gemma 3 Model Loader" + } }, - "widgets_values": [] - }, - { - "id": 285, - "type": "LoraLoaderModelOnly", - "pos": [ - 1660, - 3890 - ], - "size": [ - 430, - 140 - ], - "flags": {}, - "order": 12, - "mode": 0, - "inputs": [ - { - "localized_name": "model", - "name": "model", - "type": "MODEL", - "link": 520 - }, - { - "localized_name": "lora_name", - "name": "lora_name", - "type": "COMBO", - "widget": { - "name": "lora_name" + "3": { + "inputs": { + "text": "", + "clip": [ + "2", + 0 + ] }, - "link": 602 - } - ], - "outputs": [ - { - "localized_name": "MODEL", - "name": "MODEL", - "type": "MODEL", - "links": [ - 478, - 541, - 641 - ] - } - ], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.75", - "Node name for S&R": "LoraLoaderModelOnly", - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "models": [ - { - "name": "ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", - "url": "https://huggingface.co/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", - "directory": "loras" + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" } - ], - "ue_properties": { - "widget_ue_connectable": {}, - "version": "7.7", - "input_ue_unconnectable": {} - } }, - "widgets_values": [ - "ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", - 0.5 - ] - }, - { - "id": 286, - "type": "ResizeImagesByLongerEdge", - "pos": [ - 2070, - 4810 - ], - "size": [ - 348.624609375, - 110 - ], - "flags": { - "collapsed": false + "4": { + "inputs": { + "text": "blurry, low quality, still frame, frames, watermark, overlay, titles, has blurbox, has subtitles", + "clip": [ + "2", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } }, - "order": 13, - "mode": 0, - "inputs": [ - { - "localized_name": "images", - "name": "images", - "type": "IMAGE", - "link": 523 - } - ], - "outputs": [ - { - "localized_name": "images", - "name": "images", - "type": "IMAGE", - "links": [ - 505 - ] - } - ], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.5.1", - "Node name for S&R": "ResizeImagesByLongerEdge", - "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": {} - } + "8": { + "inputs": { + "sampler_name": "euler" + }, + "class_type": "KSamplerSelect", + "_meta": { + "title": "KSamplerSelect" + } }, - "widgets_values": [ - 1536 - ] - }, - { - "id": 287, - "type": "LTXVLatentUpsampler", - "pos": [ - 4250, - 3760 - ], - "size": [ - 330, - 120 - ], - "flags": {}, - "order": 14, - "mode": 0, - "inputs": [ - { - "localized_name": "samples", - "name": "samples", - "type": "LATENT", - "link": 547 - }, - { - "localized_name": "upscale_model", - "name": "upscale_model", - "type": "LATENT_UPSCALE_MODEL", - "link": 545 - }, - { - "localized_name": "vae", - "name": "vae", - "type": "VAE", - "link": 554 - } - ], - "outputs": [ - { - "localized_name": "LATENT", - "name": "LATENT", - "type": "LATENT", - "links": [ - 548 - ] - } - ], - "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": {} - } + "9": { + "inputs": { + "steps": 20, + "max_shift": 2.05, + "base_shift": 0.95, + "stretch": true, + "terminal": 0.1, + "latent": [ + "28", + 0 + ] + }, + "class_type": "LTXVScheduler", + "_meta": { + "title": "LTXVScheduler" + } }, - "widgets_values": [] - }, - { - "id": 288, - "type": "LTXVImgToVideoInplace", - "pos": [ - 4230, - 4100 - ], - "size": [ - 300, - 180 - ], - "flags": {}, - "order": 15, - "mode": 0, - "inputs": [ - { - "localized_name": "vae", - "name": "vae", - "type": "VAE", - "link": 552 - }, - { - "localized_name": "image", - "name": "image", - "type": "IMAGE", - "link": 515 - }, - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "link": 548 - }, - { - "localized_name": "bypass", - "name": "bypass", - "type": "BOOLEAN", - "widget": { - "name": "bypass" + "11": { + "inputs": { + "noise_seed": 10 }, - "link": 543 - } - ], - "outputs": [ - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "links": [ - 512 - ] - } - ], - "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": {} - } + "class_type": "RandomNoise", + "_meta": { + "title": "RandomNoise" + } }, - "widgets_values": [ - 1, - false - ] - }, - { - "id": 289, - "type": "LTXVPreprocess", - "pos": [ - 2100, - 5010 - ], - "size": [ - 290, - 110 - ], - "flags": {}, - "order": 16, - "mode": 0, - "inputs": [ - { - "localized_name": "image", - "name": "image", - "type": "IMAGE", - "link": 505 - } - ], - "outputs": [ - { - "localized_name": "output_image", - "name": "output_image", - "type": "IMAGE", - "links": [ - 510, - 515 - ] - } - ], - "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": {} - } + "12": { + "inputs": { + "samples": [ + "29", + 0 + ], + "vae": [ + "1", + 2 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } }, - "widgets_values": [ - 18 - ] - }, - { - "id": 290, - "type": "ResizeImageMaskNode", - "pos": [ - 1660, - 4810 - ], - "size": [ - 300, - 154 - ], - "flags": {}, - "order": 17, - "mode": 0, - "inputs": [ - { - "localized_name": "input", - "name": "input", - "type": "IMAGE,MASK", - "link": 535 - }, - { - "localized_name": "width", - "name": "resize_type.width", - "type": "INT", - "widget": { - "name": "resize_type.width" + "13": { + "inputs": { + "ckpt_name": "ltx-av-step-1751000_vocoder_24K.safetensors" }, - "link": 558 - }, - { - "localized_name": "height", - "name": "resize_type.height", - "type": "INT", - "widget": { - "name": "resize_type.height" + "class_type": "LTXVAudioVAELoader", + "_meta": { + "title": "🅛🅣🅧 LTXV Audio VAE Loader" + } + }, + "14": { + "inputs": { + "samples": [ + "29", + 1 + ], + "audio_vae": [ + "13", + 0 + ] }, - "link": 559 - } - ], - "outputs": [ - { - "localized_name": "resized", - "name": "resized", - "type": "IMAGE,MASK", - "links": [ - 523 - ] - } - ], - "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": {} - } + "class_type": "LTXVAudioVAEDecode", + "_meta": { + "title": "🅛🅣🅧 LTXV Audio VAE Decode" + } }, - "widgets_values": [ - "scale dimensions", - 1920, - 1088, - "center", - "lanczos" - ] - }, - { - "id": 291, - "type": "KSamplerSelect", - "pos": [ - 3160, - 4040 - ], - "size": [ - 280, - 110 - ], - "flags": {}, - "order": 3, - "mode": 0, - "inputs": [], - "outputs": [ - { - "localized_name": "SAMPLER", - "name": "SAMPLER", - "type": "SAMPLER", - "links": [ - 485 - ] - } - ], - "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": {} - } + "15": { + "inputs": { + "frame_rate": [ + "23", + 0 + ], + "loop_count": 0, + "filename_prefix": "AnimateDiff", + "format": "video/h264-mp4", + "pix_fmt": "yuv420p", + "crf": 19, + "save_metadata": true, + "trim_to_audio": false, + "pingpong": false, + "save_output": true, + "images": [ + "12", + 0 + ], + "audio": [ + "14", + 0 + ] + }, + "class_type": "VHS_VideoCombine", + "_meta": { + "title": "Video Combine 🎥🅥🅗🅢" + } }, - "widgets_values": [ - "euler" - ] - }, - { - "id": 292, - "type": "ComfyMathExpression", - "pos": [ - 2540, - 4830 - ], - "size": [ - 225, - 74 - ], - "flags": { - "collapsed": true + "17": { + "inputs": { + "skip_blocks": "29", + "model": [ + "28", + 1 + ], + "positive": [ + "22", + 0 + ], + "negative": [ + "22", + 1 + ], + "parameters": [ + "18", + 0 + ] + }, + "class_type": "MultimodalGuider", + "_meta": { + "title": "🅛🅣🅧 Multimodal Guider" + } }, - "order": 18, - "mode": 0, - "inputs": [ - { - "label": "a", - "localized_name": "values.a", - "name": "values.a", - "type": "FLOAT,INT,BOOLEAN", - "link": 560 - }, - { - "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": null - }, - { - "localized_name": "INT", - "name": "INT", - "type": "INT", - "links": [ - 561 - ] - }, - { - "localized_name": "BOOL", - "name": "BOOL", - "type": "BOOLEAN", - "links": null - } - ], - "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": {} - } + "18": { + "inputs": { + "modality": "VIDEO", + "cfg": 3, + "stg": 0, + "rescale": 0, + "modality_scale": 3, + "parameters": [ + "19", + 0 + ] + }, + "class_type": "GuiderParameters", + "_meta": { + "title": "🅛🅣🅧 Guider Parameters" + } }, - "widgets_values": [ - "a/2" - ] - }, - { - "id": 293, - "type": "Reroute", - "pos": [ - 3850, - 4050 - ], - "size": [ - 75, - 26 - ], - "flags": {}, - "order": 19, - "mode": 0, - "inputs": [ - { - "name": "", - "type": "*", - "link": 557 - } - ], - "outputs": [ - { - "name": "", - "type": "VAE", - "links": [ - 552, - 553, - 554 - ] - } - ], - "properties": { - "showOutputText": false, - "horizontal": false, - "ue_properties": { - "widget_ue_connectable": {}, - "version": "7.7", - "input_ue_unconnectable": {} - } - } - }, - { - "id": 294, - "type": "ComfyMathExpression", - "pos": [ - 2550, - 4890 - ], - "size": [ - 225, - 74 - ], - "flags": { - "collapsed": true + "19": { + "inputs": { + "modality": "AUDIO", + "cfg": 7, + "stg": 0, + "rescale": 0, + "modality_scale": 3 + }, + "class_type": "GuiderParameters", + "_meta": { + "title": "🅛🅣🅧 Guider Parameters" + } }, - "order": 20, - "mode": 0, - "inputs": [ - { - "label": "a", - "localized_name": "values.a", - "name": "values.a", - "type": "FLOAT,INT,BOOLEAN", - "link": 562 - }, - { - "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": null - }, - { - "localized_name": "INT", - "name": "INT", - "type": "INT", - "links": [ - 563 - ] - }, - { - "localized_name": "BOOL", - "name": "BOOL", - "type": "BOOLEAN", - "links": null - } - ], - "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": {} - } + "21": { + "inputs": { + "audioUI": "", + "audio": [ + "14", + 0 + ] + }, + "class_type": "PreviewAudio", + "_meta": { + "title": "PreviewAudio" + } }, - "widgets_values": [ - "a/2" - ] - }, - { - "id": 295, - "type": "EmptyLTXVLatentVideo", - "pos": [ - 2870, - 4940 - ], - "size": [ - 280, - 200 - ], - "flags": {}, - "order": 21, - "mode": 0, - "inputs": [ - { - "localized_name": "width", - "name": "width", - "type": "INT", - "widget": { - "name": "width" + "22": { + "inputs": { + "frame_rate": [ + "23", + 0 + ], + "positive": [ + "3", + 0 + ], + "negative": [ + "4", + 0 + ] }, - "link": 561 - }, - { - "localized_name": "height", - "name": "height", - "type": "INT", - "widget": { - "name": "height" + "class_type": "LTXVConditioning", + "_meta": { + "title": "LTXVConditioning" + } + }, + "23": { + "inputs": { + "value": 25 }, - "link": 563 - }, - { - "localized_name": "length", - "name": "length", - "type": "INT", - "widget": { - "name": "length" + "class_type": "FloatConstant", + "_meta": { + "title": "Float Constant" + } + }, + "26": { + "inputs": { + "frames_number": [ + "27", + 0 + ], + "frame_rate": [ + "42", + 0 + ], + "batch_size": 1 }, - "link": 631 - } - ], - "outputs": [ - { - "localized_name": "LATENT", - "name": "LATENT", - "type": "LATENT", - "links": [ - 511 - ] - } - ], - "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": {} - } + "class_type": "LTXVEmptyLatentAudio", + "_meta": { + "title": "🅛🅣🅧 LTXV Empty Latent Audio" + } }, - "widgets_values": [ - 768, - 512, - 97, - 1 - ] - }, - { - "id": 296, - "type": "LTXVImgToVideoInplace", - "pos": [ - 3230, - 4810 - ], - "size": [ - 280, - 180 - ], - "flags": {}, - "order": 22, - "mode": 0, - "inputs": [ - { - "localized_name": "vae", - "name": "vae", - "type": "VAE", - "link": 556 - }, - { - "localized_name": "image", - "name": "image", - "type": "IMAGE", - "link": 510 - }, - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "link": 511 - }, - { - "localized_name": "bypass", - "name": "bypass", - "type": "BOOLEAN", - "widget": { - "name": "bypass" + "27": { + "inputs": { + "value": 105 }, - "link": 542 - } - ], - "outputs": [ - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "links": [ - 497 - ] - } - ], - "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": {} - } + "class_type": "INTConstant", + "_meta": { + "title": "INT Constant" + } }, - "widgets_values": [ - 0.7, - false - ] - }, - { - "id": 297, - "type": "LTXVAudioVAEDecode", - "pos": [ - 5760, - 3970 - ], - "size": [ - 270, - 100 - ], - "flags": {}, - "order": 23, - "mode": 0, - "inputs": [ - { - "localized_name": "samples", - "name": "samples", - "type": "LATENT", - "link": 495 - }, - { - "label": "Audio VAE", - "localized_name": "audio_vae", - "name": "audio_vae", - "type": "VAE", - "link": 496 - } - ], - "outputs": [ - { - "localized_name": "Audio", - "name": "Audio", - "type": "AUDIO", - "links": [ - 534 - ] - } - ], - "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": {} - } + "28": { + "inputs": { + "video_latent": [ + "43", + 0 + ], + "audio_latent": [ + "26", + 0 + ], + "model": [ + "44", + 0 + ] + }, + "class_type": "LTXVConcatAVLatent", + "_meta": { + "title": "🅛🅣🅧 LTXV Concat AV Latent" + } }, - "widgets_values": [] - }, - { - "id": 298, - "type": "ComfyMathExpression", - "pos": [ - 2540, - 5030 - ], - "size": [ - 225, - 74 - ], - "flags": { - "collapsed": true + "29": { + "inputs": { + "av_latent": [ + "41", + 0 + ], + "model": [ + "28", + 1 + ] + }, + "class_type": "LTXVSeparateAVLatent", + "_meta": { + "title": "🅛🅣🅧 LTXV Separate AV Latent" + } }, - "order": 24, - "mode": 0, - "inputs": [ - { - "label": "a", - "localized_name": "values.a", - "name": "values.a", - "type": "FLOAT,INT,BOOLEAN", - "link": 564 - }, - { - "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": [ - 566, - 591 - ] - }, - { - "localized_name": "INT", - "name": "INT", - "type": "INT", - "links": [ - 565 - ] - }, - { - "localized_name": "BOOL", - "name": "BOOL", - "type": "BOOLEAN", - "links": null - } - ], - "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": {} - } + "41": { + "inputs": { + "noise": [ + "11", + 0 + ], + "guider": [ + "17", + 0 + ], + "sampler": [ + "8", + 0 + ], + "sigmas": [ + "9", + 0 + ], + "latent_image": [ + "28", + 0 + ] + }, + "class_type": "SamplerCustomAdvanced", + "_meta": { + "title": "SamplerCustomAdvanced" + } }, - "widgets_values": [ - "a" - ] - }, - { - "id": 299, - "type": "PrimitiveInt", - "pos": [ - 1190, - 4650 - ], - "size": [ - 370, - 110 - ], - "flags": {}, - "order": 25, - "mode": 0, - "inputs": [ - { - "localized_name": "value", - "name": "value", - "type": "INT", - "widget": { - "name": "value" + "42": { + "inputs": { + "a": [ + "23", + 0 + ] }, - "link": 598 - } - ], - "outputs": [ - { - "localized_name": "INT", - "name": "INT", - "type": "INT", - "links": [ - 559, - 562 - ] - } - ], - "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": {} - } + "class_type": "CM_FloatToInt", + "_meta": { + "title": "FloatToInt" + } }, - "widgets_values": [ - 1280, - "fixed" - ] - }, - { - "id": 300, - "type": "PrimitiveInt", - "pos": [ - 1190, - 4840 - ], - "size": [ - 370, - 110 - ], - "flags": {}, - "order": 26, - "mode": 0, - "inputs": [ - { - "localized_name": "value", - "name": "value", - "type": "INT", - "widget": { - "name": "value" + "43": { + "inputs": { + "width": 768, + "height": 512, + "length": [ + "27", + 0 + ], + "batch_size": 1 }, - "link": 624 - } - ], - "outputs": [ - { - "localized_name": "INT", - "name": "INT", - "type": "INT", - "links": [ - 564, - 629 - ] - } - ], - "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": {} - } + "class_type": "EmptyLTXVLatentVideo", + "_meta": { + "title": "EmptyLTXVLatentVideo" + } }, - "widgets_values": [ - 25, - "fixed" - ] - }, - { - "id": 301, - "type": "PrimitiveInt", - "pos": [ - 1190, - 4280 - ], - "size": [ - 370, - 110 - ], - "flags": {}, - "order": 27, - "mode": 0, - "inputs": [ - { - "localized_name": "value", - "name": "value", - "type": "INT", - "widget": { - "name": "value" + "44": { + "inputs": { + "torch_compile": true, + "disable_backup": false, + "model": [ + "1", + 0 + ] }, - "link": 599 - } - ], - "outputs": [ - { - "localized_name": "INT", - "name": "INT", - "type": "INT", - "links": [ - 628 - ] - } - ], - "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": {} - } + "class_type": "LTXVSequenceParallelMultiGPUPatcher", + "_meta": { + "title": "LTXVSequenceParallelMultiGPUPatcher" + } }, - "widgets_values": [ - 5, - "fixed" - ] - }, - { - "id": 302, - "type": "PrimitiveBoolean", - "pos": [ - 1190, - 4110 - ], - "size": [ - 370, - 100 - ], - "flags": {}, - "order": 4, - "mode": 0, - "inputs": [], - "outputs": [ - { - "localized_name": "BOOLEAN", - "name": "BOOLEAN", - "type": "BOOLEAN", - "links": [ - 542, - 543 - ] - } - ], - "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": 303, - "type": "CLIPTextEncode", - "pos": [ - 2170, - 3640 - ], - "size": [ - 600, - 390 - ], - "flags": {}, - "order": 28, - "mode": 0, - "inputs": [ - { - "localized_name": "clip", - "name": "clip", - "type": "CLIP", - "link": 642 - }, - { - "localized_name": "text", - "name": "text", - "type": "STRING", - "widget": { - "name": "text" - }, - "link": 638 - } - ], - "outputs": [ - { - "localized_name": "CONDITIONING", - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 526 - ] - } - ], - "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": 304, - "type": "LTXVConditioning", - "pos": [ - 2800, - 3810 - ], - "size": [ - 280, - 130 - ], - "flags": {}, - "order": 29, - "mode": 0, - "inputs": [ - { - "localized_name": "positive", - "name": "positive", - "type": "CONDITIONING", - "link": 526 - }, - { - "localized_name": "negative", - "name": "negative", - "type": "CONDITIONING", - "link": 527 - }, - { - "localized_name": "frame_rate", - "name": "frame_rate", - "type": "FLOAT", - "widget": { - "name": "frame_rate" - }, - "link": 566 - } - ], - "outputs": [ - { - "localized_name": "positive", - "name": "positive", - "type": "CONDITIONING", - "links": [ - 475, - 518 - ] - }, - { - "localized_name": "negative", - "name": "negative", - "type": "CONDITIONING", - "links": [ - 476, - 519 - ] - } - ], - "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": 305, - "type": "LTXVEmptyLatentAudio", - "pos": [ - 3540, - 4960 - ], - "size": [ - 280, - 170 - ], - "flags": {}, - "order": 30, - "mode": 0, - "inputs": [ - { - "localized_name": "audio_vae", - "name": "audio_vae", - "type": "VAE", - "link": 481 - }, - { - "localized_name": "frames_number", - "name": "frames_number", - "type": "INT", - "widget": { - "name": "frames_number" - }, - "link": 630 - }, - { - "localized_name": "frame_rate", - "name": "frame_rate", - "type": "INT", - "widget": { - "name": "frame_rate" - }, - "link": 565 - } - ], - "outputs": [ - { - "localized_name": "Latent", - "name": "Latent", - "type": "LATENT", - "links": [ - 498 - ] - } - ], - "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": 306, - "type": "ManualSigmas", - "pos": [ - 3160, - 4220 - ], - "size": [ - 500, - 110 - ], - "flags": {}, - "order": 5, - "mode": 0, - "inputs": [], - "outputs": [ - { - "localized_name": "SIGMAS", - "name": "SIGMAS", - "type": "SIGMAS", - "links": [ - 544 - ] - } - ], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.14.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": [ - "1.0, 0.99375, 0.9875, 0.98125, 0.975, 0.909375, 0.725, 0.421875, 0.0" - ] - }, - { - "id": 307, - "type": "LTXVSeparateAVLatent", - "pos": [ - 3820, - 3630 - ], - "size": [ - 250, - 100 - ], - "flags": {}, - "order": 31, - "mode": 0, - "inputs": [ - { - "localized_name": "av_latent", - "name": "av_latent", - "type": "LATENT", - "link": 488 - } - ], - "outputs": [ - { - "localized_name": "video_latent", - "name": "video_latent", - "type": "LATENT", - "links": [ - 477, - 547 - ] - }, - { - "localized_name": "audio_latent", - "name": "audio_latent", - "type": "LATENT", - "links": [ - 513 - ] - } - ], - "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": 308, - "type": "SamplerCustomAdvanced", - "pos": [ - 5050, - 3650 - ], - "size": [ - 230, - 170 - ], - "flags": {}, - "order": 32, - "mode": 0, - "inputs": [ - { - "localized_name": "noise", - "name": "noise", - "type": "NOISE", - "link": 490 - }, - { - "localized_name": "guider", - "name": "guider", - "type": "GUIDER", - "link": 491 - }, - { - "localized_name": "sampler", - "name": "sampler", - "type": "SAMPLER", - "link": 492 - }, - { - "localized_name": "sigmas", - "name": "sigmas", - "type": "SIGMAS", - "link": 493 - }, - { - "localized_name": "latent_image", - "name": "latent_image", - "type": "LATENT", - "link": 494 - } - ], - "outputs": [ - { - "localized_name": "output", - "name": "output", - "type": "LATENT", - "links": [ - 578 - ] - }, - { - "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": 309, - "type": "LTXVSeparateAVLatent", - "pos": [ - 5390, - 3650 - ], - "size": [ - 230, - 100 - ], - "flags": {}, - "order": 33, - "mode": 0, - "inputs": [ - { - "localized_name": "av_latent", - "name": "av_latent", - "type": "LATENT", - "link": 578 - } - ], - "outputs": [ - { - "localized_name": "video_latent", - "name": "video_latent", - "type": "LATENT", - "links": [ - 539 - ] - }, - { - "localized_name": "audio_latent", - "name": "audio_latent", - "type": "LATENT", - "links": [ - 495 - ] - } - ], - "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": 310, - "type": "CreateVideo", - "pos": [ - 6050, - 4490 - ], - "size": [ - 280, - 130 - ], - "flags": {}, - "order": 34, - "mode": 0, - "inputs": [ - { - "localized_name": "images", - "name": "images", - "type": "IMAGE", - "link": 538 - }, - { - "localized_name": "audio", - "name": "audio", - "shape": 7, - "type": "AUDIO", - "link": 534 - }, - { - "localized_name": "fps", - "name": "fps", - "type": "FLOAT", - "widget": { - "name": "fps" - }, - "link": 591 - } - ], - "outputs": [ - { - "localized_name": "VIDEO", - "name": "VIDEO", - "type": "VIDEO", - "links": [ - 536 - ] - } - ], - "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": 311, - "type": "LatentUpscaleModelLoader", - "pos": [ - 1670, - 4550 - ], - "size": [ - 400, - 110 - ], - "flags": {}, - "order": 35, - "mode": 0, - "inputs": [ - { - "localized_name": "model_name", - "name": "model_name", - "type": "COMBO", - "widget": { - "name": "model_name" + "45": { + "inputs": { + "frame_idx": 0, + "strength": 1 }, - "link": 607 - } - ], - "outputs": [ - { - "localized_name": "LATENT_UPSCALE_MODEL", - "name": "LATENT_UPSCALE_MODEL", - "type": "LATENT_UPSCALE_MODEL", - "links": [ - 545 - ] - } - ], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.7.0", - "Node name for S&R": "LatentUpscaleModelLoader", - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "models": [ - { - "name": "ltx-2.3-spatial-upscaler-x2-1.1.safetensors", - "url": "https://huggingface.co/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors", - "directory": "latent_upscale_models" + "class_type": "LTXVAddGuide", + "_meta": { + "title": "LTXVAddGuide" } - ], - "ue_properties": { - "widget_ue_connectable": {}, - "version": "7.7", - "input_ue_unconnectable": {} - } - }, - "widgets_values": [ - "ltx-2.3-spatial-upscaler-x2-1.1.safetensors" - ] - }, - { - "id": 312, - "type": "PrimitiveInt", - "pos": [ - 1190, - 4470 - ], - "size": [ - 370, - 110 - ], - "flags": {}, - "order": 36, - "mode": 0, - "inputs": [ - { - "localized_name": "value", - "name": "value", - "type": "INT", - "widget": { - "name": "value" - }, - "link": 597 - } - ], - "outputs": [ - { - "localized_name": "INT", - "name": "INT", - "type": "INT", - "links": [ - 558, - 560 - ] - } - ], - "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": [ - 720, - "fixed" - ] - }, - { - "id": 313, - "type": "CLIPTextEncode", - "pos": [ - 2180, - 4120 - ], - "size": [ - 600, - 170 - ], - "flags": {}, - "order": 37, - "mode": 0, - "inputs": [ - { - "localized_name": "clip", - "name": "clip", - "type": "CLIP", - "link": 627 - } - ], - "outputs": [ - { - "localized_name": "CONDITIONING", - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 527 - ] - } - ], - "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": [ - "pc game, console game, video game, cartoon, childish, ugly" - ], - "color": "#323", - "bgcolor": "#535" - }, - { - "id": 314, - "type": "CFGGuider", - "pos": [ - 3160, - 3810 - ], - "size": [ - 280, - 160 - ], - "flags": {}, - "order": 38, - "mode": 0, - "inputs": [ - { - "localized_name": "model", - "name": "model", - "type": "MODEL", - "link": 541 - }, - { - "localized_name": "positive", - "name": "positive", - "type": "CONDITIONING", - "link": 518 - }, - { - "localized_name": "negative", - "name": "negative", - "type": "CONDITIONING", - "link": 519 - } - ], - "outputs": [ - { - "localized_name": "GUIDER", - "name": "GUIDER", - "type": "GUIDER", - "links": [ - 484 - ] - } - ], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.64", - "Node name for S&R": "CFGGuider", - "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 - ] - }, - { - "id": 315, - "type": "VAEDecodeTiled", - "pos": [ - 5750, - 3610 - ], - "size": [ - 280, - 200 - ], - "flags": {}, - "order": 39, - "mode": 0, - "inputs": [ - { - "localized_name": "samples", - "name": "samples", - "type": "LATENT", - "link": 539 - }, - { - "localized_name": "vae", - "name": "vae", - "type": "VAE", - "link": 553 - } - ], - "outputs": [ - { - "localized_name": "IMAGE", - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 538 - ] - } - ], - "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": [ - 768, - 64, - 4096, - 4 - ] - }, - { - "id": 316, - "type": "CheckpointLoaderSimple", - "pos": [ - 1660, - 3660 - ], - "size": [ - 430, - 160 - ], - "flags": {}, - "order": 40, - "mode": 0, - "inputs": [ - { - "localized_name": "ckpt_name", - "name": "ckpt_name", - "type": "COMBO", - "widget": { - "name": "ckpt_name" - }, - "link": 601 - } - ], - "outputs": [ - { - "localized_name": "MODEL", - "name": "MODEL", - "type": "MODEL", - "links": [ - 520 - ] - }, - { - "localized_name": "CLIP", - "name": "CLIP", - "type": "CLIP", - "links": [] - }, - { - "localized_name": "VAE", - "name": "VAE", - "type": "VAE", - "links": [ - 556, - 557 - ] - } - ], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.3.56", - "Node name for S&R": "CheckpointLoaderSimple", - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "models": [ - { - "name": "ltx-2.3-22b-dev-fp8.safetensors", - "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", - "directory": "checkpoints" - } - ], - "ue_properties": { - "widget_ue_connectable": {}, - "version": "7.7", - "input_ue_unconnectable": {} - } - }, - "widgets_values": [ - "ltx-2.3-22b-dev-fp8.safetensors" - ] - }, - { - "id": 317, - "type": "LTXAVTextEncoderLoader", - "pos": [ - 1660, - 4280 - ], - "size": [ - 430, - 170 - ], - "flags": {}, - "order": 41, - "mode": 0, - "showAdvanced": false, - "inputs": [ - { - "localized_name": "text_encoder", - "name": "text_encoder", - "type": "COMBO", - "widget": { - "name": "text_encoder" - }, - "link": 606 - }, - { - "localized_name": "ckpt_name", - "name": "ckpt_name", - "type": "COMBO", - "widget": { - "name": "ckpt_name" - }, - "link": 605 - } - ], - "outputs": [ - { - "localized_name": "CLIP", - "name": "CLIP", - "type": "CLIP", - "links": [ - 627, - 642, - 643 - ] - } - ], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.7.0", - "Node name for S&R": "LTXAVTextEncoderLoader", - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "models": [ - { - "name": "ltx-2.3-22b-dev-fp8.safetensors", - "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", - "directory": "checkpoints" - }, - { - "name": "gemma_3_12B_it_fp4_mixed.safetensors", - "url": "https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors", - "directory": "text_encoders" - } - ], - "ue_properties": { - "widget_ue_connectable": {}, - "version": "7.7", - "input_ue_unconnectable": {} - } - }, - "widgets_values": [ - "gemma_3_12B_it_fp4_mixed.safetensors", - "ltx-2.3-22b-dev-fp8.safetensors", - "default" - ] - }, - { - "id": 318, - "type": "LTXVConcatAVLatent", - "pos": [ - 3860, - 4830 - ], - "size": [ - 240, - 100 - ], - "flags": {}, - "order": 42, - "mode": 0, - "inputs": [ - { - "localized_name": "video_latent", - "name": "video_latent", - "type": "LATENT", - "link": 497 - }, - { - "localized_name": "audio_latent", - "name": "audio_latent", - "type": "LATENT", - "link": 498 - } - ], - "outputs": [ - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "links": [ - 487 - ] - } - ], - "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": 319, - "type": "PrimitiveStringMultiline", - "pos": [ - 1190, - 3680 - ], - "size": [ - 370, - 350 - ], - "flags": {}, - "order": 43, - "mode": 0, - "inputs": [ - { - "localized_name": "value", - "name": "value", - "type": "STRING", - "widget": { - "name": "value" - }, - "link": 595 - } - ], - "outputs": [ - { - "localized_name": "STRING", - "name": "STRING", - "type": "STRING", - "links": [ - 639, - 640 - ] - } - ], - "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\u2014no 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: \u201cThe old gods are silent. I am not.\u201d 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": 323, - "type": "ComfyMathExpression", - "pos": [ - 1210, - 5040 - ], - "size": [ - 225, - 94 - ], - "flags": { - "collapsed": true - }, - "order": 44, - "mode": 0, - "inputs": [ - { - "label": "a", - "localized_name": "values.a", - "name": "values.a", - "type": "FLOAT,INT,BOOLEAN", - "link": 628 - }, - { - "label": "b", - "localized_name": "values.b", - "name": "values.b", - "shape": 7, - "type": "FLOAT,INT,BOOLEAN", - "link": 629 - }, - { - "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": null - }, - { - "localized_name": "INT", - "name": "INT", - "type": "INT", - "links": [ - 630, - 631 - ] - }, - { - "localized_name": "BOOL", - "name": "BOOL", - "type": "BOOLEAN", - "links": null - } - ], - "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": 324, - "type": "LoraLoader", - "pos": [ - 1200, - 2870 - ], - "size": [ - 380, - 230 - ], - "flags": {}, - "order": 45, - "mode": 0, - "inputs": [ - { - "localized_name": "model", - "name": "model", - "type": "MODEL", - "link": 641 - }, - { - "localized_name": "clip", - "name": "clip", - "type": "CLIP", - "link": 643 - }, - { - "localized_name": "lora_name", - "name": "lora_name", - "type": "COMBO", - "widget": { - "name": "lora_name" - }, - "link": 645 - } - ], - "outputs": [ - { - "localized_name": "MODEL", - "name": "MODEL", - "type": "MODEL", - "links": null - }, - { - "localized_name": "CLIP", - "name": "CLIP", - "type": "CLIP", - "links": [ - 634 - ] - } - ], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "LoraLoader", - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65, - "models": [ - { - "name": "gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", - "url": "https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", - "directory": "loras" - } - ] - }, - "widgets_values": [ - "gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", - 1, - 1 - ] - }, - { - "id": 325, - "type": "TextGenerateLTX2Prompt", - "pos": [ - 1630, - 2870 - ], - "size": [ - 400, - 412 - ], - "flags": { - "collapsed": false - }, - "order": 46, - "mode": 0, - "inputs": [ - { - "localized_name": "clip", - "name": "clip", - "type": "CLIP", - "link": 634 - }, - { - "localized_name": "image", - "name": "image", - "shape": 7, - "type": "IMAGE", - "link": null - }, - { - "localized_name": "video", - "name": "video", - "shape": 7, - "type": "IMAGE", - "link": null - }, - { - "localized_name": "audio", - "name": "audio", - "shape": 7, - "type": "AUDIO", - "link": null - }, - { - "localized_name": "prompt", - "name": "prompt", - "type": "STRING", - "widget": { - "name": "prompt" - }, - "link": 639 - } - ], - "outputs": [ - { - "localized_name": "generated_text", - "name": "generated_text", - "type": "STRING", - "links": [ - 636 - ] - } - ], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "TextGenerateLTX2Prompt", - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65 - }, - "widgets_values": [ - "A young woman holds the product up to the camera in a bright modern kitchen, turning it slowly to show the label, then smiles at the camera. Handheld iPhone footage, natural window light, shallow depth of field, authentic UGC style.", - 2048, - "on", - 0.7, - 64, - 0.95, - 0.05, - 1.05, - 0, - 0, - false, - true - ] - }, - { - "id": 326, - "type": "PreviewAny", - "pos": [ - 2470, - 2890 - ], - "size": [ - 510, - 360 - ], - "flags": {}, - "order": 47, - "mode": 0, - "inputs": [ - { - "localized_name": "source", - "name": "source", - "type": "*", - "link": 635 - } - ], - "outputs": [ - { - "localized_name": "STRING", - "name": "STRING", - "type": "STRING", - "links": [] - } - ], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.16.3", - "Node name for S&R": "PreviewAny", - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65 - }, - "widgets_values": [] - }, - { - "id": 327, - "type": "ComfySwitchNode", - "pos": [ - 2160, - 3280 - ], - "size": [ - 270, - 130 - ], - "flags": {}, - "order": 48, - "mode": 0, - "inputs": [ - { - "localized_name": "on_false", - "name": "on_false", - "type": "STRING", - "link": 640 - }, - { - "localized_name": "on_true", - "name": "on_true", - "type": "STRING", - "link": 636 - }, - { - "localized_name": "switch", - "name": "switch", - "type": "BOOLEAN", - "widget": { - "name": "switch" - }, - "link": 637 - } - ], - "outputs": [ - { - "localized_name": "output", - "name": "output", - "type": "STRING", - "links": [ - 635, - 638 - ] - } - ], - "properties": { - "cnr_id": "comfy-core", - "ver": "0.22.0", - "Node name for S&R": "ComfySwitchNode", - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65 - }, - "widgets_values": [ - false - ] - }, - { - "id": 328, - "type": "PrimitiveBoolean", - "pos": [ - 1200, - 3350 - ], - "size": [ - 270, - 100 - ], - "flags": {}, - "order": 49, - "mode": 0, - "inputs": [ - { - "localized_name": "value", - "name": "value", - "type": "BOOLEAN", - "widget": { - "name": "value" - }, - "link": 644 - } - ], - "outputs": [ - { - "localized_name": "BOOLEAN", - "name": "BOOLEAN", - "type": "BOOLEAN", - "links": [ - 637 - ] - } - ], - "title": "Boolean (Enable Prompt Enhance)", - "properties": { - "cnr_id": "comfy-core", - "ver": "0.22.0", - "Node name for S&R": "PrimitiveBoolean", - "enableTabs": false, - "tabWidth": 65, - "tabXOffset": 10, - "hasSecondTab": false, - "secondTabText": "Send Back", - "secondTabOffset": 80, - "secondTabWidth": 65 - }, - "widgets_values": [ - false - ] - } - ], - "groups": [ - { - "id": 1, - "title": "Model", - "bounding": [ - 1630, - 3550, - 480, - 1140 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 2, - "title": "Generate Low Resolution", - "bounding": [ - 3130, - 3550, - 1000, - 1140 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 3, - "title": "Prompt", - "bounding": [ - 2140, - 3550, - 960, - 1140 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 6, - "title": "Generate High Resolution", - "bounding": [ - 4670, - 3550, - 990, - 1130 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 7, - "title": "Latent Upscale", - "bounding": [ - 4160, - 3550, - 480, - 1130 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 19, - "title": "Video Settings", - "bounding": [ - 1150, - 3550, - 460, - 1610 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 20, - "title": "Image Preprocess", - "bounding": [ - 1630, - 4720, - 830, - 440 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 21, - "title": "Empty Latent", - "bounding": [ - 2820, - 4720, - 1310, - 450 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 22, - "title": "Number conversion", - "bounding": [ - 2480, - 4720, - 310, - 440 - ], - "color": "#3f789e", - "flags": {} - }, - { - "id": 26, - "title": "Prompt Enhancement", - "bounding": [ - 1160, - 2790, - 2010, - 720 - ], - "color": "#3f789e", - "flags": {} - } - ], - "links": [ - { - "id": 512, - "origin_id": 288, - "origin_slot": 0, - "target_id": 278, - "target_slot": 0, - "type": "LATENT" - }, - { - "id": 513, - "origin_id": 307, - "origin_slot": 1, - "target_id": 278, - "target_slot": 1, - "type": "LATENT" - }, - { - "id": 478, - "origin_id": 285, - "origin_slot": 0, - "target_id": 282, - "target_slot": 0, - "type": "MODEL" - }, - { - "id": 479, - "origin_id": 284, - "origin_slot": 0, - "target_id": 282, - "target_slot": 1, - "type": "CONDITIONING" - }, - { - "id": 480, - "origin_id": 284, - "origin_slot": 1, - "target_id": 282, - "target_slot": 2, - "type": "CONDITIONING" - }, - { - "id": 541, - "origin_id": 285, - "origin_slot": 0, - "target_id": 314, - "target_slot": 0, - "type": "MODEL" - }, - { - "id": 518, - "origin_id": 304, - "origin_slot": 0, - "target_id": 314, - "target_slot": 1, - "type": "CONDITIONING" - }, - { - "id": 519, - "origin_id": 304, - "origin_slot": 1, - "target_id": 314, - "target_slot": 2, - "type": "CONDITIONING" - }, - { - "id": 483, - "origin_id": 277, - "origin_slot": 0, - "target_id": 283, - "target_slot": 0, - "type": "NOISE" - }, - { - "id": 484, - "origin_id": 314, - "origin_slot": 0, - "target_id": 283, - "target_slot": 1, - "type": "GUIDER" - }, - { - "id": 485, - "origin_id": 291, - "origin_slot": 0, - "target_id": 283, - "target_slot": 2, - "type": "SAMPLER" - }, - { - "id": 544, - "origin_id": 306, - "origin_slot": 0, - "target_id": 283, - "target_slot": 3, - "type": "SIGMAS" - }, - { - "id": 487, - "origin_id": 318, - "origin_slot": 0, - "target_id": 283, - "target_slot": 4, - "type": "LATENT" - }, - { - "id": 475, - "origin_id": 304, - "origin_slot": 0, - "target_id": 284, - "target_slot": 0, - "type": "CONDITIONING" - }, - { - "id": 476, - "origin_id": 304, - "origin_slot": 1, - "target_id": 284, - "target_slot": 1, - "type": "CONDITIONING" - }, - { - "id": 477, - "origin_id": 307, - "origin_slot": 0, - "target_id": 284, - "target_slot": 2, - "type": "LATENT" - }, - { - "id": 520, - "origin_id": 316, - "origin_slot": 0, - "target_id": 285, - "target_slot": 0, - "type": "MODEL" - }, - { - "id": 523, - "origin_id": 290, - "origin_slot": 0, - "target_id": 286, - "target_slot": 0, - "type": "IMAGE" - }, - { - "id": 547, - "origin_id": 307, - "origin_slot": 0, - "target_id": 287, - "target_slot": 0, - "type": "LATENT" - }, - { - "id": 545, - "origin_id": 311, - "origin_slot": 0, - "target_id": 287, - "target_slot": 1, - "type": "LATENT_UPSCALE_MODEL" - }, - { - "id": 554, - "origin_id": 293, - "origin_slot": 0, - "target_id": 287, - "target_slot": 2, - "type": "VAE" - }, - { - "id": 552, - "origin_id": 293, - "origin_slot": 0, - "target_id": 288, - "target_slot": 0, - "type": "VAE" - }, - { - "id": 515, - "origin_id": 289, - "origin_slot": 0, - "target_id": 288, - "target_slot": 1, - "type": "IMAGE" - }, - { - "id": 548, - "origin_id": 287, - "origin_slot": 0, - "target_id": 288, - "target_slot": 2, - "type": "LATENT" - }, - { - "id": 543, - "origin_id": 302, - "origin_slot": 0, - "target_id": 288, - "target_slot": 3, - "type": "BOOLEAN" - }, - { - "id": 505, - "origin_id": 286, - "origin_slot": 0, - "target_id": 289, - "target_slot": 0, - "type": "IMAGE" - }, - { - "id": 558, - "origin_id": 312, - "origin_slot": 0, - "target_id": 290, - "target_slot": 1, - "type": "INT" - }, - { - "id": 559, - "origin_id": 299, - "origin_slot": 0, - "target_id": 290, - "target_slot": 2, - "type": "INT" - }, - { - "id": 560, - "origin_id": 312, - "origin_slot": 0, - "target_id": 292, - "target_slot": 0, - "type": "INT" - }, - { - "id": 557, - "origin_id": 316, - "origin_slot": 2, - "target_id": 293, - "target_slot": 0, - "type": "VAE" - }, - { - "id": 562, - "origin_id": 299, - "origin_slot": 0, - "target_id": 294, - "target_slot": 0, - "type": "INT" - }, - { - "id": 561, - "origin_id": 292, - "origin_slot": 1, - "target_id": 295, - "target_slot": 0, - "type": "INT" - }, - { - "id": 563, - "origin_id": 294, - "origin_slot": 1, - "target_id": 295, - "target_slot": 1, - "type": "INT" - }, - { - "id": 556, - "origin_id": 316, - "origin_slot": 2, - "target_id": 296, - "target_slot": 0, - "type": "VAE" - }, - { - "id": 510, - "origin_id": 289, - "origin_slot": 0, - "target_id": 296, - "target_slot": 1, - "type": "IMAGE" - }, - { - "id": 511, - "origin_id": 295, - "origin_slot": 0, - "target_id": 296, - "target_slot": 2, - "type": "LATENT" - }, - { - "id": 542, - "origin_id": 302, - "origin_slot": 0, - "target_id": 296, - "target_slot": 3, - "type": "BOOLEAN" - }, - { - "id": 495, - "origin_id": 309, - "origin_slot": 1, - "target_id": 297, - "target_slot": 0, - "type": "LATENT" - }, - { - "id": 496, - "origin_id": 279, - "origin_slot": 0, - "target_id": 297, - "target_slot": 1, - "type": "VAE" - }, - { - "id": 564, - "origin_id": 300, - "origin_slot": 0, - "target_id": 298, - "target_slot": 0, - "type": "INT" - }, - { - "id": 526, - "origin_id": 303, - "origin_slot": 0, - "target_id": 304, - "target_slot": 0, - "type": "CONDITIONING" - }, - { - "id": 527, - "origin_id": 313, - "origin_slot": 0, - "target_id": 304, - "target_slot": 1, - "type": "CONDITIONING" - }, - { - "id": 566, - "origin_id": 298, - "origin_slot": 0, - "target_id": 304, - "target_slot": 2, - "type": "FLOAT" - }, - { - "id": 497, - "origin_id": 296, - "origin_slot": 0, - "target_id": 318, - "target_slot": 0, - "type": "LATENT" - }, - { - "id": 498, - "origin_id": 305, - "origin_slot": 0, - "target_id": 318, - "target_slot": 1, - "type": "LATENT" - }, - { - "id": 481, - "origin_id": 279, - "origin_slot": 0, - "target_id": 305, - "target_slot": 0, - "type": "VAE" - }, - { - "id": 565, - "origin_id": 298, - "origin_slot": 1, - "target_id": 305, - "target_slot": 2, - "type": "INT" - }, - { - "id": 488, - "origin_id": 283, - "origin_slot": 0, - "target_id": 307, - "target_slot": 0, - "type": "LATENT" - }, - { - "id": 490, - "origin_id": 276, - "origin_slot": 0, - "target_id": 308, - "target_slot": 0, - "type": "NOISE" - }, - { - "id": 491, - "origin_id": 282, - "origin_slot": 0, - "target_id": 308, - "target_slot": 1, - "type": "GUIDER" - }, - { - "id": 492, - "origin_id": 280, - "origin_slot": 0, - "target_id": 308, - "target_slot": 2, - "type": "SAMPLER" - }, - { - "id": 493, - "origin_id": 281, - "origin_slot": 0, - "target_id": 308, - "target_slot": 3, - "type": "SIGMAS" - }, - { - "id": 494, - "origin_id": 278, - "origin_slot": 0, - "target_id": 308, - "target_slot": 4, - "type": "LATENT" - }, - { - "id": 578, - "origin_id": 308, - "origin_slot": 0, - "target_id": 309, - "target_slot": 0, - "type": "LATENT" - }, - { - "id": 539, - "origin_id": 309, - "origin_slot": 0, - "target_id": 315, - "target_slot": 0, - "type": "LATENT" - }, - { - "id": 553, - "origin_id": 293, - "origin_slot": 0, - "target_id": 315, - "target_slot": 1, - "type": "VAE" - }, - { - "id": 538, - "origin_id": 315, - "origin_slot": 0, - "target_id": 310, - "target_slot": 0, - "type": "IMAGE" - }, - { - "id": 534, - "origin_id": 297, - "origin_slot": 0, - "target_id": 310, - "target_slot": 1, - "type": "AUDIO" - }, - { - "id": 591, - "origin_id": 298, - "origin_slot": 0, - "target_id": 310, - "target_slot": 2, - "type": "FLOAT" - }, - { - "id": 535, - "origin_id": -10, - "origin_slot": 0, - "target_id": 290, - "target_slot": 0, - "type": "IMAGE,MASK" - }, - { - "id": 536, - "origin_id": 310, - "origin_slot": 0, - "target_id": -20, - "target_slot": 0, - "type": "VIDEO" - }, - { - "id": 595, - "origin_id": -10, - "origin_slot": 1, - "target_id": 319, - "target_slot": 0, - "type": "STRING" - }, - { - "id": 597, - "origin_id": -10, - "origin_slot": 3, - "target_id": 312, - "target_slot": 0, - "type": "INT" - }, - { - "id": 598, - "origin_id": -10, - "origin_slot": 4, - "target_id": 299, - "target_slot": 0, - "type": "INT" - }, - { - "id": 599, - "origin_id": -10, - "origin_slot": 5, - "target_id": 301, - "target_slot": 0, - "type": "INT" - }, - { - "id": 601, - "origin_id": -10, - "origin_slot": 8, - "target_id": 316, - "target_slot": 0, - "type": "COMBO" - }, - { - "id": 602, - "origin_id": -10, - "origin_slot": 9, - "target_id": 285, - "target_slot": 1, - "type": "COMBO" - }, - { - "id": 604, - "origin_id": -10, - "origin_slot": 8, - "target_id": 279, - "target_slot": 0, - "type": "COMBO" - }, - { - "id": 605, - "origin_id": -10, - "origin_slot": 8, - "target_id": 317, - "target_slot": 1, - "type": "COMBO" - }, - { - "id": 606, - "origin_id": -10, - "origin_slot": 10, - "target_id": 317, - "target_slot": 0, - "type": "COMBO" - }, - { - "id": 607, - "origin_id": -10, - "origin_slot": 11, - "target_id": 311, - "target_slot": 0, - "type": "COMBO" - }, - { - "id": 624, - "origin_id": -10, - "origin_slot": 6, - "target_id": 300, - "target_slot": 0, - "type": "INT" - }, - { - "id": 627, - "origin_id": 317, - "origin_slot": 0, - "target_id": 313, - "target_slot": 0, - "type": "CLIP" - }, - { - "id": 628, - "origin_id": 301, - "origin_slot": 0, - "target_id": 323, - "target_slot": 0, - "type": "INT" - }, - { - "id": 629, - "origin_id": 300, - "origin_slot": 0, - "target_id": 323, - "target_slot": 1, - "type": "INT" - }, - { - "id": 630, - "origin_id": 323, - "origin_slot": 1, - "target_id": 305, - "target_slot": 1, - "type": "INT" - }, - { - "id": 631, - "origin_id": 323, - "origin_slot": 1, - "target_id": 295, - "target_slot": 2, - "type": "INT" - }, - { - "id": 634, - "origin_id": 324, - "origin_slot": 1, - "target_id": 325, - "target_slot": 0, - "type": "CLIP" - }, - { - "id": 635, - "origin_id": 327, - "origin_slot": 0, - "target_id": 326, - "target_slot": 0, - "type": "*" - }, - { - "id": 636, - "origin_id": 325, - "origin_slot": 0, - "target_id": 327, - "target_slot": 1, - "type": "STRING" - }, - { - "id": 637, - "origin_id": 328, - "origin_slot": 0, - "target_id": 327, - "target_slot": 2, - "type": "BOOLEAN" - }, - { - "id": 638, - "origin_id": 327, - "origin_slot": 0, - "target_id": 303, - "target_slot": 1, - "type": "STRING" - }, - { - "id": 639, - "origin_id": 319, - "origin_slot": 0, - "target_id": 325, - "target_slot": 4, - "type": "STRING" - }, - { - "id": 640, - "origin_id": 319, - "origin_slot": 0, - "target_id": 327, - "target_slot": 0, - "type": "STRING" - }, - { - "id": 641, - "origin_id": 285, - "origin_slot": 0, - "target_id": 324, - "target_slot": 0, - "type": "MODEL" - }, - { - "id": 642, - "origin_id": 317, - "origin_slot": 0, - "target_id": 303, - "target_slot": 0, - "type": "CLIP" - }, - { - "id": 643, - "origin_id": 317, - "origin_slot": 0, - "target_id": 324, - "target_slot": 1, - "type": "CLIP" - }, - { - "id": 644, - "origin_id": -10, - "origin_slot": 2, - "target_id": 328, - "target_slot": 0, - "type": "BOOLEAN" - }, - { - "id": 645, - "origin_id": -10, - "origin_slot": 12, - "target_id": 324, - "target_slot": 2, - "type": "COMBO" - }, - { - "id": 646, - "origin_id": -10, - "origin_slot": 7, - "target_id": 277, - "target_slot": 0, - "type": "INT" - } - ], - "extra": { - "workflowRendererVersion": "Vue-corrected", - "ue_links": [] - } - } - ] - }, - "config": {}, - "extra": { - "ds": { - "scale": 0.41201716738197425, - "offset": [ - 1618.0394287109375, - -3067.713541666667 - ] - }, - "frontendVersion": "1.45.21", - "workflowRendererVersion": "Vue-corrected", - "prompt": { - "1": { - "inputs": { - "ckpt_name": "ltx-av-step-1751000_vocoder_24K.safetensors" - }, - "class_type": "CheckpointLoaderSimple", - "_meta": { - "title": "Load Checkpoint" - } - }, - "2": { - "inputs": { - "gemma_path": "gemma-3-12b-it-qat-q4_0-unquantized_readout_proj/model/model.safetensors", - "ltxv_path": "ltx-av-step-1751000_vocoder_24K.safetensors", - "max_length": 1024 - }, - "class_type": "LTXVGemmaCLIPModelLoader", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 Gemma 3 Model Loader" - } - }, - "3": { - "inputs": { - "text": "", - "clip": [ - "2", - 0 - ] - }, - "class_type": "CLIPTextEncode", - "_meta": { - "title": "CLIP Text Encode (Prompt)" - } - }, - "4": { - "inputs": { - "text": "blurry, low quality, still frame, frames, watermark, overlay, titles, has blurbox, has subtitles", - "clip": [ - "2", - 0 - ] - }, - "class_type": "CLIPTextEncode", - "_meta": { - "title": "CLIP Text Encode (Prompt)" - } - }, - "8": { - "inputs": { - "sampler_name": "euler" - }, - "class_type": "KSamplerSelect", - "_meta": { - "title": "KSamplerSelect" - } - }, - "9": { - "inputs": { - "steps": 20, - "max_shift": 2.05, - "base_shift": 0.95, - "stretch": true, - "terminal": 0.1, - "latent": [ - "28", - 0 - ] - }, - "class_type": "LTXVScheduler", - "_meta": { - "title": "LTXVScheduler" - } - }, - "11": { - "inputs": { - "noise_seed": 10 - }, - "class_type": "RandomNoise", - "_meta": { - "title": "RandomNoise" - } - }, - "12": { - "inputs": { - "samples": [ - "29", - 0 - ], - "vae": [ - "1", - 2 - ] - }, - "class_type": "VAEDecode", - "_meta": { - "title": "VAE Decode" - } - }, - "13": { - "inputs": { - "ckpt_name": "ltx-av-step-1751000_vocoder_24K.safetensors" - }, - "class_type": "LTXVAudioVAELoader", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Audio VAE Loader" - } - }, - "14": { - "inputs": { - "samples": [ - "29", - 1 - ], - "audio_vae": [ - "13", - 0 - ] - }, - "class_type": "LTXVAudioVAEDecode", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Audio VAE Decode" - } - }, - "15": { - "inputs": { - "frame_rate": [ - "23", - 0 - ], - "loop_count": 0, - "filename_prefix": "AnimateDiff", - "format": "video/h264-mp4", - "pix_fmt": "yuv420p", - "crf": 19, - "save_metadata": true, - "trim_to_audio": false, - "pingpong": false, - "save_output": true, - "images": [ - "12", - 0 - ], - "audio": [ - "14", - 0 - ] - }, - "class_type": "VHS_VideoCombine", - "_meta": { - "title": "Video Combine \ud83c\udfa5\ud83c\udd65\ud83c\udd57\ud83c\udd62" - } - }, - "17": { - "inputs": { - "skip_blocks": "29", - "model": [ - "28", - 1 - ], - "positive": [ - "22", - 0 - ], - "negative": [ - "22", - 1 - ], - "parameters": [ - "18", - 0 - ] - }, - "class_type": "MultimodalGuider", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 Multimodal Guider" - } - }, - "18": { - "inputs": { - "modality": "VIDEO", - "cfg": 3, - "stg": 0, - "rescale": 0, - "modality_scale": 3, - "parameters": [ - "19", - 0 - ] - }, - "class_type": "GuiderParameters", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 Guider Parameters" - } - }, - "19": { - "inputs": { - "modality": "AUDIO", - "cfg": 7, - "stg": 0, - "rescale": 0, - "modality_scale": 3 - }, - "class_type": "GuiderParameters", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 Guider Parameters" - } - }, - "21": { - "inputs": { - "audioUI": "", - "audio": [ - "14", - 0 - ] - }, - "class_type": "PreviewAudio", - "_meta": { - "title": "PreviewAudio" - } - }, - "22": { - "inputs": { - "frame_rate": [ - "23", - 0 - ], - "positive": [ - "3", - 0 - ], - "negative": [ - "4", - 0 - ] - }, - "class_type": "LTXVConditioning", - "_meta": { - "title": "LTXVConditioning" - } - }, - "23": { - "inputs": { - "value": 25 - }, - "class_type": "FloatConstant", - "_meta": { - "title": "Float Constant" - } - }, - "26": { - "inputs": { - "frames_number": [ - "27", - 0 - ], - "frame_rate": [ - "42", - 0 - ], - "batch_size": 1 - }, - "class_type": "LTXVEmptyLatentAudio", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Empty Latent Audio" - } - }, - "27": { - "inputs": { - "value": 105 - }, - "class_type": "INTConstant", - "_meta": { - "title": "INT Constant" - } - }, - "28": { - "inputs": { - "video_latent": [ - "43", - 0 - ], - "audio_latent": [ - "26", - 0 - ], - "model": [ - "44", - 0 - ] - }, - "class_type": "LTXVConcatAVLatent", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Concat AV Latent" - } - }, - "29": { - "inputs": { - "av_latent": [ - "41", - 0 - ], - "model": [ - "28", - 1 - ] - }, - "class_type": "LTXVSeparateAVLatent", - "_meta": { - "title": "\ud83c\udd5b\ud83c\udd63\ud83c\udd67 LTXV Separate AV Latent" - } - }, - "41": { - "inputs": { - "noise": [ - "11", - 0 - ], - "guider": [ - "17", - 0 - ], - "sampler": [ - "8", - 0 - ], - "sigmas": [ - "9", - 0 - ], - "latent_image": [ - "28", - 0 - ] - }, - "class_type": "SamplerCustomAdvanced", - "_meta": { - "title": "SamplerCustomAdvanced" - } - }, - "42": { - "inputs": { - "a": [ - "23", - 0 - ] - }, - "class_type": "CM_FloatToInt", - "_meta": { - "title": "FloatToInt" - } - }, - "43": { - "inputs": { - "width": 768, - "height": 512, - "length": [ - "27", - 0 - ], - "batch_size": 1 - }, - "class_type": "EmptyLTXVLatentVideo", - "_meta": { - "title": "EmptyLTXVLatentVideo" - } - }, - "44": { - "inputs": { - "torch_compile": true, - "disable_backup": false, - "model": [ - "1", - 0 - ] - }, - "class_type": "LTXVSequenceParallelMultiGPUPatcher", - "_meta": { - "title": "LTXVSequenceParallelMultiGPUPatcher" - } - }, - "45": { - "inputs": { - "frame_idx": 0, - "strength": 1 + } }, - "class_type": "LTXVAddGuide", - "_meta": { - "title": "LTXVAddGuide" - } - } + "comfy_fork_version": "feature/av_inference@a6994ed1", + "VHS_latentpreview": false, + "VHS_latentpreviewrate": 0, + "VHS_MetadataImage": true, + "VHS_KeepIntermediate": true, + "ue_links": [] }, - "comfy_fork_version": "feature/av_inference@a6994ed1", - "VHS_latentpreview": false, - "VHS_latentpreviewrate": 0, - "VHS_MetadataImage": true, - "VHS_KeepIntermediate": true, - "ue_links": [] - }, - "version": 0.4 + "version": 0.4 } \ No newline at end of file From 6231b06284e94e96f9f1beb1d3ec6e948ecdcd8e Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Thu, 6 Aug 2026 10:30:40 +0300 Subject: [PATCH 08/29] fix v2 --- docs/serviceTemplates/README.md | 4 +- .../ltx-video-ugc-bootstrap.sh | 16 +- .../ltx-video-ugc-multishot.json | 4 +- .../workflows/ocean_ugc_assemble.json | 4 +- .../workflows/ocean_ugc_multishot.json | 216 ++++++++++++++++-- .../workflows/ocean_ugc_product.json | 4 +- 6 files changed, 210 insertions(+), 38 deletions(-) diff --git a/docs/serviceTemplates/README.md b/docs/serviceTemplates/README.md index a8a9726ab..7b82e965d 100644 --- a/docs/serviceTemplates/README.md +++ b/docs/serviceTemplates/README.md @@ -122,8 +122,8 @@ with one consistent character. Ships two workflows: - `workflows/ocean_ugc_multishot.json` — renders one shot per Run. - `workflows/ocean_ugc_assemble.json` — concatenates rendered shots into one reel. -Upload a character reference sheet, type one prompt per line into the shot-list box, then click -**Run**. Each Run renders the shot at the current shot index and the index advances +Upload a person photo and/or a product photo — both optional, prompt-only also works — type one +prompt per line into the shot-list box, then click **Run**. Each Run renders the shot at the current shot index and the index advances automatically, so review the clip before running the next. Don't like a take? Set the index back to that shot's number and Run again — SaveVideo appends a counter rather than overwriting, so both takes land in the bucket and you choose which to use at assembly time. diff --git a/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh b/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh index d9efd97c9..e7e978324 100755 --- a/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh +++ b/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh @@ -73,17 +73,21 @@ if [ -n "$WF_ID" ] && [ -n "${COMFY_WORKFLOW:-}" ]; then # Escrow is already claimed: a corrupt payload must not kill the container. if printf '%s' "$COMFY_WORKFLOW" | base64 -d | gunzip > "$RAW"; then # `|| true`: a decoded-but-malformed payload (wrong shape, bad ids) must not abort either. - INSTALLED=$(python3.13 - "$RAW" "$PACK/example_workflows" "$SAVED" <<'PY' || true + INSTALLED=$(python3.13 - "$RAW" "$PACK/example_workflows" "$SAVED" "$WF_ID" <<'PY' || true import json, re, sys raw_path, pack_dir, saved_dir = sys.argv[1:4] try: - workflows = json.load(open(raw_path, encoding='utf-8')) - if not isinstance(workflows, dict) or not workflows: - raise ValueError('expected a non-empty object of "": ') + payload = json.load(open(raw_path, encoding='utf-8')) + if not isinstance(payload, dict) or not payload: + raise ValueError('expected a non-empty object') except Exception as e: - print(f'[ocean] COMFY_WORKFLOW did not decode to an id -> graph object: {e}', file=sys.stderr) + print(f'[ocean] COMFY_WORKFLOW did not decode to an object: {e}', file=sys.stderr) sys.exit(0) -for wf_id, graph in workflows.items(): +# A bare graph has a top-level "nodes" list; an id -> graph map does not. Without this check a +# bare graph installs one junk file per dict-valued key it happens to have (config, extra, ...). +if isinstance(payload.get('nodes'), list): + payload = {sys.argv[4]: payload} +for wf_id, graph in payload.items(): if not re.fullmatch(r'[A-Za-z0-9_.-]{1,64}', wf_id): print(f'[ocean] skipping workflow with unsafe id {wf_id!r}', file=sys.stderr) continue diff --git a/docs/serviceTemplates/ltx-video-ugc-multishot.json b/docs/serviceTemplates/ltx-video-ugc-multishot.json index d4a3bcb31..f08085cac 100644 --- a/docs/serviceTemplates/ltx-video-ugc-multishot.json +++ b/docs/serviceTemplates/ltx-video-ugc-multishot.json @@ -1,7 +1,7 @@ { "id": "ltx-video-ugc-multishot", "name": "ComfyUI — UGC multishot reel (LTX-2.3)", - "description": "ComfyUI preloaded with LTX-2.3 (IC-LoRA Ingredients) for a 15-shot vertical UGC product reel with one consistent character. Usage: upload a character reference sheet as the workflow's image input, type one prompt per line in its shot-list text box (each line a distinct camera angle/action, e.g. close-up on the product, hands unboxing, walking outdoors), then click Run once — it renders the shot at the current shot index and the index advances automatically, so review each clip before running the next; set the index back to a shot number and Run again to redo one you don't like. Clips are 9:16 vertical (704×1280, both divisible by 32 as LTX requires) at 5 seconds each (125 frames at 25 fps), saved to the bucket root as shot_00.mp4, shot_01.mp4, etc. Once every shot is good, switch to the Assemble reel workflow to concatenate them into one clip inside ComfyUI — no external editor needed. Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the ~39 GiB of weights download once and are reused, and the numbered shot clips land in the bucket root where the storage API's listFiles can see them. Needs a CUDA GPU with 48 GB+ VRAM.", + "description": "ComfyUI preloaded with LTX-2.3 (IC-LoRA Ingredients) for a 15-shot vertical UGC product reel with one consistent character. Usage: optionally upload a person photo and/or a product photo as the workflow's two image inputs — both are optional, so leaving both empty renders from the prompt alone — then type one prompt per line in its shot-list text box (each line a distinct camera angle/action, e.g. close-up on the product, hands unboxing, walking outdoors), then click Run once — it renders the shot at the current shot index and the index advances automatically, so review each clip before running the next; set the index back to a shot number and Run again to redo one you don't like. Clips are 9:16 vertical (704×1280, both divisible by 32 as LTX requires) at 5 seconds each (125 frames at 25 fps), saved to the bucket root as shot_00.mp4, shot_01.mp4, etc. Once every shot is good, switch to the Assemble reel workflow to concatenate them into one clip inside ComfyUI — no external editor needed. Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the ~39 GiB of weights download once and are reused, and the numbered shot clips land in the bucket root where the storage API's listFiles can see them. Needs a CUDA GPU with 48 GB+ VRAM.", "image": "yanwk/comfyui-boot", "tag": "cu130-megapak-pt211-20260803", "exposedPorts": [ @@ -16,7 +16,7 @@ { "id": "ocean_ugc_multishot", "name": "Multishot reel (15 shots)", - "description": "Upload a character reference sheet and a 15-line shot list, then click Run once per shot — the shot index advances automatically and you review each clip before the next. Produces numbered 9:16 clips (shot_00.mp4, shot_01.mp4, …) with one consistent character.", + "description": "Upload an optional person photo and/or product photo (both optional — prompt-only also works) and a 15-line shot list, then click Run once per shot — the shot index advances automatically and you review each clip before the next. Produces numbered 9:16 clips (shot_00.mp4, shot_01.mp4, …).", "file": "workflows/ocean_ugc_multishot.json" }, { diff --git a/docs/serviceTemplates/workflows/ocean_ugc_assemble.json b/docs/serviceTemplates/workflows/ocean_ugc_assemble.json index 12539f448..4fb092844 100644 --- a/docs/serviceTemplates/workflows/ocean_ugc_assemble.json +++ b/docs/serviceTemplates/workflows/ocean_ugc_assemble.json @@ -8,8 +8,8 @@ "id": 1, "type": "MarkdownNote", "pos": [ - 0.0, - -320.0 + -2000.0, + 0.0 ], "size": [ 1600, diff --git a/docs/serviceTemplates/workflows/ocean_ugc_multishot.json b/docs/serviceTemplates/workflows/ocean_ugc_multishot.json index 94c105ba2..bfdb5f8cd 100644 --- a/docs/serviceTemplates/workflows/ocean_ugc_multishot.json +++ b/docs/serviceTemplates/workflows/ocean_ugc_multishot.json @@ -1,8 +1,8 @@ { "id": "0112e9af-5129-48ba-af78-92c40ac40b40", "revision": 0, - "last_node_id": 732, - "last_link_id": 1833, + "last_node_id": 735, + "last_link_id": 1838, "nodes": [ { "id": 68, @@ -298,7 +298,7 @@ { "name": "image", "type": "IMAGE", - "link": 1825 + "link": 1838 }, { "name": "amount", @@ -347,7 +347,8 @@ "name": "IMAGE", "type": "IMAGE", "links": [ - 1805 + 1805, + 1835 ] } ], @@ -355,8 +356,8 @@ "Node name for S&R": "EmptyImage" }, "widgets_values": [ - 512, - 512, + 704, + 1280, 1, 0 ] @@ -653,17 +654,17 @@ "Node name for S&R": "LoadImage" }, "widgets_values": [ - "german_shepherd_news_anchor_ref.png", + "subject-girl-holding-skincare-bottle.png", "image" ], - "title": "Character reference" + "title": "Person (optional)" }, { "id": 725, "type": "PrimitiveStringMultiline", "pos": [ 0.0, - 720.0 + 1120.0 ], "size": [ 400, @@ -784,12 +785,18 @@ { "name": "string", "type": "STRING", - "link": 1828 + "link": 1828, + "widget": { + "name": "string" + } }, { "name": "regex_pattern", "type": "STRING", - "link": 1829 + "link": 1829, + "widget": { + "name": "regex_pattern" + } } ], "outputs": [ @@ -806,6 +813,8 @@ "Node name for S&R": "RegexExtract" }, "widgets_values": [ + "", + "", "First Group", true, false, @@ -957,12 +966,12 @@ "id": 732, "type": "MarkdownNote", "pos": [ - 0.0, - -280.0 + -1300.0, + 0.0 ], "size": [ - 1180.0, - 220.0 + 900, + 340 ], "flags": {}, "order": 0, @@ -972,8 +981,135 @@ "title": "How to use", "properties": {}, "widgets_values": [ - "## 15-shot vertical reel\n\n**1.** Upload your character reference sheet in *Character reference*.\n\n**2.** Type one prompt per line in *Shot list* — one shot each. If you change how many lines there are, set *Shots in list* to match.\n\n**3.** Click **Run** once. It renders the shot at the current *Shot index*, then the index advances automatically — watch it change in the node.\n\n**4.** Review the clip, then Run again for the next shot.\n\n**5.** Don't like a take? Set *Shot index* back to that shot's number and Run again. SaveVideo appends a counter instead of overwriting, so the earlier take is still there — you pick which one to use when you assemble.\n\n**6.** Once every shot looks good, switch to the **Assemble reel** workflow to stitch them into one clip.\n\nClips save as `shot_00.mp4`, `shot_01.mp4`, … — 704×1280, 5 s each." + "## 15-shot vertical reel\n\n*Person* and *Product* are both optional — leave both empty and it renders from the prompt alone.\n\n| Want | Do |\n|---|---|\n| Both images | Leave everything as-is |\n| Person only | Bypass (Ctrl+B) **Product (optional)** |\n| Product only | Set the switch on **Use person image? (else blank)** to false — don't bypass **Person (optional)** itself, it feeds a required input |\n| Neither (prompt-only) | Bypass **Product (optional)** *and* set that switch to false |\n\n**1.** One prompt per line in *Shot list*; match *Shots in list* to the count.\n\n**2.** Click **Run** once. It renders the current *Shot index*, then the index auto-advances.\n\n**3.** Redo a shot: set *Shot index* back to that number and Run again — SaveVideo appends a counter, so the earlier take is still there.\n\n**4.** Once every shot looks good, switch to the **Assemble reel** workflow to stitch them.\n\nClips save as `shot_00.mp4`, `shot_01.mp4`, … — 704×1280, 5 s each." ] + }, + { + "id": 733, + "type": "LoadImage", + "pos": [ + 0.0, + 680.0 + ], + "size": [ + 730, + 420 + ], + "flags": {}, + "order": 18, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 1837 + ] + }, + { + "name": "MASK", + "type": "MASK", + "links": null + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "brown_moisturizer_bottle.jpg", + "image" + ], + "title": "Product (optional)" + }, + { + "id": 734, + "type": "ComfySwitchNode", + "pos": [ + 440.0, + 1120.0 + ], + "size": [ + 270, + 130 + ], + "flags": {}, + "order": 19, + "mode": 0, + "inputs": [ + { + "name": "on_false", + "type": "IMAGE", + "link": 1835 + }, + { + "name": "on_true", + "type": "IMAGE", + "link": 1834 + } + ], + "outputs": [ + { + "name": "output", + "type": "IMAGE", + "links": [ + 1836 + ] + } + ], + "properties": { + "Node name for S&R": "ComfySwitchNode" + }, + "widgets_values": [ + true + ], + "title": "Use person image? (else blank)" + }, + { + "id": 735, + "type": "ImageStitch", + "pos": [ + 440.0, + 1270.0 + ], + "size": [ + 270, + 150 + ], + "flags": {}, + "order": 20, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 1836 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 1837 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 1838 + ] + } + ], + "properties": { + "Node name for S&R": "ImageStitch" + }, + "widgets_values": [ + "right", + true, + 0, + "white" + ], + "title": "Combine reference images" } ], "links": [ @@ -1073,14 +1209,6 @@ 1, "IMAGE" ], - [ - 1825, - 724, - 0, - 709, - 0, - "IMAGE" - ], [ 1826, 731, @@ -1144,6 +1272,46 @@ 731, 1, "INT" + ], + [ + 1834, + 724, + 0, + 734, + 1, + "IMAGE" + ], + [ + 1835, + 712, + 0, + 734, + 0, + "IMAGE" + ], + [ + 1836, + 734, + 0, + 735, + 0, + "IMAGE" + ], + [ + 1837, + 733, + 0, + 735, + 1, + "IMAGE" + ], + [ + 1838, + 735, + 0, + 709, + 0, + "IMAGE" ] ], "groups": [ diff --git a/docs/serviceTemplates/workflows/ocean_ugc_product.json b/docs/serviceTemplates/workflows/ocean_ugc_product.json index 5688e3453..8692c0e19 100644 --- a/docs/serviceTemplates/workflows/ocean_ugc_product.json +++ b/docs/serviceTemplates/workflows/ocean_ugc_product.json @@ -321,8 +321,8 @@ "id": 400, "type": "MarkdownNote", "pos": [ - 0.0, - -240.0 + -1580.0, + 0.0 ], "size": [ 1180.0, From c0f74d563e7da9ecfe3c41f3d54f2c28e6f54dd0 Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Thu, 6 Aug 2026 14:19:36 +0300 Subject: [PATCH 09/29] v3 try --- docs/serviceTemplates/README.md | 47 +- .../ltx-video-ugc-multishot.json | 14 +- .../workflows/ocean_ugc_assemble.json | 20 +- .../workflows/ocean_ugc_multishot.json | 6305 ++++++++++------- 4 files changed, 3650 insertions(+), 2736 deletions(-) diff --git a/docs/serviceTemplates/README.md b/docs/serviceTemplates/README.md index 7b82e965d..056b06125 100644 --- a/docs/serviceTemplates/README.md +++ b/docs/serviceTemplates/README.md @@ -116,25 +116,42 @@ goes to `/tmp` and is lost on stop. ### `ltx-video-ugc-multishot.json` — ComfyUI, LTX-2.3 multishot UGC reel (GPU) -Same image and bucket behavior, but builds a 15-shot vertical reel (704×1280, 5 s per shot) -with one consistent character. Ships two workflows: +Same image, bucket behavior and **the same generator** as the product template — both +workflows embed the identical `Image to Video (LTX-2.3)` subgraph (22B dev fp8 + distilled +LoRA, base pass at 360×640, `LTXVLatentUpsampler`, then a refine pass at 720×1280), so shot +quality matches. It builds a vertical reel one 720×1280 / 5 s shot at a time. Ships two +workflows: - `workflows/ocean_ugc_multishot.json` — renders one shot per Run. - `workflows/ocean_ugc_assemble.json` — concatenates rendered shots into one reel. -Upload a person photo and/or a product photo — both optional, prompt-only also works — type one -prompt per line into the shot-list box, then click **Run**. Each Run renders the shot at the current shot index and the index advances -automatically, so review the clip before running the next. Don't like a take? Set the index back -to that shot's number and Run again — SaveVideo appends a counter rather than overwriting, so -both takes land in the bucket and you choose which to use at assembly time. - -Clips save to the bucket root as `shot_00.mp4`, `shot_01.mp4`, etc. Once every shot looks good, -switch to the **Assemble reel** workflow, pick the shots to use in its `LoadVideo` slots, and -Run — it concatenates them (image + audio) into one clip inside ComfyUI, no external editor -needed. - -The shot index wraps at the shot count, so a run past the last line starts again at line 0. -Update *Shots in list* if you change how many lines are in the shot list. +Three inputs, following what the reference-image tools converged on: a **first frame** +(optional — a character photo; with none, flip *No character image* and the style prompt +builds the character instead), a **style box** holding everything that must not change +between shots (who the character is, wardrobe, room, lighting, palette, camera look), and a +**scene box** holding only what does (action, camera move, dialogue, ambient sound). Keeping +the style box byte-identical across runs is what holds the reel together — so it is a +separate box from the scene text rather than something you retype and drift. + +Click **Run** for a clip, edit the scene box, Run again. Clips save to the bucket root with +ComfyUI's own save counter — `shot_00001…`, `shot_00002…` — so re-takes never overwrite and +you pick the good ones at assembly time. + +**Frame chaining.** Every run also drops that clip's last frame beside it as +`lastframe_…png`. Refresh, pick it in *First frame*, and the next shot starts exactly where +the last one ended — identity carried in pixels rather than in prose, which is what the +reference-image tools rely on and what text-only character descriptions cannot do. Re-pick +the original photo instead whenever you want a hard cut to a new setup. + +Mechanically: the generator subgraph exposes its decoded frames as a second `IMAGE` output +alongside `VIDEO`; `GetImageSize` → `a - 1` → `ImageFromBatch` takes the final frame and +`SaveImage` writes it. It costs one PNG per run and needs no interaction — and because the +bootstrap points ComfyUI's `--input-directory` and `--output-directory` at the same bucket +root, the PNG shows up in `LoadImage`'s dropdown with no copying. + +Once every shot looks good, switch to the **Assemble reel** workflow, pick the clips in its +`LoadVideo` slots, bypass the slots you don't need, and Run — it concatenates them +(image + audio) into one clip inside ComfyUI, no external editor needed. ## The shared bootstrap (`ltx-video-ugc-bootstrap.sh`) diff --git a/docs/serviceTemplates/ltx-video-ugc-multishot.json b/docs/serviceTemplates/ltx-video-ugc-multishot.json index f08085cac..a7ea27de4 100644 --- a/docs/serviceTemplates/ltx-video-ugc-multishot.json +++ b/docs/serviceTemplates/ltx-video-ugc-multishot.json @@ -1,7 +1,7 @@ { "id": "ltx-video-ugc-multishot", "name": "ComfyUI — UGC multishot reel (LTX-2.3)", - "description": "ComfyUI preloaded with LTX-2.3 (IC-LoRA Ingredients) for a 15-shot vertical UGC product reel with one consistent character. Usage: optionally upload a person photo and/or a product photo as the workflow's two image inputs — both are optional, so leaving both empty renders from the prompt alone — then type one prompt per line in its shot-list text box (each line a distinct camera angle/action, e.g. close-up on the product, hands unboxing, walking outdoors), then click Run once — it renders the shot at the current shot index and the index advances automatically, so review each clip before running the next; set the index back to a shot number and Run again to redo one you don't like. Clips are 9:16 vertical (704×1280, both divisible by 32 as LTX requires) at 5 seconds each (125 frames at 25 fps), saved to the bucket root as shot_00.mp4, shot_01.mp4, etc. Once every shot is good, switch to the Assemble reel workflow to concatenate them into one clip inside ComfyUI — no external editor needed. Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the ~39 GiB of weights download once and are reused, and the numbered shot clips land in the bucket root where the storage API's listFiles can see them. Needs a CUDA GPU with 48 GB+ VRAM.", + "description": "ComfyUI preloaded with LTX-2.3 for a vertical UGC reel built one shot at a time, with the same character in every shot. It runs the same two-stage generator as the product-video template (22B dev fp8, base pass then a spatial-upscaler refine pass), so shot quality matches. Usage: optionally upload a character photo as the first frame — with no photo you turn on 'No character image' and the style prompt builds the character instead. Then fill two text boxes: 'Style — every shot' holds everything that must stay identical (who the character is, wardrobe, room, lighting, palette, camera look) and you never touch it again; 'Scene — this shot' holds only what changes (action, camera move, dialogue, ambient sound). Click Run for a clip, edit the scene box, Run again. Every run also saves that clip's last frame beside it as lastframe_….png, so you chain the next shot by picking it as the first frame — shot 2 then starts exactly where shot 1 ended and identity carries in pixels rather than in prose, the trick that holds a multi-shot reel together. Clips are 9:16 vertical (720×1280) at 5 seconds each (126 frames at 25 fps) with audio, saved to the bucket root; ComfyUI's save counter never overwrites, so re-takes accumulate and you pick the good ones later. Once every shot is good, switch to the Assemble reel workflow to concatenate up to 8 of them into one clip inside ComfyUI — no external editor needed. Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the 38 GiB of weights download once and are reused, and the numbered shot clips land in the bucket root where the storage API's listFiles can see them. Needs a CUDA GPU with 48 GB+ VRAM.", "image": "yanwk/comfyui-boot", "tag": "cu130-megapak-pt211-20260803", "exposedPorts": [ @@ -15,14 +15,14 @@ "workflows": [ { "id": "ocean_ugc_multishot", - "name": "Multishot reel (15 shots)", - "description": "Upload an optional person photo and/or product photo (both optional — prompt-only also works) and a 15-line shot list, then click Run once per shot — the shot index advances automatically and you review each clip before the next. Produces numbered 9:16 clips (shot_00.mp4, shot_01.mp4, …).", + "name": "Multishot reel — one shot per Run", + "description": "A first-frame image plus two prompt boxes — a style box reused by every shot and a scene box you retype between runs. One Run renders one 9:16 clip and saves its last frame as lastframe_….png; pick that as the next shot's first frame to chain shots together. With no character photo at all, the style prompt builds the character instead.", "file": "workflows/ocean_ugc_multishot.json" }, { "id": "ocean_ugc_assemble", "name": "Assemble reel", - "description": "Concatenates up to 8 rendered shot_NN.mp4 clips (video + audio) into a single reel using core ComfyUI video nodes — pick clips in the LoadVideo dropdowns, bypass any slots you don't need, and Run.", + "description": "Concatenates up to 8 rendered shot_000NN.mp4 clips (video + audio) into a single reel using core ComfyUI video nodes — pick clips in the LoadVideo dropdowns, bypass any slots you don't need, and Run.", "file": "workflows/ocean_ugc_assemble.json" } ], @@ -50,8 +50,8 @@ }, { "id": "disk", - "min": 45, - "recommended": 85, + "min": 40, + "recommended": 80, "unit": "GB" }, { @@ -60,7 +60,7 @@ "min": 1, "recommended": 1, "unit": "count", - "description": "CUDA GPU, 48 GB+ VRAM recommended (LTX-2.3 22B distilled fp8 + Gemma-3-12B encoder)" + "description": "CUDA GPU, 48 GB+ VRAM recommended (LTX-2.3 22B fp8 + Gemma-3-12B encoder)" } ] } diff --git a/docs/serviceTemplates/workflows/ocean_ugc_assemble.json b/docs/serviceTemplates/workflows/ocean_ugc_assemble.json index 4fb092844..f668e9a04 100644 --- a/docs/serviceTemplates/workflows/ocean_ugc_assemble.json +++ b/docs/serviceTemplates/workflows/ocean_ugc_assemble.json @@ -22,7 +22,7 @@ "outputs": [], "properties": {}, "widgets_values": [ - "## Assemble reel\n\nPick a rendered `shot_NN.mp4` in each slot's **file** dropdown below (the dropdown lists what's been generated in the bucket — hit ComfyUI's refresh icon if a clip you just rendered isn't listed yet).\n\n**Bypass (Ctrl+B) any slot you don't need.** The chain concatenates whichever slots stay active, in order, so an unused tail slot just needs bypassing — no rewiring.\n\nClick **Run** once. The stitched reel saves as `reel_00001.mp4` in the bucket root.\n\nOnly 8 slots: each 5 s clip is ~125 frames at 704×1280 in float32, about 1.3 GB as a tensor — 15 slots (the multishot template's shot count) would need ~20 GB of RAM just to hold the frames. 8 slots gives a ~40 s reel and stays comfortably inside this template's 128 GB." + "## Assemble reel\n\nPick a rendered `shot_000NN.mp4` in each slot's **file** dropdown below (the dropdown lists what's been generated in the bucket — hit ComfyUI's refresh icon if a clip you just rendered isn't listed yet). The numbering is ComfyUI's own save counter, so re-takes never overwrite: just don't select the ones you didn't like.\n\n**Bypass (Ctrl+B) any slot you don't need.** The chain concatenates whichever slots stay active, in order, so an unused tail slot just needs bypassing — no rewiring.\n\nClick **Run** once. The stitched reel saves as `reel_00001.mp4` in the bucket root.\n\nOnly 8 slots: each 5 s clip is ~126 frames at 720×1280 in float32, about 1.4 GB as a tensor. 8 slots gives a ~40 s reel and stays comfortably inside this template's 128 GB." ], "title": "How to use" }, @@ -55,7 +55,7 @@ "Node name for S&R": "LoadVideo" }, "widgets_values": [ - "shot_00.mp4" + "shot_00001.mp4" ], "title": "Shot 1" }, @@ -143,7 +143,7 @@ "Node name for S&R": "LoadVideo" }, "widgets_values": [ - "shot_01.mp4" + "shot_00002.mp4" ], "title": "Shot 2" }, @@ -229,7 +229,7 @@ "Node name for S&R": "LoadVideo" }, "widgets_values": [ - "shot_02.mp4" + "shot_00003.mp4" ], "title": "Shot 3" }, @@ -315,7 +315,7 @@ "Node name for S&R": "LoadVideo" }, "widgets_values": [ - "shot_03.mp4" + "shot_00004.mp4" ], "title": "Shot 4" }, @@ -401,7 +401,7 @@ "Node name for S&R": "LoadVideo" }, "widgets_values": [ - "shot_04.mp4" + "shot_00005.mp4" ], "title": "Shot 5" }, @@ -487,7 +487,7 @@ "Node name for S&R": "LoadVideo" }, "widgets_values": [ - "shot_05.mp4" + "shot_00006.mp4" ], "title": "Shot 6" }, @@ -573,7 +573,7 @@ "Node name for S&R": "LoadVideo" }, "widgets_values": [ - "shot_06.mp4" + "shot_00007.mp4" ], "title": "Shot 7" }, @@ -659,7 +659,7 @@ "Node name for S&R": "LoadVideo" }, "widgets_values": [ - "shot_07.mp4" + "shot_00008.mp4" ], "title": "Shot 8" }, @@ -1756,4 +1756,4 @@ } }, "version": 0.4 -} \ No newline at end of file +} diff --git a/docs/serviceTemplates/workflows/ocean_ugc_multishot.json b/docs/serviceTemplates/workflows/ocean_ugc_multishot.json index bfdb5f8cd..951ab6979 100644 --- a/docs/serviceTemplates/workflows/ocean_ugc_multishot.json +++ b/docs/serviceTemplates/workflows/ocean_ugc_multishot.json @@ -1,140 +1,284 @@ { "id": "0112e9af-5129-48ba-af78-92c40ac40b40", "revision": 0, - "last_node_id": 735, - "last_link_id": 1838, + "last_node_id": 742, + "last_link_id": 1909, "nodes": [ { - "id": 68, - "type": "SaveVideo", + "id": 732, + "type": "MarkdownNote", "pos": [ - 2160.0, + -1000.0, 0.0 ], "size": [ - 910, - 700 + 900, + 460 ], "flags": {}, - "order": 12, + "order": 0, "mode": 0, - "inputs": [ + "inputs": [], + "outputs": [], + "title": "How to use", + "properties": {}, + "widgets_values": [ + "## Multishot reel — one shot per Run\n\n**1.** Upload your creator photo in *First frame*. No photo? Turn on *No character image* and the style prompt builds them instead — describe them in detail so every shot matches.\n\n**2.** *Style — every shot* is the part you never touch again: who the character is, what they wear, the room, the light, the palette, the camera look. Keeping this identical is what keeps the reel consistent.\n\n**3.** *Scene — this shot* is the only box you edit between runs: the action, the camera move, what they say, the ambient sound.\n\n**4.** Run. Each clip lands in your bucket as `shot_…mp4`, and its **last frame is saved next to it** as `lastframe_…png` — automatically, every run.\n\n**5.** **Chain the next shot.** Hit the refresh icon, then pick that `lastframe_…png` in *First frame*. Shot 2 now starts exactly where shot 1 ended: same face, same wardrobe, same room, same light — carried by the pixels, not by the prompt. Edit the scene box, Run. Repeat.\n\nSkip the chaining and re-pick the original photo instead whenever you want a hard cut to a new setup — the style box still holds the look together.\n\n**6.** When you have every shot, switch to the **Assemble reel** workflow, pick the clips in its dropdowns, and Run.\n\n720×1280 · 5 s · 25 fps · with audio." + ] + }, + { + "id": 724, + "type": "LoadImage", + "pos": [ + 0.0, + 0.0 + ], + "size": [ + 730, + 660 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ { - "name": "video", - "type": "VIDEO", - "link": 256 + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 1900 + ] }, { - "name": "filename_prefix", + "name": "MASK", + "type": "MASK", + "links": null + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "subject-girl-holding-skincare-bottle.png", + "image" + ], + "title": "First frame — character photo, or the previous shot's lastframe_….png" + }, + { + "id": 725, + "type": "PrimitiveStringMultiline", + "pos": [ + 0.0, + 720.0 + ], + "size": [ + 730, + 300 + ], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "STRING", "type": "STRING", - "widget": { - "name": "filename_prefix" - }, - "link": 1831 + "links": [ + 1901 + ] } ], + "title": "Style — every shot", + "properties": { + "Node name for S&R": "PrimitiveStringMultiline" + }, + "widgets_values": [ + "A 24-year-old woman with shoulder-length dark wavy hair, light makeup, small gold hoop earrings, wearing an oversized cream knit sweater. Bright modern apartment, warm morning light through a large window, soft shadows, muted beige and sage palette. Shot on an iPhone, handheld, shallow depth of field, slight grain, authentic UGC look — not cinematic, not polished." + ] + }, + { + "id": 736, + "type": "PrimitiveStringMultiline", + "pos": [ + 0.0, + 1080.0 + ], + "size": [ + 730, + 300 + ], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], "outputs": [ { - "name": "video", - "type": "VIDEO", - "links": null + "name": "STRING", + "type": "STRING", + "links": [ + 1902 + ] } ], + "title": "Scene — this shot", "properties": { - "Node name for S&R": "SaveVideo", - "cnr_id": "comfy-core", - "enableTabs": false, - "hasSecondTab": false, - "secondTabOffset": 80, - "secondTabText": "Send Back", - "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, - "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.7", - "widget_ue_connectable": {} + "Node name for S&R": "PrimitiveStringMultiline" + }, + "widgets_values": [ + "She holds the moisturizer bottle up toward the camera and turns it slowly to show the label, then smiles and says: “Okay, this one actually did something.” Small natural handheld drift, no zoom. Room tone, faint street noise outside." + ] + }, + { + "id": 737, + "type": "StringFormat", + "pos": [ + 820.0, + 720.0 + ], + "size": [ + 320, + 130 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [ + { + "label": "a", + "name": "values.a", + "type": "*", + "link": 1901 }, - "ver": "0.14.1" + { + "label": "b", + "name": "values.b", + "type": "*", + "link": 1902 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 1903 + ] + } + ], + "title": "Style + scene → prompt", + "properties": { + "Node name for S&R": "StringFormat" }, "widgets_values": [ - "shot", - "auto", - "auto" + "{a}\n{b}" + ] + }, + { + "id": 738, + "type": "PrimitiveBoolean", + "pos": [ + 820.0, + 900.0 + ], + "size": [ + 320, + 90 + ], + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "BOOLEAN", + "type": "BOOLEAN", + "links": [ + 1904 + ] + } ], - "title": "Output clips" + "title": "No character image — build it from the style prompt", + "properties": { + "Node name for S&R": "PrimitiveBoolean" + }, + "widgets_values": [ + false + ] }, { "id": 129, - "type": "f9f61b10-b689-4d67-b4fa-0acc1d9b5390", + "type": "2454ad83-157c-40dd-9f19-5daaf4041ce0", "pos": [ - 1560.0, + 820.0, 0.0 ], "size": [ - 540, - 680 + 380, + 650 ], "flags": {}, - "order": 11, + "order": 5, "mode": 0, "inputs": [ { "label": "first_frame", "name": "input", "type": "IMAGE,MASK", - "link": 1805 - }, - { - "label": "control_images", - "name": "input_1", - "type": "IMAGE,MASK", - "link": 1824 + "link": 1900 }, { "label": "prompt", - "name": "text", + "name": "value", "type": "STRING", "widget": { - "name": "text" + "name": "value" }, - "link": 1830 + "link": 1903 }, { "label": "prompt_enhance", - "name": "value_4", + "name": "value_1", "type": "BOOLEAN", "widget": { - "name": "value_4" + "name": "value_1" }, "link": null }, { "label": "width", - "name": "value", + "name": "value_2", "type": "INT", "widget": { - "name": "value" + "name": "value_2" }, - "link": 1817 + "link": null }, { "label": "height", - "name": "value_1", + "name": "value_3", "type": "INT", "widget": { - "name": "value_1" + "name": "value_3" + }, + "link": null + }, + { + "label": "duration", + "name": "value_4", + "type": "INT", + "widget": { + "name": "value_4" }, - "link": 1818 + "link": null }, { "label": "fps", - "name": "value_3", + "name": "value_5", "type": "INT", "widget": { - "name": "value_3" + "name": "value_5" }, - "link": 1809 + "link": null }, { "label": "seed", @@ -146,11 +290,11 @@ "link": null }, { - "label": "ckpt_name", - "name": "ckpt_name_1", + "label": "distilled_lora", + "name": "lora_name", "type": "COMBO", "widget": { - "name": "ckpt_name_1" + "name": "lora_name" }, "link": null }, @@ -164,16 +308,16 @@ "link": null }, { - "label": "lora", - "name": "lora_name", + "label": "latent_upscale_model", + "name": "model_name", "type": "COMBO", "widget": { - "name": "lora_name" + "name": "model_name" }, "link": null }, { - "label": "ic_lora", + "label": "lora", "name": "lora_name_1", "type": "COMBO", "widget": { @@ -182,22 +326,13 @@ "link": null }, { - "label": "lora_strength", - "name": "strength_model", - "type": "FLOAT", - "widget": { - "name": "strength_model" - }, - "link": null - }, - { - "label": "bypass_first_frame", - "name": "value_2", + "label": "text_to_video", + "name": "value_6", "type": "BOOLEAN", "widget": { - "name": "value_2" + "name": "value_6" }, - "link": null + "link": 1904 } ], "outputs": [ @@ -207,130 +342,155 @@ "links": [ 256 ] + }, + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 1905, + 1906 + ] } ], "properties": { "proxyWidgets": [ [ - "209", - "prompt" + "319", + "value" ], [ - "212", + "328", "value" ], [ - "113", + "312", "value" ], [ - "98", + "299", "value" ], [ - "114", + "301", "value" ], [ - "704", - "seed" + "300", + "value" ], [ - "126", - "ckpt_name" + "277", + "noise_seed" ], [ - "103", - "text_encoder" + "316", + "ckpt_name" ], [ - "208", + "285", "lora_name" ], [ - "195", - "lora_name" + "317", + "text_encoder" + ], + [ + "311", + "model_name" ], [ - "195", - "strength_model" + "324", + "lora_name" ], [ - "711", + "302", "value" ] ], "cnr_id": "comfy-core", + "ver": "0.16.3", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, + "widget_ue_connectable": { + "value_1": true, + "value_2": true, + "value_3": true, + "value_4": true, + "lora_name": true, + "model_name": true, + "value_5": true + }, "version": "7.7", - "widget_ue_connectable": {} - }, - "ver": "0.18.1" + "input_ue_unconnectable": {} + } }, "widgets_values": [], "title": "Generate video" }, { - "id": 709, - "type": "RepeatImageBatch", + "id": 68, + "type": "SaveVideo", "pos": [ - 1180.0, - 360.0 + 1260.0, + 0.0 ], "size": [ - 270, - 110 + 910, + 700 ], - "flags": { - "collapsed": true - }, + "flags": {}, "order": 7, "mode": 0, "inputs": [ { - "name": "image", - "type": "IMAGE", - "link": 1838 - }, - { - "name": "amount", - "type": "INT", - "widget": { - "name": "amount" - }, - "link": 1812 + "name": "video", + "type": "VIDEO", + "link": 256 } ], "outputs": [ { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 1821 - ] + "name": "video", + "type": "VIDEO", + "links": null } ], "properties": { - "Node name for S&R": "RepeatImageBatch" + "Node name for S&R": "SaveVideo", + "cnr_id": "comfy-core", + "enableTabs": false, + "hasSecondTab": false, + "secondTabOffset": 80, + "secondTabText": "Send Back", + "secondTabWidth": 65, + "tabWidth": 65, + "tabXOffset": 10, + "ue_properties": { + "input_ue_unconnectable": {}, + "version": "7.7", + "widget_ue_connectable": {} + }, + "ver": "0.14.1" }, "widgets_values": [ - 125 - ] + "shot", + "auto", + "auto" + ], + "title": "Output clip" }, { - "id": 712, - "type": "EmptyImage", + "id": 739, + "type": "GetImageSize", "pos": [ - 1180.0, - 290.0 + 1260.0, + 760.0 ], "size": [ 225, @@ -339,102 +499,46 @@ "flags": { "collapsed": true }, - "order": 2, + "order": 8, "mode": 0, - "inputs": [], - "outputs": [ + "inputs": [ { - "name": "IMAGE", + "name": "image", "type": "IMAGE", - "links": [ - 1805, - 1835 - ] + "link": 1905 } ], - "properties": { - "Node name for S&R": "EmptyImage" - }, - "widgets_values": [ - 704, - 1280, - 1, - 0 - ] - }, - { - "id": 715, - "type": "PrimitiveInt", - "pos": [ - 820.0, - 300.0 - ], - "size": [ - 270, - 110 - ], - "flags": {}, - "order": 3, - "mode": 0, - "inputs": [], "outputs": [ { - "name": "INT", + "name": "width", "type": "INT", - "links": [ - 1810 - ] - } - ], - "title": "Seconds per shot", - "properties": { - "Node name for S&R": "PrimitiveInt" - }, - "widgets_values": [ - 5, - "fixed" - ] - }, - { - "id": 716, - "type": "PrimitiveInt", - "pos": [ - 820.0, - 450.0 - ], - "size": [ - 270, - 110 - ], - "flags": {}, - "order": 4, - "mode": 0, - "inputs": [], - "outputs": [ + "links": null + }, { - "name": "INT", + "name": "height", + "type": "INT", + "links": null + }, + { + "name": "batch_size", "type": "INT", "links": [ - 1809, - 1811 + 1907 ] } ], - "title": "FPS", "properties": { - "Node name for S&R": "PrimitiveInt" + "Node name for S&R": "GetImageSize" }, - "widgets_values": [ - 25, - "fixed" - ] + "widgets_values": [], + "title": "Frame count" }, { - "id": 717, + "id": 740, "type": "ComfyMathExpression", "pos": [ - 820.0, - 920.0 + 1260.0, + 810.0 ], "size": [ 225, @@ -443,21 +547,21 @@ "flags": { "collapsed": true }, - "order": 6, + "order": 9, "mode": 0, "inputs": [ { "label": "a", "name": "values.a", "type": "FLOAT,INT,BOOLEAN", - "link": 1810 + "link": 1907 }, { "label": "b", "name": "values.b", "shape": 7, "type": "FLOAT,INT,BOOLEAN", - "link": 1811 + "link": null }, { "label": "c", @@ -477,7 +581,7 @@ "name": "INT", "type": "INT", "links": [ - 1812 + 1908 ] }, { @@ -490,80 +594,37 @@ "Node name for S&R": "ComfyMathExpression" }, "widgets_values": [ - "a * b" - ] + "a - 1" + ], + "title": "Last frame index" }, { - "id": 721, - "type": "GetImageSize", + "id": 741, + "type": "ImageFromBatch", "pos": [ - 1180.0, - 220.0 + 1260.0, + 860.0 ], "size": [ - 225, - 8 + 270, + 90 ], - "flags": { - "collapsed": true - }, - "order": 9, + "flags": {}, + "order": 10, "mode": 0, "inputs": [ { "name": "image", "type": "IMAGE", - "link": 1822 - } - ], - "outputs": [ - { - "name": "width", - "type": "INT", - "links": [ - 1817 - ] - }, - { - "name": "height", - "type": "INT", - "links": [ - 1818 - ] + "link": 1906 }, { - "name": "batch_size", + "name": "batch_index", "type": "INT", - "links": null - } - ], - "properties": { - "Node name for S&R": "GetImageSize" - }, - "widgets_values": [] - }, - { - "id": 722, - "type": "ResizeAndPadImage", - "pos": [ - 1180.0, - 0.0 - ], - "size": [ - 280, - 170 - ], - "flags": { - "collapsed": true - }, - "order": 8, - "mode": 0, - "showAdvanced": false, - "inputs": [ - { - "name": "image", - "type": "IMAGE", - "link": 1821 + "widget": { + "name": "batch_index" + }, + "link": 1908 } ], "outputs": [ @@ -571,1421 +632,2203 @@ "name": "IMAGE", "type": "IMAGE", "links": [ - 1822, - 1823, - 1824 + 1909 ] } ], - "title": "Resize And Pad Image (Size)", "properties": { - "Node name for S&R": "ResizeAndPadImage" + "Node name for S&R": "ImageFromBatch" }, "widgets_values": [ - 704, - 1280, - "black", - "lanczos" + 0, + 1 ] }, { - "id": 723, - "type": "PreviewImage", + "id": 742, + "type": "SaveImage", "pos": [ - 1180.0, - 500.0 + 1260.0, + 990.0 ], "size": [ - 650, - 110 + 430, + 470 ], "flags": {}, - "order": 10, - "mode": 4, + "order": 11, + "mode": 0, "inputs": [ { "name": "images", "type": "IMAGE", - "link": 1823 - } - ], - "outputs": [ - { - "name": "images", - "type": "IMAGE", - "links": null - } - ], - "properties": { - "Node name for S&R": "PreviewImage" - }, - "widgets_values": [] - }, - { - "id": 724, - "type": "LoadImage", - "pos": [ - 0.0, - 0.0 - ], - "size": [ - 730, - 660 - ], - "flags": {}, - "order": 5, - "mode": 0, - "inputs": [], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 1825 - ] - }, - { - "name": "MASK", - "type": "MASK", - "links": null - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "subject-girl-holding-skincare-bottle.png", - "image" - ], - "title": "Person (optional)" - }, - { - "id": 725, - "type": "PrimitiveStringMultiline", - "pos": [ - 0.0, - 1120.0 - ], - "size": [ - 400, - 360 - ], - "flags": {}, - "order": 13, - "mode": 0, - "inputs": [], - "outputs": [ - { - "name": "STRING", - "type": "STRING", - "links": [ - 1828 - ] + "link": 1909 } ], - "title": "Shot list (one prompt per line)", + "outputs": [], "properties": { - "Node name for S&R": "PrimitiveStringMultiline" + "Node name for S&R": "SaveImage" }, "widgets_values": [ - "Extreme close-up on the product label, slow rotation under soft studio light, shallow depth of field.\nHands unboxing the product from its packaging on a wooden table, top-down angle.\nOver-the-shoulder shot as the person opens the product for the first time, natural window light.\nPerson walking outdoors on a city sidewalk, holding the product up to the camera, casual handheld motion.\nMirror selfie in a bright bathroom, person showing the product at chest height, phone visible in reflection.\nClose-up of hands applying the product, soft focus background, warm indoor lighting.\nPerson sitting on a couch, casually gesturing toward the product on the coffee table, medium shot.\nLow-angle shot looking up as the person raises the product triumphantly outdoors, blue sky background.\nProduct placed on a kitchen counter, slow dolly-in past morning coffee and sunlight through a window.\nPerson talking directly to camera, product held at shoulder height, blurred cafe background.\nOverhead flat-lay shot of the product surrounded by lifestyle props, a hand entering frame to pick it up.\nTracking shot following the person as they carry the product through a sunlit hallway.\nClose-up on the person's face lighting up with a smile as they look at the product, shallow depth of field.\nPerson unboxing the product in a car, phone mounted on the dashboard, natural daylight.\nSlow-motion shot of the product being set down on a marble countertop, logo facing the camera." - ] - }, - { - "id": 726, - "type": "PrimitiveInt", - "pos": [ - 820.0, - 0.0 - ], - "size": [ - 270, - 110 - ], - "flags": {}, - "order": 14, - "mode": 0, - "inputs": [], - "outputs": [ - { - "name": "INT", - "type": "INT", - "links": [ - 1832 - ] - } + "lastframe" ], - "title": "Shot index (auto-increments)", - "properties": { - "Node name for S&R": "PrimitiveInt" - }, - "widgets_values": [ - 0, - "increment" - ] - }, - { - "id": 727, - "type": "StringFormat", - "pos": [ - 820.0, - 620.0 - ], - "size": [ - 320, - 150 - ], - "flags": { - "collapsed": true - }, - "order": 15, - "mode": 0, - "inputs": [ - { - "label": "a", - "name": "values.a", - "type": "*", - "link": 1826 - } - ], - "outputs": [ - { - "name": "STRING", - "type": "STRING", - "links": [ - 1829 - ] - } - ], - "title": "Format Text (line-select regex)", - "properties": { - "Node name for S&R": "StringFormat" - }, - "widgets_values": [ - "(?s)^(?:[^\\n]*\\n){{{a}}}([^\\n]*)" + "title": "Last frame → pick this in First frame for the next shot" + } + ], + "links": [ + [ + 256, + 129, + 0, + 68, + 0, + "VIDEO" + ], + [ + 1900, + 724, + 0, + 129, + 0, + "IMAGE" + ], + [ + 1901, + 725, + 0, + 737, + 0, + "STRING" + ], + [ + 1902, + 736, + 0, + 737, + 1, + "STRING" + ], + [ + 1903, + 737, + 0, + 129, + 1, + "STRING" + ], + [ + 1904, + 738, + 0, + 129, + 12, + "BOOLEAN" + ], + [ + 1905, + 129, + 1, + 739, + 0, + "IMAGE" + ], + [ + 1906, + 129, + 1, + 741, + 0, + "IMAGE" + ], + [ + 1907, + 739, + 2, + 740, + 0, + "INT" + ], + [ + 1908, + 740, + 1, + 741, + 1, + "INT" + ], + [ + 1909, + 741, + 0, + 742, + 0, + "IMAGE" + ] + ], + "groups": [], + "config": {}, + "extra": { + "VHS_KeepIntermediate": true, + "VHS_MetadataImage": true, + "VHS_latentpreview": false, + "VHS_latentpreviewrate": 0, + "frontendVersion": "1.45.15", + "ue_links": [], + "workflowRendererVersion": "Vue-corrected", + "ds": { + "scale": 0.5959744833082783, + "offset": [ + 2409.0282524930844, + -1818.184424107724 ] - }, - { - "id": 728, - "type": "RegexExtract", - "pos": [ - 820.0, - 700.0 - ], - "size": [ - 320, - 250 - ], - "flags": { - "collapsed": true - }, - "order": 16, - "mode": 0, - "inputs": [ - { - "name": "string", - "type": "STRING", - "link": 1828, - "widget": { - "name": "string" - } + } + }, + "version": 0.4, + "definitions": { + "subgraphs": [ + { + "id": "2454ad83-157c-40dd-9f19-5daaf4041ce0", + "version": 1, + "state": { + "lastGroupId": 26, + "lastNodeId": 329, + "lastLinkId": 646, + "lastRerouteId": 0 }, - { - "name": "regex_pattern", - "type": "STRING", - "link": 1829, - "widget": { - "name": "regex_pattern" - } - } - ], - "outputs": [ - { - "name": "STRING", - "type": "STRING", - "links": [ - 1830 - ] - } - ], - "title": "Extract Text (shot N)", - "properties": { - "Node name for S&R": "RegexExtract" - }, - "widgets_values": [ - "", - "", - "First Group", - true, - false, - false, - 1 - ] - }, - { - "id": 729, - "type": "StringFormat", - "pos": [ - 820.0, - 780.0 - ], - "size": [ - 320, - 150 - ], - "flags": { - "collapsed": true - }, - "order": 17, - "mode": 0, - "inputs": [ - { - "label": "a", - "name": "values.a", - "type": "*", - "link": 1827 - } - ], - "outputs": [ - { - "name": "STRING", - "type": "STRING", - "links": [ - 1831 - ] - } - ], - "title": "Format Text (filename prefix)", - "properties": { - "Node name for S&R": "StringFormat" - }, - "widgets_values": [ - "shot_{a:02d}" - ] - }, - { - "id": 730, - "type": "PrimitiveInt", - "pos": [ - 820.0, - 150.0 - ], - "size": [ - 270, - 110 - ], - "flags": {}, - "order": 5, - "mode": 0, - "inputs": [], - "outputs": [ - { - "name": "INT", - "type": "INT", - "links": [ - 1833 + "revision": 0, + "config": {}, + "name": "Image to Video (LTX-2.3)", + "inputNode": { + "id": -10, + "bounding": [ + 730, + 4110, + 170.162109375, + 308 ] - } - ], - "title": "Shots in list", - "properties": { - "Node name for S&R": "PrimitiveInt" - }, - "widgets_values": [ - 15, - "fixed" - ] - }, - { - "id": 731, - "type": "ComfyMathExpression", - "pos": [ - 820.0, - 860.0 - ], - "size": [ - 225, - 8 - ], - "flags": { - "collapsed": true - }, - "order": 7, - "mode": 0, - "inputs": [ - { - "label": "a", - "name": "values.a", - "type": "FLOAT,INT,BOOLEAN", - "link": 1832 }, - { - "label": "b", - "name": "values.b", - "shape": 7, - "type": "FLOAT,INT,BOOLEAN", - "link": 1833 - }, - { - "label": "c", - "name": "values.c", - "shape": 7, - "type": "FLOAT,INT,BOOLEAN", - "link": null - } - ], - "outputs": [ - { - "name": "FLOAT", - "type": "FLOAT", - "links": null - }, - { - "name": "INT", - "type": "INT", - "links": [ - 1826, - 1827 - ] - }, - { - "name": "BOOL", - "type": "BOOLEAN", - "links": null - } - ], - "title": "Wrap shot index", - "properties": { - "Node name for S&R": "ComfyMathExpression" - }, - "widgets_values": [ - "a % b" - ] - }, - { - "id": 732, - "type": "MarkdownNote", - "pos": [ - -1300.0, - 0.0 - ], - "size": [ - 900, - 340 - ], - "flags": {}, - "order": 0, - "mode": 0, - "inputs": [], - "outputs": [], - "title": "How to use", - "properties": {}, - "widgets_values": [ - "## 15-shot vertical reel\n\n*Person* and *Product* are both optional — leave both empty and it renders from the prompt alone.\n\n| Want | Do |\n|---|---|\n| Both images | Leave everything as-is |\n| Person only | Bypass (Ctrl+B) **Product (optional)** |\n| Product only | Set the switch on **Use person image? (else blank)** to false — don't bypass **Person (optional)** itself, it feeds a required input |\n| Neither (prompt-only) | Bypass **Product (optional)** *and* set that switch to false |\n\n**1.** One prompt per line in *Shot list*; match *Shots in list* to the count.\n\n**2.** Click **Run** once. It renders the current *Shot index*, then the index auto-advances.\n\n**3.** Redo a shot: set *Shot index* back to that number and Run again — SaveVideo appends a counter, so the earlier take is still there.\n\n**4.** Once every shot looks good, switch to the **Assemble reel** workflow to stitch them.\n\nClips save as `shot_00.mp4`, `shot_01.mp4`, … — 704×1280, 5 s each." - ] - }, - { - "id": 733, - "type": "LoadImage", - "pos": [ - 0.0, - 680.0 - ], - "size": [ - 730, - 420 - ], - "flags": {}, - "order": 18, - "mode": 0, - "inputs": [], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 1837 - ] - }, - { - "name": "MASK", - "type": "MASK", - "links": null - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "brown_moisturizer_bottle.jpg", - "image" - ], - "title": "Product (optional)" - }, - { - "id": 734, - "type": "ComfySwitchNode", - "pos": [ - 440.0, - 1120.0 - ], - "size": [ - 270, - 130 - ], - "flags": {}, - "order": 19, - "mode": 0, - "inputs": [ - { - "name": "on_false", - "type": "IMAGE", - "link": 1835 - }, - { - "name": "on_true", - "type": "IMAGE", - "link": 1834 - } - ], - "outputs": [ - { - "name": "output", - "type": "IMAGE", - "links": [ - 1836 - ] - } - ], - "properties": { - "Node name for S&R": "ComfySwitchNode" - }, - "widgets_values": [ - true - ], - "title": "Use person image? (else blank)" - }, - { - "id": 735, - "type": "ImageStitch", - "pos": [ - 440.0, - 1270.0 - ], - "size": [ - 270, - 150 - ], - "flags": {}, - "order": 20, - "mode": 0, - "inputs": [ - { - "name": "image1", - "type": "IMAGE", - "link": 1836 - }, - { - "name": "image2", - "type": "IMAGE", - "link": 1837 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 1838 - ] - } - ], - "properties": { - "Node name for S&R": "ImageStitch" - }, - "widgets_values": [ - "right", - true, - 0, - "white" - ], - "title": "Combine reference images" - } - ], - "links": [ - [ - 256, - 129, - 0, - 68, - 0, - "VIDEO" - ], - [ - 1805, - 712, - 0, - 129, - 0, - "IMAGE" - ], - [ - 1809, - 716, - 0, - 129, - 6, - "INT" - ], - [ - 1810, - 715, - 0, - 717, - 0, - "INT" - ], - [ - 1811, - 716, - 0, - 717, - 1, - "INT" - ], - [ - 1812, - 717, - 1, - 709, - 1, - "INT" - ], - [ - 1817, - 721, - 0, - 129, - 4, - "INT" - ], - [ - 1818, - 721, - 1, - 129, - 5, - "INT" - ], - [ - 1821, - 709, - 0, - 722, - 0, - "IMAGE" - ], - [ - 1822, - 722, - 0, - 721, - 0, - "IMAGE" - ], - [ - 1823, - 722, - 0, - 723, - 0, - "IMAGE" - ], - [ - 1824, - 722, - 0, - 129, - 1, - "IMAGE" - ], - [ - 1826, - 731, - 1, - 727, - 0, - "INT" - ], - [ - 1827, - 731, - 1, - 729, - 0, - "INT" - ], - [ - 1828, - 725, - 0, - 728, - 0, - "STRING" - ], - [ - 1829, - 727, - 0, - 728, - 1, - "STRING" - ], - [ - 1830, - 728, - 0, - 129, - 2, - "STRING" - ], - [ - 1831, - 729, - 0, - 68, - 1, - "STRING" - ], - [ - 1832, - 726, - 0, - 731, - 0, - "INT" - ], - [ - 1833, - 730, - 0, - 731, - 1, - "INT" - ], - [ - 1834, - 724, - 0, - 734, - 1, - "IMAGE" - ], - [ - 1835, - 712, - 0, - 734, - 0, - "IMAGE" - ], - [ - 1836, - 734, - 0, - 735, - 0, - "IMAGE" - ], - [ - 1837, - 733, - 0, - 735, - 1, - "IMAGE" - ], - [ - 1838, - 735, - 0, - 709, - 0, - "IMAGE" - ] - ], - "groups": [ - { - "id": 28, - "title": "Video Settings", - "bounding": [ - 100, - 2240, - 740, - 690 - ], - "color": "#3f789e", - "flags": {} - } - ], - "definitions": { - "subgraphs": [ - { - "id": "f9f61b10-b689-4d67-b4fa-0acc1d9b5390", - "version": 1, - "state": { - "lastGroupId": 28, - "lastNodeId": 724, - "lastLinkId": 1825, - "lastRerouteId": 0 - }, - "revision": 0, - "config": {}, - "name": "LTX-2.3 IC-LoRA Video Generation", - "inputNode": { - "id": -10, - "bounding": [ - -160, - 3060, - 155.00390625, - 328 - ] - }, - "outputNode": { - "id": -20, - "bounding": [ - 3620, - 3120, - 128, - 68 - ] + "outputNode": { + "id": -20, + "bounding": [ + 6590, + 4360, + 128, + 88 + ] }, "inputs": [ { - "id": "6fe179c4-d96f-4383-b202-844f6de4922e", - "name": "input", - "type": "IMAGE,MASK", - "linkIds": [ - 1735, - 1786 + "id": "7afd6ea8-c738-4fd9-97b8-66fa905cd381", + "name": "input", + "type": "IMAGE,MASK", + "linkIds": [ + 535 + ], + "localized_name": "input", + "label": "first_frame", + "pos": [ + 876.162109375, + 4134 + ] + }, + { + "id": "9494c550-4172-49c6-930e-5b508f775e77", + "name": "value", + "type": "STRING", + "linkIds": [ + 595 + ], + "label": "prompt", + "pos": [ + 876.162109375, + 4154 + ] + }, + { + "id": "ec291311-2d21-49f9-aaba-24bb2e544ce0", + "name": "value_1", + "type": "BOOLEAN", + "linkIds": [ + 644 + ], + "label": "prompt_enhance", + "pos": [ + 876.162109375, + 4174 + ] + }, + { + "id": "58dbb3f6-f924-4548-96ef-e0e34610bd4e", + "name": "value_2", + "type": "INT", + "linkIds": [ + 597 + ], + "label": "width", + "pos": [ + 876.162109375, + 4194 + ] + }, + { + "id": "6086d5b8-2586-448c-a641-dd14d76dd102", + "name": "value_3", + "type": "INT", + "linkIds": [ + 598 + ], + "label": "height", + "pos": [ + 876.162109375, + 4214 + ] + }, + { + "id": "feb8c2eb-ae48-4fa8-bc24-929552d656c3", + "name": "value_4", + "type": "INT", + "linkIds": [ + 599 + ], + "label": "duration", + "pos": [ + 876.162109375, + 4234 + ] + }, + { + "id": "3e32ce15-0ae7-4cd0-909f-a354e8e9c4c9", + "name": "value_5", + "type": "INT", + "linkIds": [ + 624 + ], + "label": "fps", + "pos": [ + 876.162109375, + 4254 + ] + }, + { + "id": "dc40eadf-b8a9-421e-88f6-245042dd5424", + "name": "noise_seed", + "type": "INT", + "linkIds": [ + 646 + ], + "label": "seed", + "pos": [ + 876.162109375, + 4274 + ] + }, + { + "id": "d7255058-319a-4880-8f9a-7e542c8f3c3c", + "name": "ckpt_name", + "type": "COMBO", + "linkIds": [ + 601, + 604, + 605 + ], + "pos": [ + 876.162109375, + 4294 + ] + }, + { + "id": "4afce68d-8f65-4342-9d6d-ae0a7688c3e3", + "name": "lora_name", + "type": "COMBO", + "linkIds": [ + 602 + ], + "label": "distilled_lora", + "pos": [ + 876.162109375, + 4314 + ] + }, + { + "id": "ab842b4b-c977-4679-b421-424722785b57", + "name": "text_encoder", + "type": "COMBO", + "linkIds": [ + 606 + ], + "label": "text_encoder", + "pos": [ + 876.162109375, + 4334 + ] + }, + { + "id": "9e47372d-28d9-4311-91e9-e90d03f4eb43", + "name": "model_name", + "type": "COMBO", + "linkIds": [ + 607 + ], + "label": "latent_upscale_model", + "pos": [ + 876.162109375, + 4354 + ] + }, + { + "id": "682e457c-5d94-49b2-bf40-5731696deaf0", + "name": "lora_name_1", + "type": "COMBO", + "linkIds": [ + 645 + ], + "label": "lora", + "pos": [ + 876.162109375, + 4374 + ] + }, + { + "id": "dc9fe954-c40a-5ea6-ba85-c21a0e47366c", + "name": "value_6", + "type": "BOOLEAN", + "linkIds": [ + 647 + ], + "label": "text_to_video", + "pos": [ + 876.162109375, + 4394 + ] + } + ], + "outputs": [ + { + "id": "954ef307-c897-4eea-8b5c-5c6ce15a5357", + "name": "VIDEO", + "type": "VIDEO", + "linkIds": [ + 536 + ], + "localized_name": "VIDEO", + "pos": [ + 6614, + 4384 + ] + }, + { + "id": "516f048d-bbf1-5f25-bfdd-01109ee55cb6", + "name": "IMAGE", + "type": "IMAGE", + "linkIds": [ + 648 + ], + "localized_name": "IMAGE", + "pos": [ + 6614, + 4404 + ] + } + ], + "widgets": [], + "nodes": [ + { + "id": 276, + "type": "RandomNoise", + "pos": [ + 4700, + 3650 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "NOISE", + "name": "NOISE", + "type": "NOISE", + "links": [ + 490 + ] + } + ], + "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": 277, + "type": "RandomNoise", + "pos": [ + 3160, + 3630 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "localized_name": "noise_seed", + "name": "noise_seed", + "type": "INT", + "widget": { + "name": "noise_seed" + }, + "link": 646 + } + ], + "outputs": [ + { + "localized_name": "NOISE", + "name": "NOISE", + "type": "NOISE", + "links": [ + 483 + ] + } + ], + "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": [ + 60540193790228, + "randomize" + ] + }, + { + "id": 278, + "type": "LTXVConcatAVLatent", + "pos": [ + 4710, + 4490 + ], + "size": [ + 280, + 100 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "link": 512 + }, + { + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", + "link": 513 + } + ], + "outputs": [ + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 494 + ] + } + ], + "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": 279, + "type": "LTXVAudioVAELoader", + "pos": [ + 1660, + 4100 + ], + "size": [ + 430, + 110 + ], + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "localized_name": "ckpt_name", + "name": "ckpt_name", + "type": "COMBO", + "widget": { + "name": "ckpt_name" + }, + "link": 604 + } + ], + "outputs": [ + { + "localized_name": "Audio VAE", + "name": "Audio VAE", + "type": "VAE", + "links": [ + 481, + 496 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.3.68", + "Node name for S&R": "LTXVAudioVAELoader", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "models": [ + { + "name": "ltx-2.3-22b-dev-fp8.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", + "directory": "checkpoints" + } + ], + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } + }, + "widgets_values": [ + "ltx-2.3-22b-dev-fp8.safetensors" + ] + }, + { + "id": 280, + "type": "KSamplerSelect", + "pos": [ + 4700, + 4100 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "SAMPLER", + "name": "SAMPLER", + "type": "SAMPLER", + "links": [ + 492 + ] + } + ], + "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": [ + "euler" + ] + }, + { + "id": 281, + "type": "ManualSigmas", + "pos": [ + 4700, + 4290 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "SIGMAS", + "name": "SIGMAS", + "type": "SIGMAS", + "links": [ + 493 + ] + } + ], + "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": 282, + "type": "CFGGuider", + "pos": [ + 4700, + 3850 + ], + "size": [ + 280, + 160 + ], + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 478 + }, + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 479 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 480 + } + ], + "outputs": [ + { + "localized_name": "GUIDER", + "name": "GUIDER", + "type": "GUIDER", + "links": [ + 491 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.3.71", + "Node name for S&R": "CFGGuider", + "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 + ] + }, + { + "id": 283, + "type": "SamplerCustomAdvanced", + "pos": [ + 3550, + 3630 + ], + "size": [ + 230, + 170 + ], + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ + { + "localized_name": "noise", + "name": "noise", + "type": "NOISE", + "link": 483 + }, + { + "localized_name": "guider", + "name": "guider", + "type": "GUIDER", + "link": 484 + }, + { + "localized_name": "sampler", + "name": "sampler", + "type": "SAMPLER", + "link": 485 + }, + { + "localized_name": "sigmas", + "name": "sigmas", + "type": "SIGMAS", + "link": 544 + }, + { + "localized_name": "latent_image", + "name": "latent_image", + "type": "LATENT", + "link": 487 + } + ], + "outputs": [ + { + "localized_name": "output", + "name": "output", + "type": "LATENT", + "links": [ + 488 + ] + }, + { + "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": 284, + "type": "LTXVCropGuides", + "pos": [ + 3830, + 3810 + ], + "size": [ + 250, + 120 + ], + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 475 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 476 + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "link": 477 + } + ], + "outputs": [ + { + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "links": [ + 479 + ] + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "links": [ + 480 + ] + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "slot_index": 2, + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.3.68", + "Node name for S&R": "LTXVCropGuides", + "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": 285, + "type": "LoraLoaderModelOnly", + "pos": [ + 1660, + 3890 + ], + "size": [ + 430, + 140 + ], + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 520 + }, + { + "localized_name": "lora_name", + "name": "lora_name", + "type": "COMBO", + "widget": { + "name": "lora_name" + }, + "link": 602 + } + ], + "outputs": [ + { + "localized_name": "MODEL", + "name": "MODEL", + "type": "MODEL", + "links": [ + 478, + 541, + 641 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.3.75", + "Node name for S&R": "LoraLoaderModelOnly", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, + "models": [ + { + "name": "ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", + "url": "https://huggingface.co/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", + "directory": "loras" + } + ], + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } + }, + "widgets_values": [ + "ltx_2.3_22b_distilled_1.1_lora_dynamic_fro09_avg_rank_111_bf16.safetensors", + 0.5 + ] + }, + { + "id": 286, + "type": "ResizeImagesByLongerEdge", + "pos": [ + 2070, + 4810 + ], + "size": [ + 348.624609375, + 110 + ], + "flags": { + "collapsed": false + }, + "order": 13, + "mode": 0, + "inputs": [ + { + "localized_name": "images", + "name": "images", + "type": "IMAGE", + "link": 523 + } + ], + "outputs": [ + { + "localized_name": "images", + "name": "images", + "type": "IMAGE", + "links": [ + 505 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "ver": "0.5.1", + "Node name for S&R": "ResizeImagesByLongerEdge", + "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": [ + 1536 + ] + }, + { + "id": 287, + "type": "LTXVLatentUpsampler", + "pos": [ + 4250, + 3760 + ], + "size": [ + 330, + 120 + ], + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [ + { + "localized_name": "samples", + "name": "samples", + "type": "LATENT", + "link": 547 + }, + { + "localized_name": "upscale_model", + "name": "upscale_model", + "type": "LATENT_UPSCALE_MODEL", + "link": 545 + }, + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 554 + } + ], + "outputs": [ + { + "localized_name": "LATENT", + "name": "LATENT", + "type": "LATENT", + "links": [ + 548 + ] + } + ], + "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": 288, + "type": "LTXVImgToVideoInplace", + "pos": [ + 4230, + 4100 + ], + "size": [ + 300, + 180 + ], + "flags": {}, + "order": 15, + "mode": 0, + "inputs": [ + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 552 + }, + { + "localized_name": "image", + "name": "image", + "type": "IMAGE", + "link": 515 + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "link": 548 + }, + { + "localized_name": "bypass", + "name": "bypass", + "type": "BOOLEAN", + "widget": { + "name": "bypass" + }, + "link": 543 + } + ], + "outputs": [ + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 512 + ] + } + ], + "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": 289, + "type": "LTXVPreprocess", + "pos": [ + 2100, + 5010 + ], + "size": [ + 290, + 110 + ], + "flags": {}, + "order": 16, + "mode": 0, + "inputs": [ + { + "localized_name": "image", + "name": "image", + "type": "IMAGE", + "link": 505 + } + ], + "outputs": [ + { + "localized_name": "output_image", + "name": "output_image", + "type": "IMAGE", + "links": [ + 510, + 515 + ] + } + ], + "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": 290, + "type": "ResizeImageMaskNode", + "pos": [ + 1660, + 4810 + ], + "size": [ + 300, + 154 + ], + "flags": {}, + "order": 17, + "mode": 0, + "inputs": [ + { + "localized_name": "input", + "name": "input", + "type": "IMAGE,MASK", + "link": 535 + }, + { + "localized_name": "width", + "name": "resize_type.width", + "type": "INT", + "widget": { + "name": "resize_type.width" + }, + "link": 558 + }, + { + "localized_name": "height", + "name": "resize_type.height", + "type": "INT", + "widget": { + "name": "resize_type.height" + }, + "link": 559 + } + ], + "outputs": [ + { + "localized_name": "resized", + "name": "resized", + "type": "IMAGE,MASK", + "links": [ + 523 + ] + } + ], + "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 dimensions", + 1920, + 1088, + "center", + "lanczos" + ] + }, + { + "id": 291, + "type": "KSamplerSelect", + "pos": [ + 3160, + 4040 + ], + "size": [ + 280, + 110 + ], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [ + { + "localized_name": "SAMPLER", + "name": "SAMPLER", + "type": "SAMPLER", + "links": [ + 485 + ] + } + ], + "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" + ] + }, + { + "id": 292, + "type": "ComfyMathExpression", + "pos": [ + 2540, + 4830 + ], + "size": [ + 225, + 74 + ], + "flags": { + "collapsed": true + }, + "order": 18, + "mode": 0, + "inputs": [ + { + "label": "a", + "localized_name": "values.a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 560 + }, + { + "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": null + }, + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 561 + ] + }, + { + "localized_name": "BOOL", + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "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": 293, + "type": "Reroute", + "pos": [ + 3850, + 4050 + ], + "size": [ + 75, + 26 + ], + "flags": {}, + "order": 19, + "mode": 0, + "inputs": [ + { + "name": "", + "type": "*", + "link": 557 + } + ], + "outputs": [ + { + "name": "", + "type": "VAE", + "links": [ + 552, + 553, + 554 + ] + } + ], + "properties": { + "showOutputText": false, + "horizontal": false, + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } + } + }, + { + "id": 294, + "type": "ComfyMathExpression", + "pos": [ + 2550, + 4890 + ], + "size": [ + 225, + 74 + ], + "flags": { + "collapsed": true + }, + "order": 20, + "mode": 0, + "inputs": [ + { + "label": "a", + "localized_name": "values.a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 562 + }, + { + "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": null + }, + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 563 + ] + }, + { + "localized_name": "BOOL", + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "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": 295, + "type": "EmptyLTXVLatentVideo", + "pos": [ + 2870, + 4940 + ], + "size": [ + 280, + 200 + ], + "flags": {}, + "order": 21, + "mode": 0, + "inputs": [ + { + "localized_name": "width", + "name": "width", + "type": "INT", + "widget": { + "name": "width" + }, + "link": 561 + }, + { + "localized_name": "height", + "name": "height", + "type": "INT", + "widget": { + "name": "height" + }, + "link": 563 + }, + { + "localized_name": "length", + "name": "length", + "type": "INT", + "widget": { + "name": "length" + }, + "link": 631 + } + ], + "outputs": [ + { + "localized_name": "LATENT", + "name": "LATENT", + "type": "LATENT", + "links": [ + 511 + ] + } ], - "localized_name": "input", - "label": "first_frame", - "pos": [ - -28.99609375, - 3084 + "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": "e80df1ae-5f39-4f86-91bd-0467635e2f2d", - "name": "input_1", - "type": "IMAGE,MASK", - "linkIds": [ - 1777, - 1802 - ], - "localized_name": "input_1", - "label": "control_images", + "id": 296, + "type": "LTXVImgToVideoInplace", "pos": [ - -28.99609375, - 3104 - ] - }, - { - "id": "433148fa-bf73-4ab1-81d9-09e2e38ed861", - "name": "text", - "type": "STRING", - "linkIds": [ - 316, - 317 + 3230, + 4810 ], - "label": "prompt", - "pos": [ - -28.99609375, - 3124 - ] - }, - { - "id": "80e8d306-4496-4641-a896-249352d68a33", - "name": "value_4", - "type": "BOOLEAN", - "linkIds": [ - 315 + "size": [ + 280, + 180 ], - "label": "prompt_enhance", - "pos": [ - -28.99609375, - 3144 - ] - }, - { - "id": "36915bc8-a6ed-4d48-8619-e0e8723228e9", - "name": "value", - "type": "INT", - "linkIds": [ - 266 + "flags": {}, + "order": 22, + "mode": 0, + "inputs": [ + { + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 556 + }, + { + "localized_name": "image", + "name": "image", + "type": "IMAGE", + "link": 510 + }, + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "link": 511 + }, + { + "localized_name": "bypass", + "name": "bypass", + "type": "BOOLEAN", + "widget": { + "name": "bypass" + }, + "link": 542 + } ], - "label": "width", - "pos": [ - -28.99609375, - 3164 - ] - }, - { - "id": "425a36b8-91ab-41b7-81e9-496eba064ec8", - "name": "value_1", - "type": "INT", - "linkIds": [ - 267 + "outputs": [ + { + "localized_name": "latent", + "name": "latent", + "type": "LATENT", + "links": [ + 497 + ] + } ], - "label": "height", - "pos": [ - -28.99609375, - 3184 + "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": "581b52ff-21c5-4774-ac2a-8f69a7e09e2e", - "name": "value_3", - "type": "INT", - "linkIds": [ - 269 - ], - "label": "fps", + "id": 297, + "type": "LTXVAudioVAEDecode", "pos": [ - -28.99609375, - 3204 - ] - }, - { - "id": "d03cc171-45da-4658-99aa-77252bbcf522", - "name": "noise_seed", - "type": "INT", - "linkIds": [ - 1793 + 5760, + 3970 ], - "label": "seed", - "pos": [ - -28.99609375, - 3224 - ] - }, - { - "id": "e68e61c8-905e-43ac-8c76-65ac52270a08", - "name": "ckpt_name_1", - "type": "COMBO", - "linkIds": [ - 272, - 275, - 276 + "size": [ + 270, + 100 ], - "label": "ckpt_name", - "pos": [ - -28.99609375, - 3244 - ] - }, - { - "id": "5d065f3b-891b-499f-950b-c2df0be24536", - "name": "text_encoder", - "type": "COMBO", - "linkIds": [ - 273 + "flags": {}, + "order": 23, + "mode": 0, + "inputs": [ + { + "localized_name": "samples", + "name": "samples", + "type": "LATENT", + "link": 495 + }, + { + "label": "Audio VAE", + "localized_name": "audio_vae", + "name": "audio_vae", + "type": "VAE", + "link": 496 + } ], - "label": "text_encoder", - "pos": [ - -28.99609375, - 3264 - ] - }, - { - "id": "e9abdbac-c422-4a1e-bc0d-6b99c0730086", - "name": "lora_name", - "type": "COMBO", - "linkIds": [ - 1768 + "outputs": [ + { + "localized_name": "Audio", + "name": "Audio", + "type": "AUDIO", + "links": [ + 534 + ] + } ], - "label": "lora", - "pos": [ - -28.99609375, - 3284 - ] + "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": "c05ba793-3f43-4594-b7df-3f17fa3f99ba", - "name": "lora_name_1", - "type": "COMBO", - "linkIds": [ - 1769 - ], - "label": "ic_lora", + "id": 298, + "type": "ComfyMathExpression", "pos": [ - -28.99609375, - 3304 - ] - }, - { - "id": "b475372d-89e7-44bb-995b-647f8e29c484", - "name": "strength_model", - "type": "FLOAT", - "linkIds": [ - 1770 + 2540, + 5030 ], - "label": "lora_strength", - "pos": [ - -28.99609375, - 3324 - ] - }, - { - "id": "bfc27fa2-b100-413c-9c64-d38ab1ed5a2d", - "name": "value_2", - "type": "BOOLEAN", - "linkIds": [ - 1804 + "size": [ + 225, + 74 ], - "label": "bypass_first_frame", - "pos": [ - -28.99609375, - 3344 - ] - } - ], - "outputs": [ - { - "id": "0c8c2dc0-c67c-4bc2-9e57-6aa00db2e3a9", - "name": "VIDEO", - "type": "VIDEO", - "linkIds": [ - 252 + "flags": { + "collapsed": true + }, + "order": 24, + "mode": 0, + "inputs": [ + { + "label": "a", + "localized_name": "values.a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 564 + }, + { + "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": [ + 566, + 591 + ] + }, + { + "localized_name": "INT", + "name": "INT", + "type": "INT", + "links": [ + 565 + ] + }, + { + "localized_name": "BOOL", + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } ], - "localized_name": "VIDEO", - "pos": [ - 3644, - 3144 + "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" ] - } - ], - "widgets": [], - "nodes": [ + }, { - "id": 101, - "type": "LTXVEmptyLatentAudio", + "id": 299, + "type": "PrimitiveInt", "pos": [ - 1180, - 3800 + 1190, + 4650 ], "size": [ - 280, - 170 + 370, + 110 ], "flags": {}, - "order": 1, + "order": 25, "mode": 0, "inputs": [ { - "localized_name": "audio_vae", - "name": "audio_vae", - "type": "VAE", - "link": 205 - }, - { - "localized_name": "frames_number", - "name": "frames_number", - "type": "INT", - "widget": { - "name": "frames_number" - }, - "link": 1801 - }, - { - "localized_name": "frame_rate", - "name": "frame_rate", + "localized_name": "value", + "name": "value", "type": "INT", "widget": { - "name": "frame_rate" + "name": "value" }, - "link": 207 + "link": 598 } ], "outputs": [ { - "localized_name": "Latent", - "name": "Latent", - "type": "LATENT", + "localized_name": "INT", + "name": "INT", + "type": "INT", "links": [ - 245 + 559, + 562 ] } ], + "title": "Height", "properties": { - "Node name for S&R": "LTXVEmptyLatentAudio", "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "PrimitiveInt", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.5.2", - "widget_ue_connectable": {} - }, - "ver": "0.3.68" + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, "widgets_values": [ - 97, - 25, - 1 + 1280, + "fixed" ] }, { - "id": 106, - "type": "LTXVCropGuides", + "id": 300, + "type": "PrimitiveInt", "pos": [ - 2430, - 2450 + 1190, + 4840 ], "size": [ - 280, - 120 + 370, + 110 ], "flags": {}, - "order": 4, + "order": 26, "mode": 0, "inputs": [ { - "localized_name": "positive", - "name": "positive", - "type": "CONDITIONING", - "link": 290 - }, - { - "localized_name": "negative", - "name": "negative", - "type": "CONDITIONING", - "link": 292 - }, - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "link": 215 + "localized_name": "value", + "name": "value", + "type": "INT", + "widget": { + "name": "value" + }, + "link": 624 } ], "outputs": [ { - "localized_name": "positive", - "name": "positive", - "type": "CONDITIONING", - "links": [] - }, - { - "localized_name": "negative", - "name": "negative", - "type": "CONDITIONING", - "links": [] - }, - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", + "localized_name": "INT", + "name": "INT", + "type": "INT", "links": [ - 211 + 564, + 629 ] } ], + "title": "Frame Rate", "properties": { - "Node name for S&R": "LTXVCropGuides", "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "PrimitiveInt", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.5.2", - "widget_ue_connectable": {} - }, - "ver": "0.8.2" + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, - "widgets_values": [] + "widgets_values": [ + 25, + "fixed" + ] }, { - "id": 108, - "type": "EmptyLTXVLatentVideo", + "id": 301, + "type": "PrimitiveInt", "pos": [ - 1180, - 3550 + 1190, + 4280 ], "size": [ - 280, - 200 + 370, + 110 ], "flags": {}, - "order": 6, + "order": 27, "mode": 0, "inputs": [ { - "localized_name": "width", - "name": "width", - "type": "INT", - "widget": { - "name": "width" - }, - "link": 1778 - }, - { - "localized_name": "height", - "name": "height", - "type": "INT", - "widget": { - "name": "height" - }, - "link": 1779 - }, - { - "localized_name": "length", - "name": "length", + "localized_name": "value", + "name": "value", "type": "INT", "widget": { - "name": "length" + "name": "value" }, - "link": 1800 + "link": 599 } ], "outputs": [ { - "localized_name": "LATENT", - "name": "LATENT", - "type": "LATENT", + "localized_name": "INT", + "name": "INT", + "type": "INT", "links": [ - 296 + 628 ] } ], + "title": "Duration", "properties": { - "Node name for S&R": "EmptyLTXVLatentVideo", "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "PrimitiveInt", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.5.2", - "widget_ue_connectable": {} - }, - "ver": "0.3.60" + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, "widgets_values": [ - 768, - 512, - 97, - 1 + 5, + "fixed" ] }, { - "id": 109, - "type": "LTXVConditioning", + "id": 302, + "type": "PrimitiveBoolean", "pos": [ - 1180, - 3350 + 1190, + 4110 ], "size": [ - 280, - 130 + 370, + 100 ], "flags": {}, - "order": 7, + "order": 4, "mode": 0, "inputs": [ { - "localized_name": "positive", - "name": "positive", - "type": "CONDITIONING", - "link": 221 - }, - { - "localized_name": "negative", - "name": "negative", - "type": "CONDITIONING", - "link": 222 - }, - { - "localized_name": "frame_rate", - "name": "frame_rate", - "type": "FLOAT", + "localized_name": "value", + "name": "value", + "type": "BOOLEAN", "widget": { - "name": "frame_rate" + "name": "value" }, - "link": 223 + "link": 647 } ], "outputs": [ { - "localized_name": "positive", - "name": "positive", - "type": "CONDITIONING", - "links": [ - 236 - ] - }, - { - "localized_name": "negative", - "name": "negative", - "type": "CONDITIONING", + "localized_name": "BOOLEAN", + "name": "BOOLEAN", + "type": "BOOLEAN", "links": [ - 237 + 542, + 543 ] } ], + "title": "Switch to Text to Video?", "properties": { - "Node name for S&R": "LTXVConditioning", "cnr_id": "comfy-core", + "ver": "0.16.0", + "Node name for S&R": "PrimitiveBoolean", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.5.2", - "widget_ue_connectable": {} - }, - "ver": "0.3.56" + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, "widgets_values": [ - 25 + false ] }, { - "id": 114, - "type": "PrimitiveInt", + "id": 303, + "type": "CLIPTextEncode", "pos": [ - 760, - 3840 + 2170, + 3640 ], "size": [ - 230, - 110 + 600, + 390 ], "flags": {}, - "order": 10, + "order": 28, "mode": 0, "inputs": [ { - "localized_name": "value", - "name": "value", - "type": "INT", + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 642 + }, + { + "localized_name": "text", + "name": "text", + "type": "STRING", "widget": { - "name": "value" + "name": "text" }, - "link": 269 + "link": 638 } ], "outputs": [ { - "localized_name": "INT", - "name": "INT", - "type": "INT", + "localized_name": "CONDITIONING", + "name": "CONDITIONING", + "type": "CONDITIONING", "links": [ - 207, - 235 + 526 ] } ], - "title": "Frame Rate(int)", "properties": { - "Node name for S&R": "PrimitiveInt", "cnr_id": "comfy-core", + "ver": "0.3.56", + "Node name for S&R": "CLIPTextEncode", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.5.2", - "widget_ue_connectable": {} - }, - "ver": "0.7.0" + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, "widgets_values": [ - 25, - "fixed" - ] + "" + ], + "color": "#232", + "bgcolor": "#353" }, { - "id": 115, - "type": "LTXVAddGuide", + "id": 304, + "type": "LTXVConditioning", "pos": [ - 2030, - 3360 + 2800, + 3810 ], "size": [ 280, - 310 + 130 ], "flags": {}, - "order": 11, + "order": 29, "mode": 0, "inputs": [ { "localized_name": "positive", "name": "positive", "type": "CONDITIONING", - "link": 236 + "link": 526 }, { "localized_name": "negative", "name": "negative", "type": "CONDITIONING", - "link": 237 - }, - { - "localized_name": "vae", - "name": "vae", - "type": "VAE", - "link": 307 - }, - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "link": 289 + "link": 527 }, { - "localized_name": "image", - "name": "image", - "type": "IMAGE", - "link": 1777 - }, - { - "localized_name": "attention_mask", - "name": "attention_mask", - "shape": 7, - "type": "MASK", - "link": null - }, - { - "localized_name": "iclora_parameters", - "name": "iclora_parameters", - "shape": 7, - "type": "IC_LORA_PARAMETERS", - "link": 288 + "localized_name": "frame_rate", + "name": "frame_rate", + "type": "FLOAT", + "widget": { + "name": "frame_rate" + }, + "link": 566 } ], "outputs": [ @@ -1994,8 +2837,8 @@ "name": "positive", "type": "CONDITIONING", "links": [ - 290, - 1791 + 475, + 518 ] }, { @@ -2003,375 +2846,378 @@ "name": "negative", "type": "CONDITIONING", "links": [ - 292, - 1790 - ] - }, - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "links": [ - 287 + 476, + 519 ] } ], "properties": { - "Node name for S&R": "LTXVAddGuide", "cnr_id": "comfy-core", + "ver": "0.3.56", + "Node name for S&R": "LTXVConditioning", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, + "widget_ue_connectable": {}, "version": "7.7", - "widget_ue_connectable": {} - }, - "ver": "0.12.3" + "input_ue_unconnectable": {} + } }, "widgets_values": [ - 0, - 1 + 24 ] }, { - "id": 119, - "type": "LTXVConcatAVLatent", + "id": 305, + "type": "LTXVEmptyLatentAudio", "pos": [ - 2030, - 2390 + 3540, + 4960 ], "size": [ 280, - 100 + 170 ], "flags": {}, - "order": 12, + "order": 30, "mode": 0, "inputs": [ { - "localized_name": "video_latent", - "name": "video_latent", - "type": "LATENT", - "link": 287 + "localized_name": "audio_vae", + "name": "audio_vae", + "type": "VAE", + "link": 481 }, { - "localized_name": "audio_latent", - "name": "audio_latent", - "type": "LATENT", - "link": 245 + "localized_name": "frames_number", + "name": "frames_number", + "type": "INT", + "widget": { + "name": "frames_number" + }, + "link": 630 + }, + { + "localized_name": "frame_rate", + "name": "frame_rate", + "type": "INT", + "widget": { + "name": "frame_rate" + }, + "link": 565 } ], "outputs": [ { - "localized_name": "latent", - "name": "latent", + "localized_name": "Latent", + "name": "Latent", "type": "LATENT", "links": [ - 1789 + 498 ] } ], "properties": { - "Node name for S&R": "LTXVConcatAVLatent", "cnr_id": "comfy-core", + "ver": "0.3.68", + "Node name for S&R": "LTXVEmptyLatentAudio", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.5.2", - "widget_ue_connectable": {} - }, - "ver": "0.7.0" + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, - "widgets_values": [] + "widgets_values": [ + 97, + 25, + 1 + ] }, { - "id": 123, - "type": "ComfyMathExpression", + "id": 306, + "type": "ManualSigmas", "pos": [ - 770, - 4000 + 3160, + 4220 ], "size": [ - 230, - 80 + 500, + 110 ], - "flags": { - "collapsed": true - }, - "order": 15, + "flags": {}, + "order": 5, "mode": 0, - "inputs": [ - { - "label": "a", - "localized_name": "values.a", - "name": "values.a", - "type": "FLOAT,INT,BOOLEAN", - "link": 235 - }, - { - "label": "b", - "localized_name": "values.b", - "name": "values.b", - "shape": 7, - "type": "FLOAT,INT,BOOLEAN", - "link": null - } - ], + "inputs": [], "outputs": [ { - "localized_name": "FLOAT", - "name": "FLOAT", - "type": "FLOAT", + "localized_name": "SIGMAS", + "name": "SIGMAS", + "type": "SIGMAS", "links": [ - 223, - 234 + 544 ] - }, - { - "localized_name": "INT", - "name": "INT", - "type": "INT", - "links": [] - }, - { - "localized_name": "BOOL", - "name": "BOOL", - "type": "BOOLEAN", - "links": null } ], "properties": { - "Node name for S&R": "ComfyMathExpression", "cnr_id": "comfy-core", + "ver": "0.14.1", + "Node name for S&R": "ManualSigmas", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, + "widget_ue_connectable": {}, "version": "7.7", - "widget_ue_connectable": {} - }, - "ver": "0.17.0" + "input_ue_unconnectable": {} + } }, "widgets_values": [ - "a" + "1.0, 0.99375, 0.9875, 0.98125, 0.975, 0.909375, 0.725, 0.421875, 0.0" ] }, { - "id": 113, - "type": "PrimitiveInt", + "id": 307, + "type": "LTXVSeparateAVLatent", "pos": [ - 760, - 3340 + 3820, + 3630 ], "size": [ - 230, - 110 + 250, + 100 ], "flags": {}, - "order": 9, + "order": 31, "mode": 0, "inputs": [ { - "localized_name": "value", - "name": "value", - "type": "INT", - "widget": { - "name": "value" - }, - "link": 266 + "localized_name": "av_latent", + "name": "av_latent", + "type": "LATENT", + "link": 488 } ], "outputs": [ { - "localized_name": "INT", - "name": "INT", - "type": "INT", + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "links": [ + 477, + 547 + ] + }, + { + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", "links": [ - 1778 + 513 ] } ], - "title": "Width", "properties": { - "Node name for S&R": "PrimitiveInt", "cnr_id": "comfy-core", + "ver": "0.5.1", + "Node name for S&R": "LTXVSeparateAVLatent", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.5.2", - "widget_ue_connectable": {} - }, - "ver": "0.7.0" + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, - "widgets_values": [ - 704, - "fixed" - ] + "widgets_values": [] }, { - "id": 98, - "type": "PrimitiveInt", + "id": 308, + "type": "SamplerCustomAdvanced", "pos": [ - 760, - 3490 + 5050, + 3650 ], "size": [ 230, - 110 + 170 ], "flags": {}, - "order": 0, + "order": 32, "mode": 0, "inputs": [ { - "localized_name": "value", - "name": "value", - "type": "INT", - "widget": { - "name": "value" - }, - "link": 267 + "localized_name": "noise", + "name": "noise", + "type": "NOISE", + "link": 490 + }, + { + "localized_name": "guider", + "name": "guider", + "type": "GUIDER", + "link": 491 + }, + { + "localized_name": "sampler", + "name": "sampler", + "type": "SAMPLER", + "link": 492 + }, + { + "localized_name": "sigmas", + "name": "sigmas", + "type": "SIGMAS", + "link": 493 + }, + { + "localized_name": "latent_image", + "name": "latent_image", + "type": "LATENT", + "link": 494 } ], "outputs": [ { - "localized_name": "INT", - "name": "INT", - "type": "INT", + "localized_name": "output", + "name": "output", + "type": "LATENT", "links": [ - 1779 + 578 ] + }, + { + "localized_name": "denoised_output", + "name": "denoised_output", + "type": "LATENT", + "links": [] } ], - "title": "height", "properties": { - "Node name for S&R": "PrimitiveInt", "cnr_id": "comfy-core", + "ver": "0.3.75", + "Node name for S&R": "SamplerCustomAdvanced", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.5.2", - "widget_ue_connectable": {} - }, - "ver": "0.7.0" + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, - "widgets_values": [ - 1280, - "fixed" - ] + "widgets_values": [] }, { - "id": 112, - "type": "CLIPTextEncode", + "id": 309, + "type": "LTXVSeparateAVLatent", "pos": [ - 1320, - 2870 + 5390, + 3650 ], "size": [ - 590, - 200 + 230, + 100 ], - "flags": { - "collapsed": false - }, - "order": 8, + "flags": {}, + "order": 33, "mode": 0, "inputs": [ { - "localized_name": "clip", - "name": "clip", - "type": "CLIP", - "link": 230 + "localized_name": "av_latent", + "name": "av_latent", + "type": "LATENT", + "link": 578 } ], "outputs": [ { - "localized_name": "CONDITIONING", - "name": "CONDITIONING", - "type": "CONDITIONING", + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "links": [ + 539 + ] + }, + { + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", "links": [ - 222 + 495 ] } ], "properties": { - "Node name for S&R": "CLIPTextEncode", "cnr_id": "comfy-core", + "ver": "0.5.1", + "Node name for S&R": "LTXVSeparateAVLatent", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.5.2", - "widget_ue_connectable": {} - }, - "ver": "0.3.56" + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, - "widgets_values": [ - "blurry, out of focus, overexposed, underexposed, low contrast, washed out colors, excessive noise, grainy texture, poor lighting, flickering, motion blur, distorted proportions, unnatural skin tones, deformed facial features, asymmetrical face, missing facial features, extra limbs, disfigured hands, wrong hand count, artifacts around text, unreadable text on shirt or hat, incorrect lettering on cap (“PNTR”), incorrect t-shirt slogan (“JUST DO IT”), missing microphone, misplaced microphone, inconsistent perspective, camera shake, incorrect depth of field, background too sharp, background clutter, distracting reflections, harsh shadows, inconsistent lighting direction, color banding, cartoonish rendering, 3D CGI look, unrealistic materials, uncanny valley effect, incorrect ethnicity, wrong gender, exaggerated expressions, smiling, laughing, exaggerated sadness, wrong gaze direction, eyes looking at camera, mismatched lip sync, silent or muted audio, distorted voice, robotic voice, echo, background noise, off-sync audio, missing sniff sounds, incorrect dialogue, added dialogue, repetitive speech, jittery movement, awkward pauses, incorrect timing, unnatural transitions, inconsistent framing, tilted camera, missing door or shelves, missing shallow depth of field, flat lighting, inconsistent tone, cinematic oversaturation, stylized filters, or AI artifacts." - ], - "color": "#223", - "bgcolor": "#335" + "widgets_values": [] }, { - "id": 122, + "id": 310, "type": "CreateVideo", "pos": [ - 2890, - 2900 + 6050, + 4490 ], "size": [ 280, - 160 + 130 ], "flags": {}, - "order": 14, + "order": 34, "mode": 0, "inputs": [ { "localized_name": "images", "name": "images", "type": "IMAGE", - "link": 232 + "link": 538 }, { "localized_name": "audio", "name": "audio", "shape": 7, "type": "AUDIO", - "link": 233 + "link": 534 }, { "localized_name": "fps", @@ -2380,7 +3226,7 @@ "widget": { "name": "fps" }, - "link": 234 + "link": 591 } ], "outputs": [ @@ -2389,26 +3235,26 @@ "name": "VIDEO", "type": "VIDEO", "links": [ - 252 + 536 ] } ], "properties": { - "Node name for S&R": "CreateVideo", "cnr_id": "comfy-core", + "ver": "0.5.1", + "Node name for S&R": "CreateVideo", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, + "widget_ue_connectable": {}, "version": "7.7", - "widget_ue_connectable": {} - }, - "ver": "0.14.1" + "input_ue_unconnectable": {} + } }, "widgets_values": [ 24, @@ -2416,261 +3262,322 @@ ] }, { - "id": 105, - "type": "VAEDecodeTiled", + "id": 311, + "type": "LatentUpscaleModelLoader", "pos": [ - 2430, - 2630 + 1670, + 4550 ], "size": [ - 280, - 200 + 400, + 110 ], "flags": {}, - "order": 3, + "order": 35, "mode": 0, "inputs": [ { - "localized_name": "samples", - "name": "samples", - "type": "LATENT", - "link": 211 - }, - { - "localized_name": "vae", - "name": "vae", - "type": "VAE", - "link": 212 + "localized_name": "model_name", + "name": "model_name", + "type": "COMBO", + "widget": { + "name": "model_name" + }, + "link": 607 } ], "outputs": [ { - "localized_name": "IMAGE", - "name": "IMAGE", - "type": "IMAGE", + "localized_name": "LATENT_UPSCALE_MODEL", + "name": "LATENT_UPSCALE_MODEL", + "type": "LATENT_UPSCALE_MODEL", "links": [ - 232 + 545 ] } ], "properties": { - "Node name for S&R": "VAEDecodeTiled", "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "LatentUpscaleModelLoader", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, + "models": [ + { + "name": "ltx-2.3-spatial-upscaler-x2-1.1.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3/resolve/main/ltx-2.3-spatial-upscaler-x2-1.1.safetensors", + "directory": "latent_upscale_models" + } + ], "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.5.2", - "widget_ue_connectable": {} - }, - "ver": "0.7.0" + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, "widgets_values": [ - 768, - 64, - 4096, - 64 + "ltx-2.3-spatial-upscaler-x2-1.1.safetensors" ] }, { - "id": 107, - "type": "LTXVAudioVAEDecode", + "id": 312, + "type": "PrimitiveInt", "pos": [ - 2430, - 2920 + 1190, + 4470 ], "size": [ - 280, - 100 + 370, + 110 ], "flags": {}, - "order": 5, + "order": 36, "mode": 0, "inputs": [ { - "localized_name": "samples", - "name": "samples", - "type": "LATENT", - "link": 216 - }, - { - "label": "Audio VAE", - "localized_name": "audio_vae", - "name": "audio_vae", - "type": "VAE", - "link": 217 + "localized_name": "value", + "name": "value", + "type": "INT", + "widget": { + "name": "value" + }, + "link": 597 } ], "outputs": [ { - "localized_name": "Audio", - "name": "Audio", - "type": "AUDIO", + "localized_name": "INT", + "name": "INT", + "type": "INT", "links": [ - 233 + 558, + 560 ] } ], + "title": "Width", "properties": { - "Node name for S&R": "LTXVAudioVAEDecode", "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "PrimitiveInt", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.5.2", - "widget_ue_connectable": {} - }, - "ver": "0.7.0" + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, - "widgets_values": [] + "widgets_values": [ + 720, + "fixed" + ] }, { - "id": 121, - "type": "LTXVSeparateAVLatent", + "id": 313, + "type": "CLIPTextEncode", "pos": [ - 2040, - 3010 + 2180, + 4120 ], "size": [ - 250, - 100 + 600, + 170 ], "flags": {}, - "order": 13, + "order": 37, "mode": 0, "inputs": [ { - "localized_name": "av_latent", - "name": "av_latent", - "type": "LATENT", - "link": 1788 + "localized_name": "clip", + "name": "clip", + "type": "CLIP", + "link": 627 } ], "outputs": [ { - "localized_name": "video_latent", - "name": "video_latent", - "type": "LATENT", + "localized_name": "CONDITIONING", + "name": "CONDITIONING", + "type": "CONDITIONING", "links": [ - 215 + 527 ] + } + ], + "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": [ + "pc game, console game, video game, cartoon, childish, ugly" + ], + "color": "#323", + "bgcolor": "#535" + }, + { + "id": 314, + "type": "CFGGuider", + "pos": [ + 3160, + 3810 + ], + "size": [ + 280, + 160 + ], + "flags": {}, + "order": 38, + "mode": 0, + "inputs": [ + { + "localized_name": "model", + "name": "model", + "type": "MODEL", + "link": 541 }, { - "localized_name": "audio_latent", - "name": "audio_latent", - "type": "LATENT", + "localized_name": "positive", + "name": "positive", + "type": "CONDITIONING", + "link": 518 + }, + { + "localized_name": "negative", + "name": "negative", + "type": "CONDITIONING", + "link": 519 + } + ], + "outputs": [ + { + "localized_name": "GUIDER", + "name": "GUIDER", + "type": "GUIDER", "links": [ - 216 + 484 ] } ], "properties": { - "Node name for S&R": "LTXVSeparateAVLatent", "cnr_id": "comfy-core", + "ver": "0.3.64", + "Node name for S&R": "CFGGuider", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.5.2", - "widget_ue_connectable": {} - }, - "ver": "0.5.1" + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, - "widgets_values": [] + "widgets_values": [ + 1 + ] }, { - "id": 128, - "type": "CLIPTextEncode", + "id": 315, + "type": "VAEDecodeTiled", "pos": [ - 1310, - 2380 + 5750, + 3610 ], "size": [ - 620, - 420 + 280, + 200 ], "flags": {}, - "order": 18, + "order": 39, "mode": 0, "inputs": [ { - "localized_name": "clip", - "name": "clip", - "type": "CLIP", - "link": 231 + "localized_name": "samples", + "name": "samples", + "type": "LATENT", + "link": 539 }, { - "localized_name": "text", - "name": "text", - "type": "STRING", - "widget": { - "name": "text" - }, - "link": 1808 + "localized_name": "vae", + "name": "vae", + "type": "VAE", + "link": 553 } ], "outputs": [ { - "localized_name": "CONDITIONING", - "name": "CONDITIONING", - "type": "CONDITIONING", + "localized_name": "IMAGE", + "name": "IMAGE", + "type": "IMAGE", "links": [ - 221 + 538 ] } ], "properties": { - "Node name for S&R": "CLIPTextEncode", "cnr_id": "comfy-core", + "ver": "0.14.1", + "Node name for S&R": "VAEDecodeTiled", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.5.2", - "widget_ue_connectable": {} - }, - "ver": "0.3.56" + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, "widgets_values": [ - "A slow forward dolly shot on a bright, sunlit day in a lush jungle ruin. A lone figure in nature-themed armor stands before a weathered stone arch overgrown with ivy. A textured marble sphere wrapped in twisting vines levitates in the arch’s center, spinning slowly. As the camera glides forward, vines sway softly, leaves flutter in the light breeze. Strong golden sunlight streams through the canopy, illuminating the mossy ruins with bright, clear light. The scene feels vibrant and peaceful, with subtle natural motion." - ], - "color": "#232", - "bgcolor": "#353" + 768, + 64, + 4096, + 4 + ] }, { - "id": 127, + "id": 316, "type": "CheckpointLoaderSimple", "pos": [ - 770, - 2380 + 1660, + 3660 ], "size": [ - 420, + 430, 160 ], "flags": {}, - "order": 17, + "order": 40, "mode": 0, "inputs": [ { @@ -2680,7 +3587,7 @@ "widget": { "name": "ckpt_name" }, - "link": 276 + "link": 601 } ], "outputs": [ @@ -2689,8 +3596,7 @@ "name": "MODEL", "type": "MODEL", "links": [ - 279, - 313 + 520 ] }, { @@ -2704,118 +3610,54 @@ "name": "VAE", "type": "VAE", "links": [ - 212, - 306, - 307 + 556, + 557 ] } ], "properties": { - "Node name for S&R": "CheckpointLoaderSimple", "cnr_id": "comfy-core", + "ver": "0.3.56", + "Node name for S&R": "CheckpointLoaderSimple", "enableTabs": false, - "hasSecondTab": false, - "models": [ - { - "name": "ltx-2.3-22b-distilled-fp8.safetensors", - "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-distilled-fp8.safetensors", - "directory": "checkpoints" - } - ], - "secondTabOffset": 80, - "secondTabText": "Send Back", - "secondTabWidth": 65, "tabWidth": 65, "tabXOffset": 10, - "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.5.2", - "widget_ue_connectable": {} - }, - "ver": "0.10.0" - }, - "widgets_values": [ - "ltx-2.3-22b-distilled-fp8.safetensors" - ] - }, - { - "id": 126, - "type": "LTXVAudioVAELoader", - "pos": [ - 770, - 2590 - ], - "size": [ - 420, - 110 - ], - "flags": {}, - "order": 16, - "mode": 0, - "inputs": [ - { - "localized_name": "ckpt_name", - "name": "ckpt_name", - "type": "COMBO", - "widget": { - "name": "ckpt_name" - }, - "link": 272 - } - ], - "outputs": [ - { - "localized_name": "Audio VAE", - "name": "Audio VAE", - "type": "VAE", - "links": [ - 205, - 217 - ] - } - ], - "properties": { - "Node name for S&R": "LTXVAudioVAELoader", - "cnr_id": "comfy-core", - "enableTabs": false, "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, "models": [ { - "name": "ltx-2.3-22b-distilled-fp8.safetensors", - "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-distilled-fp8.safetensors", + "name": "ltx-2.3-22b-dev-fp8.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", "directory": "checkpoints" } ], - "secondTabOffset": 80, - "secondTabText": "Send Back", - "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.5.2", - "widget_ue_connectable": {} - }, - "ver": "0.10.0" + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, "widgets_values": [ - "ltx-2.3-22b-distilled-fp8.safetensors" + "ltx-2.3-22b-dev-fp8.safetensors" ] }, { - "id": 103, + "id": 317, "type": "LTXAVTextEncoderLoader", "pos": [ - 770, - 2750 + 1660, + 4280 ], "size": [ - 410, + 430, 170 ], "flags": {}, - "order": 2, + "order": 41, "mode": 0, + "showAdvanced": false, "inputs": [ { "localized_name": "text_encoder", @@ -2824,7 +3666,7 @@ "widget": { "name": "text_encoder" }, - "link": 273 + "link": 606 }, { "localized_name": "ckpt_name", @@ -2833,7 +3675,7 @@ "widget": { "name": "ckpt_name" }, - "link": 275 + "link": 605 } ], "outputs": [ @@ -2842,268 +3684,274 @@ "name": "CLIP", "type": "CLIP", "links": [ - 230, - 231, - 314 + 627, + 642, + 643 ] } ], "properties": { - "Node name for S&R": "LTXAVTextEncoderLoader", "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "LTXAVTextEncoderLoader", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, "models": [ + { + "name": "ltx-2.3-22b-dev-fp8.safetensors", + "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-dev-fp8.safetensors", + "directory": "checkpoints" + }, { "name": "gemma_3_12B_it_fp4_mixed.safetensors", "url": "https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/text_encoders/gemma_3_12B_it_fp4_mixed.safetensors", "directory": "text_encoders" - }, - { - "name": "ltx-2.3-22b-distilled-fp8.safetensors", - "url": "https://huggingface.co/Lightricks/LTX-2.3-fp8/resolve/main/ltx-2.3-22b-distilled-fp8.safetensors", - "directory": "checkpoints" } ], - "secondTabOffset": 80, - "secondTabText": "Send Back", - "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, "ue_properties": { - "input_ue_unconnectable": {}, - "version": "7.5.2", - "widget_ue_connectable": {} - }, - "ver": "0.10.0" + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, "widgets_values": [ "gemma_3_12B_it_fp4_mixed.safetensors", - "ltx-2.3-22b-distilled-fp8.safetensors", + "ltx-2.3-22b-dev-fp8.safetensors", "default" ] }, { - "id": 195, - "type": "LoraLoaderModelOnly", + "id": 318, + "type": "LTXVConcatAVLatent", "pos": [ - 750, - 3020 + 3860, + 4830 ], "size": [ - 470, - 140 + 240, + 100 ], "flags": {}, - "order": 19, + "order": 42, "mode": 0, "inputs": [ { - "localized_name": "model", - "name": "model", - "type": "MODEL", - "link": 279 - }, - { - "localized_name": "lora_name", - "name": "lora_name", - "type": "COMBO", - "widget": { - "name": "lora_name" - }, - "link": 1769 + "localized_name": "video_latent", + "name": "video_latent", + "type": "LATENT", + "link": 497 }, { - "localized_name": "strength_model", - "name": "strength_model", - "type": "FLOAT", - "widget": { - "name": "strength_model" - }, - "link": 1770 + "localized_name": "audio_latent", + "name": "audio_latent", + "type": "LATENT", + "link": 498 } ], "outputs": [ { - "localized_name": "MODEL", - "name": "MODEL", - "type": "MODEL", + "localized_name": "latent", + "name": "latent", + "type": "LATENT", "links": [ - 277, - 1792 + 487 ] } ], "properties": { - "Node name for S&R": "LoraLoaderModelOnly", "cnr_id": "comfy-core", + "ver": "0.7.0", + "Node name for S&R": "LTXVConcatAVLatent", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "models": [ - { - "name": "ltx-2.3-22b-ic-lora-ingredients-0.9.safetensors", - "url": "https://huggingface.co/Comfy-Org/ltx-2.3/resolve/main/split_files/loras/ltx-2.3-22b-ic-lora-ingredients-0.9.safetensors", - "directory": "loras" - } - ], - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, - "ver": "0.22.0" + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, - "widgets_values": [ - "ltx-2.3-22b-ic-lora-ingredients-0.9.safetensors", - 1 - ], - "color": "#323", - "bgcolor": "#535" + "widgets_values": [] }, { - "id": 196, - "type": "GetICLoRAParameters", + "id": 319, + "type": "PrimitiveStringMultiline", "pos": [ - 1590, - 3630 + 1190, + 3680 ], "size": [ - 300, - 80 + 370, + 350 ], "flags": {}, - "order": 20, + "order": 43, "mode": 0, "inputs": [ { - "localized_name": "iclora_model", - "name": "iclora_model", - "type": "MODEL", - "link": 277 + "localized_name": "value", + "name": "value", + "type": "STRING", + "widget": { + "name": "value" + }, + "link": 595 } ], "outputs": [ { - "localized_name": "iclora_parameters", - "name": "iclora_parameters", - "type": "IC_LORA_PARAMETERS", + "localized_name": "STRING", + "name": "STRING", + "type": "STRING", "links": [ - 288 + 639, + 640 ] } ], + "title": "Prompt", "properties": { - "Node name for S&R": "GetICLoRAParameters", "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "PrimitiveStringMultiline", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, - "ver": "0.22.0" + "ue_properties": { + "widget_ue_connectable": {}, + "version": "7.7", + "input_ue_unconnectable": {} + } }, - "widgets_values": [], - "color": "#323", - "bgcolor": "#535" + "widgets_values": [ + "" + ] }, { - "id": 198, - "type": "LTXVImgToVideoInplace", + "id": 323, + "type": "ComfyMathExpression", "pos": [ - 1580, - 3360 + 1210, + 5040 ], "size": [ - 270, - 180 + 225, + 94 ], - "flags": {}, - "order": 21, + "flags": { + "collapsed": true + }, + "order": 44, "mode": 0, "inputs": [ { - "localized_name": "vae", - "name": "vae", - "type": "VAE", - "link": 306 - }, - { - "localized_name": "image", - "name": "image", - "type": "IMAGE", - "link": 1786 - }, - { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", - "link": 296 + "label": "a", + "localized_name": "values.a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 628 }, { - "localized_name": "bypass", - "name": "bypass", - "type": "BOOLEAN", - "widget": { - "name": "bypass" - }, - "link": 1803 + "label": "b", + "localized_name": "values.b", + "name": "values.b", + "shape": 7, + "type": "FLOAT,INT,BOOLEAN", + "link": 629 + }, + { + "label": "c", + "localized_name": "values.c", + "name": "values.c", + "shape": 7, + "type": "FLOAT,INT,BOOLEAN", + "link": null } ], "outputs": [ { - "localized_name": "latent", - "name": "latent", - "type": "LATENT", + "localized_name": "FLOAT", + "name": "FLOAT", + "type": "FLOAT", + "links": null + }, + { + "localized_name": "INT", + "name": "INT", + "type": "INT", "links": [ - 289 + 630, + 631 ] + }, + { + "localized_name": "BOOL", + "name": "BOOL", + "type": "BOOLEAN", + "links": null } ], + "title": "Math Expression (length)", "properties": { - "Node name for S&R": "LTXVImgToVideoInplace", "cnr_id": "comfy-core", + "ver": "0.18.1", + "Node name for S&R": "ComfyMathExpression", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", + "secondTabOffset": 80, "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, - "ver": "0.22.0" + "ue_properties": { + "widget_ue_connectable": {}, + "input_ue_unconnectable": {}, + "version": "7.7" + } }, "widgets_values": [ - 1, - true + "a * b + 1" ] }, { - "id": 208, + "id": 324, "type": "LoraLoader", "pos": [ - 770, - 1570 + 1200, + 2870 ], "size": [ 380, 230 ], "flags": {}, - "order": 22, + "order": 45, "mode": 0, "inputs": [ { "localized_name": "model", "name": "model", "type": "MODEL", - "link": 313 + "link": 641 }, { "localized_name": "clip", "name": "clip", "type": "CLIP", - "link": 314 + "link": 643 }, { "localized_name": "lora_name", @@ -3112,7 +3960,7 @@ "widget": { "name": "lora_name" }, - "link": 1768 + "link": 645 } ], "outputs": [ @@ -3127,28 +3975,28 @@ "name": "CLIP", "type": "CLIP", "links": [ - 309 + 634 ] } ], "properties": { - "Node name for S&R": "LoraLoader", "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "LoraLoader", "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65, "models": [ { "name": "gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", "url": "https://huggingface.co/Comfy-Org/ltx-2/resolve/main/split_files/loras/gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", "directory": "loras" } - ], - "secondTabOffset": 80, - "secondTabText": "Send Back", - "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, - "ver": "0.16.3" + ] }, "widgets_values": [ "gemma-3-12b-it-abliterated_lora_rank64_bf16.safetensors", @@ -3157,34 +4005,34 @@ ] }, { - "id": 209, + "id": 325, "type": "TextGenerateLTX2Prompt", "pos": [ - 1200, - 1570 + 1630, + 2870 ], "size": [ 400, - 420 + 412 ], "flags": { "collapsed": false }, - "order": 23, + "order": 46, "mode": 0, "inputs": [ { "localized_name": "clip", "name": "clip", "type": "CLIP", - "link": 309 + "link": 634 }, { "localized_name": "image", "name": "image", "shape": 7, "type": "IMAGE", - "link": 1735 + "link": null }, { "localized_name": "video", @@ -3207,7 +4055,7 @@ "widget": { "name": "prompt" }, - "link": 316 + "link": 639 } ], "outputs": [ @@ -3216,24 +4064,24 @@ "name": "generated_text", "type": "STRING", "links": [ - 311 + 636 ] } ], "properties": { - "Node name for S&R": "TextGenerateLTX2Prompt", "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "TextGenerateLTX2Prompt", "enableTabs": false, - "hasSecondTab": false, - "secondTabOffset": 80, - "secondTabText": "Send Back", - "secondTabWidth": 65, "tabWidth": 65, "tabXOffset": 10, - "ver": "0.16.3" + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65 }, "widgets_values": [ - "### Reference Sheet Description **Top Row Left (Character):** An anthropomorphic bipedal German Shepherd news anchor with realistic brown, tan, and black fur, a calm professional expression, and thin round copper-bronze framed glasses. He is shown in close-up portraits and full-body front, three-quarter, side, and back views standing upright like a person, with a humanoid torso and limbs and a long bushy German Shepherd tail. He wears a vibrant long-sleeve button-down shirt with an abstract multicolored pink-purple-turquoise-yellow woven pattern, dark charcoal dress pants, and dark leather dress shoes. **Top Row Right (Prop):** A professional black studio condenser microphone on a short circular desk stand shown from multiple angles, plus black over-the-ear wireless earpieces / headsets for broadcast cues. **Middle Row Right (Prop):** A flat product view of the same vibrant long-sleeve multicolored patterned button-down shirt, clearly showing the abstract pink, purple, turquoise, and yellow woven texture. **Bottom Row (Setting):** A wide shot of a high-end professional news studio with a large curved dark teal anchor desk in the foreground, a massive digital backdrop screen displaying bold white \"NEWS\" lettering over soft blue-green abstract graphics, and polished cinematic broadcast lighting with studio fixtures visible around the set.\n\n### Target Description A cozy, cinematic scene inside a high-end professional news studio. The camera begins on a wide establishing shot of the large curved dark teal anchor desk and the soft-focus blue-green \"NEWS\" backdrop, then smoothly pushes in to a steady medium shot of the anthropomorphic bipedal German Shepherd news anchor seated behind the desk. He has realistic brown-tan-black fur, thin round copper-bronze glasses, and a calm professional expression. He wears the vibrant long-sleeve multicolored pink-purple-turquoise-yellow patterned button-down shirt with dark charcoal dress pants. His paw-like hands rest on the desk near the black studio condenser microphone. The studio is bathed in polished cinematic broadcast light from the backdrop and overhead fixtures. His initial expression is focused and composed, then he leans slightly toward the microphone, softens into a confident on-air smile, and speaks clearly to camera: \"Good evening, and welcome to tonight's top stories.\" He pauses briefly, glances down at the desk, then looks back up and continues: \"Here's what you need to know.\" The background \"NEWS\" screen and studio lights remain softly detailed behind him, emphasizing his face, glasses, and colorful shirt under the clean broadcast lighting.", + "A young woman holds the product up to the camera in a bright modern kitchen, turning it slowly to show the label, then smiles at the camera. Handheld iPhone footage, natural window light, shallow depth of field, authentic UGC style.", 2048, "on", 0.7, @@ -3248,25 +4096,25 @@ ] }, { - "id": 210, + "id": 326, "type": "PreviewAny", "pos": [ - 2040, - 1590 + 2470, + 2890 ], "size": [ 510, 360 ], "flags": {}, - "order": 24, - "mode": 4, + "order": 47, + "mode": 0, "inputs": [ { "localized_name": "source", "name": "source", "type": "*", - "link": 310 + "link": 635 } ], "outputs": [ @@ -3274,288 +4122,100 @@ "localized_name": "STRING", "name": "STRING", "type": "STRING", - "links": [ - 1808 - ] + "links": [] } ], "properties": { - "Node name for S&R": "PreviewAny", "cnr_id": "comfy-core", + "ver": "0.16.3", + "Node name for S&R": "PreviewAny", "enableTabs": false, - "hasSecondTab": false, - "secondTabOffset": 80, - "secondTabText": "Send Back", - "secondTabWidth": 65, "tabWidth": 65, "tabXOffset": 10, - "ver": "0.16.3" - }, - "widgets_values": [ - null, - null, - null - ] - }, - { - "id": 211, - "type": "ComfySwitchNode", - "pos": [ - 1730, - 1980 - ], - "size": [ - 270, - 130 - ], - "flags": {}, - "order": 25, - "mode": 0, - "inputs": [ - { - "localized_name": "on_false", - "name": "on_false", - "type": "STRING", - "link": 317 - }, - { - "localized_name": "on_true", - "name": "on_true", - "type": "STRING", - "link": 311 - }, - { - "localized_name": "switch", - "name": "switch", - "type": "BOOLEAN", - "widget": { - "name": "switch" - }, - "link": 312 - } - ], - "outputs": [ - { - "localized_name": "output", - "name": "output", - "type": "STRING", - "links": [ - 310 - ] - } - ], - "properties": { - "Node name for S&R": "ComfySwitchNode", - "cnr_id": "comfy-core", - "enableTabs": false, "hasSecondTab": false, - "secondTabOffset": 80, "secondTabText": "Send Back", - "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, - "ver": "0.22.0" - }, - "widgets_values": [ - false - ] - }, - { - "id": 212, - "type": "PrimitiveBoolean", - "pos": [ - 770, - 2050 - ], - "size": [ - 270, - 100 - ], - "flags": {}, - "order": 26, - "mode": 0, - "inputs": [ - { - "localized_name": "value", - "name": "value", - "type": "BOOLEAN", - "widget": { - "name": "value" - }, - "link": 315 - } - ], - "outputs": [ - { - "localized_name": "BOOLEAN", - "name": "BOOLEAN", - "type": "BOOLEAN", - "links": [ - 312 - ] - } - ], - "title": "Boolean (Enable Prompt Enhance)", - "properties": { - "Node name for S&R": "PrimitiveBoolean", - "cnr_id": "comfy-core", - "enableTabs": false, - "hasSecondTab": false, "secondTabOffset": 80, - "secondTabText": "Send Back", - "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, - "ver": "0.22.0" + "secondTabWidth": 65 }, - "widgets_values": [ - false - ] + "widgets_values": [] }, { - "id": 704, - "type": "KSampler", + "id": 327, + "type": "ComfySwitchNode", "pos": [ - 2030, - 2570 + 2160, + 3280 ], "size": [ 270, - 350 - ], - "flags": {}, - "order": 27, - "mode": 0, - "inputs": [ - { - "localized_name": "model", - "name": "model", - "type": "MODEL", - "link": 1792 - }, - { - "localized_name": "positive", - "name": "positive", - "type": "CONDITIONING", - "link": 1791 - }, - { - "localized_name": "negative", - "name": "negative", - "type": "CONDITIONING", - "link": 1790 - }, - { - "localized_name": "latent_image", - "name": "latent_image", - "type": "LATENT", - "link": 1789 - }, - { - "localized_name": "seed", - "name": "seed", - "type": "INT", - "widget": { - "name": "seed" - }, - "link": 1793 - } - ], - "outputs": [ - { - "localized_name": "LATENT", - "name": "LATENT", - "type": "LATENT", - "links": [ - 1788 - ] - } - ], - "properties": { - "Node name for S&R": "KSampler", - "cnr_id": "comfy-core", - "enableTabs": false, - "hasSecondTab": false, - "secondTabOffset": 80, - "secondTabText": "Send Back", - "secondTabWidth": 65, - "tabWidth": 65, - "tabXOffset": 10, - "ver": "0.22.0" - }, - "widgets_values": [ - 288370150520961, - "randomize", - 8, - 1, - "euler_ancestral", - "linear_quadratic", - 1 - ] - }, - { - "id": 710, - "type": "GetImageSize", - "pos": [ - 770, - 3650 - ], - "size": [ - 230, - 120 + 130 ], "flags": {}, - "order": 28, + "order": 48, "mode": 0, "inputs": [ { - "localized_name": "image", - "name": "image", - "type": "IMAGE", - "link": 1802 - } - ], - "outputs": [ - { - "localized_name": "width", - "name": "width", - "type": "INT", - "links": null + "localized_name": "on_false", + "name": "on_false", + "type": "STRING", + "link": 640 }, { - "localized_name": "height", - "name": "height", - "type": "INT", - "links": null + "localized_name": "on_true", + "name": "on_true", + "type": "STRING", + "link": 636 }, { - "localized_name": "batch_size", - "name": "batch_size", - "type": "INT", + "localized_name": "switch", + "name": "switch", + "type": "BOOLEAN", + "widget": { + "name": "switch" + }, + "link": 637 + } + ], + "outputs": [ + { + "localized_name": "output", + "name": "output", + "type": "STRING", "links": [ - 1800, - 1801 + 635, + 638 ] } ], "properties": { - "Node name for S&R": "GetImageSize" + "cnr_id": "comfy-core", + "ver": "0.22.0", + "Node name for S&R": "ComfySwitchNode", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65 }, - "widgets_values": [] + "widgets_values": [ + false + ] }, { - "id": 711, + "id": 328, "type": "PrimitiveBoolean", "pos": [ - 750, - 4080 + 1200, + 3350 ], "size": [ 270, 100 ], "flags": {}, - "order": 29, + "order": 49, "mode": 0, "inputs": [ { @@ -3565,7 +4225,7 @@ "widget": { "name": "value" }, - "link": 1804 + "link": 644 } ], "outputs": [ @@ -3574,98 +4234,144 @@ "name": "BOOLEAN", "type": "BOOLEAN", "links": [ - 1803 + 637 ] } ], + "title": "Boolean (Enable Prompt Enhance)", "properties": { - "Node name for S&R": "PrimitiveBoolean" + "cnr_id": "comfy-core", + "ver": "0.22.0", + "Node name for S&R": "PrimitiveBoolean", + "enableTabs": false, + "tabWidth": 65, + "tabXOffset": 10, + "hasSecondTab": false, + "secondTabText": "Send Back", + "secondTabOffset": 80, + "secondTabWidth": 65 }, "widgets_values": [ - true + false ] } ], "groups": [ { "id": 1, - "title": "Conditioning", + "title": "Model", "bounding": [ - 1050, - 3250, - 1700, - 960 + 1630, + 3550, + 480, + 1140 ], "color": "#3f789e", "flags": {} }, { "id": 2, - "title": "Settings", + "title": "Generate Low Resolution", "bounding": [ - 730, - 3250, - 300, - 960 + 3130, + 3550, + 1000, + 1140 ], "color": "#3f789e", "flags": {} }, { - "id": 5, - "title": "Model", + "id": 3, + "title": "Prompt", "bounding": [ - 730, - 2240, - 500, - 980 + 2140, + 3550, + 960, + 1140 ], "color": "#3f789e", "flags": {} }, { "id": 6, - "title": "Prompt", + "title": "Generate High Resolution", "bounding": [ - 1260, - 2240, - 680, - 980 + 4670, + 3550, + 990, + 1130 ], "color": "#3f789e", "flags": {} }, { "id": 7, - "title": "Sampling", + "title": "Latent Upscale", "bounding": [ - 1970, - 2240, - 380, - 980 + 4160, + 3550, + 480, + 1130 ], "color": "#3f789e", "flags": {} }, { - "id": 8, - "title": "Decoding", + "id": 19, + "title": "Video Settings", "bounding": [ - 2380, - 2240, - 370, - 980 + 1150, + 3550, + 460, + 1610 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 20, + "title": "Image Preprocess", + "bounding": [ + 1630, + 4720, + 830, + 440 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 21, + "title": "Empty Latent", + "bounding": [ + 2820, + 4720, + 1310, + 450 + ], + "color": "#3f789e", + "flags": {} + }, + { + "id": 22, + "title": "Number conversion", + "bounding": [ + 2480, + 4720, + 310, + 440 ], "color": "#3f789e", "flags": {} }, { - "id": 24, + "id": 26, "title": "Prompt Enhancement", "bounding": [ - 730, - 1490, - 2020, + 1160, + 2790, + 2010, 720 ], "color": "#3f789e", @@ -3674,556 +4380,747 @@ ], "links": [ { - "id": 205, - "origin_id": 126, + "id": 512, + "origin_id": 288, + "origin_slot": 0, + "target_id": 278, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 513, + "origin_id": 307, + "origin_slot": 1, + "target_id": 278, + "target_slot": 1, + "type": "LATENT" + }, + { + "id": 478, + "origin_id": 285, + "origin_slot": 0, + "target_id": 282, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 479, + "origin_id": 284, + "origin_slot": 0, + "target_id": 282, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 480, + "origin_id": 284, + "origin_slot": 1, + "target_id": 282, + "target_slot": 2, + "type": "CONDITIONING" + }, + { + "id": 541, + "origin_id": 285, + "origin_slot": 0, + "target_id": 314, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 518, + "origin_id": 304, + "origin_slot": 0, + "target_id": 314, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 519, + "origin_id": 304, + "origin_slot": 1, + "target_id": 314, + "target_slot": 2, + "type": "CONDITIONING" + }, + { + "id": 483, + "origin_id": 277, + "origin_slot": 0, + "target_id": 283, + "target_slot": 0, + "type": "NOISE" + }, + { + "id": 484, + "origin_id": 314, + "origin_slot": 0, + "target_id": 283, + "target_slot": 1, + "type": "GUIDER" + }, + { + "id": 485, + "origin_id": 291, + "origin_slot": 0, + "target_id": 283, + "target_slot": 2, + "type": "SAMPLER" + }, + { + "id": 544, + "origin_id": 306, "origin_slot": 0, - "target_id": 101, + "target_id": 283, + "target_slot": 3, + "type": "SIGMAS" + }, + { + "id": 487, + "origin_id": 318, + "origin_slot": 0, + "target_id": 283, + "target_slot": 4, + "type": "LATENT" + }, + { + "id": 475, + "origin_id": 304, + "origin_slot": 0, + "target_id": 284, + "target_slot": 0, + "type": "CONDITIONING" + }, + { + "id": 476, + "origin_id": 304, + "origin_slot": 1, + "target_id": 284, + "target_slot": 1, + "type": "CONDITIONING" + }, + { + "id": 477, + "origin_id": 307, + "origin_slot": 0, + "target_id": 284, + "target_slot": 2, + "type": "LATENT" + }, + { + "id": 520, + "origin_id": 316, + "origin_slot": 0, + "target_id": 285, + "target_slot": 0, + "type": "MODEL" + }, + { + "id": 523, + "origin_id": 290, + "origin_slot": 0, + "target_id": 286, + "target_slot": 0, + "type": "IMAGE" + }, + { + "id": 547, + "origin_id": 307, + "origin_slot": 0, + "target_id": 287, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 545, + "origin_id": 311, + "origin_slot": 0, + "target_id": 287, + "target_slot": 1, + "type": "LATENT_UPSCALE_MODEL" + }, + { + "id": 554, + "origin_id": 293, + "origin_slot": 0, + "target_id": 287, + "target_slot": 2, + "type": "VAE" + }, + { + "id": 552, + "origin_id": 293, + "origin_slot": 0, + "target_id": 288, "target_slot": 0, "type": "VAE" }, { - "id": 207, - "origin_id": 114, + "id": 515, + "origin_id": 289, + "origin_slot": 0, + "target_id": 288, + "target_slot": 1, + "type": "IMAGE" + }, + { + "id": 548, + "origin_id": 287, + "origin_slot": 0, + "target_id": 288, + "target_slot": 2, + "type": "LATENT" + }, + { + "id": 543, + "origin_id": 302, + "origin_slot": 0, + "target_id": 288, + "target_slot": 3, + "type": "BOOLEAN" + }, + { + "id": 505, + "origin_id": 286, + "origin_slot": 0, + "target_id": 289, + "target_slot": 0, + "type": "IMAGE" + }, + { + "id": 558, + "origin_id": 312, + "origin_slot": 0, + "target_id": 290, + "target_slot": 1, + "type": "INT" + }, + { + "id": 559, + "origin_id": 299, "origin_slot": 0, - "target_id": 101, + "target_id": 290, "target_slot": 2, "type": "INT" }, { - "id": 215, - "origin_id": 121, + "id": 560, + "origin_id": 312, + "origin_slot": 0, + "target_id": 292, + "target_slot": 0, + "type": "INT" + }, + { + "id": 557, + "origin_id": 316, + "origin_slot": 2, + "target_id": 293, + "target_slot": 0, + "type": "VAE" + }, + { + "id": 562, + "origin_id": 299, + "origin_slot": 0, + "target_id": 294, + "target_slot": 0, + "type": "INT" + }, + { + "id": 561, + "origin_id": 292, + "origin_slot": 1, + "target_id": 295, + "target_slot": 0, + "type": "INT" + }, + { + "id": 563, + "origin_id": 294, + "origin_slot": 1, + "target_id": 295, + "target_slot": 1, + "type": "INT" + }, + { + "id": 556, + "origin_id": 316, + "origin_slot": 2, + "target_id": 296, + "target_slot": 0, + "type": "VAE" + }, + { + "id": 510, + "origin_id": 289, + "origin_slot": 0, + "target_id": 296, + "target_slot": 1, + "type": "IMAGE" + }, + { + "id": 511, + "origin_id": 295, + "origin_slot": 0, + "target_id": 296, + "target_slot": 2, + "type": "LATENT" + }, + { + "id": 542, + "origin_id": 302, + "origin_slot": 0, + "target_id": 296, + "target_slot": 3, + "type": "BOOLEAN" + }, + { + "id": 495, + "origin_id": 309, + "origin_slot": 1, + "target_id": 297, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 496, + "origin_id": 279, + "origin_slot": 0, + "target_id": 297, + "target_slot": 1, + "type": "VAE" + }, + { + "id": 564, + "origin_id": 300, "origin_slot": 0, - "target_id": 106, - "target_slot": 2, - "type": "LATENT" + "target_id": 298, + "target_slot": 0, + "type": "INT" }, { - "id": 221, - "origin_id": 128, + "id": 526, + "origin_id": 303, "origin_slot": 0, - "target_id": 109, + "target_id": 304, "target_slot": 0, "type": "CONDITIONING" }, { - "id": 222, - "origin_id": 112, + "id": 527, + "origin_id": 313, "origin_slot": 0, - "target_id": 109, + "target_id": 304, "target_slot": 1, "type": "CONDITIONING" }, { - "id": 223, - "origin_id": 123, + "id": 566, + "origin_id": 298, "origin_slot": 0, - "target_id": 109, + "target_id": 304, "target_slot": 2, "type": "FLOAT" }, { - "id": 236, - "origin_id": 109, + "id": 497, + "origin_id": 296, "origin_slot": 0, - "target_id": 115, + "target_id": 318, "target_slot": 0, - "type": "CONDITIONING" - }, - { - "id": 237, - "origin_id": 109, - "origin_slot": 1, - "target_id": 115, - "target_slot": 1, - "type": "CONDITIONING" + "type": "LATENT" }, { - "id": 245, - "origin_id": 101, + "id": 498, + "origin_id": 305, "origin_slot": 0, - "target_id": 119, + "target_id": 318, "target_slot": 1, "type": "LATENT" }, { - "id": 235, - "origin_id": 114, + "id": 481, + "origin_id": 279, "origin_slot": 0, - "target_id": 123, + "target_id": 305, "target_slot": 0, + "type": "VAE" + }, + { + "id": 565, + "origin_id": 298, + "origin_slot": 1, + "target_id": 305, + "target_slot": 2, "type": "INT" }, { - "id": 230, - "origin_id": 103, + "id": 488, + "origin_id": 283, "origin_slot": 0, - "target_id": 112, + "target_id": 307, "target_slot": 0, - "type": "CLIP" + "type": "LATENT" }, { - "id": 232, - "origin_id": 105, + "id": 490, + "origin_id": 276, "origin_slot": 0, - "target_id": 122, + "target_id": 308, "target_slot": 0, - "type": "IMAGE" + "type": "NOISE" }, { - "id": 233, - "origin_id": 107, + "id": 491, + "origin_id": 282, "origin_slot": 0, - "target_id": 122, + "target_id": 308, "target_slot": 1, - "type": "AUDIO" + "type": "GUIDER" }, { - "id": 234, - "origin_id": 123, + "id": 492, + "origin_id": 280, "origin_slot": 0, - "target_id": 122, + "target_id": 308, "target_slot": 2, - "type": "FLOAT" + "type": "SAMPLER" }, { - "id": 211, - "origin_id": 106, - "origin_slot": 2, - "target_id": 105, + "id": 493, + "origin_id": 281, + "origin_slot": 0, + "target_id": 308, + "target_slot": 3, + "type": "SIGMAS" + }, + { + "id": 494, + "origin_id": 278, + "origin_slot": 0, + "target_id": 308, + "target_slot": 4, + "type": "LATENT" + }, + { + "id": 578, + "origin_id": 308, + "origin_slot": 0, + "target_id": 309, "target_slot": 0, "type": "LATENT" }, { - "id": 212, - "origin_id": 127, - "origin_slot": 2, - "target_id": 105, + "id": 539, + "origin_id": 309, + "origin_slot": 0, + "target_id": 315, + "target_slot": 0, + "type": "LATENT" + }, + { + "id": 553, + "origin_id": 293, + "origin_slot": 0, + "target_id": 315, "target_slot": 1, "type": "VAE" }, { - "id": 216, - "origin_id": 121, - "origin_slot": 1, - "target_id": 107, + "id": 538, + "origin_id": 315, + "origin_slot": 0, + "target_id": 310, "target_slot": 0, - "type": "LATENT" + "type": "IMAGE" }, { - "id": 217, - "origin_id": 126, + "id": 534, + "origin_id": 297, "origin_slot": 0, - "target_id": 107, + "target_id": 310, "target_slot": 1, - "type": "VAE" + "type": "AUDIO" + }, + { + "id": 591, + "origin_id": 298, + "origin_slot": 0, + "target_id": 310, + "target_slot": 2, + "type": "FLOAT" }, { - "id": 231, - "origin_id": 103, + "id": 535, + "origin_id": -10, "origin_slot": 0, - "target_id": 128, + "target_id": 290, "target_slot": 0, - "type": "CLIP" + "type": "IMAGE,MASK" }, { - "id": 252, - "origin_id": 122, + "id": 536, + "origin_id": 310, "origin_slot": 0, "target_id": -20, "target_slot": 0, "type": "VIDEO" }, { - "id": 266, + "id": 595, "origin_id": -10, - "origin_slot": 4, - "target_id": 113, + "origin_slot": 1, + "target_id": 319, + "target_slot": 0, + "type": "STRING" + }, + { + "id": 597, + "origin_id": -10, + "origin_slot": 3, + "target_id": 312, "target_slot": 0, "type": "INT" }, { - "id": 267, + "id": 598, "origin_id": -10, - "origin_slot": 5, - "target_id": 98, + "origin_slot": 4, + "target_id": 299, "target_slot": 0, "type": "INT" }, { - "id": 269, + "id": 599, "origin_id": -10, - "origin_slot": 6, - "target_id": 114, + "origin_slot": 5, + "target_id": 301, "target_slot": 0, "type": "INT" }, { - "id": 272, + "id": 601, "origin_id": -10, "origin_slot": 8, - "target_id": 126, + "target_id": 316, "target_slot": 0, "type": "COMBO" }, { - "id": 273, + "id": 602, "origin_id": -10, "origin_slot": 9, - "target_id": 103, - "target_slot": 0, + "target_id": 285, + "target_slot": 1, "type": "COMBO" }, { - "id": 275, + "id": 604, "origin_id": -10, "origin_slot": 8, - "target_id": 103, - "target_slot": 1, + "target_id": 279, + "target_slot": 0, "type": "COMBO" }, { - "id": 276, + "id": 605, "origin_id": -10, "origin_slot": 8, - "target_id": 127, - "target_slot": 0, + "target_id": 317, + "target_slot": 1, "type": "COMBO" }, { - "id": 277, - "origin_id": 195, - "origin_slot": 0, - "target_id": 196, + "id": 606, + "origin_id": -10, + "origin_slot": 10, + "target_id": 317, "target_slot": 0, - "type": "MODEL" + "type": "COMBO" }, { - "id": 279, - "origin_id": 127, - "origin_slot": 0, - "target_id": 195, + "id": 607, + "origin_id": -10, + "origin_slot": 11, + "target_id": 311, "target_slot": 0, - "type": "MODEL" + "type": "COMBO" }, { - "id": 287, - "origin_id": 115, - "origin_slot": 2, - "target_id": 119, + "id": 624, + "origin_id": -10, + "origin_slot": 6, + "target_id": 300, "target_slot": 0, - "type": "LATENT" + "type": "INT" }, { - "id": 288, - "origin_id": 196, + "id": 627, + "origin_id": 317, "origin_slot": 0, - "target_id": 115, - "target_slot": 6, - "type": "IC_LORA_PARAMETERS" + "target_id": 313, + "target_slot": 0, + "type": "CLIP" }, { - "id": 289, - "origin_id": 198, + "id": 628, + "origin_id": 301, "origin_slot": 0, - "target_id": 115, - "target_slot": 3, - "type": "LATENT" + "target_id": 323, + "target_slot": 0, + "type": "INT" }, { - "id": 290, - "origin_id": 115, + "id": 629, + "origin_id": 300, "origin_slot": 0, - "target_id": 106, - "target_slot": 0, - "type": "CONDITIONING" + "target_id": 323, + "target_slot": 1, + "type": "INT" }, { - "id": 292, - "origin_id": 115, + "id": 630, + "origin_id": 323, "origin_slot": 1, - "target_id": 106, + "target_id": 305, "target_slot": 1, - "type": "CONDITIONING" - }, - { - "id": 296, - "origin_id": 108, - "origin_slot": 0, - "target_id": 198, - "target_slot": 2, - "type": "LATENT" - }, - { - "id": 306, - "origin_id": 127, - "origin_slot": 2, - "target_id": 198, - "target_slot": 0, - "type": "VAE" + "type": "INT" }, { - "id": 307, - "origin_id": 127, - "origin_slot": 2, - "target_id": 115, + "id": 631, + "origin_id": 323, + "origin_slot": 1, + "target_id": 295, "target_slot": 2, - "type": "VAE" + "type": "INT" }, { - "id": 309, - "origin_id": 208, + "id": 634, + "origin_id": 324, "origin_slot": 1, - "target_id": 209, + "target_id": 325, "target_slot": 0, "type": "CLIP" }, { - "id": 310, - "origin_id": 211, + "id": 635, + "origin_id": 327, "origin_slot": 0, - "target_id": 210, + "target_id": 326, "target_slot": 0, "type": "*" }, { - "id": 311, - "origin_id": 209, + "id": 636, + "origin_id": 325, "origin_slot": 0, - "target_id": 211, + "target_id": 327, "target_slot": 1, "type": "STRING" }, { - "id": 312, - "origin_id": 212, + "id": 637, + "origin_id": 328, "origin_slot": 0, - "target_id": 211, + "target_id": 327, "target_slot": 2, "type": "BOOLEAN" }, { - "id": 313, - "origin_id": 127, - "origin_slot": 0, - "target_id": 208, - "target_slot": 0, - "type": "MODEL" - }, - { - "id": 314, - "origin_id": 103, + "id": 638, + "origin_id": 327, "origin_slot": 0, - "target_id": 208, + "target_id": 303, "target_slot": 1, - "type": "CLIP" - }, - { - "id": 315, - "origin_id": -10, - "origin_slot": 3, - "target_id": 212, - "target_slot": 0, - "type": "BOOLEAN" - }, - { - "id": 316, - "origin_id": -10, - "origin_slot": 2, - "target_id": 209, - "target_slot": 4, - "type": "STRING" - }, - { - "id": 317, - "origin_id": -10, - "origin_slot": 2, - "target_id": 211, - "target_slot": 0, "type": "STRING" }, { - "id": 1735, - "origin_id": -10, + "id": 639, + "origin_id": 319, "origin_slot": 0, - "target_id": 209, - "target_slot": 1, - "type": "IMAGE" - }, - { - "id": 1768, - "origin_id": -10, - "origin_slot": 10, - "target_id": 208, - "target_slot": 2, - "type": "COMBO" - }, - { - "id": 1769, - "origin_id": -10, - "origin_slot": 11, - "target_id": 195, - "target_slot": 1, - "type": "COMBO" - }, - { - "id": 1770, - "origin_id": -10, - "origin_slot": 12, - "target_id": 195, - "target_slot": 2, - "type": "FLOAT" - }, - { - "id": 1777, - "origin_id": -10, - "origin_slot": 1, - "target_id": 115, + "target_id": 325, "target_slot": 4, - "type": "IMAGE" + "type": "STRING" }, { - "id": 1778, - "origin_id": 113, + "id": 640, + "origin_id": 319, "origin_slot": 0, - "target_id": 108, + "target_id": 327, "target_slot": 0, - "type": "INT" - }, - { - "id": 1779, - "origin_id": 98, - "origin_slot": 0, - "target_id": 108, - "target_slot": 1, - "type": "INT" - }, - { - "id": 1786, - "origin_id": -10, - "origin_slot": 0, - "target_id": 198, - "target_slot": 1, - "type": "IMAGE" + "type": "STRING" }, { - "id": 1788, - "origin_id": 704, + "id": 641, + "origin_id": 285, "origin_slot": 0, - "target_id": 121, + "target_id": 324, "target_slot": 0, - "type": "LATENT" + "type": "MODEL" }, { - "id": 1789, - "origin_id": 119, + "id": 642, + "origin_id": 317, "origin_slot": 0, - "target_id": 704, - "target_slot": 3, - "type": "LATENT" - }, - { - "id": 1790, - "origin_id": 115, - "origin_slot": 1, - "target_id": 704, - "target_slot": 2, - "type": "CONDITIONING" + "target_id": 303, + "target_slot": 0, + "type": "CLIP" }, { - "id": 1791, - "origin_id": 115, + "id": 643, + "origin_id": 317, "origin_slot": 0, - "target_id": 704, + "target_id": 324, "target_slot": 1, - "type": "CONDITIONING" + "type": "CLIP" }, { - "id": 1792, - "origin_id": 195, - "origin_slot": 0, - "target_id": 704, + "id": 644, + "origin_id": -10, + "origin_slot": 2, + "target_id": 328, "target_slot": 0, - "type": "MODEL" + "type": "BOOLEAN" }, { - "id": 1793, + "id": 645, "origin_id": -10, - "origin_slot": 7, - "target_id": 704, - "target_slot": 4, - "type": "INT" - }, - { - "id": 1800, - "origin_id": 710, - "origin_slot": 2, - "target_id": 108, + "origin_slot": 12, + "target_id": 324, "target_slot": 2, - "type": "INT" - }, - { - "id": 1801, - "origin_id": 710, - "origin_slot": 2, - "target_id": 101, - "target_slot": 1, - "type": "INT" + "type": "COMBO" }, { - "id": 1802, + "id": 646, "origin_id": -10, - "origin_slot": 1, - "target_id": 710, + "origin_slot": 7, + "target_id": 277, "target_slot": 0, - "type": "IMAGE" - }, - { - "id": 1803, - "origin_id": 711, - "origin_slot": 0, - "target_id": 198, - "target_slot": 3, - "type": "BOOLEAN" + "type": "INT" }, { - "id": 1804, + "id": 647, "origin_id": -10, "origin_slot": 13, - "target_id": 711, + "target_id": 302, "target_slot": 0, "type": "BOOLEAN" }, { - "id": 1808, - "origin_id": 210, + "id": 648, + "origin_id": 315, "origin_slot": 0, - "target_id": 128, + "target_id": -20, "target_slot": 1, - "type": "STRING" + "type": "IMAGE" } ], "extra": { + "workflowRendererVersion": "Vue-corrected", "ue_links": [] } } ] - }, - "config": {}, - "extra": { - "VHS_KeepIntermediate": true, - "VHS_MetadataImage": true, - "VHS_latentpreview": false, - "VHS_latentpreviewrate": 0, - "frontendVersion": "1.45.15", - "ue_links": [], - "workflowRendererVersion": "Vue-corrected", - "ds": { - "scale": 0.5959744833082783, - "offset": [ - 2409.0282524930844, - -1818.184424107724 - ] - } - }, - "version": 0.4 -} \ No newline at end of file + } +} From 3866a6e116398611913cb202e7a4ae0924fa85a2 Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Thu, 6 Aug 2026 15:18:37 +0300 Subject: [PATCH 10/29] voice concat --- docs/serviceTemplates/README.md | 35 +++- .../ltx-video-ugc-bootstrap.sh | 28 +++ .../ltx-video-ugc-multishot.json | 4 +- .../workflows/ocean_ugc_assemble.json | 172 ++++++++++++++++-- 4 files changed, 224 insertions(+), 15 deletions(-) diff --git a/docs/serviceTemplates/README.md b/docs/serviceTemplates/README.md index 056b06125..87b2e6455 100644 --- a/docs/serviceTemplates/README.md +++ b/docs/serviceTemplates/README.md @@ -150,8 +150,29 @@ bootstrap points ComfyUI's `--input-directory` and `--output-directory` at the s root, the PNG shows up in `LoadImage`'s dropdown with no copying. Once every shot looks good, switch to the **Assemble reel** workflow, pick the clips in its -`LoadVideo` slots, bypass the slots you don't need, and Run — it concatenates them -(image + audio) into one clip inside ComfyUI, no external editor needed. +`LoadVideo` slots, bypass the slots you don't need, and Run — it concatenates them into one +clip inside ComfyUI, no external editor needed. + +**Voice.** LTX builds each clip's audio from a fresh `LTXVEmptyLatentAudio` conditioned only +on the text — there is no speaker embedding, so a spoken line is a different person on every +cut and no amount of prompting locks it. Frame chaining carries the face; nothing carries the +voice. + +Assemble concatenates the clips' own audio, which keeps ambience and picture in sync, then +runs the stitched track through **voice conversion** — the same thing dubbing pipelines do. +`UnifiedVoiceChangerNode` remaps every line to one reference speaker while leaving the words, +their timing and the room tone alone. That is why conversion beats dubbing a voiceover over +the footage: the phonemes never move, so ambience survives and the lips still match. Upload a +few seconds of clean speech as the reference voice; `refinement_passes` 1 is usually right +(above ~5 it distorts) and `max_chunk_duration` bounds VRAM, rejoining chunks with +timing-preserving concatenation. + +Scripting still helps and costs nothing: dialogue in one or two shots, action and ambience in +the rest, means fewer conversions to get right. + +If the voice nodes load red, the pack failed to install — delete both and wire the last +`AudioConcat` straight into `CreateVideo`, which is the plain stitched audio the workflow +used before. The node's own how-to says so too. ## The shared bootstrap (`ltx-video-ugc-bootstrap.sh`) @@ -170,6 +191,16 @@ graph itself, so each template fetches only what it loads and a new workflow nee here. A template's `envVars` cannot drive this — nothing merges them into a service container (`SERVICE_START` has no template id; the container env comes only from `userData`). +Custom nodes follow the same graph-driven rule. The script installs +[TTS-Audio-Suite](https://github.com/diodiogod/TTS-Audio-Suite) — for the assemble workflow's +voice conversion — only when an installed graph mentions `UnifiedVoiceChangerNode`, so the +product template never pays for it. The clone lands in the bucket's `custom_nodes`, but pip +installs into the container and is lost on stop, hence the unconditional reinstall on every +launch; it is cheap because `XDG_CACHE_HOME` puts pip's wheel cache in the bucket too. It +installs into the container's own site-packages rather than `--target` + `PYTHONPATH`: a +second `numpy`/`torch` ahead of the container's would break ComfyUI itself. Every step is +non-fatal — escrow is already claimed by then, and the video workflows need none of it. + ### `automatic1111.json` — Stable Diffusion WebUI (A1111) (GPU) The classic AUTOMATIC1111 UI (`universonic/stable-diffusion-webui`). The image entrypoint diff --git a/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh b/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh index e7e978324..ab7e3755a 100755 --- a/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh +++ b/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh @@ -184,9 +184,37 @@ fi export HOME="$BASE" export PYTHONPYCACHEPREFIX="$BASE/.cache/pycache" +# Set before the pip install below, not just for ComfyUI: it puts pip's wheel cache in the +# bucket, so the reinstall on every later launch resolves from disk instead of the network. export XDG_CACHE_HOME="$BASE/.cache" export HF_HOME="$BASE/.cache/huggingface" +# Voice conversion for the assemble workflow: LTX re-rolls the speaker on every clip, so a +# stitched reel changes voice at each cut. The node pack that fixes it is not in the image. +# Driven by the graph, like the model URLs are — a template that doesn't use the node pays +# nothing. Cloned code lands in the bucket; pip installs land in the container and are lost +# on stop, hence the unconditional reinstall (cheap, cache is in the bucket). Plain install, +# NOT --target: a second numpy/torch ahead of the container's on PYTHONPATH would break +# ComfyUI itself. Every failure here is non-fatal — escrow is claimed and the video +# workflows need none of this. +if [ -n "${PACK:-}" ] && grep -qls UnifiedVoiceChangerNode "$PACK"/example_workflows/*.json 2>/dev/null; then + VC_DIR="$BASE/custom_nodes/TTS-Audio-Suite" + if ! command -v git >/dev/null 2>&1; then + echo "[ocean] no git in the image — skipping voice-conversion nodes" >&2 + elif [ -d "$VC_DIR/.git" ] || git clone --depth 1 \ + https://github.com/diodiogod/TTS-Audio-Suite.git "$VC_DIR"; then + echo "[ocean] installing voice-conversion dependencies (first launch is slow)" + python3.13 -m pip install --no-input --disable-pip-version-check \ + -r "$VC_DIR/requirements.txt" || + echo "[ocean] voice-conversion dependencies failed to install — the Voice Changer node" \ + "will be missing; delete it in the assemble workflow and wire Audio Concat straight" \ + "into Create reel" >&2 + else + echo "[ocean] could not clone TTS-Audio-Suite — the Voice Changer node will be missing" >&2 + rm -rf "$VC_DIR" + fi +fi + echo "[ocean] starting ComfyUI with base directory $BASE" exec python3.13 /default-comfyui-bundle/ComfyUI/main.py \ --base-directory "$BASE" ${OUTPUT_DIR_ARGS} --listen --port 8188 ${CLI_ARGS:-} diff --git a/docs/serviceTemplates/ltx-video-ugc-multishot.json b/docs/serviceTemplates/ltx-video-ugc-multishot.json index a7ea27de4..64a50c3a2 100644 --- a/docs/serviceTemplates/ltx-video-ugc-multishot.json +++ b/docs/serviceTemplates/ltx-video-ugc-multishot.json @@ -1,7 +1,7 @@ { "id": "ltx-video-ugc-multishot", "name": "ComfyUI — UGC multishot reel (LTX-2.3)", - "description": "ComfyUI preloaded with LTX-2.3 for a vertical UGC reel built one shot at a time, with the same character in every shot. It runs the same two-stage generator as the product-video template (22B dev fp8, base pass then a spatial-upscaler refine pass), so shot quality matches. Usage: optionally upload a character photo as the first frame — with no photo you turn on 'No character image' and the style prompt builds the character instead. Then fill two text boxes: 'Style — every shot' holds everything that must stay identical (who the character is, wardrobe, room, lighting, palette, camera look) and you never touch it again; 'Scene — this shot' holds only what changes (action, camera move, dialogue, ambient sound). Click Run for a clip, edit the scene box, Run again. Every run also saves that clip's last frame beside it as lastframe_….png, so you chain the next shot by picking it as the first frame — shot 2 then starts exactly where shot 1 ended and identity carries in pixels rather than in prose, the trick that holds a multi-shot reel together. Clips are 9:16 vertical (720×1280) at 5 seconds each (126 frames at 25 fps) with audio, saved to the bucket root; ComfyUI's save counter never overwrites, so re-takes accumulate and you pick the good ones later. Once every shot is good, switch to the Assemble reel workflow to concatenate up to 8 of them into one clip inside ComfyUI — no external editor needed. Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the 38 GiB of weights download once and are reused, and the numbered shot clips land in the bucket root where the storage API's listFiles can see them. Needs a CUDA GPU with 48 GB+ VRAM.", + "description": "ComfyUI preloaded with LTX-2.3 for a vertical UGC reel built one shot at a time, with the same character in every shot. It runs the same two-stage generator as the product-video template (22B dev fp8, base pass then a spatial-upscaler refine pass), so shot quality matches. Usage: optionally upload a character photo as the first frame — with no photo you turn on 'No character image' and the style prompt builds the character instead. Then fill two text boxes: 'Style — every shot' holds everything that must stay identical (who the character is, wardrobe, room, lighting, palette, camera look) and you never touch it again; 'Scene — this shot' holds only what changes (action, camera move, dialogue, ambient sound). Click Run for a clip, edit the scene box, Run again. Every run also saves that clip's last frame beside it as lastframe_….png, so you chain the next shot by picking it as the first frame — shot 2 then starts exactly where shot 1 ended and identity carries in pixels rather than in prose, the trick that holds a multi-shot reel together. Clips are 9:16 vertical (720×1280) at 5 seconds each (126 frames at 25 fps) with audio, saved to the bucket root; ComfyUI's save counter never overwrites, so re-takes accumulate and you pick the good ones later. Once every shot is good, switch to the Assemble reel workflow to concatenate up to 8 of them into one clip inside ComfyUI — no external editor needed. The assemble workflow keeps each clip's own audio and runs it through a voice-conversion node: LTX re-rolls the speaker on every clip, so the stitched track would otherwise change voice at each cut. Upload a few seconds of clean speech as the reference voice and every line is converted to that one speaker, with words, timing and room tone untouched — so the picture stays in sync and the lips still match. The node pack is not in the image; the bootstrap clones it and installs its dependencies on launch, but only when the graph actually uses it, so the first launch of this template is slower and the product template is unaffected. Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the 38 GiB of weights download once and are reused, and the numbered shot clips land in the bucket root where the storage API's listFiles can see them. Needs a CUDA GPU with 48 GB+ VRAM.", "image": "yanwk/comfyui-boot", "tag": "cu130-megapak-pt211-20260803", "exposedPorts": [ @@ -22,7 +22,7 @@ { "id": "ocean_ugc_assemble", "name": "Assemble reel", - "description": "Concatenates up to 8 rendered shot_000NN.mp4 clips (video + audio) into a single reel using core ComfyUI video nodes — pick clips in the LoadVideo dropdowns, bypass any slots you don't need, and Run.", + "description": "Concatenates up to 8 rendered shot clips (video + audio) into a single reel using core ComfyUI video nodes, then converts every voice in the stitched track to one reference speaker so the reel does not change voice at each cut — pick clips in the LoadVideo dropdowns, bypass any slots you don't need, upload a reference voice, and Run.", "file": "workflows/ocean_ugc_assemble.json" } ], diff --git a/docs/serviceTemplates/workflows/ocean_ugc_assemble.json b/docs/serviceTemplates/workflows/ocean_ugc_assemble.json index f668e9a04..54fa2b909 100644 --- a/docs/serviceTemplates/workflows/ocean_ugc_assemble.json +++ b/docs/serviceTemplates/workflows/ocean_ugc_assemble.json @@ -1,8 +1,8 @@ { "id": "f0a7b59b-e37f-4ce2-9564-e772ecd7d9c2", "revision": 0, - "last_node_id": 51, - "last_link_id": 40, + "last_node_id": 62, + "last_link_id": 64, "nodes": [ { "id": 1, @@ -22,7 +22,7 @@ "outputs": [], "properties": {}, "widgets_values": [ - "## Assemble reel\n\nPick a rendered `shot_000NN.mp4` in each slot's **file** dropdown below (the dropdown lists what's been generated in the bucket — hit ComfyUI's refresh icon if a clip you just rendered isn't listed yet). The numbering is ComfyUI's own save counter, so re-takes never overwrite: just don't select the ones you didn't like.\n\n**Bypass (Ctrl+B) any slot you don't need.** The chain concatenates whichever slots stay active, in order, so an unused tail slot just needs bypassing — no rewiring.\n\nClick **Run** once. The stitched reel saves as `reel_00001.mp4` in the bucket root.\n\nOnly 8 slots: each 5 s clip is ~126 frames at 720×1280 in float32, about 1.4 GB as a tensor. 8 slots gives a ~40 s reel and stays comfortably inside this template's 128 GB." + "## Assemble reel\n\nPick a rendered `shot_…mp4` in each slot's **file** dropdown below (the dropdown lists what's been generated in the bucket — hit ComfyUI's refresh icon if a clip you just rendered isn't listed yet). The numbering is ComfyUI's own save counter, so re-takes never overwrite: just don't select the ones you didn't like.\n\n**Bypass (Ctrl+B) any slot you don't need.** The chain concatenates whichever slots stay active, in order, so an unused tail slot just needs bypassing — no rewiring.\n\nClick **Run** once. The stitched reel saves as `reel_00001…` in the bucket root.\n\n### Voice\n\nLTX generates each clip's audio from scratch — there is no speaker to carry across a cut — so the stitched track changes voice every 5 seconds. **Voice Changer** fixes that: it converts every line to one target speaker while leaving the words, the timing and the room tone alone, so the picture stays in sync and the lips still match.\n\nUpload a few seconds of clean speech in **Reference voice** — that is the voice the whole reel ends up in. Anything works: your own recording, a clip you like, or one shot's audio you thought sounded right.\n\n- *refinement_passes* — 1 is usually right. Raise it if the conversion sounds half-applied; above ~5 it distorts.\n- *max_chunk_duration* — chunks long audio to avoid running out of VRAM, then rejoins preserving timing. Leave at 30.\n\n**If the Voice Changer and Voice engine nodes show up red**, their node pack failed to install on launch (check the container log for `[ocean]`). Delete both, then drag the last **Audio Concat**'s output onto **Create reel**'s `audio` input — you are back to the raw stitched audio and everything else still works.\n\nOnly 8 slots: each 5 s clip is ~126 frames at 720×1280 in float32, about 1.4 GB as a tensor. 8 slots gives a ~40 s reel and stays comfortably inside this template's 128 GB." ], "title": "How to use" }, @@ -1313,7 +1313,7 @@ "name": "AUDIO", "type": "AUDIO", "links": [ - 39 + 61 ] } ], @@ -1357,7 +1357,7 @@ "name": "audio", "type": "AUDIO", "shape": 7, - "link": 39 + "link": 64 } ], "outputs": [ @@ -1417,6 +1417,132 @@ "auto" ], "title": "Output reel" + }, + { + "id": 60, + "type": "LoadAudio", + "pos": [ + 2180.0, + 560.0 + ], + "size": [ + 330, + 140 + ], + "flags": {}, + "order": 20, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 62 + ] + } + ], + "properties": { + "Node name for S&R": "LoadAudio" + }, + "widgets_values": [ + "reference_voice.mp3", + null, + null + ], + "title": "Reference voice — every line is converted to this" + }, + { + "id": 61, + "type": "ChatterBoxEngineNode", + "pos": [ + 2180.0, + 760.0 + ], + "size": [ + 340, + 190 + ], + "flags": {}, + "order": 21, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "TTS_engine", + "type": "TTS_ENGINE", + "links": [ + 63 + ] + } + ], + "properties": { + "Node name for S&R": "ChatterBoxEngineNode" + }, + "widgets_values": [ + "English", + "auto", + 0.5, + 0.8, + 0.5, + "hmm ,, {seg} hmm ,," + ], + "title": "Voice engine (ChatterBox)" + }, + { + "id": 62, + "type": "UnifiedVoiceChangerNode", + "pos": [ + 2560.0, + 560.0 + ], + "size": [ + 340, + 180 + ], + "flags": {}, + "order": 22, + "mode": 0, + "inputs": [ + { + "name": "TTS_engine", + "type": "TTS_ENGINE", + "link": 63 + }, + { + "name": "source_audio", + "type": "AUDIO", + "link": 61 + }, + { + "name": "narrator_target", + "type": "AUDIO", + "link": 62 + } + ], + "outputs": [ + { + "name": "converted_audio", + "type": "AUDIO", + "links": [ + 64 + ] + }, + { + "name": "conversion_info", + "type": "STRING", + "links": null + } + ], + "properties": { + "Node name for S&R": "UnifiedVoiceChangerNode" + }, + "widgets_values": [ + 1, + 30, + "smart" + ], + "title": "Voice Changer — one speaker for the whole reel" } ], "links": [ @@ -1725,20 +1851,44 @@ "FLOAT" ], [ - 39, + 40, + 50, + 0, + 51, + 0, + "VIDEO" + ], + [ + 61, 46, 0, - 50, + 62, + 1, + "AUDIO" + ], + [ + 62, + 60, + 0, + 62, 2, "AUDIO" ], [ - 40, - 50, + 63, + 61, 0, - 51, + 62, 0, - "VIDEO" + "TTS_ENGINE" + ], + [ + 64, + 62, + 0, + 50, + 2, + "AUDIO" ] ], "groups": [], From 989a93ab01b6795e9306e4e1973195249ed392f6 Mon Sep 17 00:00:00 2001 From: Denis <61563365+dnsi0@users.noreply.github.com> Date: Thu, 6 Aug 2026 15:42:28 +0300 Subject: [PATCH 11/29] update ugc product template to include new fields necessary on dashboard --- docs/serviceTemplates/README.md | 23 ++++++++- .../ltx-video-ugc-product.json | 36 ++++++++++++++ src/@types/C2D/ServiceOnDemand.ts | 32 +++++++++++++ src/utils/config/schemas.ts | 47 ++++++++++++++++++- 4 files changed, 136 insertions(+), 2 deletions(-) diff --git a/docs/serviceTemplates/README.md b/docs/serviceTemplates/README.md index 87b2e6455..854e8cae3 100644 --- a/docs/serviceTemplates/README.md +++ b/docs/serviceTemplates/README.md @@ -30,10 +30,31 @@ Templates are validated against `ServiceTemplateSchema` | `command` / `entrypoint` | Docker CMD / ENTRYPOINT overrides | | `commandFile` | Path to a script, resolved relative to this directory and inlined as `command[0]` at load time (mutually exclusive with `command`) | | `envVars` | Fixed operator-set env vars (values never returned to callers) | -| `userConfigurableEnvVars` | Env vars the consumer supplies via ECIES-encrypted `userData` (optional regex `validation`, `sensitive` UI hint) | +| `userConfigurableEnvVars` | Env vars the consumer supplies via ECIES-encrypted `userData` (optional regex `validation`, `sensitive` UI hint, `required` hint — advisory, never enforced node-side) | | `requiredResources` / `recommendedResources` | Gate/score environment selection (`min` is enforced at `SERVICE_START`) | | `workflows` | Selectable graphs for UI-driven templates; each entry is `id` / `name` / `file` (a path to the graph JSON, resolved relative to this directory and inlined into `graph` at load time) | +### Catalogue metadata (services vs bundles) + +Optional, purely descriptive fields. They change nothing about how the container runs — +they travel to clients through the `getServiceTemplates` sanitizer and only affect how the +entry is presented in a catalogue. A template that omits all of them is a plain **service**. + +| Field | Meaning | +| ---------- | ---------------------------------------------------------------------------------------------------------------- | +| `kind` | `service` (bare app, the default when absent) or `bundle` (the same app whose command pre-downloads a curated model set) | +| `service` | Bundles only, **required on them**: `id` of the service template this is a variant of (may not exist on this node) | +| `outcome` | Bundles only: the one concrete thing this gets done, one sentence | +| `category` | One of `image` / `video` / `llm` / `serving` / `notebook` / `embeddings` / `app` | +| `includes` | Bundles only: manifest of what the command downloads — `name`, `kind` (`model` / `workflow` / `customnode` / `other`), optional `sizeGb`, `repoId`, `url`. Display metadata; nothing here is fetched or verified by the node | + +Keep `includes` in step with what the script actually downloads: clients use its length as +the denominator for a "preparing models — N of M" progress line, driven by `[models]` +markers on the container's stdout (`downloading ` / `ready: ` / +`already present: ` / `WARNING: could not download ` / `bundle complete`). The +markers are a convention, not a protocol — a script that prints none simply shows no +progress. + ## Templates in this folder ### `vllm-hf-model.json` — vLLM, any Hugging Face model (GPU) diff --git a/docs/serviceTemplates/ltx-video-ugc-product.json b/docs/serviceTemplates/ltx-video-ugc-product.json index b8367a324..535e537de 100644 --- a/docs/serviceTemplates/ltx-video-ugc-product.json +++ b/docs/serviceTemplates/ltx-video-ugc-product.json @@ -2,6 +2,42 @@ "id": "ltx-video-ugc-product", "name": "ComfyUI — UGC product video (LTX-2.3)", "description": "ComfyUI preloaded with LTX-2.3 for vertical short-form product video: a product photo becomes a 9:16 clip with camera motion and ambient audio, capped at the graph's 5 seconds (126 frames at 25 fps). Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the 38 GiB of weights download once and are reused, and generated clips land in the bucket root. Needs a CUDA GPU with 48 GB+ VRAM.", + "kind": "bundle", + "service": "comfyui", + "outcome": "Turn a product photo into a 9:16 clip with camera motion and ambient audio.", + "category": "video", + "includes": [ + { + "name": "LTX-2.3 22B dev (fp8)", + "kind": "model", + "sizeGb": 29.2, + "repoId": "Lightricks/LTX-2.3-fp8" + }, + { + "name": "Gemma-3-12B-it text encoder (fp4 mixed)", + "kind": "model", + "sizeGb": 9.5, + "repoId": "Comfy-Org/ltx-2" + }, + { + "name": "LTX-2.3 22B distilled LoRA (rank 111)", + "kind": "model", + "sizeGb": 2.7, + "repoId": "Comfy-Org/ltx-2.3" + }, + { + "name": "LTX-2.3 spatial upscaler x2", + "kind": "model", + "sizeGb": 1.0, + "repoId": "Lightricks/LTX-2.3" + }, + { + "name": "Gemma-3-12B-it abliterated LoRA (rank 64)", + "kind": "model", + "sizeGb": 0.6, + "repoId": "Comfy-Org/ltx-2" + } + ], "image": "yanwk/comfyui-boot", "tag": "cu130-megapak-pt211-20260803", "exposedPorts": [ diff --git a/src/@types/C2D/ServiceOnDemand.ts b/src/@types/C2D/ServiceOnDemand.ts index 1d866c3de..fbb97477e 100644 --- a/src/@types/C2D/ServiceOnDemand.ts +++ b/src/@types/C2D/ServiceOnDemand.ts @@ -20,6 +20,32 @@ export interface UserConfigurableEnvVar { key: string // env var name, passed in userData validation?: string // optional regex; validated at SERVICE_START time sensitive?: boolean // advisory hint for clients/UI (e.g. mask on input). The node receives ALL userData ECIES-encrypted, so this does not change node-side storage. + required?: boolean // advisory hint: the app cannot do its job without it (e.g. HF_TOKEN for a gated model). Not enforced node-side. +} + +// ── Catalogue classification (advisory; consumed by UIs) ─────────────── + +// How an entry presents itself. Absent means 'service' — every template published before this field. +export type ServiceTemplateKind = 'service' | 'bundle' + +// Closed set so catalogue buckets stay consistent across nodes. +export type ServiceTemplateCategory = + | 'image' + | 'video' + | 'llm' + | 'serving' + | 'notebook' + | 'embeddings' + | 'app' + +// One thing a bundle pre-downloads. Display metadata only: the template's own +// `command`/`commandFile` does the fetching, and nothing here is verified node-side. +export interface TemplateIncludedItem { + name: string + kind: 'model' | 'workflow' | 'customnode' | 'other' + sizeGb?: number // download size — drives the "N models, X GB" line and setup-time hints + repoId?: string // Hugging Face repo id, when the item is a plain HF repo + url?: string // direct download URL for anything that isn't a plain HF repo } export interface ServiceTemplateWorkflow { @@ -34,6 +60,12 @@ export interface ServiceTemplate { id: string // [a-z0-9][a-z0-9_-]{0,63} name?: string description?: string + // ── Catalogue metadata — advisory, never affects how the container runs ── + kind?: ServiceTemplateKind // default 'service' + service?: string // bundles only: id of the service template this is a variant of + outcome?: string // bundles only: the one concrete thing this gets done + category?: ServiceTemplateCategory + includes?: TemplateIncludedItem[] // bundles only: manifest of what the command downloads // Image specification — exactly one of (tag | checksum | dockerfile) must be set: image: string // base image name tag?: string // e.g. "latest" — mutually exclusive with checksum/dockerfile diff --git a/src/utils/config/schemas.ts b/src/utils/config/schemas.ts index f6df2c071..1ab45376a 100644 --- a/src/utils/config/schemas.ts +++ b/src/utils/config/schemas.ts @@ -339,7 +339,22 @@ const UserConfigurableEnvVarSchema = z .object({ key: z.string().min(1), validation: z.string().optional(), - sensitive: z.boolean().optional() + sensitive: z.boolean().optional(), + // Advisory only — the node never rejects a start for a missing value; clients use it to + // decide whether to prompt (e.g. HF_TOKEN for a gated model). + required: z.boolean().optional() + }) + .strict() + +// Catalogue classification. Purely descriptive: none of it changes how the container runs, +// it travels to clients through the sanitizer and drives how the entry is presented. +const TemplateIncludedItemSchema = z + .object({ + name: z.string().min(1), + kind: z.enum(['model', 'workflow', 'customnode', 'other']), + sizeGb: z.number().positive().optional(), + repoId: z.string().min(1).optional(), + url: z.string().url().optional() }) .strict() @@ -365,6 +380,19 @@ export const ServiceTemplateSchema = z }), name: z.string().optional(), description: z.string().optional(), + // Catalogue metadata (all optional; absent `kind` means 'service') + kind: z.enum(['service', 'bundle']).optional(), + service: z + .string() + .regex(/^[a-z0-9][a-z0-9_-]{0,63}$/, { + message: '"service" must be a template id matching [a-z0-9][a-z0-9_-]{0,63}' + }) + .optional(), + outcome: z.string().min(1).optional(), + category: z + .enum(['image', 'video', 'llm', 'serving', 'notebook', 'embeddings', 'app']) + .optional(), + includes: z.array(TemplateIncludedItemSchema).optional(), image: z.string().min(1), tag: z.string().min(1).optional(), checksum: z @@ -430,6 +458,23 @@ export const ServiceTemplateSchema = z }) } + // A bundle without a parent id renders as a plain service in clients (they key the + // grouping off `service`), so a half-declared bundle is a template bug, not a variant. + if (tmpl.kind === 'bundle' && !tmpl.service) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: '"service" (the parent template id) is required when kind is "bundle"', + path: ['service'] + }) + } + if (tmpl.service && tmpl.kind !== 'bundle') { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: '"service" only applies to a bundle — set kind: "bundle" or drop it', + path: ['service'] + }) + } + if (tmpl.command && tmpl.commandFile) { ctx.addIssue({ code: z.ZodIssueCode.custom, From 6e87150e9baad2dbb0b967caaaf9dd74cc1b7ca2 Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Thu, 6 Aug 2026 15:44:30 +0300 Subject: [PATCH 12/29] concat voices too --- .../ltx-video-ugc-multishot.json | 4 +-- .../workflows/ocean_ugc_assemble.json | 31 +++++++++---------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/docs/serviceTemplates/ltx-video-ugc-multishot.json b/docs/serviceTemplates/ltx-video-ugc-multishot.json index 64a50c3a2..7e6a897ef 100644 --- a/docs/serviceTemplates/ltx-video-ugc-multishot.json +++ b/docs/serviceTemplates/ltx-video-ugc-multishot.json @@ -1,7 +1,7 @@ { "id": "ltx-video-ugc-multishot", "name": "ComfyUI — UGC multishot reel (LTX-2.3)", - "description": "ComfyUI preloaded with LTX-2.3 for a vertical UGC reel built one shot at a time, with the same character in every shot. It runs the same two-stage generator as the product-video template (22B dev fp8, base pass then a spatial-upscaler refine pass), so shot quality matches. Usage: optionally upload a character photo as the first frame — with no photo you turn on 'No character image' and the style prompt builds the character instead. Then fill two text boxes: 'Style — every shot' holds everything that must stay identical (who the character is, wardrobe, room, lighting, palette, camera look) and you never touch it again; 'Scene — this shot' holds only what changes (action, camera move, dialogue, ambient sound). Click Run for a clip, edit the scene box, Run again. Every run also saves that clip's last frame beside it as lastframe_….png, so you chain the next shot by picking it as the first frame — shot 2 then starts exactly where shot 1 ended and identity carries in pixels rather than in prose, the trick that holds a multi-shot reel together. Clips are 9:16 vertical (720×1280) at 5 seconds each (126 frames at 25 fps) with audio, saved to the bucket root; ComfyUI's save counter never overwrites, so re-takes accumulate and you pick the good ones later. Once every shot is good, switch to the Assemble reel workflow to concatenate up to 8 of them into one clip inside ComfyUI — no external editor needed. The assemble workflow keeps each clip's own audio and runs it through a voice-conversion node: LTX re-rolls the speaker on every clip, so the stitched track would otherwise change voice at each cut. Upload a few seconds of clean speech as the reference voice and every line is converted to that one speaker, with words, timing and room tone untouched — so the picture stays in sync and the lips still match. The node pack is not in the image; the bootstrap clones it and installs its dependencies on launch, but only when the graph actually uses it, so the first launch of this template is slower and the product template is unaffected. Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the 38 GiB of weights download once and are reused, and the numbered shot clips land in the bucket root where the storage API's listFiles can see them. Needs a CUDA GPU with 48 GB+ VRAM.", + "description": "ComfyUI preloaded with LTX-2.3 for a vertical UGC reel built one shot at a time, with the same character in every shot. It runs the same two-stage generator as the product-video template (22B dev fp8, base pass then a spatial-upscaler refine pass), so shot quality matches. Usage: optionally upload a character photo as the first frame — with no photo you turn on 'No character image' and the style prompt builds the character instead. Then fill two text boxes: 'Style — every shot' holds everything that must stay identical (who the character is, wardrobe, room, lighting, palette, camera look) and you never touch it again; 'Scene — this shot' holds only what changes (action, camera move, dialogue, ambient sound). Click Run for a clip, edit the scene box, Run again. Every run also saves that clip's last frame beside it as lastframe_….png, so you chain the next shot by picking it as the first frame — shot 2 then starts exactly where shot 1 ended and identity carries in pixels rather than in prose, the trick that holds a multi-shot reel together. Clips are 9:16 vertical (720×1280) at 5 seconds each (126 frames at 25 fps) with audio, saved to the bucket root; ComfyUI's save counter never overwrites, so re-takes accumulate and you pick the good ones later. Once every shot is good, switch to the Assemble reel workflow to concatenate up to 8 of them into one clip inside ComfyUI — no external editor needed. The assemble workflow keeps each clip's own audio and runs it through a voice-conversion node: LTX re-rolls the speaker on every clip, so the stitched track would otherwise change voice at each cut. It takes the reference voice from Shot 1's own audio — nothing to upload and nothing to type, since this is speech-to-speech rather than transcription — and converts every line to that one speaker, with words, timing and room tone untouched — so the picture stays in sync and the lips still match. The node pack is not in the image; the bootstrap clones it and installs its dependencies on launch, but only when the graph actually uses it, so the first launch of this template is slower and the product template is unaffected. Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the 38 GiB of weights download once and are reused, and the numbered shot clips land in the bucket root where the storage API's listFiles can see them. Needs a CUDA GPU with 48 GB+ VRAM.", "image": "yanwk/comfyui-boot", "tag": "cu130-megapak-pt211-20260803", "exposedPorts": [ @@ -22,7 +22,7 @@ { "id": "ocean_ugc_assemble", "name": "Assemble reel", - "description": "Concatenates up to 8 rendered shot clips (video + audio) into a single reel using core ComfyUI video nodes, then converts every voice in the stitched track to one reference speaker so the reel does not change voice at each cut — pick clips in the LoadVideo dropdowns, bypass any slots you don't need, upload a reference voice, and Run.", + "description": "Concatenates up to 8 rendered shot clips (video + audio) into a single reel using core ComfyUI video nodes, then converts every voice in the stitched track to Shot 1's voice so the reel does not change speaker at each cut — pick clips in the LoadVideo dropdowns, bypass any slots you don't need, and Run. No upload and no script: it reads the reference voice straight off the clips you already rendered.", "file": "workflows/ocean_ugc_assemble.json" } ], diff --git a/docs/serviceTemplates/workflows/ocean_ugc_assemble.json b/docs/serviceTemplates/workflows/ocean_ugc_assemble.json index 54fa2b909..50e077f4b 100644 --- a/docs/serviceTemplates/workflows/ocean_ugc_assemble.json +++ b/docs/serviceTemplates/workflows/ocean_ugc_assemble.json @@ -2,7 +2,7 @@ "id": "f0a7b59b-e37f-4ce2-9564-e772ecd7d9c2", "revision": 0, "last_node_id": 62, - "last_link_id": 64, + "last_link_id": 65, "nodes": [ { "id": 1, @@ -22,7 +22,7 @@ "outputs": [], "properties": {}, "widgets_values": [ - "## Assemble reel\n\nPick a rendered `shot_…mp4` in each slot's **file** dropdown below (the dropdown lists what's been generated in the bucket — hit ComfyUI's refresh icon if a clip you just rendered isn't listed yet). The numbering is ComfyUI's own save counter, so re-takes never overwrite: just don't select the ones you didn't like.\n\n**Bypass (Ctrl+B) any slot you don't need.** The chain concatenates whichever slots stay active, in order, so an unused tail slot just needs bypassing — no rewiring.\n\nClick **Run** once. The stitched reel saves as `reel_00001…` in the bucket root.\n\n### Voice\n\nLTX generates each clip's audio from scratch — there is no speaker to carry across a cut — so the stitched track changes voice every 5 seconds. **Voice Changer** fixes that: it converts every line to one target speaker while leaving the words, the timing and the room tone alone, so the picture stays in sync and the lips still match.\n\nUpload a few seconds of clean speech in **Reference voice** — that is the voice the whole reel ends up in. Anything works: your own recording, a clip you like, or one shot's audio you thought sounded right.\n\n- *refinement_passes* — 1 is usually right. Raise it if the conversion sounds half-applied; above ~5 it distorts.\n- *max_chunk_duration* — chunks long audio to avoid running out of VRAM, then rejoins preserving timing. Leave at 30.\n\n**If the Voice Changer and Voice engine nodes show up red**, their node pack failed to install on launch (check the container log for `[ocean]`). Delete both, then drag the last **Audio Concat**'s output onto **Create reel**'s `audio` input — you are back to the raw stitched audio and everything else still works.\n\nOnly 8 slots: each 5 s clip is ~126 frames at 720×1280 in float32, about 1.4 GB as a tensor. 8 slots gives a ~40 s reel and stays comfortably inside this template's 128 GB." + "## Assemble reel\n\nPick a rendered `shot_…mp4` in each slot's **file** dropdown below (the dropdown lists what's been generated in the bucket — hit ComfyUI's refresh icon if a clip you just rendered isn't listed yet). The numbering is ComfyUI's own save counter, so re-takes never overwrite: just don't select the ones you didn't like.\n\n**Bypass (Ctrl+B) any slot you don't need.** The chain concatenates whichever slots stay active, in order, so an unused tail slot just needs bypassing — no rewiring.\n\nClick **Run** once. The stitched reel saves as `reel_00001…` in the bucket root.\n\n### Voice — nothing to upload, nothing to type\n\nLTX generates each clip's audio from scratch, so the stitched track changes speaker every 5 seconds. **Voice Changer** converts the whole track to a single voice — and it takes that voice from **Shot 1's own audio**, which is already in the graph.\n\nThis is speech-to-speech, not transcription: the words, their timing and the room tone are left exactly as they are, only the speaker identity is remapped. Nothing is re-read, nothing is retyped, and because no phoneme moves, the picture stays in sync and the lips still match.\n\n**Want a different voice?** Drag any other shot's **Get Video Components** `audio` output onto Voice Changer's `narrator_target` — that shot's voice becomes the reel's. Or upload a clean sample in **Reference voice override** and drag that in instead. A shot with clear speech and little background makes the best reference; a shot with no speech at all makes a poor one, so if Shot 1 is a silent product beauty shot, point this at a talking shot instead.\n\n- *refinement_passes* — 1 is usually right. Raise it if the conversion sounds half-applied; above ~5 it distorts.\n- *max_chunk_duration* — bounds VRAM on long audio, rejoining chunks with timing preserved. Leave at 30.\n\n**If the Voice Changer and Voice engine nodes show up red**, their node pack failed to install on launch (check the container log for `[ocean]`). Delete both, then drag the last **Audio Concat**'s output onto **Create reel**'s `audio` input — you are back to the raw stitched audio and everything else still works.\n\nOnly 8 slots: each 5 s clip is ~126 frames at 720×1280 in float32, about 1.4 GB as a tensor. 8 slots gives a ~40 s reel and stays comfortably inside this template's 128 GB." ], "title": "How to use" }, @@ -92,7 +92,8 @@ "name": "audio", "type": "AUDIO", "links": [ - 23 + 23, + 65 ] }, { @@ -1437,9 +1438,7 @@ { "name": "AUDIO", "type": "AUDIO", - "links": [ - 62 - ] + "links": null } ], "properties": { @@ -1450,7 +1449,7 @@ null, null ], - "title": "Reference voice — every line is converted to this" + "title": "Reference voice override (optional — not wired)" }, { "id": 61, @@ -1517,7 +1516,7 @@ { "name": "narrator_target", "type": "AUDIO", - "link": 62 + "link": 65 } ], "outputs": [ @@ -1866,14 +1865,6 @@ 1, "AUDIO" ], - [ - 62, - 60, - 0, - 62, - 2, - "AUDIO" - ], [ 63, 61, @@ -1889,6 +1880,14 @@ 50, 2, "AUDIO" + ], + [ + 65, + 20, + 1, + 62, + 2, + "AUDIO" ] ], "groups": [], From 434f22132942489eaa2308cbbe9d6a29da30c307 Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Fri, 7 Aug 2026 11:29:18 +0300 Subject: [PATCH 13/29] install missing services --- .../ltx-video-ugc-bootstrap.sh | 7 +- .../ltx-video-ugc-multishot.json | 45 ++- .../workflows/ocean_ugc_assemble.json | 265 ++++++++++++------ 3 files changed, 233 insertions(+), 84 deletions(-) diff --git a/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh b/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh index ab7e3755a..d49c32822 100755 --- a/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh +++ b/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh @@ -204,8 +204,11 @@ if [ -n "${PACK:-}" ] && grep -qls UnifiedVoiceChangerNode "$PACK"/example_workf elif [ -d "$VC_DIR/.git" ] || git clone --depth 1 \ https://github.com/diodiogod/TTS-Audio-Suite.git "$VC_DIR"; then echo "[ocean] installing voice-conversion dependencies (first launch is slow)" - python3.13 -m pip install --no-input --disable-pip-version-check \ - -r "$VC_DIR/requirements.txt" || + # install.py, not `pip install -r requirements.txt`: that file deliberately omits librosa + # and descript-audio-codec, which install.py adds with --no-deps so pip cannot downgrade + # numpy/torch under ComfyUI. Installing the requirements alone leaves ChatterboxVC + # unimportable ("ChatterboxVC not available - check installation"). + ( cd "$VC_DIR" && python3.13 install.py ) || echo "[ocean] voice-conversion dependencies failed to install — the Voice Changer node" \ "will be missing; delete it in the assemble workflow and wire Audio Concat straight" \ "into Create reel" >&2 diff --git a/docs/serviceTemplates/ltx-video-ugc-multishot.json b/docs/serviceTemplates/ltx-video-ugc-multishot.json index 7e6a897ef..d57a6b85f 100644 --- a/docs/serviceTemplates/ltx-video-ugc-multishot.json +++ b/docs/serviceTemplates/ltx-video-ugc-multishot.json @@ -2,6 +2,47 @@ "id": "ltx-video-ugc-multishot", "name": "ComfyUI — UGC multishot reel (LTX-2.3)", "description": "ComfyUI preloaded with LTX-2.3 for a vertical UGC reel built one shot at a time, with the same character in every shot. It runs the same two-stage generator as the product-video template (22B dev fp8, base pass then a spatial-upscaler refine pass), so shot quality matches. Usage: optionally upload a character photo as the first frame — with no photo you turn on 'No character image' and the style prompt builds the character instead. Then fill two text boxes: 'Style — every shot' holds everything that must stay identical (who the character is, wardrobe, room, lighting, palette, camera look) and you never touch it again; 'Scene — this shot' holds only what changes (action, camera move, dialogue, ambient sound). Click Run for a clip, edit the scene box, Run again. Every run also saves that clip's last frame beside it as lastframe_….png, so you chain the next shot by picking it as the first frame — shot 2 then starts exactly where shot 1 ended and identity carries in pixels rather than in prose, the trick that holds a multi-shot reel together. Clips are 9:16 vertical (720×1280) at 5 seconds each (126 frames at 25 fps) with audio, saved to the bucket root; ComfyUI's save counter never overwrites, so re-takes accumulate and you pick the good ones later. Once every shot is good, switch to the Assemble reel workflow to concatenate up to 8 of them into one clip inside ComfyUI — no external editor needed. The assemble workflow keeps each clip's own audio and runs it through a voice-conversion node: LTX re-rolls the speaker on every clip, so the stitched track would otherwise change voice at each cut. It takes the reference voice from Shot 1's own audio — nothing to upload and nothing to type, since this is speech-to-speech rather than transcription — and converts every line to that one speaker, with words, timing and room tone untouched — so the picture stays in sync and the lips still match. The node pack is not in the image; the bootstrap clones it and installs its dependencies on launch, but only when the graph actually uses it, so the first launch of this template is slower and the product template is unaffected. Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the 38 GiB of weights download once and are reused, and the numbered shot clips land in the bucket root where the storage API's listFiles can see them. Needs a CUDA GPU with 48 GB+ VRAM.", + "kind": "bundle", + "service": "comfyui", + "outcome": "Build a multi-shot 9:16 UGC reel with one character and one voice throughout.", + "category": "video", + "includes": [ + { + "name": "LTX-2.3 22B dev (fp8)", + "kind": "model", + "sizeGb": 29.2, + "repoId": "Lightricks/LTX-2.3-fp8" + }, + { + "name": "Gemma-3-12B-it text encoder (fp4 mixed)", + "kind": "model", + "sizeGb": 9.5, + "repoId": "Comfy-Org/ltx-2" + }, + { + "name": "LTX-2.3 22B distilled LoRA (rank 111)", + "kind": "model", + "sizeGb": 2.7, + "repoId": "Comfy-Org/ltx-2.3" + }, + { + "name": "LTX-2.3 spatial upscaler x2", + "kind": "model", + "sizeGb": 1.0, + "repoId": "Lightricks/LTX-2.3" + }, + { + "name": "Gemma-3-12B-it abliterated LoRA (rank 64)", + "kind": "model", + "sizeGb": 0.6, + "repoId": "Comfy-Org/ltx-2" + }, + { + "name": "TTS-Audio-Suite (voice conversion for the assemble workflow)", + "kind": "customnode", + "url": "https://github.com/diodiogod/TTS-Audio-Suite" + } + ], "image": "yanwk/comfyui-boot", "tag": "cu130-megapak-pt211-20260803", "exposedPorts": [ @@ -50,8 +91,8 @@ }, { "id": "disk", - "min": 40, - "recommended": 80, + "min": 45, + "recommended": 85, "unit": "GB" }, { diff --git a/docs/serviceTemplates/workflows/ocean_ugc_assemble.json b/docs/serviceTemplates/workflows/ocean_ugc_assemble.json index 50e077f4b..c41c9a09d 100644 --- a/docs/serviceTemplates/workflows/ocean_ugc_assemble.json +++ b/docs/serviceTemplates/workflows/ocean_ugc_assemble.json @@ -8,12 +8,12 @@ "id": 1, "type": "MarkdownNote", "pos": [ - -2000.0, + -1000.0, 0.0 ], "size": [ - 1600, - 260 + 900, + 760 ], "flags": {}, "order": 0, @@ -22,7 +22,7 @@ "outputs": [], "properties": {}, "widgets_values": [ - "## Assemble reel\n\nPick a rendered `shot_…mp4` in each slot's **file** dropdown below (the dropdown lists what's been generated in the bucket — hit ComfyUI's refresh icon if a clip you just rendered isn't listed yet). The numbering is ComfyUI's own save counter, so re-takes never overwrite: just don't select the ones you didn't like.\n\n**Bypass (Ctrl+B) any slot you don't need.** The chain concatenates whichever slots stay active, in order, so an unused tail slot just needs bypassing — no rewiring.\n\nClick **Run** once. The stitched reel saves as `reel_00001…` in the bucket root.\n\n### Voice — nothing to upload, nothing to type\n\nLTX generates each clip's audio from scratch, so the stitched track changes speaker every 5 seconds. **Voice Changer** converts the whole track to a single voice — and it takes that voice from **Shot 1's own audio**, which is already in the graph.\n\nThis is speech-to-speech, not transcription: the words, their timing and the room tone are left exactly as they are, only the speaker identity is remapped. Nothing is re-read, nothing is retyped, and because no phoneme moves, the picture stays in sync and the lips still match.\n\n**Want a different voice?** Drag any other shot's **Get Video Components** `audio` output onto Voice Changer's `narrator_target` — that shot's voice becomes the reel's. Or upload a clean sample in **Reference voice override** and drag that in instead. A shot with clear speech and little background makes the best reference; a shot with no speech at all makes a poor one, so if Shot 1 is a silent product beauty shot, point this at a talking shot instead.\n\n- *refinement_passes* — 1 is usually right. Raise it if the conversion sounds half-applied; above ~5 it distorts.\n- *max_chunk_duration* — bounds VRAM on long audio, rejoining chunks with timing preserved. Leave at 30.\n\n**If the Voice Changer and Voice engine nodes show up red**, their node pack failed to install on launch (check the container log for `[ocean]`). Delete both, then drag the last **Audio Concat**'s output onto **Create reel**'s `audio` input — you are back to the raw stitched audio and everything else still works.\n\nOnly 8 slots: each 5 s clip is ~126 frames at 720×1280 in float32, about 1.4 GB as a tensor. 8 slots gives a ~40 s reel and stays comfortably inside this template's 128 GB." + "## Assemble reel\n\nEach **Shot** group is one slot: pick a rendered `shot_…mp4` in its **file** dropdown. The dropdown lists what is in the bucket — hit ComfyUI's refresh icon if a clip you just rendered is not there yet. Re-takes never overwrite, so just don't select the ones you didn't like.\n\n### Using fewer than 8 shots\n\nRight-click the group → **Bypass Group Nodes**. Do this for every shot slot you are not using.\n\nBypassing only the *Load Video* node is not enough — the Image Batch and Audio Concat in that row still demand a second input and the run fails validation with `Required input is missing: image2`. That is why each row is grouped: bypassing the group takes out all four nodes at once, and the batch/concat nodes then pass their first input straight through, so the chain closes over the gap.\n\n**Shot 1 cannot be bypassed.** It heads both chains and supplies the reference voice.\n\nClick **Run** once. The reel saves as `reel_00001…` in the bucket root.\n\n### Voice — nothing to upload, nothing to type\n\nLTX generates each clip's audio from scratch, so the stitched track changes speaker every 5 seconds. **Voice Changer** converts the whole track to a single voice, taken from **Shot 1's own audio** — already in the graph.\n\nThis is speech-to-speech, not transcription: words, timing and room tone are left exactly as they are and only speaker identity is remapped. Nothing is re-read, nothing is retyped, and because no phoneme moves, the picture stays in sync and the lips still match.\n\n**A different voice?** Drag any other shot's **Get Video Components** `audio` output onto Voice Changer's `narrator_target`. Or upload a clean sample in **Reference voice override** and drag that in. Pick a shot with clear speech — a silent product shot makes a poor reference.\n\n- *refinement_passes* — 1 is usually right. Raise it if the conversion sounds half-applied; above ~5 it distorts.\n- *max_chunk_duration* — bounds VRAM on long audio, rejoining chunks with timing preserved. Leave at 30.\n\n**If Voice Changer / Voice engine load red or throw `ChatterboxVC not available`**, the node pack failed to install on launch — check the container log for `[ocean]`. Delete both nodes, then drag the last **Audio Concat** onto **Create reel**'s `audio` input: raw stitched audio, everything else unaffected." ], "title": "How to use" }, @@ -34,8 +34,8 @@ 0.0 ], "size": [ - 270, - 100 + 340, + 380 ], "flags": {}, "order": 1, @@ -63,7 +63,7 @@ "id": 20, "type": "GetVideoComponents", "pos": [ - 350.0, + 400.0, 0.0 ], "size": [ @@ -120,11 +120,11 @@ "type": "LoadVideo", "pos": [ 0.0, - 150.0 + 480.0 ], "size": [ - 270, - 100 + 340, + 380 ], "flags": {}, "order": 3, @@ -152,8 +152,8 @@ "id": 21, "type": "GetVideoComponents", "pos": [ - 350.0, - 150.0 + 400.0, + 480.0 ], "size": [ 270, @@ -206,11 +206,11 @@ "type": "LoadVideo", "pos": [ 0.0, - 300.0 + 960.0 ], "size": [ - 270, - 100 + 340, + 380 ], "flags": {}, "order": 5, @@ -238,8 +238,8 @@ "id": 22, "type": "GetVideoComponents", "pos": [ - 350.0, - 300.0 + 400.0, + 960.0 ], "size": [ 270, @@ -292,11 +292,11 @@ "type": "LoadVideo", "pos": [ 0.0, - 450.0 + 1440.0 ], "size": [ - 270, - 100 + 340, + 380 ], "flags": {}, "order": 7, @@ -324,8 +324,8 @@ "id": 23, "type": "GetVideoComponents", "pos": [ - 350.0, - 450.0 + 400.0, + 1440.0 ], "size": [ 270, @@ -378,11 +378,11 @@ "type": "LoadVideo", "pos": [ 0.0, - 600.0 + 1920.0 ], "size": [ - 270, - 100 + 340, + 380 ], "flags": {}, "order": 9, @@ -410,8 +410,8 @@ "id": 24, "type": "GetVideoComponents", "pos": [ - 350.0, - 600.0 + 400.0, + 1920.0 ], "size": [ 270, @@ -464,11 +464,11 @@ "type": "LoadVideo", "pos": [ 0.0, - 750.0 + 2400.0 ], "size": [ - 270, - 100 + 340, + 380 ], "flags": {}, "order": 11, @@ -496,8 +496,8 @@ "id": 25, "type": "GetVideoComponents", "pos": [ - 350.0, - 750.0 + 400.0, + 2400.0 ], "size": [ 270, @@ -550,11 +550,11 @@ "type": "LoadVideo", "pos": [ 0.0, - 900.0 + 2880.0 ], "size": [ - 270, - 100 + 340, + 380 ], "flags": {}, "order": 13, @@ -582,8 +582,8 @@ "id": 26, "type": "GetVideoComponents", "pos": [ - 350.0, - 900.0 + 400.0, + 2880.0 ], "size": [ 270, @@ -636,11 +636,11 @@ "type": "LoadVideo", "pos": [ 0.0, - 1050.0 + 3360.0 ], "size": [ - 270, - 100 + 340, + 380 ], "flags": {}, "order": 15, @@ -668,8 +668,8 @@ "id": 27, "type": "GetVideoComponents", "pos": [ - 350.0, - 1050.0 + 400.0, + 3360.0 ], "size": [ 270, @@ -721,8 +721,8 @@ "id": 30, "type": "ImageBatch", "pos": [ - 760.0, - 260.0 + 740.0, + 480.0 ], "size": [ 210, @@ -763,8 +763,8 @@ "id": 31, "type": "ImageBatch", "pos": [ - 950.0, - 260.0 + 740.0, + 960.0 ], "size": [ 210, @@ -805,8 +805,8 @@ "id": 32, "type": "ImageBatch", "pos": [ - 1140.0, - 260.0 + 740.0, + 1440.0 ], "size": [ 210, @@ -847,8 +847,8 @@ "id": 33, "type": "ImageBatch", "pos": [ - 1330.0, - 260.0 + 740.0, + 1920.0 ], "size": [ 210, @@ -889,8 +889,8 @@ "id": 34, "type": "ImageBatch", "pos": [ - 1520.0, - 260.0 + 740.0, + 2400.0 ], "size": [ 210, @@ -931,8 +931,8 @@ "id": 35, "type": "ImageBatch", "pos": [ - 1710.0, - 260.0 + 740.0, + 2880.0 ], "size": [ 210, @@ -973,8 +973,8 @@ "id": 36, "type": "ImageBatch", "pos": [ - 1900.0, - 260.0 + 740.0, + 3360.0 ], "size": [ 210, @@ -1015,7 +1015,7 @@ "id": 40, "type": "AudioConcat", "pos": [ - 760.0, + 990.0, 480.0 ], "size": [ @@ -1060,8 +1060,8 @@ "id": 41, "type": "AudioConcat", "pos": [ - 950.0, - 480.0 + 990.0, + 960.0 ], "size": [ 210, @@ -1105,8 +1105,8 @@ "id": 42, "type": "AudioConcat", "pos": [ - 1140.0, - 480.0 + 990.0, + 1440.0 ], "size": [ 210, @@ -1150,8 +1150,8 @@ "id": 43, "type": "AudioConcat", "pos": [ - 1330.0, - 480.0 + 990.0, + 1920.0 ], "size": [ 210, @@ -1195,8 +1195,8 @@ "id": 44, "type": "AudioConcat", "pos": [ - 1520.0, - 480.0 + 990.0, + 2400.0 ], "size": [ 210, @@ -1240,8 +1240,8 @@ "id": 45, "type": "AudioConcat", "pos": [ - 1710.0, - 480.0 + 990.0, + 2880.0 ], "size": [ 210, @@ -1285,8 +1285,8 @@ "id": 46, "type": "AudioConcat", "pos": [ - 1900.0, - 480.0 + 990.0, + 3360.0 ], "size": [ 210, @@ -1330,8 +1330,8 @@ "id": 50, "type": "CreateVideo", "pos": [ - 2180.0, - 350.0 + 1720.0, + 0.0 ], "size": [ 270, @@ -1384,8 +1384,8 @@ "id": 51, "type": "SaveVideo", "pos": [ - 2520.0, - 350.0 + 1720.0, + 210.0 ], "size": [ 400, @@ -1423,8 +1423,8 @@ "id": 60, "type": "LoadAudio", "pos": [ - 2180.0, - 560.0 + 1300.0, + 490.0 ], "size": [ 330, @@ -1455,8 +1455,8 @@ "id": 61, "type": "ChatterBoxEngineNode", "pos": [ - 2180.0, - 760.0 + 1300.0, + 0.0 ], "size": [ 340, @@ -1492,8 +1492,8 @@ "id": 62, "type": "UnifiedVoiceChangerNode", "pos": [ - 2560.0, - 560.0 + 1300.0, + 250.0 ], "size": [ 340, @@ -1890,7 +1890,112 @@ "AUDIO" ] ], - "groups": [], + "groups": [ + { + "id": 1, + "title": "Shot 1 — chain head, keep", + "bounding": [ + -20.0, + -50.0, + 1250.0, + 450.0 + ], + "color": "#88A", + "font_size": 24, + "flags": {} + }, + { + "id": 2, + "title": "Shot 2", + "bounding": [ + -20.0, + 430.0, + 1250.0, + 450.0 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "id": 3, + "title": "Shot 3", + "bounding": [ + -20.0, + 910.0, + 1250.0, + 450.0 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "id": 4, + "title": "Shot 4", + "bounding": [ + -20.0, + 1390.0, + 1250.0, + 450.0 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "id": 5, + "title": "Shot 5", + "bounding": [ + -20.0, + 1870.0, + 1250.0, + 450.0 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "id": 6, + "title": "Shot 6", + "bounding": [ + -20.0, + 2350.0, + 1250.0, + 450.0 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "id": 7, + "title": "Shot 7", + "bounding": [ + -20.0, + 2830.0, + 1250.0, + 450.0 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "id": 8, + "title": "Shot 8", + "bounding": [ + -20.0, + 3310.0, + 1250.0, + 450.0 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + } + ], "definitions": { "subgraphs": [] }, From 3fe722e7900bad2c02e5d8b6d26fed1a9197aab6 Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Fri, 7 Aug 2026 13:18:24 +0300 Subject: [PATCH 14/29] cut to new scene --- docs/serviceTemplates/README.md | 17 +- .../ltx-video-ugc-multishot.json | 4 +- .../workflows/ocean_ugc_multishot.json | 220 +++++++++++++++++- 3 files changed, 230 insertions(+), 11 deletions(-) diff --git a/docs/serviceTemplates/README.md b/docs/serviceTemplates/README.md index 854e8cae3..52f7a99a9 100644 --- a/docs/serviceTemplates/README.md +++ b/docs/serviceTemplates/README.md @@ -159,10 +159,21 @@ ComfyUI's own save counter — `shot_00001…`, `shot_00002…` — so re-takes you pick the good ones at assembly time. **Frame chaining.** Every run also drops that clip's last frame beside it as -`lastframe_…png`. Refresh, pick it in *First frame*, and the next shot starts exactly where +`lastframe_…png`. Refresh, pick it in the image slot, and the next shot starts exactly where the last one ended — identity carried in pixels rather than in prose, which is what the -reference-image tools rely on and what text-only character descriptions cannot do. Re-pick -the original photo instead whenever you want a hard cut to a new setup. +reference-image tools rely on and what text-only character descriptions cannot do. + +**Hard cuts.** The *Shot start* dial controls how literally that image is taken. It drives +the `strength` of both `LTXVImgToVideoInplace` passes, promoted out of the subgraph: the +refine pass directly, the base pass through `a * 0.7` so the dial at **1.0** reproduces the +strengths the graph shipped with (1.0 refine / 0.7 base) exactly. At **1.0** frame 0 *is* the +image and the take continues seamlessly. Around **0.35** the image only guides look and +character while the model composes a new frame — a hard cut to a new scene with the same +face and wardrobe. The separate *No character image* toggle still bypasses the image +entirely (`Switch to Text to Video?` inside the subgraph) for a shot built from the prompt +alone. + +Three ways to start a shot, then: continue it, cut to it, or generate it fresh. Mechanically: the generator subgraph exposes its decoded frames as a second `IMAGE` output alongside `VIDEO`; `GetImageSize` → `a - 1` → `ImageFromBatch` takes the final frame and diff --git a/docs/serviceTemplates/ltx-video-ugc-multishot.json b/docs/serviceTemplates/ltx-video-ugc-multishot.json index d57a6b85f..8e2bc9d22 100644 --- a/docs/serviceTemplates/ltx-video-ugc-multishot.json +++ b/docs/serviceTemplates/ltx-video-ugc-multishot.json @@ -1,7 +1,7 @@ { "id": "ltx-video-ugc-multishot", "name": "ComfyUI — UGC multishot reel (LTX-2.3)", - "description": "ComfyUI preloaded with LTX-2.3 for a vertical UGC reel built one shot at a time, with the same character in every shot. It runs the same two-stage generator as the product-video template (22B dev fp8, base pass then a spatial-upscaler refine pass), so shot quality matches. Usage: optionally upload a character photo as the first frame — with no photo you turn on 'No character image' and the style prompt builds the character instead. Then fill two text boxes: 'Style — every shot' holds everything that must stay identical (who the character is, wardrobe, room, lighting, palette, camera look) and you never touch it again; 'Scene — this shot' holds only what changes (action, camera move, dialogue, ambient sound). Click Run for a clip, edit the scene box, Run again. Every run also saves that clip's last frame beside it as lastframe_….png, so you chain the next shot by picking it as the first frame — shot 2 then starts exactly where shot 1 ended and identity carries in pixels rather than in prose, the trick that holds a multi-shot reel together. Clips are 9:16 vertical (720×1280) at 5 seconds each (126 frames at 25 fps) with audio, saved to the bucket root; ComfyUI's save counter never overwrites, so re-takes accumulate and you pick the good ones later. Once every shot is good, switch to the Assemble reel workflow to concatenate up to 8 of them into one clip inside ComfyUI — no external editor needed. The assemble workflow keeps each clip's own audio and runs it through a voice-conversion node: LTX re-rolls the speaker on every clip, so the stitched track would otherwise change voice at each cut. It takes the reference voice from Shot 1's own audio — nothing to upload and nothing to type, since this is speech-to-speech rather than transcription — and converts every line to that one speaker, with words, timing and room tone untouched — so the picture stays in sync and the lips still match. The node pack is not in the image; the bootstrap clones it and installs its dependencies on launch, but only when the graph actually uses it, so the first launch of this template is slower and the product template is unaffected. Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the 38 GiB of weights download once and are reused, and the numbered shot clips land in the bucket root where the storage API's listFiles can see them. Needs a CUDA GPU with 48 GB+ VRAM.", + "description": "ComfyUI preloaded with LTX-2.3 for a vertical UGC reel built one shot at a time, with the same character in every shot. It runs the same two-stage generator as the product-video template (22B dev fp8, base pass then a spatial-upscaler refine pass), so shot quality matches. Usage: optionally upload a character photo as the first frame — with no photo you turn on 'No character image' and the style prompt builds the character instead. Then fill two text boxes: 'Style — every shot' holds everything that must stay identical (who the character is, wardrobe, room, lighting, palette, camera look) and you never touch it again; 'Scene — this shot' holds only what changes (action, camera move, dialogue, ambient sound). Click Run for a clip, edit the scene box, Run again. Every run also saves that clip's last frame beside it as lastframe_….png, and a Shot start dial decides how it is used: at 1.0 it is frame 0 and the shot continues seamlessly, while around 0.35 it acts as a character reference only, so the model composes a new frame and you get a hard cut to a new scene with the same character. Chaining shots this way — shot 2 then starts exactly where shot 1 ended and identity carries in pixels rather than in prose, the trick that holds a multi-shot reel together. Clips are 9:16 vertical (720×1280) at 5 seconds each (126 frames at 25 fps) with audio, saved to the bucket root; ComfyUI's save counter never overwrites, so re-takes accumulate and you pick the good ones later. Once every shot is good, switch to the Assemble reel workflow to concatenate up to 8 of them into one clip inside ComfyUI — no external editor needed. The assemble workflow keeps each clip's own audio and runs it through a voice-conversion node: LTX re-rolls the speaker on every clip, so the stitched track would otherwise change voice at each cut. It takes the reference voice from Shot 1's own audio — nothing to upload and nothing to type, since this is speech-to-speech rather than transcription — and converts every line to that one speaker, with words, timing and room tone untouched — so the picture stays in sync and the lips still match. The node pack is not in the image; the bootstrap clones it and installs its dependencies on launch, but only when the graph actually uses it, so the first launch of this template is slower and the product template is unaffected. Select a persistent-storage bucket: it holds ComfyUI's whole base directory, so the 38 GiB of weights download once and are reused, and the numbered shot clips land in the bucket root where the storage API's listFiles can see them. Needs a CUDA GPU with 48 GB+ VRAM.", "kind": "bundle", "service": "comfyui", "outcome": "Build a multi-shot 9:16 UGC reel with one character and one voice throughout.", @@ -57,7 +57,7 @@ { "id": "ocean_ugc_multishot", "name": "Multishot reel — one shot per Run", - "description": "A first-frame image plus two prompt boxes — a style box reused by every shot and a scene box you retype between runs. One Run renders one 9:16 clip and saves its last frame as lastframe_….png; pick that as the next shot's first frame to chain shots together. With no character photo at all, the style prompt builds the character instead.", + "description": "An image input plus two prompt boxes — a style box reused by every shot and a scene box you retype between runs. One Run renders one 9:16 clip and saves its last frame as lastframe_….png. The Shot start dial decides whether that image continues the take seamlessly (1.0) or acts as a character reference for a hard cut to a new scene (~0.35). With no image at all, the style prompt builds the character instead.", "file": "workflows/ocean_ugc_multishot.json" }, { diff --git a/docs/serviceTemplates/workflows/ocean_ugc_multishot.json b/docs/serviceTemplates/workflows/ocean_ugc_multishot.json index 951ab6979..cefa72e02 100644 --- a/docs/serviceTemplates/workflows/ocean_ugc_multishot.json +++ b/docs/serviceTemplates/workflows/ocean_ugc_multishot.json @@ -1,8 +1,8 @@ { "id": "0112e9af-5129-48ba-af78-92c40ac40b40", "revision": 0, - "last_node_id": 742, - "last_link_id": 1909, + "last_node_id": 744, + "last_link_id": 1912, "nodes": [ { "id": 732, @@ -13,7 +13,7 @@ ], "size": [ 900, - 460 + 560 ], "flags": {}, "order": 0, @@ -23,7 +23,7 @@ "title": "How to use", "properties": {}, "widgets_values": [ - "## Multishot reel — one shot per Run\n\n**1.** Upload your creator photo in *First frame*. No photo? Turn on *No character image* and the style prompt builds them instead — describe them in detail so every shot matches.\n\n**2.** *Style — every shot* is the part you never touch again: who the character is, what they wear, the room, the light, the palette, the camera look. Keeping this identical is what keeps the reel consistent.\n\n**3.** *Scene — this shot* is the only box you edit between runs: the action, the camera move, what they say, the ambient sound.\n\n**4.** Run. Each clip lands in your bucket as `shot_…mp4`, and its **last frame is saved next to it** as `lastframe_…png` — automatically, every run.\n\n**5.** **Chain the next shot.** Hit the refresh icon, then pick that `lastframe_…png` in *First frame*. Shot 2 now starts exactly where shot 1 ended: same face, same wardrobe, same room, same light — carried by the pixels, not by the prompt. Edit the scene box, Run. Repeat.\n\nSkip the chaining and re-pick the original photo instead whenever you want a hard cut to a new setup — the style box still holds the look together.\n\n**6.** When you have every shot, switch to the **Assemble reel** workflow, pick the clips in its dropdowns, and Run.\n\n720×1280 · 5 s · 25 fps · with audio." + "## Multishot reel — one shot per Run\n\n**1.** *Style — every shot* is the part you never touch again: who the character is, what they wear, the room, the light, the palette, the camera look. Keeping this identical is what holds the reel together.\n\n**2.** *Scene — this shot* is the only box you edit between runs: the action, the camera move, what they say, the ambient sound.\n\n**3.** Run. Each clip lands in your bucket as `shot_…mp4`, and its **last frame is saved beside it** as `lastframe_…png`, automatically, every run.\n\n### How the next shot starts — the *Shot start* dial\n\n| Setting | What happens | Use it for |\n|---|---|---|\n| **1.0** | Frame 0 *is* the image. The shot continues seamlessly. | Staying in one continuous take |\n| **~0.35** | The image guides look and character, but the model composes a new frame. | **Hard cut to a new scene**, same character |\n| *No character image* ON | The image is ignored; everything comes from the style prompt. | Shot 1, or a deliberate fresh start |\n\nSo a **hard cut** is: pick a `lastframe_…png` of the character you want to keep, drop *Shot start* to about 0.35, and write the new scene. You get a new angle, new staging, new location — with the same face and wardrobe carried over. Push toward 0.5 if the character drifts; toward 0.25 if the old composition is still bleeding through.\n\nAt **1.0** the two sampler passes run at exactly the strengths this graph shipped with, so leaving the dial alone changes nothing.\n\n**4.** Repeat. Re-takes never overwrite, so bad ones are just skipped later.\n\n**5.** When every shot is good, switch to **Assemble reel**, pick the clips, and Run.\n\n720×1280 · 25 fps · with audio · duration is the *duration* widget on **Generate video**." ] }, { @@ -62,7 +62,7 @@ "subject-girl-holding-skincare-bottle.png", "image" ], - "title": "First frame — character photo, or the previous shot's lastframe_….png" + "title": "Image — first frame, or character reference on a hard cut" }, { "id": 725, @@ -333,6 +333,24 @@ "name": "value_6" }, "link": 1904 + }, + { + "label": "first_frame_strength", + "name": "value_7", + "type": "FLOAT", + "widget": { + "name": "value_7" + }, + "link": 1910 + }, + { + "label": "base_strength", + "name": "value_8", + "type": "FLOAT", + "widget": { + "name": "value_8" + }, + "link": 1912 } ], "outputs": [ @@ -405,6 +423,14 @@ [ "302", "value" + ], + [ + "288", + "strength" + ], + [ + "296", + "strength" ] ], "cnr_id": "comfy-core", @@ -673,6 +699,104 @@ "lastframe" ], "title": "Last frame → pick this in First frame for the next shot" + }, + { + "id": 743, + "type": "PrimitiveFloat", + "pos": [ + 820.0, + 1020.0 + ], + "size": [ + 320, + 90 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "FLOAT", + "type": "FLOAT", + "links": [ + 1910, + 1911 + ] + } + ], + "properties": { + "Node name for S&R": "PrimitiveFloat" + }, + "widgets_values": [ + 1.0 + ], + "title": "Shot start — 1.0 continue from image · 0.35 hard cut" + }, + { + "id": 744, + "type": "ComfyMathExpression", + "pos": [ + 820.0, + 1140.0 + ], + "size": [ + 225, + 8 + ], + "flags": { + "collapsed": true + }, + "order": 8, + "mode": 0, + "inputs": [ + { + "label": "a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 1911 + }, + { + "label": "b", + "name": "values.b", + "shape": 7, + "type": "FLOAT,INT,BOOLEAN", + "link": null + }, + { + "label": "c", + "name": "values.c", + "shape": 7, + "type": "FLOAT,INT,BOOLEAN", + "link": null + } + ], + "outputs": [ + { + "name": "FLOAT", + "type": "FLOAT", + "links": [ + 1912 + ] + }, + { + "name": "INT", + "type": "INT", + "links": null + }, + { + "name": "BOOL", + "type": "BOOLEAN", + "links": null + } + ], + "properties": { + "Node name for S&R": "ComfyMathExpression" + }, + "widgets_values": [ + "a * 0.7" + ], + "title": "Base pass strength" } ], "links": [ @@ -763,6 +887,30 @@ 742, 0, "IMAGE" + ], + [ + 1910, + 743, + 0, + 129, + 13, + "FLOAT" + ], + [ + 1911, + 743, + 0, + 744, + 0, + "FLOAT" + ], + [ + 1912, + 744, + 0, + 129, + 14, + "FLOAT" ] ], "groups": [], @@ -813,7 +961,7 @@ 6590, 4360, 128, - 88 + 128 ] }, "inputs": [ @@ -1000,6 +1148,32 @@ 876.162109375, 4394 ] + }, + { + "id": "1bd79e1f-321b-5084-bbb3-840859ae93c5", + "name": "value_7", + "type": "FLOAT", + "linkIds": [ + 649 + ], + "label": "first_frame_strength", + "pos": [ + 876.162109375, + 4414 + ] + }, + { + "id": "6110e041-ae6e-59fa-9b41-6c51aaeafe1a", + "name": "value_8", + "type": "FLOAT", + "linkIds": [ + 650 + ], + "label": "base_strength", + "pos": [ + 876.162109375, + 4434 + ] } ], "outputs": [ @@ -1804,6 +1978,15 @@ "name": "bypass" }, "link": 543 + }, + { + "localized_name": "strength", + "name": "strength", + "type": "FLOAT", + "widget": { + "name": "strength" + }, + "link": 649 } ], "outputs": [ @@ -2325,6 +2508,15 @@ "name": "bypass" }, "link": 542 + }, + { + "localized_name": "strength", + "name": "strength", + "type": "FLOAT", + "widget": { + "name": "strength" + }, + "link": 650 } ], "outputs": [ @@ -5114,6 +5306,22 @@ "target_id": -20, "target_slot": 1, "type": "IMAGE" + }, + { + "id": 649, + "origin_id": -10, + "origin_slot": 14, + "target_id": 288, + "target_slot": 4, + "type": "FLOAT" + }, + { + "id": 650, + "origin_id": -10, + "origin_slot": 15, + "target_id": 296, + "target_slot": 4, + "type": "FLOAT" } ], "extra": { From 26f8ddeebebb7bfe81609a26f85023098bdfa9cf Mon Sep 17 00:00:00 2001 From: Denis <61563365+dnsi0@users.noreply.github.com> Date: Tue, 11 Aug 2026 14:17:21 +0300 Subject: [PATCH 15/29] remove sizeGb --- docs/serviceTemplates/README.md | 2 +- docs/serviceTemplates/ltx-video-ugc-product.json | 5 ----- src/@types/C2D/ServiceOnDemand.ts | 1 - src/utils/config/schemas.ts | 1 - 4 files changed, 1 insertion(+), 8 deletions(-) diff --git a/docs/serviceTemplates/README.md b/docs/serviceTemplates/README.md index 52f7a99a9..9d7adfed9 100644 --- a/docs/serviceTemplates/README.md +++ b/docs/serviceTemplates/README.md @@ -46,7 +46,7 @@ entry is presented in a catalogue. A template that omits all of them is a plain | `service` | Bundles only, **required on them**: `id` of the service template this is a variant of (may not exist on this node) | | `outcome` | Bundles only: the one concrete thing this gets done, one sentence | | `category` | One of `image` / `video` / `llm` / `serving` / `notebook` / `embeddings` / `app` | -| `includes` | Bundles only: manifest of what the command downloads — `name`, `kind` (`model` / `workflow` / `customnode` / `other`), optional `sizeGb`, `repoId`, `url`. Display metadata; nothing here is fetched or verified by the node | +| `includes` | Bundles only: manifest of what the command downloads — `name`, `kind` (`model` / `workflow` / `customnode` / `other`), optional `repoId`, `url`. Display metadata; nothing here is fetched or verified by the node | Keep `includes` in step with what the script actually downloads: clients use its length as the denominator for a "preparing models — N of M" progress line, driven by `[models]` diff --git a/docs/serviceTemplates/ltx-video-ugc-product.json b/docs/serviceTemplates/ltx-video-ugc-product.json index 535e537de..b8d6973c1 100644 --- a/docs/serviceTemplates/ltx-video-ugc-product.json +++ b/docs/serviceTemplates/ltx-video-ugc-product.json @@ -10,31 +10,26 @@ { "name": "LTX-2.3 22B dev (fp8)", "kind": "model", - "sizeGb": 29.2, "repoId": "Lightricks/LTX-2.3-fp8" }, { "name": "Gemma-3-12B-it text encoder (fp4 mixed)", "kind": "model", - "sizeGb": 9.5, "repoId": "Comfy-Org/ltx-2" }, { "name": "LTX-2.3 22B distilled LoRA (rank 111)", "kind": "model", - "sizeGb": 2.7, "repoId": "Comfy-Org/ltx-2.3" }, { "name": "LTX-2.3 spatial upscaler x2", "kind": "model", - "sizeGb": 1.0, "repoId": "Lightricks/LTX-2.3" }, { "name": "Gemma-3-12B-it abliterated LoRA (rank 64)", "kind": "model", - "sizeGb": 0.6, "repoId": "Comfy-Org/ltx-2" } ], diff --git a/src/@types/C2D/ServiceOnDemand.ts b/src/@types/C2D/ServiceOnDemand.ts index fbb97477e..b8e8634c6 100644 --- a/src/@types/C2D/ServiceOnDemand.ts +++ b/src/@types/C2D/ServiceOnDemand.ts @@ -43,7 +43,6 @@ export type ServiceTemplateCategory = export interface TemplateIncludedItem { name: string kind: 'model' | 'workflow' | 'customnode' | 'other' - sizeGb?: number // download size — drives the "N models, X GB" line and setup-time hints repoId?: string // Hugging Face repo id, when the item is a plain HF repo url?: string // direct download URL for anything that isn't a plain HF repo } diff --git a/src/utils/config/schemas.ts b/src/utils/config/schemas.ts index 1ab45376a..fb1f498c9 100644 --- a/src/utils/config/schemas.ts +++ b/src/utils/config/schemas.ts @@ -352,7 +352,6 @@ const TemplateIncludedItemSchema = z .object({ name: z.string().min(1), kind: z.enum(['model', 'workflow', 'customnode', 'other']), - sizeGb: z.number().positive().optional(), repoId: z.string().min(1).optional(), url: z.string().url().optional() }) From 803503a764675b4ec0f3dea7f5288ccf1a128c05 Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Tue, 11 Aug 2026 14:49:13 +0300 Subject: [PATCH 16/29] cleanup --- src/@types/C2D/ServiceOnDemand.ts | 5 +- src/components/c2d/compute_engine_docker.ts | 30 ++++----- src/components/core/service/startService.ts | 9 +-- src/components/core/service/templateLoader.ts | 61 +++++++++---------- src/utils/config/schemas.ts | 2 +- 5 files changed, 50 insertions(+), 57 deletions(-) diff --git a/src/@types/C2D/ServiceOnDemand.ts b/src/@types/C2D/ServiceOnDemand.ts index fbb97477e..231cf91b1 100644 --- a/src/@types/C2D/ServiceOnDemand.ts +++ b/src/@types/C2D/ServiceOnDemand.ts @@ -76,8 +76,9 @@ export interface ServiceTemplate { envVars?: Record // fixed env vars — operator-set, never returned to callers userConfigurableEnvVars?: UserConfigurableEnvVar[] command?: string[] // Docker CMD override; ${KEY} expanded from userData - commandFile?: string // path relative to the templates dir; inlined into command[0] at load - // time and dropped (mutually exclusive with `command`) + // path relative to the templates dir; inlined into command[0] at load time and dropped + // (mutually exclusive with `command`) + commandFile?: string entrypoint?: string[] // Docker ENTRYPOINT override requiredResources?: TemplateResourceRequirement[] // MUST satisfy — gates SERVICE_START recommendedResources?: TemplateResourceRequirement[] // SHOULD satisfy — used for scoring + UI diff --git a/src/components/c2d/compute_engine_docker.ts b/src/components/c2d/compute_engine_docker.ts index 1e4cae7f5..4f80e916a 100755 --- a/src/components/c2d/compute_engine_docker.ts +++ b/src/components/c2d/compute_engine_docker.ts @@ -3346,6 +3346,16 @@ export class C2DEngineDocker extends C2DEngine { } } + // Bind-mount for the job's output bucket, when it has one. Throws instead of returning an + // empty list: an unmounted container silently re-downloads its models and writes results + // nowhere, so a mount failure must fail the start/restart. + private async serviceOutputMounts(job: ServiceJob): Promise { + if (!job.outputBucketId) return [] + const ps = OceanNode.getInstance().getPersistentStorage() + if (!ps) throw new Error('Persistent storage is not configured on this node') + return [await ps.getDockerOutputMountObject(job.outputBucketId, job.owner)] + } + // Handler-facing: persist the initial Starting record and return immediately so the HTTP // response carries the serviceId without waiting for escrow/image/container. The background // loop then calls processServiceStart() to advance it. Persisting Starting also reserves the @@ -3614,14 +3624,6 @@ export class C2DEngineDocker extends C2DEngine { job.environment ) - // Mount failure must fail the start: an unmounted container silently re-downloads its models. - const Mounts: DockerMountObject[] = [] - if (job.outputBucketId) { - const ps = OceanNode.getInstance().getPersistentStorage() - if (!ps) throw new Error('Persistent storage is not configured on this node') - Mounts.push(await ps.getDockerOutputMountObject(job.outputBucketId, job.owner)) - } - container = await this.docker.createContainer({ Image: job.containerImage, Cmd: cmd, @@ -3638,7 +3640,7 @@ export class C2DEngineDocker extends C2DEngine { SecurityOpt: ['no-new-privileges'], // security plan #5 CapDrop: ['ALL'], PidsLimit: 512, - Mounts + Mounts: await this.serviceOutputMounts(job) } }) CORE_LOGGER.debug( @@ -4322,14 +4324,6 @@ export class C2DEngineDocker extends C2DEngine { ) // 8. Create and start new container - // Same bind-mount as service start (see above). - const Mounts: DockerMountObject[] = [] - if (job.outputBucketId) { - const ps = OceanNode.getInstance().getPersistentStorage() - if (!ps) throw new Error('Persistent storage is not configured on this node') - Mounts.push(await ps.getDockerOutputMountObject(job.outputBucketId, job.owner)) - } - container = await this.docker.createContainer({ Image: effContainerImage, Cmd: cmd, @@ -4346,7 +4340,7 @@ export class C2DEngineDocker extends C2DEngine { SecurityOpt: ['no-new-privileges'], CapDrop: ['ALL'], PidsLimit: 512, - Mounts + Mounts: await this.serviceOutputMounts(job) } }) CORE_LOGGER.debug( diff --git a/src/components/core/service/startService.ts b/src/components/core/service/startService.ts index 34fc662fe..e603d643b 100644 --- a/src/components/core/service/startService.ts +++ b/src/components/core/service/startService.ts @@ -122,15 +122,16 @@ export class ServiceStartHandler extends CommandHandler { } } - // Must run before createServiceJob claims escrow, or a bad bucket burns the user's payment. - const isValidOutputBucket = await validateOutputBucket( + // Must run before createServiceJob claims escrow, or a bad bucket burns the user's + // payment. No-op when the task carries no bucket. '' = no `output` dir to conflict with. + const outputBucketCheck = await validateOutputBucket( node, task.outputBucketId, '', task.consumerAddress ) - if (isValidOutputBucket.status.httpStatus !== 200) { - return isValidOutputBucket + if (outputBucketCheck.status.httpStatus !== 200) { + return outputBucketCheck } // 4. Duration limit diff --git a/src/components/core/service/templateLoader.ts b/src/components/core/service/templateLoader.ts index 3ad66852a..36bb2f8b2 100644 --- a/src/components/core/service/templateLoader.ts +++ b/src/components/core/service/templateLoader.ts @@ -7,13 +7,25 @@ import type { import { ServiceTemplateSchema } from '../../../utils/config/schemas.js' import { CORE_LOGGER } from '../../../utils/logging/common.js' -// Null when `relPath` escapes `resolvedDir` — template paths are author-controlled. -function resolveInTemplatesDir(resolvedDir: string, relPath: string): string | null { +// Reads a file a template points at. Null (with a warning naming `what`) when the path +// escapes the templates dir or cannot be read — template paths are author-controlled, so +// both are authoring mistakes rather than node failures. +async function readTemplateFile( + resolvedDir: string, + relPath: string, + what: string +): Promise { const target = resolve(resolvedDir, relPath) if (target !== resolvedDir && !target.startsWith(resolvedDir + sep)) { + CORE_LOGGER.warn(`${what}: "${relPath}" resolves outside the templates dir`) + return null + } + try { + return await readFile(target, 'utf8') + } catch (e) { + CORE_LOGGER.warn(`${what}: cannot read "${relPath}" (${e.message})`) return null } - return target } // Re-reads on every call so operators can add/edit/remove template files without a restart. @@ -68,23 +80,15 @@ export async function loadServiceTemplates(dir?: string): Promise Date: Tue, 11 Aug 2026 15:02:27 +0300 Subject: [PATCH 17/29] readd sizegb and schema --- docs/serviceTemplates/README.md | 2 +- docs/serviceTemplates/ltx-video-ugc-product.json | 5 +++++ src/@types/C2D/ServiceOnDemand.ts | 1 + src/utils/config/schemas.ts | 1 + 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/serviceTemplates/README.md b/docs/serviceTemplates/README.md index 9d7adfed9..52f7a99a9 100644 --- a/docs/serviceTemplates/README.md +++ b/docs/serviceTemplates/README.md @@ -46,7 +46,7 @@ entry is presented in a catalogue. A template that omits all of them is a plain | `service` | Bundles only, **required on them**: `id` of the service template this is a variant of (may not exist on this node) | | `outcome` | Bundles only: the one concrete thing this gets done, one sentence | | `category` | One of `image` / `video` / `llm` / `serving` / `notebook` / `embeddings` / `app` | -| `includes` | Bundles only: manifest of what the command downloads — `name`, `kind` (`model` / `workflow` / `customnode` / `other`), optional `repoId`, `url`. Display metadata; nothing here is fetched or verified by the node | +| `includes` | Bundles only: manifest of what the command downloads — `name`, `kind` (`model` / `workflow` / `customnode` / `other`), optional `sizeGb`, `repoId`, `url`. Display metadata; nothing here is fetched or verified by the node | Keep `includes` in step with what the script actually downloads: clients use its length as the denominator for a "preparing models — N of M" progress line, driven by `[models]` diff --git a/docs/serviceTemplates/ltx-video-ugc-product.json b/docs/serviceTemplates/ltx-video-ugc-product.json index b8d6973c1..535e537de 100644 --- a/docs/serviceTemplates/ltx-video-ugc-product.json +++ b/docs/serviceTemplates/ltx-video-ugc-product.json @@ -10,26 +10,31 @@ { "name": "LTX-2.3 22B dev (fp8)", "kind": "model", + "sizeGb": 29.2, "repoId": "Lightricks/LTX-2.3-fp8" }, { "name": "Gemma-3-12B-it text encoder (fp4 mixed)", "kind": "model", + "sizeGb": 9.5, "repoId": "Comfy-Org/ltx-2" }, { "name": "LTX-2.3 22B distilled LoRA (rank 111)", "kind": "model", + "sizeGb": 2.7, "repoId": "Comfy-Org/ltx-2.3" }, { "name": "LTX-2.3 spatial upscaler x2", "kind": "model", + "sizeGb": 1.0, "repoId": "Lightricks/LTX-2.3" }, { "name": "Gemma-3-12B-it abliterated LoRA (rank 64)", "kind": "model", + "sizeGb": 0.6, "repoId": "Comfy-Org/ltx-2" } ], diff --git a/src/@types/C2D/ServiceOnDemand.ts b/src/@types/C2D/ServiceOnDemand.ts index bd48baeb6..231cf91b1 100644 --- a/src/@types/C2D/ServiceOnDemand.ts +++ b/src/@types/C2D/ServiceOnDemand.ts @@ -43,6 +43,7 @@ export type ServiceTemplateCategory = export interface TemplateIncludedItem { name: string kind: 'model' | 'workflow' | 'customnode' | 'other' + sizeGb?: number // download size — drives the "N models, X GB" line and setup-time hints repoId?: string // Hugging Face repo id, when the item is a plain HF repo url?: string // direct download URL for anything that isn't a plain HF repo } diff --git a/src/utils/config/schemas.ts b/src/utils/config/schemas.ts index dad3f4b00..3bb87af80 100644 --- a/src/utils/config/schemas.ts +++ b/src/utils/config/schemas.ts @@ -352,6 +352,7 @@ const TemplateIncludedItemSchema = z .object({ name: z.string().min(1), kind: z.enum(['model', 'workflow', 'customnode', 'other']), + sizeGb: z.number().positive().optional(), repoId: z.string().min(1).optional(), url: z.string().url().optional() }) From 07ec8c780527b1a3ba0cc9fdc327505c620e3015 Mon Sep 17 00:00:00 2001 From: giurgiur99 Date: Wed, 12 Aug 2026 12:55:53 +0300 Subject: [PATCH 18/29] minimax flow --- docs/serviceTemplates/README.md | 83 +- ...-bootstrap.sh => comfyui-ugc-bootstrap.sh} | 88 +- .../ltx-video-ugc-multishot.json | 2 +- .../ltx-video-ugc-product.json | 2 +- .../minimax-h3-video-ugc-multishot.json | 108 + .../workflows/ocean_h3_ugc_assemble.json | 1864 +++++++++ .../workflows/ocean_h3_ugc_multishot.json | 3339 +++++++++++++++++ .../workflows/ocean_ugc_assemble.json | 16 +- src/test/unit/service/serviceSchemas.test.ts | 8 +- 9 files changed, 5472 insertions(+), 38 deletions(-) rename docs/serviceTemplates/{ltx-video-ugc-bootstrap.sh => comfyui-ugc-bootstrap.sh} (72%) create mode 100644 docs/serviceTemplates/minimax-h3-video-ugc-multishot.json create mode 100644 docs/serviceTemplates/workflows/ocean_h3_ugc_assemble.json create mode 100644 docs/serviceTemplates/workflows/ocean_h3_ugc_multishot.json diff --git a/docs/serviceTemplates/README.md b/docs/serviceTemplates/README.md index 52f7a99a9..e12ae7b03 100644 --- a/docs/serviceTemplates/README.md +++ b/docs/serviceTemplates/README.md @@ -206,9 +206,62 @@ If the voice nodes load red, the pack failed to install — delete both and wire `AudioConcat` straight into `CreateVideo`, which is the plain stitched audio the workflow used before. The node's own how-to says so too. -## The shared bootstrap (`ltx-video-ugc-bootstrap.sh`) - -Both templates inline this script via `commandFile`. It runs ComfyUI from the image's +### `minimax-h3-video-ugc-multishot.json` — ComfyUI, MiniMax H3 UGC reel (GPU) + +Same image and bucket behavior as the LTX templates, but a different generator — MiniMax H3 +(open-weights, int8) — and a different unit of work: one Run here is a ~12 s **beat** that can +itself contain several internal cuts (the shipped example prompt holds two shots in one beat), +rather than LTX's one continuous take per Run. A 30 s reel is 2–3 Runs of this template versus +the 6–8 Runs LTX multishot needs for the same length. Needs a CUDA GPU, 24 GB+ VRAM recommended +(12 GB works with offloading). Ships two workflows: + +- `workflows/ocean_h3_ugc_multishot.json` — renders one beat per Run. +- `workflows/ocean_h3_ugc_assemble.json` — concatenates up to 8 rendered beats into one reel. + +**Native audio, no voice-conversion pass.** H3 generates voice, room tone and music in the +same forward pass as the video, so there is no separate TTS step and nothing analogous to the +LTX templates' `UnifiedVoiceChangerNode` pass. The bootstrap's TTS-Audio-Suite install is gated +on the installed graph containing `UnifiedVoiceChangerNode`; this workflow never does, so the +install never runs for this template — no custom node pack rides along. + +**Six prompt boxes, two lifecycles.** Three are casting — `subject_definitions`, +`retention_analysis`, `non_diegetic_music` — filled once and never retyped. Three are per-beat +— `summary`, `detailed_description`, `overall_soundscape` — retyped every Run. `retention_analysis` +is the box actually holding the character's face across a beat's internal cuts: a +`fully_preserved` / `attribute_transfer` line per subject. It plays the same role here that the +style box plays for LTX — keep it byte-identical across Runs rather than retyping it. + +**Hero-beat referencing.** The Continuity group (`LoadVideo` + `GetVideoComponents`, pointed at +a rendered beat) ships bypassed. From beat 2 on, un-bypass it and point `LoadVideo` at +**beat 1**, never at the newest beat: chaining beat N off beat N−1 compounds artifacts on every +generation, while every beat referencing the same hero beat does not. + +**Ref2VA / FL2VA toggle.** A single switch picks the checkpoint: off (default) is Ref2VA — +reference images, and optionally a reference video and voice clip, feed the model — for +anything with dialogue; on is FL2VA — first-frame/last-frame interpolation for action and +B-roll only. The switch is lazy, so only the selected 19.5 GB checkpoint is ever loaded, which +is how both fit in one graph. FL2VA has no reference-audio path, so it re-rolls the speaker on +every beat — never use it for a beat with dialogue. + +**Turbo LoRA, present but bypassed.** The graph ships a 4-step turbo LoRA node, off by default: +at 4 steps the audio path clips and gets noisy, so full-step (20-step) sampling is the default. +The graph's own note recommends un-bypassing at **8 steps** (not 4) with the `euler` sampler — +about 2.5x faster than the default and usable, though slightly below 20-step quality. + +**Size.** Default is **672×1184 at 0.8 MP / 9:16, 24 fps**, 12 s beats (5–15 s range). A 1.0 MP +setting is available, capping at H3's native 768×1344 — the model's 768 px short edge is the +ceiling at 1.0 MP, not at the 0.8 MP default. MiniMax's 2K mode (hosted `H3-Regenerate-2K`) is +absent from the open-weights release, so there is no 2K path here. + +Pick a persistent-storage bucket on launch: it holds ComfyUI's whole base directory, and +without one the roughly 60 GB of weights (two 19.5 GB checkpoints, a 14.6 GB text encoder, +video and audio VAEs, the turbo LoRA) re-downloads every launch and is discarded on stop; with +a bucket selected, beat and reel clips land in the bucket root where the storage API's +`listFiles` can see them. + +## The shared bootstrap (`comfyui-ugc-bootstrap.sh`) + +All three templates inline this script via `commandFile`. It runs ComfyUI from the image's read-only bundle with `--base-directory` pointed at the bucket, bypassing the image entrypoint, which writes to `/root/ComfyUI` and fails wherever the container is not uid 0. @@ -216,17 +269,31 @@ The workflow arrives as userData (`COMFY_WORKFLOW_ID` + gzipped `COMFY_WORKFLOW` installed at `custom_nodes//example_workflows/.json`, which ComfyUI serves at `/api/workflow_templates//.json` — so `?template=&source=` deep-links it. `source` must name the module; `source=all` only searches ComfyUI's own templates. It is also -copied into `user/default/workflows/` so it appears in the Workflows sidebar. +copied into `user/default/workflows/` so it appears in the Workflows sidebar. For a template +with more than one `workflows[]` entry, `COMFY_WORKFLOW_ID` — and so the weight download and +the deep link — always comes from the first entry that carries a `graph`, so that entry must +stay first. Weights are not listed here: the script downloads the HuggingFace URLs carried by the installed graph itself, so each template fetches only what it loads and a new workflow needs no change -here. A template's `envVars` cannot drive this — nothing merges them into a service container -(`SERVICE_START` has no template id; the container env comes only from `userData`). +here. Each URL is routed into the matching `models/` subdirectory by pattern-matching its path — +`checkpoints`, `text_encoders`, `loras`, `latent_upscale_models`, plus `diffusion_models` and +`vae` for the MiniMax H3 template's weights. The H3 turbo LoRA's URL has no `/loras/` path +segment (the file sits at the repo root), so a bare `*[Ll]ora*` pattern arm catches it before +the catch-all default of `checkpoints` — without that arm the LoRA would land in `checkpoints` +and its `LoraLoaderModelOnly` node would show red. A template's `envVars` cannot drive this — +nothing merges them into a service container (`SERVICE_START` has no template id; the container +env comes only from `userData`). Custom nodes follow the same graph-driven rule. The script installs [TTS-Audio-Suite](https://github.com/diodiogod/TTS-Audio-Suite) — for the assemble workflow's -voice conversion — only when an installed graph mentions `UnifiedVoiceChangerNode`, so the -product template never pays for it. The clone lands in the bucket's `custom_nodes`, but pip +voice conversion — only when an installed graph mentions `UnifiedVoiceChangerNode`. The grep +covers *every* workflow the template installs, not just the deep-linked one, so +`ltx-video-ugc-multishot` pays for the install on account of its assemble workflow even though +its generator never mentions the node. `ltx-video-ugc-product` skips it because it ships one +workflow that has no voice conversion, and `minimax-h3-video-ugc-multishot` skips it because +H3 generates the voice natively and its assemble workflow is a plain stitcher. The clone lands +in the bucket's `custom_nodes`, but pip installs into the container and is lost on stop, hence the unconditional reinstall on every launch; it is cheap because `XDG_CACHE_HOME` puts pip's wheel cache in the bucket too. It installs into the container's own site-packages rather than `--target` + `PYTHONPATH`: a diff --git a/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh b/docs/serviceTemplates/comfyui-ugc-bootstrap.sh similarity index 72% rename from docs/serviceTemplates/ltx-video-ugc-bootstrap.sh rename to docs/serviceTemplates/comfyui-ugc-bootstrap.sh index d49c32822..1fd60fcaa 100755 --- a/docs/serviceTemplates/ltx-video-ugc-bootstrap.sh +++ b/docs/serviceTemplates/comfyui-ugc-bootstrap.sh @@ -31,7 +31,8 @@ fi MODELS="$BASE/models" mkdir -p "$MODELS/checkpoints" "$MODELS/loras" "$MODELS/text_encoders" \ - "$MODELS/latent_upscale_models" "$BASE/output" "$INPUT_DIR" "$BASE/temp" "$BASE/user" + "$MODELS/latent_upscale_models" "$MODELS/diffusion_models" "$MODELS/vae" \ + "$BASE/output" "$INPUT_DIR" "$BASE/temp" "$BASE/user" # .part then rename: a truncated file in a persistent bucket would look cached forever. get() { @@ -146,10 +147,13 @@ PY fi for url in $MODEL_URLS; do case "$url" in - */text_encoders/*) sub=text_encoders ;; - */loras/*) sub=loras ;; - *upscaler*) sub=latent_upscale_models ;; - *) sub=checkpoints ;; + */diffusion_models/*) sub=diffusion_models ;; + */text_encoders/*) sub=text_encoders ;; + */vae/*) sub=vae ;; + */loras/*) sub=loras ;; + *[Ll]ora*) sub=loras ;; + *upscaler*) sub=latent_upscale_models ;; + *) sub=checkpoints ;; esac # One renamed file must not cost the whole paid session. get "$url" "$MODELS/$sub/$(basename "$url")" || @@ -159,26 +163,74 @@ else echo "[ocean] no workflow supplied — skipping model download" >&2 fi -# The graph's LoadImage/LoadAudio widgets name example assets that ship inside the -# comfyui-workflow-templates package. Copying them into input/ is what makes the first Queue -# work without the user uploading anything. +# The graph's LoadImage/LoadAudio widgets name example assets. Putting them in input/ is what +# makes the first Queue work without the user uploading anything — without it ComfyUI rejects +# the prompt with "Value not in list: image", because it validates combo widgets across the +# whole reachable graph even for nodes the selected branch never runs. if [ -n "$WORKFLOW_JSON" ]; then python3.13 - "$WORKFLOW_JSON" "$INPUT_DIR" <<'PY' || true -import json, shutil, sys +import json, shutil, sys, urllib.parse, urllib.request from pathlib import Path + +# These assets live at input/ in Comfy-Org/workflow_templates. The pip package used to vendor +# them, but every release since 0.11.26 is a ~10 KB meta-package carrying none — so the local +# lookup below is a fast path that currently always misses, and the download is what actually +# seeds. Both are kept: the package may start shipping assets again. +RAW = 'https://raw.githubusercontent.com/Comfy-Org/workflow_templates/main/input/' + +dirs = [] try: import comfyui_workflow_templates as pkg - src = Path(pkg.__file__).parent / 'templates' + base = Path(pkg.__file__).parent + dirs = [base / 'templates' / 'input', base / 'templates', base / 'input'] +except Exception: + pass + +try: graph = json.load(open(sys.argv[1])) - dest = Path(sys.argv[2]) - for node in graph.get('nodes', []): - if node.get('type') in ('LoadImage', 'LoadAudio'): - name = (node.get('widgets_values') or [None])[0] - if name and (src / name).is_file() and not (dest / name).exists(): - shutil.copy2(src / name, dest / name) - print(f'[ocean] seeded input {name}') except Exception as e: - print(f'[ocean] could not seed example inputs: {e}', file=sys.stderr) + print(f'[ocean] could not read the workflow for seeding: {e}', file=sys.stderr) + raise SystemExit(0) +dest = Path(sys.argv[2]) + +for node in graph.get('nodes', []): + # Per-node, because the graph is client-supplied: a name with a NUL or over 255 bytes makes + # even the cleanup below raise, and one malformed node must not stop the rest from seeding. + try: + if not isinstance(node, dict) or node.get('type') not in ('LoadImage', 'LoadAudio'): + continue + widgets = node.get('widgets_values') + name = widgets[0] if isinstance(widgets, list) and widgets else None + # The graph arrives from the client, so `name` is untrusted and becomes both a URL segment + # and a write path. Basename only: Path('../x').name and Path('/etc/x').name both differ + # from the original, and Path('..').name is '', so traversal cannot survive this. + if not isinstance(name, str) or not name or Path(name).name != name or name[0] == '.': + continue + if (dest / name).exists(): + continue + local = next((d / name for d in dirs if (d / name).is_file()), None) + if local: + shutil.copy2(local, dest / name) + print(f'[ocean] seeded input {name}') + continue + # .part then rename, like the model downloads above: a truncated asset in a persistent + # bucket would look seeded forever and fail at Queue time instead of here. + part = dest / (name + '.part') + try: + url = RAW + urllib.parse.quote(name) + with urllib.request.urlopen(url, timeout=30) as r, open(part, 'wb') as f: + shutil.copyfileobj(r, f) + part.rename(dest / name) + print(f'[ocean] fetched example input {name}') + except Exception as e: + try: + part.unlink(missing_ok=True) + except Exception: + pass + # Non-fatal: escrow is claimed, and the user can always upload their own. + print(f'[ocean] no example input for {name} ({e}) — upload one in the UI', file=sys.stderr) + except Exception as e: + print(f'[ocean] skipped an input node while seeding: {e}', file=sys.stderr) PY fi diff --git a/docs/serviceTemplates/ltx-video-ugc-multishot.json b/docs/serviceTemplates/ltx-video-ugc-multishot.json index 8e2bc9d22..fc14b84f4 100644 --- a/docs/serviceTemplates/ltx-video-ugc-multishot.json +++ b/docs/serviceTemplates/ltx-video-ugc-multishot.json @@ -52,7 +52,7 @@ "/bin/bash", "-c" ], - "commandFile": "ltx-video-ugc-bootstrap.sh", + "commandFile": "comfyui-ugc-bootstrap.sh", "workflows": [ { "id": "ocean_ugc_multishot", diff --git a/docs/serviceTemplates/ltx-video-ugc-product.json b/docs/serviceTemplates/ltx-video-ugc-product.json index 535e537de..d0d95e387 100644 --- a/docs/serviceTemplates/ltx-video-ugc-product.json +++ b/docs/serviceTemplates/ltx-video-ugc-product.json @@ -47,7 +47,7 @@ "/bin/bash", "-c" ], - "commandFile": "ltx-video-ugc-bootstrap.sh", + "commandFile": "comfyui-ugc-bootstrap.sh", "workflows": [ { "id": "ocean_ugc_product", diff --git a/docs/serviceTemplates/minimax-h3-video-ugc-multishot.json b/docs/serviceTemplates/minimax-h3-video-ugc-multishot.json new file mode 100644 index 000000000..dc96ef7a2 --- /dev/null +++ b/docs/serviceTemplates/minimax-h3-video-ugc-multishot.json @@ -0,0 +1,108 @@ +{ + "id": "minimax-h3-video-ugc-multishot", + "name": "ComfyUI — UGC multishot reel (MiniMax H3)", + "description": "ComfyUI preloaded with MiniMax H3 (open-weights, int8) for a vertical UGC reel where every beat carries native stereo audio — voice, room tone and music generated in the same forward pass, so there is no TTS step and no voice-conversion node pack riding along the way the LTX UGC templates need. One Run renders one ~12-second beat that can itself contain several internal cuts, not one continuous take, so a 30-second reel is 2–3 Runs here versus the 6–8 shot-by-shot Runs the LTX multishot template needs for the same length. Six prompt boxes split into what you set once — subject_definitions, retention_analysis, non_diegetic_music — and what you retype every beat — summary, detailed_description, overall_soundscape; retention_analysis is the box actually doing the work of holding the character's face steady across the internal cuts, so treat it the way the LTX template treats its style box. Continuity between beats ships bypassed: from beat 2 onward, un-bypass it and always point LoadVideo at beat 1, never at the newest beat — chaining beat N off beat N−1 compounds artifacts on every generation, while every beat referencing the same hero beat does not. A green Mode switch picks the checkpoint: off is Ref2VA (default; reference images, and optionally a reference video and voice clip — use for anything with dialogue), on is FL2VA (first-frame/last-frame interpolation for action and B-roll only, since it has no reference-audio path and re-rolls the speaker every beat). The switch is lazy, so only one of the two 19.5 GB checkpoints is ever loaded — that is how both fit in one graph. The turbo 4-step LoRA ships bypassed on purpose: it is about 2.5x faster, but at 4 steps the audio path clips and gets noisy, so full-step sampling is the default and un-bypassing it is a deliberate quality tradeoff, not a missing feature. Beats render at 24 fps, 5–15 s each (12 s default); the shipped Resolution default is 0.8 MP at 9:16, which the node rounds to 672×1184, with a 1.0 MP setting available up to H3's native 768×1344 / 768 px short edge cap. Select a persistent-storage bucket on launch: it holds ComfyUI's whole base directory, and without one the roughly 60 GB of weights (two 19.5 GB checkpoints, a 14.6 GB text encoder, video and audio VAEs, the turbo LoRA) re-downloads every launch and is discarded on stop; with a bucket selected, beat and reel clips land in the bucket root where the storage API's listFiles can see them. This template tops out at H3's native resolution: MiniMax's 2K mode (hosted `H3-Regenerate-2K`) is a hosted-only feature, absent from the open-weights release, so there is no 2K path here.", + "kind": "bundle", + "service": "comfyui", + "outcome": "Build a multi-shot 9:16 UGC reel with native synced audio, one character and one voice throughout.", + "category": "video", + "includes": [ + { + "name": "MiniMax H3 Ref2VA (int8)", + "kind": "model", + "sizeGb": 19.5, + "repoId": "Comfy-Org/MiniMax-H3" + }, + { + "name": "MiniMax H3 FL2VA (int8)", + "kind": "model", + "sizeGb": 19.5, + "repoId": "Comfy-Org/MiniMax-H3" + }, + { + "name": "Qwen3-VL-32B text encoder (nvfp4 awq)", + "kind": "model", + "sizeGb": 14.6, + "repoId": "Comfy-Org/MiniMax-H3" + }, + { + "name": "H3 video VAE (fp16)", + "kind": "model", + "sizeGb": 4.9, + "repoId": "Comfy-Org/MiniMax-H3" + }, + { + "name": "H3 audio VAE (fp32, stereo)", + "kind": "model", + "sizeGb": 0.6, + "repoId": "Comfy-Org/MiniMax-H3" + }, + { + "name": "H3 Turbo 4-step LoRA (optional, bypassed by default)", + "kind": "model", + "sizeGb": 0.6, + "repoId": "drbaph/MiniMax-H3-Turbo-Lora-ComfyUI" + } + ], + "image": "yanwk/comfyui-boot", + "tag": "cu130-megapak-pt211-20260812", + "exposedPorts": [ + 8188 + ], + "entrypoint": [ + "/bin/bash", + "-c" + ], + "commandFile": "comfyui-ugc-bootstrap.sh", + "workflows": [ + { + "id": "ocean_h3_ugc_multishot", + "name": "Multishot beat — one Run, several shots", + "description": "One Run renders one ~12 s beat with native synced voice, room tone and music — no separate TTS or voice-conversion step. Casting boxes (subject_definitions, retention_analysis, non_diegetic_music) are set once; This-beat boxes (summary, detailed_description, overall_soundscape) are retyped every Run. A lazy Mode switch picks Ref2VA (reference-driven, for dialogue) or FL2VA (interpolation only, for action/B-roll — no reference-audio path, so it re-rolls the speaker). Continuity ships bypassed; from beat 2 on, point it at beat 1, never the newest beat, or artifacts compound.", + "file": "workflows/ocean_h3_ugc_multishot.json" + }, + { + "id": "ocean_h3_ugc_assemble", + "name": "Assemble reel", + "description": "Concatenates up to 8 rendered beat clips (video + audio, already final) into a single reel using core ComfyUI video nodes — no external editor and no voice-conversion pass, since every beat already carries its own synced audio. Pick clips in the Beat 1–8 LoadVideo dropdowns, bypass any slots you don't need, and Run.", + "file": "workflows/ocean_h3_ugc_assemble.json" + } + ], + "userConfigurableEnvVars": [ + { + "key": "COMFY_WORKFLOW_ID", + "validation": "^[A-Za-z0-9_-]+$" + }, + { + "key": "COMFY_WORKFLOW" + } + ], + "requiredResources": [ + { + "id": "cpu", + "min": 8, + "recommended": 16, + "unit": "cores" + }, + { + "id": "ram", + "min": 64, + "recommended": 128, + "unit": "GB" + }, + { + "id": "disk", + "min": 70, + "recommended": 140, + "unit": "GB" + }, + { + "kind": "discrete", + "type": "gpu", + "min": 1, + "recommended": 1, + "unit": "count", + "description": "CUDA GPU, 24 GB+ VRAM recommended; runs on 12 GB with offloading" + } + ] +} diff --git a/docs/serviceTemplates/workflows/ocean_h3_ugc_assemble.json b/docs/serviceTemplates/workflows/ocean_h3_ugc_assemble.json new file mode 100644 index 000000000..bd67dbfba --- /dev/null +++ b/docs/serviceTemplates/workflows/ocean_h3_ugc_assemble.json @@ -0,0 +1,1864 @@ +{ + "id": "f0a7b59b-e37f-4ce2-9564-e772ecd7d9c2", + "revision": 0, + "last_node_id": 62, + "last_link_id": 65, + "nodes": [ + { + "id": 1, + "type": "MarkdownNote", + "pos": [ + -1000.0, + 0.0 + ], + "size": [ + 900, + 760 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": {}, + "widgets_values": [ + "## Assemble reel\n\nEach **Beat** group is one slot: pick a rendered `beat_\u2026mp4` in its **file** dropdown. The dropdown lists what is in the bucket \u2014 hit ComfyUI's refresh icon if a clip you just rendered is not there yet. Re-takes never overwrite, so just don't select the ones you didn't like.\n\n### Using fewer than 8 beats\n\nRight-click the group \u2192 **Bypass Group Nodes**. Do this for every beat slot you are not using.\n\nBypassing only the *Load Video* node is not enough \u2014 the Image Batch and Audio Concat in that row still demand a second input and the run fails validation with `Required input is missing: image2`. That is why each row is grouped: bypassing the group takes out all four nodes at once, and the batch/concat nodes then pass their first input straight through, so the chain closes over the gap.\n\n**Beat 1 cannot be bypassed.** It heads both the image and audio chains.\n\nClick **Run** once. The reel saves as `reel_00001\u2026` in the bucket root.\n\n### Voice\n\nMiniMax H3 generates each clip's voice from the reference inputs, so the stitched track is already one consistent speaker across beats \u2014 no conversion step needed. The last **Audio Concat** feeds **Create reel**'s `audio` input directly.\n\n### Memory\n\n8 \u00d7 12 s at 768\u00d71344 is ~2300 frames batched in RAM. If it OOMs, assemble in two passes \u2014 the output of one assemble is a valid input to the next." + ], + "title": "How to use" + }, + { + "id": 10, + "type": "LoadVideo", + "pos": [ + 0.0, + 0.0 + ], + "size": [ + 340, + 380 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 1 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "LoadVideo" + }, + "widgets_values": [ + "beat_00001_.mp4" + ], + "title": "Beat 1" + }, + { + "id": 20, + "type": "GetVideoComponents", + "pos": [ + 400.0, + 0.0 + ], + "size": [ + 270, + 126 + ], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 1 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 9 + ] + }, + { + "name": "audio", + "type": "AUDIO", + "links": [ + 23 + ] + }, + { + "name": "fps", + "type": "FLOAT", + "links": [ + 38 + ] + }, + { + "name": "bit_depth", + "type": "INT", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "GetVideoComponents" + }, + "title": "Beat 1 components" + }, + { + "id": 11, + "type": "LoadVideo", + "pos": [ + 0.0, + 480.0 + ], + "size": [ + 340, + 380 + ], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 2 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "LoadVideo" + }, + "widgets_values": [ + "beat_00002_.mp4" + ], + "title": "Beat 2" + }, + { + "id": 21, + "type": "GetVideoComponents", + "pos": [ + 400.0, + 480.0 + ], + "size": [ + 270, + 126 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 2 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 10 + ] + }, + { + "name": "audio", + "type": "AUDIO", + "links": [ + 24 + ] + }, + { + "name": "fps", + "type": "FLOAT", + "links": [] + }, + { + "name": "bit_depth", + "type": "INT", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "GetVideoComponents" + }, + "title": "Beat 2 components" + }, + { + "id": 12, + "type": "LoadVideo", + "pos": [ + 0.0, + 960.0 + ], + "size": [ + 340, + 380 + ], + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 3 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "LoadVideo" + }, + "widgets_values": [ + "beat_00003_.mp4" + ], + "title": "Beat 3" + }, + { + "id": 22, + "type": "GetVideoComponents", + "pos": [ + 400.0, + 960.0 + ], + "size": [ + 270, + 126 + ], + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 3 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 12 + ] + }, + { + "name": "audio", + "type": "AUDIO", + "links": [ + 26 + ] + }, + { + "name": "fps", + "type": "FLOAT", + "links": [] + }, + { + "name": "bit_depth", + "type": "INT", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "GetVideoComponents" + }, + "title": "Beat 3 components" + }, + { + "id": 13, + "type": "LoadVideo", + "pos": [ + 0.0, + 1440.0 + ], + "size": [ + 340, + 380 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 4 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "LoadVideo" + }, + "widgets_values": [ + "beat_00004_.mp4" + ], + "title": "Beat 4" + }, + { + "id": 23, + "type": "GetVideoComponents", + "pos": [ + 400.0, + 1440.0 + ], + "size": [ + 270, + 126 + ], + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 4 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 14 + ] + }, + { + "name": "audio", + "type": "AUDIO", + "links": [ + 28 + ] + }, + { + "name": "fps", + "type": "FLOAT", + "links": [] + }, + { + "name": "bit_depth", + "type": "INT", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "GetVideoComponents" + }, + "title": "Beat 4 components" + }, + { + "id": 14, + "type": "LoadVideo", + "pos": [ + 0.0, + 1920.0 + ], + "size": [ + 340, + 380 + ], + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 5 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "LoadVideo" + }, + "widgets_values": [ + "beat_00005_.mp4" + ], + "title": "Beat 5" + }, + { + "id": 24, + "type": "GetVideoComponents", + "pos": [ + 400.0, + 1920.0 + ], + "size": [ + 270, + 126 + ], + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 5 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 16 + ] + }, + { + "name": "audio", + "type": "AUDIO", + "links": [ + 30 + ] + }, + { + "name": "fps", + "type": "FLOAT", + "links": [] + }, + { + "name": "bit_depth", + "type": "INT", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "GetVideoComponents" + }, + "title": "Beat 5 components" + }, + { + "id": 15, + "type": "LoadVideo", + "pos": [ + 0.0, + 2400.0 + ], + "size": [ + 340, + 380 + ], + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 6 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "LoadVideo" + }, + "widgets_values": [ + "beat_00006_.mp4" + ], + "title": "Beat 6" + }, + { + "id": 25, + "type": "GetVideoComponents", + "pos": [ + 400.0, + 2400.0 + ], + "size": [ + 270, + 126 + ], + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 6 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 18 + ] + }, + { + "name": "audio", + "type": "AUDIO", + "links": [ + 32 + ] + }, + { + "name": "fps", + "type": "FLOAT", + "links": [] + }, + { + "name": "bit_depth", + "type": "INT", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "GetVideoComponents" + }, + "title": "Beat 6 components" + }, + { + "id": 16, + "type": "LoadVideo", + "pos": [ + 0.0, + 2880.0 + ], + "size": [ + 340, + 380 + ], + "flags": {}, + "order": 13, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 7 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "LoadVideo" + }, + "widgets_values": [ + "beat_00007_.mp4" + ], + "title": "Beat 7" + }, + { + "id": 26, + "type": "GetVideoComponents", + "pos": [ + 400.0, + 2880.0 + ], + "size": [ + 270, + 126 + ], + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 7 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 20 + ] + }, + { + "name": "audio", + "type": "AUDIO", + "links": [ + 34 + ] + }, + { + "name": "fps", + "type": "FLOAT", + "links": [] + }, + { + "name": "bit_depth", + "type": "INT", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "GetVideoComponents" + }, + "title": "Beat 7 components" + }, + { + "id": 17, + "type": "LoadVideo", + "pos": [ + 0.0, + 3360.0 + ], + "size": [ + 340, + 380 + ], + "flags": {}, + "order": 15, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 8 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "LoadVideo" + }, + "widgets_values": [ + "beat_00008_.mp4" + ], + "title": "Beat 8" + }, + { + "id": 27, + "type": "GetVideoComponents", + "pos": [ + 400.0, + 3360.0 + ], + "size": [ + 270, + 126 + ], + "flags": {}, + "order": 16, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 8 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 22 + ] + }, + { + "name": "audio", + "type": "AUDIO", + "links": [ + 36 + ] + }, + { + "name": "fps", + "type": "FLOAT", + "links": [] + }, + { + "name": "bit_depth", + "type": "INT", + "links": [] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "GetVideoComponents" + }, + "title": "Beat 8 components" + }, + { + "id": 30, + "type": "ImageBatch", + "pos": [ + 740.0, + 480.0 + ], + "size": [ + 210, + 60 + ], + "flags": { + "collapsed": true + }, + "order": 17, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 9 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 10 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 11 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 31, + "type": "ImageBatch", + "pos": [ + 740.0, + 960.0 + ], + "size": [ + 210, + 60 + ], + "flags": { + "collapsed": true + }, + "order": 18, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 11 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 12 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 13 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 32, + "type": "ImageBatch", + "pos": [ + 740.0, + 1440.0 + ], + "size": [ + 210, + 60 + ], + "flags": { + "collapsed": true + }, + "order": 19, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 13 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 14 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 15 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 33, + "type": "ImageBatch", + "pos": [ + 740.0, + 1920.0 + ], + "size": [ + 210, + 60 + ], + "flags": { + "collapsed": true + }, + "order": 20, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 15 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 16 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 17 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 34, + "type": "ImageBatch", + "pos": [ + 740.0, + 2400.0 + ], + "size": [ + 210, + 60 + ], + "flags": { + "collapsed": true + }, + "order": 21, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 17 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 18 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 19 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 35, + "type": "ImageBatch", + "pos": [ + 740.0, + 2880.0 + ], + "size": [ + 210, + 60 + ], + "flags": { + "collapsed": true + }, + "order": 22, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 19 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 20 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 21 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 36, + "type": "ImageBatch", + "pos": [ + 740.0, + 3360.0 + ], + "size": [ + 210, + 60 + ], + "flags": { + "collapsed": true + }, + "order": 23, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 21 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 22 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 37 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 40, + "type": "AudioConcat", + "pos": [ + 990.0, + 480.0 + ], + "size": [ + 210, + 78 + ], + "flags": { + "collapsed": true + }, + "order": 24, + "mode": 0, + "inputs": [ + { + "name": "audio1", + "type": "AUDIO", + "link": 23 + }, + { + "name": "audio2", + "type": "AUDIO", + "link": 24 + } + ], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 25 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "AudioConcat" + }, + "widgets_values": [ + "after" + ] + }, + { + "id": 41, + "type": "AudioConcat", + "pos": [ + 990.0, + 960.0 + ], + "size": [ + 210, + 78 + ], + "flags": { + "collapsed": true + }, + "order": 25, + "mode": 0, + "inputs": [ + { + "name": "audio1", + "type": "AUDIO", + "link": 25 + }, + { + "name": "audio2", + "type": "AUDIO", + "link": 26 + } + ], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 27 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "AudioConcat" + }, + "widgets_values": [ + "after" + ] + }, + { + "id": 42, + "type": "AudioConcat", + "pos": [ + 990.0, + 1440.0 + ], + "size": [ + 210, + 78 + ], + "flags": { + "collapsed": true + }, + "order": 26, + "mode": 0, + "inputs": [ + { + "name": "audio1", + "type": "AUDIO", + "link": 27 + }, + { + "name": "audio2", + "type": "AUDIO", + "link": 28 + } + ], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 29 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "AudioConcat" + }, + "widgets_values": [ + "after" + ] + }, + { + "id": 43, + "type": "AudioConcat", + "pos": [ + 990.0, + 1920.0 + ], + "size": [ + 210, + 78 + ], + "flags": { + "collapsed": true + }, + "order": 27, + "mode": 0, + "inputs": [ + { + "name": "audio1", + "type": "AUDIO", + "link": 29 + }, + { + "name": "audio2", + "type": "AUDIO", + "link": 30 + } + ], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 31 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "AudioConcat" + }, + "widgets_values": [ + "after" + ] + }, + { + "id": 44, + "type": "AudioConcat", + "pos": [ + 990.0, + 2400.0 + ], + "size": [ + 210, + 78 + ], + "flags": { + "collapsed": true + }, + "order": 28, + "mode": 0, + "inputs": [ + { + "name": "audio1", + "type": "AUDIO", + "link": 31 + }, + { + "name": "audio2", + "type": "AUDIO", + "link": 32 + } + ], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 33 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "AudioConcat" + }, + "widgets_values": [ + "after" + ] + }, + { + "id": 45, + "type": "AudioConcat", + "pos": [ + 990.0, + 2880.0 + ], + "size": [ + 210, + 78 + ], + "flags": { + "collapsed": true + }, + "order": 29, + "mode": 0, + "inputs": [ + { + "name": "audio1", + "type": "AUDIO", + "link": 33 + }, + { + "name": "audio2", + "type": "AUDIO", + "link": 34 + } + ], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 35 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "AudioConcat" + }, + "widgets_values": [ + "after" + ] + }, + { + "id": 46, + "type": "AudioConcat", + "pos": [ + 990.0, + 3360.0 + ], + "size": [ + 210, + 78 + ], + "flags": { + "collapsed": true + }, + "order": 30, + "mode": 0, + "inputs": [ + { + "name": "audio1", + "type": "AUDIO", + "link": 35 + }, + { + "name": "audio2", + "type": "AUDIO", + "link": 36 + } + ], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 61 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "AudioConcat" + }, + "widgets_values": [ + "after" + ] + }, + { + "id": 50, + "type": "CreateVideo", + "pos": [ + 1720.0, + 0.0 + ], + "size": [ + 270, + 150 + ], + "flags": {}, + "order": 31, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 37 + }, + { + "name": "fps", + "type": "FLOAT", + "widget": { + "name": "fps" + }, + "link": 38 + }, + { + "name": "audio", + "type": "AUDIO", + "shape": 7, + "link": 61 + } + ], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 40 + ] + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "CreateVideo" + }, + "widgets_values": [ + 24, + 8 + ], + "title": "Create reel" + }, + { + "id": 51, + "type": "SaveVideo", + "pos": [ + 1720.0, + 210.0 + ], + "size": [ + 400, + 300 + ], + "flags": {}, + "order": 32, + "mode": 0, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 40 + } + ], + "outputs": [ + { + "name": "video", + "type": "VIDEO", + "links": null + } + ], + "properties": { + "cnr_id": "comfy-core", + "Node name for S&R": "SaveVideo" + }, + "widgets_values": [ + "reel", + "auto", + "auto" + ], + "title": "Output reel" + } + ], + "links": [ + [ + 1, + 10, + 0, + 20, + 0, + "VIDEO" + ], + [ + 2, + 11, + 0, + 21, + 0, + "VIDEO" + ], + [ + 3, + 12, + 0, + 22, + 0, + "VIDEO" + ], + [ + 4, + 13, + 0, + 23, + 0, + "VIDEO" + ], + [ + 5, + 14, + 0, + 24, + 0, + "VIDEO" + ], + [ + 6, + 15, + 0, + 25, + 0, + "VIDEO" + ], + [ + 7, + 16, + 0, + 26, + 0, + "VIDEO" + ], + [ + 8, + 17, + 0, + 27, + 0, + "VIDEO" + ], + [ + 9, + 20, + 0, + 30, + 0, + "IMAGE" + ], + [ + 10, + 21, + 0, + 30, + 1, + "IMAGE" + ], + [ + 11, + 30, + 0, + 31, + 0, + "IMAGE" + ], + [ + 12, + 22, + 0, + 31, + 1, + "IMAGE" + ], + [ + 13, + 31, + 0, + 32, + 0, + "IMAGE" + ], + [ + 14, + 23, + 0, + 32, + 1, + "IMAGE" + ], + [ + 15, + 32, + 0, + 33, + 0, + "IMAGE" + ], + [ + 16, + 24, + 0, + 33, + 1, + "IMAGE" + ], + [ + 17, + 33, + 0, + 34, + 0, + "IMAGE" + ], + [ + 18, + 25, + 0, + 34, + 1, + "IMAGE" + ], + [ + 19, + 34, + 0, + 35, + 0, + "IMAGE" + ], + [ + 20, + 26, + 0, + 35, + 1, + "IMAGE" + ], + [ + 21, + 35, + 0, + 36, + 0, + "IMAGE" + ], + [ + 22, + 27, + 0, + 36, + 1, + "IMAGE" + ], + [ + 23, + 20, + 1, + 40, + 0, + "AUDIO" + ], + [ + 24, + 21, + 1, + 40, + 1, + "AUDIO" + ], + [ + 25, + 40, + 0, + 41, + 0, + "AUDIO" + ], + [ + 26, + 22, + 1, + 41, + 1, + "AUDIO" + ], + [ + 27, + 41, + 0, + 42, + 0, + "AUDIO" + ], + [ + 28, + 23, + 1, + 42, + 1, + "AUDIO" + ], + [ + 29, + 42, + 0, + 43, + 0, + "AUDIO" + ], + [ + 30, + 24, + 1, + 43, + 1, + "AUDIO" + ], + [ + 31, + 43, + 0, + 44, + 0, + "AUDIO" + ], + [ + 32, + 25, + 1, + 44, + 1, + "AUDIO" + ], + [ + 33, + 44, + 0, + 45, + 0, + "AUDIO" + ], + [ + 34, + 26, + 1, + 45, + 1, + "AUDIO" + ], + [ + 35, + 45, + 0, + 46, + 0, + "AUDIO" + ], + [ + 36, + 27, + 1, + 46, + 1, + "AUDIO" + ], + [ + 37, + 36, + 0, + 50, + 0, + "IMAGE" + ], + [ + 38, + 20, + 2, + 50, + 1, + "FLOAT" + ], + [ + 40, + 50, + 0, + 51, + 0, + "VIDEO" + ], + [ + 61, + 46, + 0, + 50, + 2, + "AUDIO" + ] + ], + "groups": [ + { + "id": 1, + "title": "Beat 1 \u2014 chain head, keep", + "bounding": [ + -20.0, + -50.0, + 1250.0, + 450.0 + ], + "color": "#88A", + "font_size": 24, + "flags": {} + }, + { + "id": 2, + "title": "Beat 2", + "bounding": [ + -20.0, + 430.0, + 1250.0, + 450.0 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "id": 3, + "title": "Beat 3", + "bounding": [ + -20.0, + 910.0, + 1250.0, + 450.0 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "id": 4, + "title": "Beat 4", + "bounding": [ + -20.0, + 1390.0, + 1250.0, + 450.0 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "id": 5, + "title": "Beat 5", + "bounding": [ + -20.0, + 1870.0, + 1250.0, + 450.0 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "id": 6, + "title": "Beat 6", + "bounding": [ + -20.0, + 2350.0, + 1250.0, + 450.0 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "id": 7, + "title": "Beat 7", + "bounding": [ + -20.0, + 2830.0, + 1250.0, + 450.0 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "id": 8, + "title": "Beat 8", + "bounding": [ + -20.0, + 3310.0, + 1250.0, + 450.0 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + } + ], + "definitions": { + "subgraphs": [] + }, + "config": {}, + "extra": { + "ds": { + "scale": 1, + "offset": [ + 0, + 0 + ] + } + }, + "version": 0.4 +} diff --git a/docs/serviceTemplates/workflows/ocean_h3_ugc_multishot.json b/docs/serviceTemplates/workflows/ocean_h3_ugc_multishot.json new file mode 100644 index 000000000..e05a891b4 --- /dev/null +++ b/docs/serviceTemplates/workflows/ocean_h3_ugc_multishot.json @@ -0,0 +1,3339 @@ +{ + "id": "9c1a4d2e-7b58-4f36-a0d1-3e6b52f7c418", + "revision": 0, + "last_node_id": 206, + "last_link_id": 72, + "nodes": [ + { + "id": 1, + "type": "UNETLoader", + "pos": [ + 20, + 60 + ], + "size": [ + 720, + 90 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 1 + ] + } + ], + "properties": { + "Node name for S&R": "UNETLoader", + "models": [ + { + "name": "minimax_h3_ref2va_pruned_int8_convrot.safetensors", + "url": "https://huggingface.co/Comfy-Org/MiniMax-H3/resolve/main/diffusion_models/minimax_h3_ref2va_pruned_int8_convrot.safetensors", + "directory": "diffusion_models" + } + ] + }, + "title": "Ref2VA model — dialogue", + "widgets_values": [ + "minimax_h3_ref2va_pruned_int8_convrot.safetensors", + "default" + ] + }, + { + "id": 2, + "type": "UNETLoader", + "pos": [ + 20, + 190 + ], + "size": [ + 720, + 90 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 2 + ] + } + ], + "properties": { + "Node name for S&R": "UNETLoader", + "models": [ + { + "name": "minimax_h3_fl2va_pruned_int8_convrot.safetensors", + "url": "https://huggingface.co/Comfy-Org/MiniMax-H3/resolve/main/diffusion_models/minimax_h3_fl2va_pruned_int8_convrot.safetensors", + "directory": "diffusion_models" + } + ] + }, + "title": "FL2VA model — action", + "widgets_values": [ + "minimax_h3_fl2va_pruned_int8_convrot.safetensors", + "default" + ] + }, + { + "id": 3, + "type": "CLIPLoader", + "pos": [ + 20, + 320 + ], + "size": [ + 720, + 120 + ], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "CLIP", + "type": "CLIP", + "links": [ + 10, + 11 + ] + } + ], + "properties": { + "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": 4, + "type": "VAELoader", + "pos": [ + 20, + 480 + ], + "size": [ + 720, + 70 + ], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VAE", + "type": "VAE", + "links": [ + 12, + 13, + 14 + ] + } + ], + "properties": { + "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" + } + ] + }, + "title": "Video VAE", + "widgets_values": [ + "minimax_h3_video_vae_fp16.safetensors" + ] + }, + { + "id": 5, + "type": "VAELoader", + "pos": [ + 20, + 590 + ], + "size": [ + 720, + 70 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "VAE", + "type": "VAE", + "links": [ + 15, + 16 + ] + } + ], + "properties": { + "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" + } + ] + }, + "title": "Audio VAE", + "widgets_values": [ + "minimax_h3_audio_vae_fp32.safetensors" + ] + }, + { + "id": 10, + "type": "PrimitiveBoolean", + "pos": [ + 820, + 60 + ], + "size": [ + 340, + 90 + ], + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "BOOLEAN", + "type": "BOOLEAN", + "links": [ + 3, + 4, + 5 + ] + } + ], + "properties": { + "Node name for S&R": "PrimitiveBoolean" + }, + "title": "Mode — off = Ref2VA (dialogue) · on = FL2VA (action)", + "widgets_values": [ + false + ], + "color": "#232", + "bgcolor": "#353" + }, + { + "id": 11, + "type": "ComfySwitchNode", + "pos": [ + 820, + 190 + ], + "size": [ + 340, + 90 + ], + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "name": "on_false", + "type": "MODEL", + "link": 1 + }, + { + "name": "on_true", + "type": "MODEL", + "link": 2 + }, + { + "name": "switch", + "type": "BOOLEAN", + "widget": { + "name": "switch" + }, + "link": 3 + } + ], + "outputs": [ + { + "name": "output", + "type": "MODEL", + "links": [ + 6 + ] + } + ], + "properties": { + "Node name for S&R": "ComfySwitchNode", + "cnr_id": "comfy-core" + }, + "title": "Model switch", + "widgets_values": [ + false + ] + }, + { + "id": 12, + "type": "LoraLoaderModelOnly", + "pos": [ + 820, + 400 + ], + "size": [ + 340, + 110 + ], + "flags": {}, + "order": 7, + "mode": 4, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 6 + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 7 + ] + } + ], + "properties": { + "Node name for S&R": "LoraLoaderModelOnly", + "models": [ + { + "name": "minimax_h3_turbo_4step_pruned_comfyui.safetensors", + "url": "https://huggingface.co/drbaph/MiniMax-H3-Turbo-Lora-ComfyUI/resolve/main/minimax_h3_turbo_4step_pruned_comfyui.safetensors", + "directory": "loras" + } + ] + }, + "title": "Turbo LoRA (bypassed)", + "widgets_values": [ + "minimax_h3_turbo_4step_pruned_comfyui.safetensors", + 1 + ] + }, + { + "id": 13, + "type": "MiniMaxH3SigmaShift", + "pos": [ + 820, + 680 + ], + "size": [ + 340, + 90 + ], + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 7 + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 8, + 9 + ] + } + ], + "properties": { + "Node name for S&R": "MiniMaxH3SigmaShift" + }, + "widgets_values": [ + 12, + 3 + ] + }, + { + "id": 20, + "type": "PrimitiveStringMultiline", + "pos": [ + 1660, + 60 + ], + "size": [ + 680, + 340 + ], + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 17 + ] + } + ], + "properties": { + "Node name for S&R": "PrimitiveStringMultiline" + }, + "title": "subject_definitions", + "widgets_values": [ + "subject_definitions:\n (, , ): Maya, a woman in her late twenties with warm brown skin, dark shoulder-length curls parted on the left, and a small mole under her right eye. She wears an oversized cream ribbed sweater. is her three-quarter view holding the product, her straight-on close-up, her profile.\n (): the product, a 50 ml frosted-glass jar with a matte white screw lid and one line of thin black serif type reading \"AURELIE\".\n: the room, a small apartment bathroom with white subway tile, a round brass-framed mirror, and one window camera-left throwing soft overcast daylight across her face." + ], + "color": "#232", + "bgcolor": "#353" + }, + { + "id": 21, + "type": "PrimitiveStringMultiline", + "pos": [ + 1660, + 440 + ], + "size": [ + 680, + 300 + ], + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 20 + ] + } + ], + "properties": { + "Node name for S&R": "PrimitiveStringMultiline" + }, + "title": "retention_analysis", + "widgets_values": [ + "retention_analysis:\n (appears in [Shot 1], [Shot 2]): fully_preserved - face geometry, the mole under the right eye, the curl pattern and hair part, and the cream ribbed sweater carry across both shots unchanged.\n (appears in [Shot 1], [Shot 2]): fully_preserved - jar proportions, matte white lid and the \"AURELIE\" label type stay identical, and the label stays legible and correctly spelled at every distance.\n (appears in [Shot 1], [Shot 2]): attribute_transfer - the tile, mirror and window light of carry into both shots; the camera position and framing change, the room does not." + ], + "color": "#232", + "bgcolor": "#353" + }, + { + "id": 22, + "type": "PrimitiveStringMultiline", + "pos": [ + 1660, + 780 + ], + "size": [ + 680, + 260 + ], + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 26, + 35 + ] + } + ], + "properties": { + "Node name for S&R": "PrimitiveStringMultiline" + }, + "title": "non_diegetic_music", + "widgets_values": [ + "non_diegetic_music:\nA single nylon-string guitar figure at roughly 80 BPM, plucked in steady eighth notes with a soft brushed shaker on the offbeat. It enters under the first line, holds flat through the cut, and drops about 6 dB under the second line." + ], + "color": "#232", + "bgcolor": "#353" + }, + { + "id": 23, + "type": "PrimitiveStringMultiline", + "pos": [ + 1660, + 1240 + ], + "size": [ + 680, + 220 + ], + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 18, + 29 + ] + } + ], + "properties": { + "Node name for S&R": "PrimitiveStringMultiline" + }, + "title": "summary", + "widgets_values": [ + "summary:\nMaya sets the jar down on the sink ledge and tells the camera what changed for her skin, then the shot cuts closer as she twists the lid open and shows the texture on her fingertip." + ], + "color": "#322", + "bgcolor": "#533" + }, + { + "id": 24, + "type": "PrimitiveStringMultiline", + "pos": [ + 1660, + 1500 + ], + "size": [ + 680, + 420 + ], + "flags": {}, + "order": 13, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 22, + 31 + ] + } + ], + "properties": { + "Node name for S&R": "PrimitiveStringMultiline" + }, + "title": "detailed_description", + "widgets_values": [ + "detailed_description:\n[Shot 1] Medium shot, waist up, centered with the brass mirror behind her left shoulder. She sets down on the tile ledge with her right hand, looks into the lens and speaks. The camera pushes in with small amplitude at slow speed across the whole shot. (S1) says: [English] Okay, three weeks in, and I finally have to talk about this one.\n[Shot 2] At 00:06.000, the camera cuts to a close-up of her hands and the lower half of her face. She twists the matte white lid off , tips the jar toward the lens and presses one fingertip into the cream. The camera tilts down with medium amplitude at slow speed to follow her hands, then holds. (S1) says: [English] It is thicker than it looks, you barely need this much." + ], + "color": "#322", + "bgcolor": "#533" + }, + { + "id": 25, + "type": "PrimitiveStringMultiline", + "pos": [ + 1660, + 1960 + ], + "size": [ + 680, + 260 + ], + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 24, + 33 + ] + } + ], + "properties": { + "Node name for S&R": "PrimitiveStringMultiline" + }, + "title": "overall_soundscape", + "widgets_values": [ + "overall_soundscape:\nClose, dry indoor room tone with the faint hum of a bathroom fan. The glass jar sets down on the tile with one short hard tap in [Shot 1]. In [Shot 2] the lid gives a fine gritty twist as it unthreads, and the cream makes a soft wet press under her fingertip. She takes a short audible breath in before her second line." + ], + "color": "#322", + "bgcolor": "#533" + }, + { + "id": 30, + "type": "StringFormat", + "pos": [ + 2420, + 60 + ], + "size": [ + 460, + 130 + ], + "flags": {}, + "order": 15, + "mode": 0, + "inputs": [ + { + "label": "a", + "name": "values.a", + "type": "*", + "link": 17 + }, + { + "label": "b", + "name": "values.b", + "type": "*", + "link": 18 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 19 + ] + } + ], + "properties": { + "Node name for S&R": "StringFormat" + }, + "title": "Ref2VA 1/5 — subject_definitions + summary", + "widgets_values": [ + "{a}\n\n{b}" + ] + }, + { + "id": 31, + "type": "StringFormat", + "pos": [ + 2420, + 220 + ], + "size": [ + 460, + 130 + ], + "flags": {}, + "order": 16, + "mode": 0, + "inputs": [ + { + "label": "a", + "name": "values.a", + "type": "*", + "link": 19 + }, + { + "label": "b", + "name": "values.b", + "type": "*", + "link": 20 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 21 + ] + } + ], + "properties": { + "Node name for S&R": "StringFormat" + }, + "title": "Ref2VA 2/5 — + retention_analysis", + "widgets_values": [ + "{a}\n\n{b}" + ] + }, + { + "id": 32, + "type": "StringFormat", + "pos": [ + 2420, + 380 + ], + "size": [ + 460, + 130 + ], + "flags": {}, + "order": 17, + "mode": 0, + "inputs": [ + { + "label": "a", + "name": "values.a", + "type": "*", + "link": 21 + }, + { + "label": "b", + "name": "values.b", + "type": "*", + "link": 22 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 23 + ] + } + ], + "properties": { + "Node name for S&R": "StringFormat" + }, + "title": "Ref2VA 3/5 — + detailed_description", + "widgets_values": [ + "{a}\n\n{b}" + ] + }, + { + "id": 33, + "type": "StringFormat", + "pos": [ + 2420, + 540 + ], + "size": [ + 460, + 130 + ], + "flags": {}, + "order": 18, + "mode": 0, + "inputs": [ + { + "label": "a", + "name": "values.a", + "type": "*", + "link": 23 + }, + { + "label": "b", + "name": "values.b", + "type": "*", + "link": 24 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 25 + ] + } + ], + "properties": { + "Node name for S&R": "StringFormat" + }, + "title": "Ref2VA 4/5 — + overall_soundscape", + "widgets_values": [ + "{a}\n\n{b}" + ] + }, + { + "id": 34, + "type": "StringFormat", + "pos": [ + 2420, + 700 + ], + "size": [ + 460, + 130 + ], + "flags": {}, + "order": 19, + "mode": 0, + "inputs": [ + { + "label": "a", + "name": "values.a", + "type": "*", + "link": 25 + }, + { + "label": "b", + "name": "values.b", + "type": "*", + "link": 26 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 27 + ] + } + ], + "properties": { + "Node name for S&R": "StringFormat" + }, + "title": "Ref2VA 5/5 — + non_diegetic_music", + "widgets_values": [ + "{a}\n\n{b}" + ] + }, + { + "id": 40, + "type": "PrimitiveStringMultiline", + "pos": [ + 2420, + 880 + ], + "size": [ + 460, + 200 + ], + "flags": {}, + "order": 20, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 28 + ] + } + ], + "properties": { + "Node name for S&R": "PrimitiveStringMultiline" + }, + "title": "FL2VA image-alignment line", + "widgets_values": [ + "Match the given first frame exactly: same person, same face, same wardrobe, same product and label, same room and lighting. Continue the motion out of that frame — do not restage, recast or relight. Treat the summary and detailed_description below as one integrated_multimodal_description." + ] + }, + { + "id": 41, + "type": "StringFormat", + "pos": [ + 2420, + 1120 + ], + "size": [ + 460, + 130 + ], + "flags": {}, + "order": 21, + "mode": 0, + "inputs": [ + { + "label": "a", + "name": "values.a", + "type": "*", + "link": 28 + }, + { + "label": "b", + "name": "values.b", + "type": "*", + "link": 29 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 30 + ] + } + ], + "properties": { + "Node name for S&R": "StringFormat" + }, + "title": "FL2VA 1/4 — alignment + summary", + "widgets_values": [ + "{a}\n\n{b}" + ] + }, + { + "id": 42, + "type": "StringFormat", + "pos": [ + 2420, + 1280 + ], + "size": [ + 460, + 130 + ], + "flags": {}, + "order": 22, + "mode": 0, + "inputs": [ + { + "label": "a", + "name": "values.a", + "type": "*", + "link": 30 + }, + { + "label": "b", + "name": "values.b", + "type": "*", + "link": 31 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 32 + ] + } + ], + "properties": { + "Node name for S&R": "StringFormat" + }, + "title": "FL2VA 2/4 — + detailed_description", + "widgets_values": [ + "{a}\n\n{b}" + ] + }, + { + "id": 43, + "type": "StringFormat", + "pos": [ + 2420, + 1440 + ], + "size": [ + 460, + 130 + ], + "flags": {}, + "order": 23, + "mode": 0, + "inputs": [ + { + "label": "a", + "name": "values.a", + "type": "*", + "link": 32 + }, + { + "label": "b", + "name": "values.b", + "type": "*", + "link": 33 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 34 + ] + } + ], + "properties": { + "Node name for S&R": "StringFormat" + }, + "title": "FL2VA 3/4 — + overall_soundscape", + "widgets_values": [ + "{a}\n\n{b}" + ] + }, + { + "id": 44, + "type": "StringFormat", + "pos": [ + 2420, + 1600 + ], + "size": [ + 460, + 130 + ], + "flags": {}, + "order": 24, + "mode": 0, + "inputs": [ + { + "label": "a", + "name": "values.a", + "type": "*", + "link": 34 + }, + { + "label": "b", + "name": "values.b", + "type": "*", + "link": 35 + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 36 + ] + } + ], + "properties": { + "Node name for S&R": "StringFormat" + }, + "title": "FL2VA 4/4 — + non_diegetic_music", + "widgets_values": [ + "{a}\n\n{b}" + ] + }, + { + "id": 50, + "type": "ResolutionSelector", + "pos": [ + 2960, + 60 + ], + "size": [ + 460, + 170 + ], + "flags": {}, + "order": 25, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "width", + "type": "INT", + "links": [ + 37, + 38 + ] + }, + { + "name": "height", + "type": "INT", + "links": [ + 39, + 40 + ] + } + ], + "properties": { + "Node name for S&R": "ResolutionSelector" + }, + "title": "Resolution", + "widgets_values": [ + "9:16 (Portrait Widescreen)", + 0.8, + 32 + ], + "color": "#322", + "bgcolor": "#533", + "showAdvanced": false + }, + { + "id": 51, + "type": "PrimitiveFloat", + "pos": [ + 2960, + 260 + ], + "size": [ + 460, + 70 + ], + "flags": {}, + "order": 26, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "FLOAT", + "type": "FLOAT", + "links": [ + 41 + ] + } + ], + "properties": { + "Node name for S&R": "PrimitiveFloat" + }, + "title": "Duration (seconds)", + "widgets_values": [ + 12 + ], + "color": "#322", + "bgcolor": "#533" + }, + { + "id": 52, + "type": "ComfyMathExpression", + "pos": [ + 2960, + 360 + ], + "size": [ + 460, + 60 + ], + "flags": {}, + "order": 27, + "mode": 0, + "inputs": [ + { + "label": "a", + "name": "values.a", + "type": "FLOAT,INT,BOOLEAN", + "link": 41 + }, + { + "label": "b", + "name": "values.b", + "shape": 7, + "type": "FLOAT,INT,BOOLEAN", + "link": null + } + ], + "outputs": [ + { + "name": "FLOAT", + "type": "FLOAT", + "links": [] + }, + { + "name": "INT", + "type": "INT", + "links": [ + 42, + 43 + ] + }, + { + "name": "BOOL", + "type": "BOOLEAN", + "links": [] + } + ], + "properties": { + "Node name for S&R": "ComfyMathExpression" + }, + "title": "Duration → length", + "widgets_values": [ + "max(5, round(a * 24)) + (5 - (max(5, round(a * 24)) % 17)) % 17" + ] + }, + { + "id": 60, + "type": "LoadImage", + "pos": [ + 2960, + 600 + ], + "size": [ + 360, + 380 + ], + "flags": {}, + "order": 28, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 44 + ] + }, + { + "name": "MASK", + "type": "MASK", + "links": null + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "title": "", + "widgets_values": [ + "subject-girl-holding-skincare-bottle.png", + "image" + ] + }, + { + "id": 61, + "type": "LoadImage", + "pos": [ + 3340, + 600 + ], + "size": [ + 360, + 380 + ], + "flags": {}, + "order": 29, + "mode": 4, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 45 + ] + }, + { + "name": "MASK", + "type": "MASK", + "links": null + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "title": "", + "widgets_values": [ + "subject-girl-holding-skincare-bottle.png", + "image" + ] + }, + { + "id": 62, + "type": "LoadImage", + "pos": [ + 3720, + 600 + ], + "size": [ + 360, + 380 + ], + "flags": {}, + "order": 30, + "mode": 4, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 46 + ] + }, + { + "name": "MASK", + "type": "MASK", + "links": null + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "title": "", + "widgets_values": [ + "subject-girl-holding-skincare-bottle.png", + "image" + ] + }, + { + "id": 63, + "type": "LoadVideo", + "pos": [ + 2960, + 1120 + ], + "size": [ + 340, + 340 + ], + "flags": {}, + "order": 31, + "mode": 4, + "inputs": [], + "outputs": [ + { + "name": "VIDEO", + "type": "VIDEO", + "links": [ + 47 + ] + } + ], + "properties": { + "Node name for S&R": "LoadVideo", + "cnr_id": "comfy-core" + }, + "title": "Hero beat", + "widgets_values": [ + "beat_00001_.mp4" + ] + }, + { + "id": 64, + "type": "GetVideoComponents", + "pos": [ + 3340, + 1120 + ], + "size": [ + 340, + 130 + ], + "flags": {}, + "order": 32, + "mode": 4, + "inputs": [ + { + "name": "video", + "type": "VIDEO", + "link": 47 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 48 + ] + }, + { + "name": "audio", + "type": "AUDIO", + "links": [ + 49 + ] + }, + { + "name": "fps", + "type": "FLOAT", + "links": [] + }, + { + "name": "bit_depth", + "type": "INT", + "links": [] + } + ], + "properties": { + "Node name for S&R": "GetVideoComponents", + "cnr_id": "comfy-core" + }, + "title": "Hero beat → frames + audio" + }, + { + "id": 65, + "type": "LoadAudio", + "pos": [ + 3760, + 1120 + ], + "size": [ + 340, + 160 + ], + "flags": {}, + "order": 33, + "mode": 4, + "inputs": [], + "outputs": [ + { + "name": "AUDIO", + "type": "AUDIO", + "links": [ + 50 + ] + } + ], + "properties": { + "Node name for S&R": "LoadAudio" + }, + "title": "