Spaces:
Running on Zero
Running on Zero
| """Extract six mode-specific workflow templates from the master LTX 2.3 All-In-One workflow. | |
| Each ComfyUI group whose title starts with a number (e.g. "01 Text to Video") becomes | |
| a mode template containing only that group's nodes plus shared scaffolding (Models, | |
| Lora, Setting, Prompt, Load Audio/Image/Video, Output groups). | |
| Group title -> output filename mapping: | |
| 01 -> t2v.json | |
| 02 -> a2v.json | |
| 03 -> i2v.json | |
| 04 -> lipsync.json | |
| 05 -> keyframe.json | |
| 06 -> style.json | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import json | |
| import pathlib | |
| import sys | |
| from collections.abc import Iterable | |
| GROUP_TO_FILENAME: dict[str, str] = { | |
| "01": "t2v.json", | |
| "02": "a2v.json", | |
| "03": "i2v.json", | |
| "04": "lipsync.json", | |
| "05": "keyframe.json", | |
| "06": "style.json", | |
| } | |
| SHARED_GROUP_PREFIXES: tuple[str, ...] = ( | |
| "Models", | |
| "Lora", | |
| "Setting", | |
| "Prompt", | |
| "Load Audio", | |
| "Load Image", | |
| "Load Images", | |
| "Load Video", | |
| "Output", | |
| ) | |
| def _node_in_group(node: dict, group: dict) -> bool: | |
| """Test whether a node's position lies inside a group's bounding box.""" | |
| if "pos" not in node or "bounding" not in group: | |
| return False | |
| nx, ny = node["pos"][0], node["pos"][1] | |
| gx, gy, gw, gh = group["bounding"] | |
| return (gx <= nx <= gx + gw) and (gy <= ny <= gy + gh) | |
| def _select_groups(master: dict, mode_prefix: str) -> list[dict]: | |
| """Pick the mode group plus all shared groups.""" | |
| selected: list[dict] = [] | |
| for g in master.get("groups", []): | |
| title = (g.get("title") or "").strip() | |
| if title.startswith(mode_prefix + " "): | |
| selected.append(g) | |
| elif any(title.startswith(p) for p in SHARED_GROUP_PREFIXES): | |
| selected.append(g) | |
| return selected | |
| def _collect_nodes(master: dict, groups: Iterable[dict]) -> list[dict]: | |
| """Return all nodes lying inside any of the given groups.""" | |
| groups_list = list(groups) | |
| keep: list[dict] = [] | |
| for node in master.get("nodes", []): | |
| if any(_node_in_group(node, g) for g in groups_list): | |
| keep.append(node) | |
| return keep | |
| def _collect_links(master: dict, kept_node_ids: set[int]) -> list[list]: | |
| """Keep only links where both endpoints are in the surviving node set.""" | |
| return [ | |
| link | |
| for link in master.get("links", []) | |
| # ComfyUI link tuple format: [link_id, src_node_id, src_out, dst_node_id, dst_in, type] | |
| if link[1] in kept_node_ids and link[3] in kept_node_ids | |
| ] | |
| def extract_mode(master: dict, mode_prefix: str) -> dict: | |
| """Build a focused workflow JSON for the given mode group prefix.""" | |
| groups = _select_groups(master, mode_prefix) | |
| nodes = _collect_nodes(master, groups) | |
| kept_ids = {n["id"] for n in nodes} | |
| links = _collect_links(master, kept_ids) | |
| return { | |
| "id": f"ltx23-aio-{mode_prefix}", | |
| "revision": 0, | |
| "last_node_id": max(kept_ids, default=0), | |
| "last_link_id": max((link[0] for link in links), default=0), | |
| "nodes": nodes, | |
| "links": links, | |
| "groups": groups, | |
| "definitions": master.get("definitions", {}), | |
| "config": master.get("config", {}), | |
| "extra": master.get("extra", {}), | |
| "version": master.get("version", 0.4), | |
| } | |
| def main(argv: list[str] | None = None) -> int: | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument("--master", type=pathlib.Path, required=True) | |
| parser.add_argument("--out", type=pathlib.Path, required=True) | |
| args = parser.parse_args(argv) | |
| master = json.loads(args.master.read_text()) | |
| args.out.mkdir(parents=True, exist_ok=True) | |
| for prefix, filename in GROUP_TO_FILENAME.items(): | |
| wf = extract_mode(master, prefix) | |
| out_path = args.out / filename | |
| out_path.write_text(json.dumps(wf, indent=2)) | |
| print(f" -> wrote {out_path} ({len(wf['nodes'])} nodes, {len(wf['links'])} links)") | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main()) | |