Files
siliconflow-BizyAir/nodes.py
Yao ChiandFengWen 46741cfc6c fix shareid inference (#263)
* try to fix

* fix_infer_share_id (#266)

* fix_infer_share_id

* refine

---------

Co-authored-by: FengWen <109639975+ccssu@users.noreply.github.com>
2024-12-06 17:18:48 +08:00

1210 lines
35 KiB
Python

import os
from typing import List
import comfy
from bizyair import BizyAirBaseNode, BizyAirNodeIO, create_node_data, data_types
from bizyair.configs.conf import config_manager
from bizyair.path_utils import path_manager as folder_paths
LOGO = "☁️"
PREFIX = f"{LOGO}BizyAir"
MAX_RESOLUTION = 16384 # https://github.com/comfyanonymous/ComfyUI/blob/7390ff3b1ec2e15017ba4a52d6eaabc4aa4636e3/nodes.py#L45
class ProgressCallback:
def __init__(self, total=None) -> None:
comfy.model_management.throw_exception_if_processing_interrupted()
self.pbar = comfy.utils.ProgressBar(None)
def __call__(self, value, total=None, preview=None):
self.pbar.update_absolute(value, total, preview)
class BizyAir_KSampler(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"model": (data_types.MODEL,),
"seed": (
"INT",
{"default": 0, "min": 0, "max": 0xFFFFFFFFFFFFFFFF},
),
"steps": ("INT", {"default": 20, "min": 1, "max": 50}),
"cfg": (
"FLOAT",
{
"default": 8.0,
"min": 0.0,
"max": 100.0,
"step": 0.1,
"round": 0.01,
},
),
"sampler_name": (comfy.samplers.KSampler.SAMPLERS,),
"scheduler": (comfy.samplers.KSampler.SCHEDULERS,),
"positive": (data_types.CONDITIONING,),
"negative": (data_types.CONDITIONING,),
"latent_image": ("LATENT",),
"denoise": (
"FLOAT",
{"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01},
),
}
}
RETURN_TYPES = ("LATENT",)
FUNCTION = "sample"
RETURN_NAMES = (f"LATENT",)
CATEGORY = f"{PREFIX}/sampling"
def sample(
self,
model,
seed,
steps,
cfg,
sampler_name,
scheduler,
positive,
negative,
latent_image,
denoise=1,
):
new_model: BizyAirNodeIO = model.copy(self.assigned_id)
new_model.add_node_data(
class_type="KSampler",
inputs={
"model": model,
"seed": seed,
"steps": steps,
"cfg": cfg,
"sampler_name": sampler_name,
"scheduler": scheduler,
"positive": positive,
"negative": negative,
"latent_image": latent_image,
"denoise": denoise,
},
outputs={"slot_index": 0},
)
progress_callback = ProgressCallback()
return new_model.send_request(progress_callback=progress_callback)
class KSamplerAdvanced(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"model": (data_types.MODEL,),
"add_noise": (["enable", "disable"],),
"noise_seed": (
"INT",
{"default": 0, "min": 0, "max": 0xFFFFFFFFFFFFFFFF},
),
"steps": ("INT", {"default": 20, "min": 1, "max": 10000}),
"cfg": (
"FLOAT",
{
"default": 8.0,
"min": 0.0,
"max": 100.0,
"step": 0.1,
"round": 0.01,
},
),
"sampler_name": (comfy.samplers.KSampler.SAMPLERS,),
"scheduler": (comfy.samplers.KSampler.SCHEDULERS,),
"positive": (data_types.CONDITIONING,),
"negative": (data_types.CONDITIONING,),
"latent_image": ("LATENT",),
"start_at_step": ("INT", {"default": 0, "min": 0, "max": 10000}),
"end_at_step": ("INT", {"default": 10000, "min": 0, "max": 10000}),
"return_with_leftover_noise": (["disable", "enable"],),
}
}
RETURN_TYPES = ("LATENT",)
FUNCTION = "sample"
CATEGORY = "sampling"
def sample(self, model, **kwargs):
new_model: BizyAirNodeIO = model.copy(self.assigned_id)
kwargs["model"] = model
new_model.add_node_data(class_type="KSamplerAdvanced", inputs=kwargs)
progress_callback = ProgressCallback()
return new_model.send_request(progress_callback=progress_callback)
class BizyAir_CheckpointLoaderSimple(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"ckpt_name": (folder_paths.get_filename_list("checkpoints"),),
}
}
RETURN_TYPES = (data_types.MODEL, data_types.CLIP, data_types.VAE)
FUNCTION = "load_checkpoint"
CATEGORY = f"{PREFIX}/loaders"
RETURN_NAMES = (
f"model",
f"clip",
f"vae",
)
def load_checkpoint(self, ckpt_name):
node_datas = [
create_node_data(
class_type="CheckpointLoaderSimple",
inputs={"ckpt_name": ckpt_name},
outputs={"slot_index": slot_index},
)
for slot_index in range(3)
]
config_file = folder_paths.guess_config(ckpt_name=ckpt_name)
assigned_id = self.assigned_id
outs = [
BizyAirNodeIO(
assigned_id,
{assigned_id: data},
config_file=config_file,
)
for data in node_datas
]
return (
outs[0],
outs[1],
outs[2],
)
class BizyAir_CLIPTextEncode(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"text": (
"STRING",
{"multiline": True, "dynamicPrompts": True},
),
"clip": (data_types.CLIP,),
}
}
RETURN_TYPES = (data_types.CONDITIONING,)
RETURN_NAMES = ("CONDITIONING",)
FUNCTION = "encode"
CATEGORY = f"{PREFIX}/conditioning"
def encode(self, clip, text):
new_clip: BizyAirNodeIO = clip.copy(self.assigned_id)
new_clip.add_node_data(
class_type="CLIPTextEncode",
inputs={
"text": text,
"clip": clip,
},
outputs={"slot_index": 0},
)
return (new_clip,)
class BizyAir_VAEDecode(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {"required": {"samples": ("LATENT",), "vae": (data_types.VAE,)}}
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = (f"IMAGE",)
FUNCTION = "decode"
CATEGORY = f"{PREFIX}/latent"
def decode(self, vae, samples):
new_vae: BizyAirNodeIO = vae.copy(self.assigned_id)
new_vae.add_node_data(
class_type="VAEDecode",
inputs={
"samples": samples,
"vae": vae,
},
outputs={"slot_index": 0},
)
return new_vae.send_request()
class BizyAir_LoraLoader(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"model": (data_types.MODEL,),
"clip": (data_types.CLIP,),
"lora_name": (
[
"to choose",
],
),
"strength_model": (
"FLOAT",
{"default": 1.0, "min": -100.0, "max": 100.0, "step": 0.01},
),
"strength_clip": (
"FLOAT",
{"default": 1.0, "min": -100.0, "max": 100.0, "step": 0.01},
),
"model_version_id": (
"STRING",
{
"default": "",
},
),
}
}
RETURN_TYPES = (data_types.MODEL, data_types.CLIP)
RETURN_NAMES = ("MODEL", "CLIP")
FUNCTION = "load_lora"
CATEGORY = f"{PREFIX}/loaders"
def load_lora(
self,
model,
clip,
lora_name,
strength_model,
strength_clip,
model_version_id: str = None,
):
assigned_id = self.assigned_id
new_model: BizyAirNodeIO = model.copy(assigned_id)
new_clip: BizyAirNodeIO = clip.copy(assigned_id)
instances: List[BizyAirNodeIO] = [new_model, new_clip]
if model_version_id is not None and model_version_id != "":
# use model version id as lora name
lora_name = (
f"{config_manager.get_model_version_id_prefix()}{model_version_id}"
)
for slot_index, ins in zip(range(2), instances):
ins.add_node_data(
class_type="LoraLoader",
inputs={
"model": model,
"clip": clip,
"lora_name": lora_name,
"strength_model": strength_model,
"strength_clip": strength_clip,
},
outputs={"slot_index": slot_index},
)
return (
new_model,
new_clip,
)
@classmethod
def VALIDATE_INPUTS(cls, lora_name):
if lora_name == "" or lora_name is None:
return False
return True
class BizyAir_LoraLoader_Legacy(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"model": (data_types.MODEL,),
"clip": (data_types.CLIP,),
"lora_name": (folder_paths.get_filename_list("loras"),),
"strength_model": (
"FLOAT",
{"default": 1.0, "min": -100.0, "max": 100.0, "step": 0.01},
),
"strength_clip": (
"FLOAT",
{"default": 1.0, "min": -100.0, "max": 100.0, "step": 0.01},
),
}
}
RETURN_TYPES = (data_types.MODEL, data_types.CLIP)
RETURN_NAMES = ("MODEL", "CLIP")
FUNCTION = "load_lora"
CATEGORY = f"{PREFIX}/loaders"
def load_lora(self, model, clip, lora_name, strength_model, strength_clip):
assigned_id = self.assigned_id
new_model: BizyAirNodeIO = model.copy(assigned_id)
new_clip: BizyAirNodeIO = clip.copy(assigned_id)
instances: List[BizyAirNodeIO] = [new_model, new_clip]
for slot_index, ins in zip(range(2), instances):
ins.add_node_data(
class_type="LoraLoader",
inputs={
"model": model,
"clip": clip,
"lora_name": lora_name,
"strength_model": strength_model,
"strength_clip": strength_clip,
},
outputs={"slot_index": slot_index},
)
return (
new_model,
new_clip,
)
class BizyAir_VAEEncode(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {"required": {"pixels": ("IMAGE",), "vae": (data_types.VAE,)}}
RETURN_TYPES = ("LATENT",)
RETURN_NAMES = (f"LATENT",)
FUNCTION = "encode"
CATEGORY = f"{PREFIX}/latent"
def encode(self, vae, pixels):
new_vae: BizyAirNodeIO = vae.copy(self.assigned_id)
new_vae.add_node_data(
class_type="VAEEncode",
inputs={
"vae": vae,
"pixels": pixels,
},
outputs={"slot_index": 0},
)
return new_vae.send_request()
class BizyAir_VAEEncodeForInpaint(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"pixels": ("IMAGE",),
"vae": (data_types.VAE,),
"mask": ("MASK",),
"grow_mask_by": ("INT", {"default": 6, "min": 0, "max": 64, "step": 1}),
}
}
RETURN_TYPES = (f"LATENT",)
RETURN_NAMES = (f"LATENT",)
FUNCTION = "encode"
CATEGORY = f"{PREFIX}/latent/inpaint"
def encode(self, vae, pixels, mask, grow_mask_by=6):
new_vae: BizyAirNodeIO = vae.copy(self.assigned_id)
new_vae.add_node_data(
class_type="VAEEncodeForInpaint",
inputs={
"vae": vae,
"pixels": pixels,
"mask": mask,
"grow_mask_by": grow_mask_by,
},
outputs={"slot_index": 0},
)
return new_vae.send_request()
class BizyAir_ControlNetLoader(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"control_net_name": (
[
"to choose",
],
),
"model_version_id": ("STRING", {"default": "", "multiline": False}),
}
}
RETURN_TYPES = (data_types.CONTROL_NET,)
RETURN_NAMES = ("CONTROL_NET",)
FUNCTION = "load_controlnet"
CATEGORY = f"{PREFIX}/loaders"
@classmethod
def VALIDATE_INPUTS(cls, control_net_name, model_version_id):
if control_net_name == "to choose":
return False
if model_version_id is not None and model_version_id != "":
return True
return True
def load_controlnet(self, control_net_name, model_version_id):
if model_version_id is not None and model_version_id != "":
control_net_name = (
f"{config_manager.get_model_version_id_prefix()}{model_version_id}"
)
node_data = create_node_data(
class_type="ControlNetLoader",
inputs={
"control_net_name": control_net_name,
},
outputs={"slot_index": 0},
)
assigned_id = self.assigned_id
node = BizyAirNodeIO(assigned_id, {assigned_id: node_data})
return (node,)
class BizyAir_ControlNetLoader_Legacy(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"control_net_name": (folder_paths.get_filename_list("controlnet"),)
}
}
RETURN_TYPES = (data_types.CONTROL_NET,)
RETURN_NAMES = ("CONTROL_NET",)
FUNCTION = "load_controlnet"
CATEGORY = f"{PREFIX}/loaders"
def load_controlnet(self, control_net_name):
node_data = create_node_data(
class_type="ControlNetLoader",
inputs={
"control_net_name": control_net_name,
},
outputs={"slot_index": 0},
)
assigned_id = self.assigned_id
node = BizyAirNodeIO(assigned_id, {assigned_id: node_data})
return (node,)
class BizyAir_ControlNetApplyAdvanced(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"positive": (data_types.CONDITIONING,),
"negative": (data_types.CONDITIONING,),
"control_net": (data_types.CONTROL_NET,),
"image": ("IMAGE",),
"strength": (
"FLOAT",
{"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01},
),
"start_percent": (
"FLOAT",
{"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001},
),
"end_percent": (
"FLOAT",
{"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001},
),
}
}
RETURN_TYPES = (data_types.CONDITIONING, data_types.CONDITIONING)
RETURN_NAMES = ("positive", "negative")
FUNCTION = "apply_controlnet"
CATEGORY = "conditioning"
def apply_controlnet(self, **kwargs):
new_positive = kwargs["positive"].copy(self.assigned_id)
new_negative = kwargs["negative"].copy(self.assigned_id)
outs = [
new_positive,
new_negative,
]
for slot_index, out in zip(range(0, 2), outs):
out.add_node_data(
class_type="ControlNetApplyAdvanced",
inputs=kwargs,
outputs={"slot_index": slot_index},
)
return outs
class BizyAir_ControlNetApply(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"conditioning": (data_types.CONDITIONING,),
"control_net": (data_types.CONTROL_NET,),
"image": ("IMAGE",),
"strength": (
"FLOAT",
{"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01},
),
}
}
RETURN_TYPES = (data_types.CONDITIONING,)
RETURN_NAMES = ("CONDITIONING",)
FUNCTION = "apply_controlnet"
CATEGORY = f"{PREFIX}/conditioning/controlnet"
def apply_controlnet(
self, conditioning, control_net: BizyAirNodeIO, image, strength
):
new_cond: BizyAirNodeIO = conditioning.copy(self.assigned_id)
new_cond.add_node_data(
class_type="ControlNetApply",
inputs={
"conditioning": conditioning,
"control_net": control_net,
"image": image,
"strength": strength,
},
outputs={"slot_index": 0},
)
return (new_cond,)
class BizyAir_CLIPVisionLoader(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"clip_name": (folder_paths.get_filename_list("clip_vision"),),
}
}
RETURN_TYPES = ("CLIP_VISION",)
FUNCTION = "load_clip"
CATEGORY = "loaders"
def load_clip(self, clip_name):
node_data = create_node_data(
class_type="CLIPVisionLoader",
inputs={"clip_name": clip_name},
outputs={"slot_index": 0},
)
clip_vision = BizyAirNodeIO(self.assigned_id, {self.assigned_id: node_data})
return (clip_vision,)
class VAELoader(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {"required": {"vae_name": (folder_paths.get_filename_list("vae"),)}}
RETURN_TYPES = (data_types.VAE,)
RETURN_NAMES = ("vae",)
FUNCTION = "load_vae"
CATEGORY = "loaders"
def load_vae(self, vae_name):
node_data = create_node_data(
class_type="VAELoader",
inputs={"vae_name": vae_name},
outputs={"slot_index": 0},
)
vae = BizyAirNodeIO(
self.assigned_id,
{self.assigned_id: node_data},
config_file=folder_paths.guess_config(vae_name=vae_name),
)
return (vae,)
class UNETLoader(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"unet_name": (folder_paths.get_filename_list("unet"),),
"weight_dtype": (["default", "fp8_e4m3fn", "fp8_e5m2"],),
}
}
RETURN_TYPES = (data_types.MODEL,)
FUNCTION = "load_unet"
CATEGORY = "advanced/loaders"
def load_unet(self, unet_name, weight_dtype):
node_data = create_node_data(
class_type="UNETLoader",
inputs={
"unet_name": unet_name,
"weight_dtype": weight_dtype,
},
outputs={"slot_index": 0},
)
model = BizyAirNodeIO(
self.assigned_id,
{self.assigned_id: node_data},
config_file=folder_paths.guess_config(unet_name=unet_name),
)
return (model,)
class SamplerCustomAdvanced(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"noise": ("NOISE",),
"guider": ("GUIDER",),
"sampler": ("SAMPLER",),
"sigmas": ("SIGMAS",),
"latent_image": ("LATENT",),
}
}
RETURN_TYPES = ("LATENT", "LATENT")
RETURN_NAMES = ("output", "denoised_output")
# FUNCTION = "sample"
CATEGORY = "sampling/custom_sampling"
# def sample(self, **kwargs):
# guider: BizyAirNodeIO = kwargs["guider"].copy(self.assigned_id)
# guider.add_node_data(
# class_type="SamplerCustomAdvanced",
# inputs=kwargs,
# outputs={"slot_index": 0},
# )
# return (guider, None)
class BasicGuider(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"model": (data_types.MODEL,),
"conditioning": (data_types.CONDITIONING,),
}
}
RETURN_TYPES = ("GUIDER",)
FUNCTION = "get_guider"
CATEGORY = "sampling/custom_sampling/guiders"
def get_guider(self, model: BizyAirNodeIO, conditioning):
new_model = model.copy(self.assigned_id)
new_model.add_node_data(
class_type="BasicGuider",
inputs={
"model": model,
"conditioning": conditioning,
},
outputs={"slot_index": 0},
)
return (new_model,)
class BasicScheduler(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"model": (data_types.MODEL,),
"scheduler": (comfy.samplers.SCHEDULER_NAMES,),
"steps": ("INT", {"default": 20, "min": 1, "max": 10000}),
"denoise": (
"FLOAT",
{"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01},
),
}
}
RETURN_TYPES = ("SIGMAS",)
CATEGORY = "sampling/custom_sampling/schedulers"
FUNCTION = "get_sigmas"
def get_sigmas(self, **kwargs):
new_model: BizyAirNodeIO = kwargs["model"].copy(self.assigned_id)
new_model.add_node_data(
class_type="BasicScheduler",
inputs=kwargs,
outputs={"slot_index": 0},
)
return (new_model,)
class DualCLIPLoader(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"clip_name1": (folder_paths.get_filename_list("clip"),),
"clip_name2": (folder_paths.get_filename_list("clip"),),
"type": (["sdxl", "sd3", "flux"],),
}
}
RETURN_TYPES = (data_types.CLIP,)
FUNCTION = "load_clip"
CATEGORY = "advanced/loaders"
def load_clip(self, clip_name1, clip_name2, type):
node_data = create_node_data(
class_type="DualCLIPLoader",
inputs={
"clip_name1": clip_name1,
"clip_name2": clip_name2,
"type": type,
},
outputs={"slot_index": 0},
)
model = BizyAirNodeIO(
self.assigned_id,
{self.assigned_id: node_data},
config_file=folder_paths.guess_config(clip_name=clip_name1),
)
return (model,)
class KSamplerSelect(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"sampler_name": (comfy.samplers.SAMPLER_NAMES,),
}
}
RETURN_TYPES = ("SAMPLER",)
CATEGORY = "sampling/custom_sampling/samplers"
FUNCTION = "get_sampler"
def get_sampler(self, **kwargs):
node_data = create_node_data(
class_type="KSamplerSelect",
inputs=kwargs,
outputs={"slot_index": 0},
)
model = BizyAirNodeIO(
self.assigned_id,
{self.assigned_id: node_data},
)
return (model,)
class RandomNoise(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"noise_seed": (
"INT",
{"default": 0, "min": 0, "max": 0xFFFFFFFFFFFFFFFF},
),
}
}
RETURN_TYPES = ("NOISE",)
FUNCTION = "get_noise"
CATEGORY = "sampling/custom_sampling/noise"
def get_noise(self, noise_seed):
node_data = create_node_data(
class_type="RandomNoise",
inputs={
"noise_seed": noise_seed,
},
outputs={"slot_index": 0},
)
model = BizyAirNodeIO(
self.assigned_id,
{self.assigned_id: node_data},
)
return (model,)
class CLIPSetLastLayer(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"clip": (data_types.CLIP,),
"stop_at_clip_layer": (
"INT",
{"default": -1, "min": -24, "max": -1, "step": 1},
),
}
}
RETURN_TYPES = (data_types.CLIP,)
FUNCTION = "set_last_layer"
CATEGORY = "conditioning"
def set_last_layer(self, clip: BizyAirNodeIO, stop_at_clip_layer):
new_clip = clip.copy(new_node_id=self.assigned_id)
new_clip.add_node_data(
class_type="CLIPSetLastLayer",
inputs={
"stop_at_clip_layer": stop_at_clip_layer,
"clip": clip,
},
outputs={"slot_index": 0},
)
return (new_clip,)
class InpaintModelConditioning(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"positive": (data_types.CONDITIONING,),
"negative": (data_types.CONDITIONING,),
"vae": (data_types.VAE,),
"pixels": ("IMAGE",),
"mask": ("MASK",),
}
}
RETURN_TYPES = (data_types.CONDITIONING, data_types.CONDITIONING, "LATENT")
RETURN_NAMES = ("positive", "negative", "latent")
# FUNCTION = "encode"
CATEGORY = "conditioning/inpaint"
# noise_mask newly added in https://github.com/comfyanonymous/ComfyUI/blob/8f0009aad0591ceee59a147738aa227187b07898/nodes.py#L385
# "noise_mask": ("BOOLEAN", {"default": False, "tooltip": "Add a noise mask to the latent so sampling will only happen within the mask. Might improve results or completely break things depending on the model."}),
class InpaintModelConditioning_v2(InpaintModelConditioning):
CLASS_TYPE_NAME = "InpaintModelConditioning"
@classmethod
def INPUT_TYPES(s):
ret = super().INPUT_TYPES()
ret["required"]["noise_mask"] = (
"BOOLEAN",
{
"default": False,
"tooltip": "Add a noise mask to the latent so sampling will only happen within the mask. Might improve results or completely break things depending on the model.",
},
)
return ret
class SharedLoraLoader(BizyAir_LoraLoader_Legacy):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"share_id": ("STRING", {"default": "share_id"}),
"lora_name": ([],),
"model": (data_types.MODEL,),
"clip": (data_types.CLIP,),
"strength_model": (
"FLOAT",
{"default": 1.0, "min": -100.0, "max": 100.0, "step": 0.01},
),
"strength_clip": (
"FLOAT",
{"default": 1.0, "min": -100.0, "max": 100.0, "step": 0.01},
),
}
}
RETURN_TYPES = (data_types.MODEL, data_types.CLIP)
RETURN_NAMES = ("MODEL", "CLIP")
FUNCTION = "shared_load_lora"
CATEGORY = f"{PREFIX}/loaders"
NODE_DISPLAY_NAME = "Shared Lora Loader"
@classmethod
def VALIDATE_INPUTS(cls, share_id: str, lora_name: str):
if lora_name in folder_paths.filename_path_mapping.get("loras", {}):
return True
outs = folder_paths.get_share_filename_list("loras", share_id=share_id)
if lora_name not in outs:
raise ValueError(
f"Lora {lora_name} not found in share {share_id} with {outs}"
)
return True
def shared_load_lora(
self, model, clip, lora_name, strength_model, strength_clip, **kwargs
):
resolved_path = folder_paths.filename_path_mapping["loras"][lora_name]
return super().load_lora(
model=model,
clip=clip,
lora_name=resolved_path,
strength_model=strength_model,
strength_clip=strength_clip,
)
class ConditioningCombine(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"conditioning_1": (data_types.CONDITIONING,),
"conditioning_2": (data_types.CONDITIONING,),
}
}
RETURN_TYPES = (data_types.CONDITIONING,)
# FUNCTION = "combine"
NODE_DISPLAY_NAME = "Conditioning (Combine)"
CATEGORY = "conditioning"
class ConditioningAverage(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"conditioning_to": (data_types.CONDITIONING,),
"conditioning_from": (data_types.CONDITIONING,),
"conditioning_to_strength": (
"FLOAT",
{"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01},
),
}
}
RETURN_TYPES = (data_types.CONDITIONING,)
# FUNCTION = "addWeighted"
NODE_DISPLAY_NAME = "Conditioning (Average)"
CATEGORY = "conditioning"
class ConditioningConcat(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"conditioning_to": (data_types.CONDITIONING,),
"conditioning_from": (data_types.CONDITIONING,),
}
}
RETURN_TYPES = (data_types.CONDITIONING,)
# FUNCTION = "concat"
NODE_DISPLAY_NAME = "Conditioning (Concat)"
CATEGORY = "conditioning"
class ConditioningSetArea(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"conditioning": (data_types.CONDITIONING,),
"width": (
"INT",
{"default": 64, "min": 64, "max": MAX_RESOLUTION, "step": 8},
),
"height": (
"INT",
{"default": 64, "min": 64, "max": MAX_RESOLUTION, "step": 8},
),
"x": (
"INT",
{"default": 0, "min": 0, "max": MAX_RESOLUTION, "step": 8},
),
"y": (
"INT",
{"default": 0, "min": 0, "max": MAX_RESOLUTION, "step": 8},
),
"strength": (
"FLOAT",
{"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01},
),
}
}
RETURN_TYPES = (data_types.CONDITIONING,)
# FUNCTION = "append"
NODE_DISPLAY_NAME = "Conditioning (Set Area)"
CATEGORY = "conditioning"
class ConditioningSetAreaPercentage(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"conditioning": (data_types.CONDITIONING,),
"width": (
"FLOAT",
{"default": 1.0, "min": 0, "max": 1.0, "step": 0.01},
),
"height": (
"FLOAT",
{"default": 1.0, "min": 0, "max": 1.0, "step": 0.01},
),
"x": ("FLOAT", {"default": 0, "min": 0, "max": 1.0, "step": 0.01}),
"y": ("FLOAT", {"default": 0, "min": 0, "max": 1.0, "step": 0.01}),
"strength": (
"FLOAT",
{"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01},
),
}
}
RETURN_TYPES = (data_types.CONDITIONING,)
# FUNCTION = "append"
NODE_DISPLAY_NAME = "Conditioning (Set Area with Percentage)"
CATEGORY = "conditioning"
class ConditioningSetMask(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"conditioning": (data_types.CONDITIONING,),
"mask": ("MASK",),
"strength": (
"FLOAT",
{"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01},
),
"set_cond_area": (["default", "mask bounds"],),
}
}
RETURN_TYPES = (data_types.CONDITIONING,)
# FUNCTION = "append"
NODE_DISPLAY_NAME = "Conditioning (Set Mask)"
CATEGORY = "conditioning"
class ConditioningZeroOut(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {"required": {"conditioning": (data_types.CONDITIONING,)}}
RETURN_TYPES = (data_types.CONDITIONING,)
# FUNCTION = "zero_out"
CATEGORY = "advanced/conditioning"
class ConditioningSetTimestepRange(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"conditioning": (data_types.CONDITIONING,),
"start": (
"FLOAT",
{"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001},
),
"end": (
"FLOAT",
{"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001},
),
}
}
RETURN_TYPES = (data_types.CONDITIONING,)
# FUNCTION = "set_range"
CATEGORY = "advanced/conditioning"
class SharedControlNetLoader(BizyAir_ControlNetLoader_Legacy):
@classmethod
def INPUT_TYPES(s):
ret = super().INPUT_TYPES()
ret["required"]["share_id"] = ("STRING", {"default": "share_id"})
return ret
NODE_DISPLAY_NAME = "Shared Load ControlNet Model"
@classmethod
def VALIDATE_INPUTS(cls, share_id: str, control_net_name: str):
if control_net_name in folder_paths.filename_path_mapping.get("controlnet", {}):
return True
outs = folder_paths.get_share_filename_list("controlnet", share_id=share_id)
if control_net_name not in outs:
raise ValueError(
f"ControlNet {control_net_name} not found in share {share_id} with {outs}"
)
return True
def load_controlnet(self, control_net_name, share_id, **kwargs):
resolved_path = folder_paths.filename_path_mapping["controlnet"][
control_net_name
]
return super().load_controlnet(control_net_name=resolved_path, **kwargs)
class CLIPVisionEncode(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {"required": {"clip_vision": ("CLIP_VISION",), "image": ("IMAGE",)}}
RETURN_TYPES = ("CLIP_VISION_OUTPUT",)
# FUNCTION = "encode"
CATEGORY = "conditioning"
class StyleModelLoader(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"style_model_name": (folder_paths.get_filename_list("style_models"),)
}
}
RETURN_TYPES = (data_types.STYLE_MODEL,)
# FUNCTION = "load_style_model"
CATEGORY = "loaders"
class StyleModelApply(BizyAirBaseNode):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"conditioning": (data_types.CONDITIONING,),
"style_model": (data_types.STYLE_MODEL,),
"clip_vision_output": ("CLIP_VISION_OUTPUT",),
}
}
RETURN_TYPES = (data_types.CONDITIONING,)
# FUNCTION = "apply_stylemodel"
CATEGORY = "conditioning/style_model"