Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
2ca43c3
change recursion style execution to worklist style execution
ltdrdata Jun 3, 2023
a1298fe
Bug fix for a crash occurring under specific conditions when handling…
ltdrdata Jun 3, 2023
6f35017
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 3, 2023
e09d339
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 3, 2023
5325e90
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 3, 2023
54f03a5
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 3, 2023
c93fa15
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 5, 2023
31b7f82
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 6, 2023
28657c6
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 7, 2023
502c7a7
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 8, 2023
59c2c5c
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 8, 2023
0be6ed7
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 9, 2023
d5f43bd
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 10, 2023
0ca8ba4
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 10, 2023
fedc20e
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 11, 2023
db4535e
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 12, 2023
f03eaac
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 13, 2023
56fc17c
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 13, 2023
78d0ead
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 15, 2023
e1e59d8
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 15, 2023
e5bf87e
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 16, 2023
067e2ac
* The functionality of interrupting a specific execution path in a no…
Jun 16, 2023
173bdd2
loop support added
ltdrdata Jun 16, 2023
dce406d
Add InputZip, InputUnzip
ltdrdata Jun 16, 2023
2e791db
For final nodes where there are no further outputs like the preview n…
ltdrdata Jun 16, 2023
e3bd4ee
Support execution control feature.
ltdrdata Jun 17, 2023
4040292
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 17, 2023
7cde744
robust patch for None return
ltdrdata Jun 17, 2023
d60b306
bugfix: LoopControl return type
ltdrdata Jun 17, 2023
8b0ec81
bugfix: loop explosion by multiple input nodes
ltdrdata Jun 17, 2023
e8cb166
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 17, 2023
241536d
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 18, 2023
6e4b44a
prevent erasing output of muted nodes
ltdrdata Jun 18, 2023
35b3d6f
Merge remote-tracking branch 'origin/refactor/execution' into refacto…
ltdrdata Jun 18, 2023
d1bef83
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 18, 2023
7859fb4
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 19, 2023
be62255
crash fix
ltdrdata Jun 19, 2023
debeaff
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 20, 2023
41c3219
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 20, 2023
a97d317
Merge branch 'Main' into refactor/execution
Jun 21, 2023
a9a086a
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 21, 2023
357082e
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 22, 2023
c220495
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 23, 2023
c60d07e
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 23, 2023
d40a603
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 23, 2023
6ae4b15
Merge branch 'Main' into refactor/execution
ltdrdata Jun 24, 2023
c588cd8
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 25, 2023
91f5102
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 25, 2023
b85158e
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 26, 2023
01a43fb
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 27, 2023
06e7ccd
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 27, 2023
efbdeee
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 28, 2023
5162b78
robust patch
ltdrdata Jun 28, 2023
9db03ab
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 29, 2023
9aed6cd
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jun 30, 2023
ddeb4aa
Merge branch 'Main' into refactor/execution
ltdrdata Jul 1, 2023
5372c5e
object storage applied
ltdrdata Jul 1, 2023
4c37e6f
object storage application fix
ltdrdata Jul 1, 2023
10fb995
object storage application fix2
ltdrdata Jul 1, 2023
28e1856
Merge branch 'refactor/execution' of https://github.com/ltdrdata/Comf…
ltdrdata Jul 1, 2023
fb54fda
Merge branch 'Main' into refactor/execution
ltdrdata Jul 1, 2023
01ebdfe
bugfix: pass 'prompt' and 'extra_data' to get_input_data for determin…
ltdrdata Jul 1, 2023
af55bb7
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 2, 2023
8b57063
support object_storage in IS_CHANGED
ltdrdata Jul 2, 2023
c196526
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 2, 2023
d0f1e5d
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 2, 2023
f6555e5
hotfix: ExecutionOneOf
ltdrdata Jul 2, 2023
194c222
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 3, 2023
e3d819a
Merge branch 'Main' into execution
ltdrdata Jul 4, 2023
b3fd3c3
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 4, 2023
06734b8
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 4, 2023
80df372
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 5, 2023
b5b9918
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 6, 2023
e042485
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 6, 2023
5e66f40
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 7, 2023
cce0eee
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 8, 2023
dda2190
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 9, 2023
0485828
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 9, 2023
d484088
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 10, 2023
bb4d538
Merge branch 'Main' into refactor/execution
Jul 11, 2023
3856763
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 12, 2023
c21caf3
Handling the workflow execution of a node composed solely of optional…
ltdrdata Jul 12, 2023
3262f02
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 13, 2023
a800874
Merge branch 'Main' into refactor/execution
Jul 14, 2023
83b01a3
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 14, 2023
fb5c7ce
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 15, 2023
eb1ff03
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 16, 2023
ef5680b
robust patch
ltdrdata Jul 16, 2023
78568dd
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 17, 2023
8159c6c
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 18, 2023
932dbf0
add CATEGORY for execution nodes
Jul 18, 2023
41179d5
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 19, 2023
c179691
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 19, 2023
948f9d5
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 19, 2023
4c1ed52
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 20, 2023
ddb5c28
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 20, 2023
4987001
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 21, 2023
1ea6da1
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 22, 2023
f9f7dc0
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 22, 2023
01c1d83
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 23, 2023
2bbbc94
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 25, 2023
859f2f5
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 26, 2023
3074cf8
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 27, 2023
cd32eda
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 28, 2023
f86755f
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 30, 2023
3b77780
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Jul 31, 2023
35cde85
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Aug 1, 2023
5c49b07
Merge branch 'Main' into refactor/execution
Aug 3, 2023
bffa6b5
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Aug 3, 2023
946b6f4
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Aug 5, 2023
e3aa8d8
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Aug 5, 2023
4b30365
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Aug 6, 2023
316a836
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Aug 7, 2023
27aa6a4
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Aug 10, 2023
61ce670
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Aug 12, 2023
1c93485
Merge branch 'comfyanonymous:master' into refactor/execution
ltdrdata Aug 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 191 additions & 0 deletions comfy_extras/nodes_execution_control.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
class LoopControl:
@classmethod
def INPUT_TYPES(s):
return {"required": {
"loop_condition": ("LOOP_CONDITION", ),
"initial_input": ("*", ),
"loopback_input": ("*", ),
},
}

RETURN_TYPES = ("*", )
FUNCTION = "doit"

CATEGORY = "execution"
def doit(s, **kwargs):
if 'loopback_input' not in kwargs or kwargs['loopback_input'] is None:
current = kwargs['initial_input']
else:
current = kwargs['loopback_input']

result = kwargs['loop_condition'].get_next(kwargs['initial_input'], current)
if result is None:
return None
else:
return (result, )


class CounterCondition:
def __init__(self, value):
self.max = value
self.current = 0

def get_next(self, initial_value, value):
print(f"CounterCondition: {self.current}/{self.max}")

self.current += 1
if self.current == 1:
return initial_value
elif self.current <= self.max:
return value
else:
return None


class LoopCounterCondition:
@classmethod
def INPUT_TYPES(s):
return {"required": {
"count": ("INT", {"default": 1, "min": 0, "max": 9999999, "step": 1}),
"trigger": (["A", "B"], )
},
}

RETURN_TYPES = ("LOOP_CONDITION", )
FUNCTION = "doit"

CATEGORY = "execution"
def doit(s, count, trigger):
return (CounterCondition(count), )


# To facilitate the use of multiple inputs as loopback inputs, InputZip and InputUnzip are provided.
class InputZip:
@classmethod
def INPUT_TYPES(s):
return {"required": {
"input1": ("*", ),
"input2": ("*", ),
},
}

RETURN_TYPES = ("*", )
FUNCTION = "doit"

CATEGORY = "execution"
def doit(s, input1, input2):
return ((input1, input2), )


class InputUnzip:
@classmethod
def INPUT_TYPES(s):
return {"required": {
"zipped_input": ("*", ),
},
}

RETURN_TYPES = ("*", "*", )
FUNCTION = "doit"

CATEGORY = "execution"
def doit(s, zipped_input):
input1, input2 = zipped_input
return (input1, input2, )


class ExecutionBlocker:
@classmethod
def INPUT_TYPES(s):
return {"required": {
"input": ("*", ),
"signal": ("*", ),
},
}

RETURN_TYPES = ("*", )
FUNCTION = "doit"

CATEGORY = "execution"
def doit(s, input, signal):
return input


class ExecutionOneOf:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"input1": ("*", ),
},
"optional": {
"input2": ("*", ),
"input3": ("*", ),
"input4": ("*", ),
"input5": ("*", ),
},
}

RETURN_TYPES = ("*", )
FUNCTION = "doit"

CATEGORY = "execution"
def doit(s, **kwargs):
if 'input1' in kwargs and kwargs['input1'] is not None:
return (kwargs['input1'], )
elif 'input2' in kwargs and kwargs['input2'] is not None:
return (kwargs['input2'], )
elif 'input3' in kwargs and kwargs['input3'] is not None:
return (kwargs['input3'],)
elif 'input4' in kwargs and kwargs['input4'] is not None:
return (kwargs['input4'],)
elif 'input5' in kwargs and kwargs['input5'] is not None:
return (kwargs['input5'],)
else:
return None


class ExecutionSwitch:
@classmethod
def INPUT_TYPES(s):
return {"required": {
"select": ("INT", {"default": 1, "min": 0, "max": 5}),
"input1": ("*", ),
},
"optional": {
"input2_opt": ("*", ),
"input3_opt": ("*", ),
"input4_opt": ("*", ),
"input5_opt": ("*", ),
}
}

RETURN_TYPES = ("*", "*", "*", "*", "*", )
FUNCTION = "doit"

CATEGORY = "execution"

def doit(s, select, input1, input2_opt=None, input3_opt=None, input4_opt=None, input5_opt=None):
if select == 1:
return input1, None, None, None, None
elif select == 2:
return None, input2_opt, None, None, None
elif select == 3:
return None, None, input3_opt, None, None
elif select == 4:
return None, None, None, input4_opt, None
elif select == 5:
return None, None, None, None, input5_opt
else:
return None, None, None, None, None


NODE_CLASS_MAPPINGS = {
"ExecutionSwitch": ExecutionSwitch,
"ExecutionBlocker": ExecutionBlocker,
"ExecutionOneOf": ExecutionOneOf,
"LoopControl": LoopControl,
"LoopCounterCondition": LoopCounterCondition,
"InputZip": InputZip,
"InputUnzip": InputUnzip,
}
72 changes: 51 additions & 21 deletions execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,16 @@ def get_input_data(inputs, class_def, unique_id, outputs={}, prompt={}, extra_da
if isinstance(input_data, list):
input_unique_id = input_data[0]
output_index = input_data[1]
if input_unique_id not in outputs:
return None
obj = outputs[input_unique_id][output_index]
input_data_all[x] = obj
if input_unique_id in outputs and len(outputs[input_unique_id]) == 0:
input_data_all[x] = []
else:
if class_def.__name__ != "LoopControl" and class_def.__name__ != "ExecutionOneOf":
if input_unique_id not in outputs or outputs[input_unique_id][input_data[1]] == [None]:
return None

if input_unique_id in outputs and outputs[input_unique_id][input_data[1]] != [None]:
obj = outputs[input_unique_id][output_index]
input_data_all[x] = obj
else:
if ("required" in valid_inputs and x in valid_inputs["required"]) or ("optional" in valid_inputs and x in valid_inputs["optional"]):
input_data_all[x] = [input_data]
Expand All @@ -46,16 +52,20 @@ def map_node_over_list(obj, input_data_all, func, allow_interrupt=False):
if hasattr(obj, "INPUT_IS_LIST"):
input_is_list = obj.INPUT_IS_LIST

if len(input_data_all) == 0:
max_len_input = 0
else:
if input_data_all is not None and len(input_data_all) > 0:
max_len_input = max([len(x) for x in input_data_all.values()])

else:
max_len_input = 0

# get a slice of inputs, repeat last input when list isn't long enough
def slice_dict(d, i):
d_new = dict()
for k,v in d.items():
d_new[k] = v[i if len(v) > i else -1]

for k, v in d.items():
if not v:
continue
else:
d_new[k] = v[i if len(v) > i else -1]
return d_new

results = []
Expand All @@ -71,15 +81,24 @@ def slice_dict(d, i):
for i in range(max_len_input):
if allow_interrupt:
nodes.before_node_execution()
results.append(getattr(obj, func)(**slice_dict(input_data_all, i)))

params = slice_dict(input_data_all, i)

if params is None:
return None

results.append(getattr(obj, func)(**params))
return results


def get_output_data(obj, input_data_all):

results = []
uis = []
return_values = map_node_over_list(obj, input_data_all, obj.FUNCTION, allow_interrupt=True)

if return_values is None:
return None, None

for r in return_values:
if isinstance(r, dict):
if 'ui' in r:
Expand All @@ -90,7 +109,7 @@ def get_output_data(obj, input_data_all):
results.append(r)

output = []
if len(results) > 0:
if len(results) > 0 and results[0] is not None:
# check which outputs need concatenating
output_is_list = [False] * len(results[0])
if hasattr(obj, "OUTPUT_IS_LIST"):
Expand All @@ -103,7 +122,7 @@ def get_output_data(obj, input_data_all):
else:
output.append([o[i] for o in results])

ui = dict()
ui = dict()
if len(uis) > 0:
ui = {k: [y for x in uis for y in x[k]] for k in uis[0].keys()}
return output, ui
Expand Down Expand Up @@ -210,7 +229,7 @@ def recursive_will_execute(prompt, outputs, current_item):

return will_execute + [unique_id]

def recursive_output_delete_if_changed(prompt, old_prompt, outputs, current_item):
def recursive_output_delete_if_changed(prompt, old_prompt, outputs, current_item, object_storage):
unique_id = current_item
inputs = prompt[unique_id]['inputs']
class_type = prompt[unique_id]['class_type']
Expand All @@ -219,6 +238,12 @@ def recursive_output_delete_if_changed(prompt, old_prompt, outputs, current_item
is_changed_old = ''
is_changed = ''
to_delete = False

obj = object_storage.get((unique_id, class_type), None)
if obj is None:
obj = class_def()
object_storage[(unique_id, class_type)] = obj

if hasattr(class_def, 'IS_CHANGED'):
if unique_id in old_prompt and 'is_changed' in old_prompt[unique_id]:
is_changed_old = old_prompt[unique_id]['is_changed']
Expand All @@ -227,7 +252,7 @@ def recursive_output_delete_if_changed(prompt, old_prompt, outputs, current_item
if input_data_all is not None:
try:
#is_changed = class_def.IS_CHANGED(**input_data_all)
is_changed = map_node_over_list(class_def, input_data_all, "IS_CHANGED")
is_changed = map_node_over_list(obj, input_data_all, "IS_CHANGED")
prompt[unique_id]['is_changed'] = is_changed
except:
to_delete = True
Expand All @@ -250,7 +275,7 @@ def recursive_output_delete_if_changed(prompt, old_prompt, outputs, current_item
input_unique_id = input_data[0]
output_index = input_data[1]
if input_unique_id in outputs:
to_delete = recursive_output_delete_if_changed(prompt, old_prompt, outputs, input_unique_id)
to_delete = recursive_output_delete_if_changed(prompt, old_prompt, outputs, input_unique_id, object_storage)
else:
to_delete = True
if to_delete:
Expand Down Expand Up @@ -346,7 +371,7 @@ def execute(self, prompt, prompt_id, extra_data={}, execute_outputs=[]):
del d

for x in prompt:
recursive_output_delete_if_changed(prompt, self.old_prompt, self.outputs, x)
recursive_output_delete_if_changed(prompt, self.old_prompt, self.outputs, x, self.object_storage)

current_outputs = set(self.outputs.keys())
for x in list(self.outputs_ui.keys()):
Expand Down Expand Up @@ -382,7 +407,12 @@ def execute(self, prompt, prompt_id, extra_data={}, execute_outputs=[]):



def validate_inputs(prompt, item, validated):
def validate_inputs(prompt, item, validated, visited=set()):
if item in visited:
return (True, [], item)
else:
visited.add(item)

unique_id = item
if unique_id in validated:
return validated[unique_id]
Expand Down Expand Up @@ -431,7 +461,7 @@ def validate_inputs(prompt, item, validated):
o_id = val[0]
o_class_type = prompt[o_id]['class_type']
r = nodes.NODE_CLASS_MAPPINGS[o_class_type].RETURN_TYPES
if r[val[1]] != type_input:
if r[val[1]] != type_input and r[val[1]] != '*' and type_input != '*':
received_type = r[val[1]]
details = f"{x}, {received_type} != {type_input}"
error = {
Expand All @@ -448,7 +478,7 @@ def validate_inputs(prompt, item, validated):
errors.append(error)
continue
try:
r = validate_inputs(prompt, o_id, validated)
r = validate_inputs(prompt, o_id, validated, visited)
if r[0] is False:
# `r` will be set in `validated[o_id]` already
valid = False
Expand Down
5 changes: 4 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def execute_script(script_path):
# Main code
import asyncio
import itertools
import os
import shutil
import threading
import gc
Expand All @@ -67,6 +68,8 @@ def execute_script(script_path):
import yaml

import execution
import worklist_execution
import folder_paths
import server
from server import BinaryEventTypes
from nodes import init_custom_nodes
Expand All @@ -84,7 +87,7 @@ def cuda_malloc_warning():
print("\nWARNING: this card most likely does not support cuda-malloc, if you get \"CUDA error\" please run ComfyUI with: --disable-cuda-malloc\n")

def prompt_worker(q, server):
e = execution.PromptExecutor(server)
e = worklist_execution.PromptExecutor(server)
while True:
item, item_id = q.get()
execution_start_time = time.perf_counter()
Expand Down
Empty file removed models/loras/put_loras_here
Empty file.
1 change: 1 addition & 0 deletions nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1697,4 +1697,5 @@ def init_custom_nodes():
load_custom_node(os.path.join(os.path.join(os.path.dirname(os.path.realpath(__file__)), "comfy_extras"), "nodes_tomesd.py"))
load_custom_node(os.path.join(os.path.join(os.path.dirname(os.path.realpath(__file__)), "comfy_extras"), "nodes_clip_sdxl.py"))
load_custom_node(os.path.join(os.path.join(os.path.dirname(os.path.realpath(__file__)), "comfy_extras"), "nodes_canny.py"))
load_custom_node(os.path.join(os.path.join(os.path.dirname(os.path.realpath(__file__)), "comfy_extras"), "nodes_execution_control.py"))
load_custom_nodes()
Loading