Accept section sets directly in director

This commit is contained in:
OpenClaw Agent
2026-07-20 09:24:16 +00:00
parent e01ceef71b
commit e113472c7d
2 changed files with 30 additions and 11 deletions

View File

@@ -11550,6 +11550,10 @@ app.registerExtension({
self.removeInput(idx); self.removeInput(idx);
} }
} }
const timelineIdx = self.inputs.findIndex(i => i?.name === "timeline");
if (timelineIdx !== -1 && self.inputs[timelineIdx]?.link == null) {
self.removeInput(timelineIdx);
}
}; };
this._resolveNodeLinkedValue = function (targetNode, inputName, options = {}) { this._resolveNodeLinkedValue = function (targetNode, inputName, options = {}) {
const originNode = self._findLinkedOriginNode(targetNode, inputName); const originNode = self._findLinkedOriginNode(targetNode, inputName);
@@ -11583,14 +11587,18 @@ app.registerExtension({
return { imageFile, imageB64: imageUrl }; return { imageFile, imageB64: imageUrl };
}; };
this._buildExternalTimelinePayload = function () { this._buildExternalTimelinePayload = function () {
const timelineNode = self._findLinkedOriginNode(self, "timeline"); let sectionSetNode = self._findLinkedOriginNode(self, "section_set");
const comfyClass = timelineNode?.comfyClass || timelineNode?.type || ""; let setClass = sectionSetNode?.comfyClass || sectionSetNode?.type || "";
if (!timelineNode || comfyClass !== "TimelineCS") { if (!sectionSetNode || setClass !== "TimelineSectionSetCS") {
return null; const timelineNode = self._findLinkedOriginNode(self, "timeline");
const comfyClass = timelineNode?.comfyClass || timelineNode?.type || "";
if (!timelineNode || comfyClass !== "TimelineCS") {
return null;
}
sectionSetNode = self._findLinkedOriginNode(timelineNode, "section_set");
setClass = sectionSetNode?.comfyClass || sectionSetNode?.type || "";
} }
const sectionSetNode = self._findLinkedOriginNode(timelineNode, "section_set");
const setClass = sectionSetNode?.comfyClass || sectionSetNode?.type || "";
const sections = []; const sections = [];
let duration = 0; let duration = 0;
if (sectionSetNode && setClass === "TimelineSectionSetCS") { if (sectionSetNode && setClass === "TimelineSectionSetCS") {

View File

@@ -33,7 +33,7 @@ from .prompt_relay import (
from .patches import detect_model_type, apply_patches from .patches import detect_model_type, apply_patches
from .msr_character import MSRCharacterSetData from .msr_character import MSRCharacterSetData
from .timeline_nodes import TimelineData from .timeline_nodes import TimelineData, TimelineSectionSetData
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@@ -2044,10 +2044,15 @@ class LTXDirector(io.ComfyNode):
optional=True, optional=True,
tooltip="Optional external MSR Character Set. Replaces the legacy inline character panel in the director UI.", tooltip="Optional external MSR Character Set. Replaces the legacy inline character panel in the director UI.",
), ),
TimelineSectionSetData.Input(
"section_set",
optional=True,
tooltip="Optional external Timeline Section Set DUMAS payload. When connected, it populates the main timeline track and derives the duration from the sections.",
),
TimelineData.Input( TimelineData.Input(
"timeline", "timeline",
optional=True, optional=True,
tooltip="Optional external Timeline DUMAS payload. When connected, it populates the main timeline track and duration.", tooltip="Legacy external Timeline DUMAS payload kept for backward compatibility with older workflows.",
), ),
io.Float.Input( io.Float.Input(
"start", force_input=True, optional=True, default=0.0, "start", force_input=True, optional=True, default=0.0,
@@ -2084,7 +2089,7 @@ class LTXDirector(io.ComfyNode):
custom_width=768, custom_height=512, resize_method="maintain aspect ratio", custom_width=768, custom_height=512, resize_method="maintain aspect ratio",
divisible_by=32, img_compression=0, audio_vae=None, optional_latent=None, divisible_by=32, img_compression=0, audio_vae=None, optional_latent=None,
use_custom_audio=False, inpaint_audio=True, use_custom_motion=True, override_audio=False, use_custom_audio=False, inpaint_audio=True, use_custom_motion=True, override_audio=False,
vae=None, reference_strength=1.0, character_set=None, timeline=None, vae=None, reference_strength=1.0, character_set=None, section_set=None, timeline=None,
start=None, end=None, duration=None) -> io.NodeOutput: start=None, end=None, duration=None) -> io.NodeOutput:
input_dir = folder_paths.get_input_directory() input_dir = folder_paths.get_input_directory()
image_cache = {} image_cache = {}
@@ -2101,9 +2106,15 @@ class LTXDirector(io.ComfyNode):
processed_image_cache[cache_key] = processed processed_image_cache[cache_key] = processed
return processed return processed
if timeline is not None: external_timeline_source = None
if section_set is not None:
external_timeline_source = {"sections": list((section_set or {}).get("sections") or [])}
elif timeline is not None:
external_timeline_source = timeline
if external_timeline_source is not None:
external_tdata, external_local_prompts, external_segment_lengths, external_duration_seconds, external_duration_frames = _build_runtime_timeline_payload( external_tdata, external_local_prompts, external_segment_lengths, external_duration_seconds, external_duration_frames = _build_runtime_timeline_payload(
timeline, external_timeline_source,
float(frame_rate) if frame_rate else 24.0, float(frame_rate) if frame_rate else 24.0,
) )
try: try: