diff --git a/README.md b/README.md index 13a15c6e735071a663fea2522f699ae56b7d30b2..b3a1ffdc427bb42b1845062483e2f019f25aea06 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ models: - Comfy-Org/Lens - Comfy-Org/LongCat-Image - Comfy-Org/Lumina_Image_2.0_Repackaged + - Comfy-Org/Mage-Flow - Comfy-Org/NewBie-image-Exp0.1_repackaged - Comfy-Org/Omnigen2_ComfyUI_repackaged - Comfy-Org/Ovis-Image @@ -144,6 +145,10 @@ models: - meituan-longcat/LongCat-Image - microsoft/Lens - microsoft/Lens-Turbo + - microsoft/Mage-Flow + - microsoft/Mage-Flow-Edit + - microsoft/Mage-Flow-Edit-Turbo + - microsoft/Mage-Flow-Turbo - NewBie-AI/NewBie-image-Exp0.1 - nvidia/PiD - nvidia/PixelDiT-1300M-1024px diff --git a/chain_injectors/reference_image_injector.py b/chain_injectors/reference_image_injector.py new file mode 100644 index 0000000000000000000000000000000000000000..c588c1b593c0c2d84342277135014df126915ccf --- /dev/null +++ b/chain_injectors/reference_image_injector.py @@ -0,0 +1,64 @@ +import os + +def inject(assembler, chain_definition, chain_items): + if not chain_items: + return + + valid_images = [] + for item in chain_items: + if not item: + continue + img_path = item + if isinstance(item, dict): + img_path = item.get('image') or item.get('filename') or item.get('path') + if img_path: + valid_images.append(img_path) + + if not valid_images: + return + + text_encode_name = chain_definition.get('text_encode_node') + text_encode_id = None + if text_encode_name and text_encode_name in assembler.node_map: + text_encode_id = assembler.node_map[text_encode_name] + else: + for node_id, node in assembler.workflow.items(): + if isinstance(node, dict) and node.get('class_type') == 'TextEncodeMageFlowEdit': + text_encode_id = node_id + break + + if not text_encode_id or text_encode_id not in assembler.workflow: + print("Warning: TextEncodeMageFlowEdit node not found for Reference Image chain. Skipping.") + return + + vae_node_name = chain_definition.get('vae_node', 'vae_loader') + vae_node_id = assembler.node_map.get(vae_node_name) + if not vae_node_id: + for node_id, node in assembler.workflow.items(): + if isinstance(node, dict) and node.get('class_type') == 'VAELoader': + vae_node_id = node_id + break + + if vae_node_id: + assembler.workflow[text_encode_id]['inputs']['vae'] = [vae_node_id, 0] + + for i, img_filename in enumerate(valid_images): + load_id = assembler._get_unique_id() + load_node = assembler._get_node_template("LoadImage") + load_node['inputs']['image'] = img_filename + load_node['_meta']['title'] = f"Load Reference Image {i+1}" + assembler.workflow[load_id] = load_node + + scale_id = assembler._get_unique_id() + scale_node = assembler._get_node_template("ImageScaleToTotalPixels") + scale_node['inputs']['megapixels'] = 1.0 + scale_node['inputs']['upscale_method'] = "nearest-exact" + scale_node['inputs']['resolution_steps'] = 1 + scale_node['inputs']['image'] = [load_id, 0] + scale_node['_meta']['title'] = f"Scale Reference {i+1}" + assembler.workflow[scale_id] = scale_node + + input_key = f"images.image_{i+1}" + assembler.workflow[text_encode_id]['inputs'][input_key] = [scale_id, 0] + + print(f"Reference Image injector applied. Injected {len(valid_images)} reference images to TextEncodeMageFlowEdit node '{text_encode_id}'.") diff --git a/core/pipelines/pipeline_input_processor.py b/core/pipelines/pipeline_input_processor.py index fa566e7592c6968c7eaaeb51d7839b39e2a85656..e955c083e2bf3554f1d5dff1dea231eb07071e08 100644 --- a/core/pipelines/pipeline_input_processor.py +++ b/core/pipelines/pipeline_input_processor.py @@ -351,6 +351,17 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo temp_files_to_clean.append(temp_path) active_joyai_reference.append(os.path.basename(temp_path)) + reference_image_data = ui_inputs.get('reference_image_data', []) + active_reference_images = [] + if reference_image_data: + for img in reference_image_data: + if img: + if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR) + temp_path = os.path.join(INPUT_DIR, f"temp_ref_img_{random.randint(1000, 9999)}.png") + img.save(temp_path, "PNG") + temp_files_to_clean.append(temp_path) + active_reference_images.append(os.path.basename(temp_path)) + vae_source = ui_inputs.get('vae_source') vae_id = ui_inputs.get('vae_id') vae_name_override = None @@ -390,6 +401,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo "active_reference_latents": active_reference_latents, "active_hidream_o1_reference": active_hidream_o1_reference, "active_joyai_reference": active_joyai_reference, + "active_reference_images": active_reference_images, "active_conditioning": active_conditioning, "temp_files_to_clean": temp_files_to_clean } \ No newline at end of file diff --git a/core/pipelines/sd_image_pipeline.py b/core/pipelines/sd_image_pipeline.py index 78d591b37cd31d84509776c1413bc84716fdec32..f92fe3a8849f56df79e011967d0cbd1e044d9245 100644 --- a/core/pipelines/sd_image_pipeline.py +++ b/core/pipelines/sd_image_pipeline.py @@ -117,6 +117,7 @@ class SdImagePipeline(BasePipeline): active_reference_latents = processed["active_reference_latents"] active_hidream_o1_reference = processed["active_hidream_o1_reference"] active_joyai_reference = processed.get("active_joyai_reference", []) + active_reference_images = processed.get("active_reference_images", []) active_conditioning = processed["active_conditioning"] loras_string = f"LoRAs: [{', '.join(active_loras_for_meta)}]" if active_loras_for_meta else "" @@ -174,6 +175,7 @@ class SdImagePipeline(BasePipeline): "reference_latent_chain": active_reference_latents, "hidream_o1_reference_chain": active_hidream_o1_reference, "joyai_reference_chain": active_joyai_reference, + "reference_image_chain": active_reference_images, "vae_chain": [ui_inputs.get('vae_name')] if ui_inputs.get('vae_name') else [], "hidream_o1_smoothing_chain": hidream_o1_smoothing_data, "pid_chain": [ui_inputs.get('pid_settings', 'OFF')] if is_pid_enabled else [], diff --git a/core/pipelines/workflow_executor.py b/core/pipelines/workflow_executor.py index 372538514b3f206cfb4ba9f89d1c473dd0a88a7e..04117e4468d7e670cc13759d86e29c5214020617 100644 --- a/core/pipelines/workflow_executor.py +++ b/core/pipelines/workflow_executor.py @@ -42,6 +42,30 @@ class WorkflowExecutor: try: sorted_node_ids = WorkflowExecutor.topological_sort(workflow) + + final_node_id = None + for node_id in reversed(sorted_node_ids): + if workflow[node_id].get('class_type') == 'SaveImage': + final_node_id = node_id + break + + if final_node_id: + required_nodes = set() + nodes_to_visit = [final_node_id] + while nodes_to_visit: + curr_id = nodes_to_visit.pop() + if curr_id in required_nodes: + continue + required_nodes.add(curr_id) + curr_info = workflow.get(curr_id, {}) + for input_val in curr_info.get('inputs', {}).values(): + if isinstance(input_val, list) and len(input_val) == 2 and isinstance(input_val[0], str): + src_id = input_val[0] + if src_id in workflow and src_id not in required_nodes: + nodes_to_visit.append(src_id) + + sorted_node_ids = [nid for nid in sorted_node_ids if nid in required_nodes] + print(f"--- [Workflow Executor] Execution order: {sorted_node_ids}") except RuntimeError as e: print("--- [Workflow Executor] ERROR: Failed to sort workflow. Dumping graph details. ---") diff --git a/core/pipelines/workflow_recipes/_partials/_base_sampler_sd.yaml b/core/pipelines/workflow_recipes/_partials/_base_sampler_sd.yaml index 64780e0f91c03c4e26d2c48381ef2aef6453dd2a..6a5143983756f5db7d20ca4a4896fbffae713997 100644 --- a/core/pipelines/workflow_recipes/_partials/_base_sampler_sd.yaml +++ b/core/pipelines/workflow_recipes/_partials/_base_sampler_sd.yaml @@ -1,10 +1,4 @@ nodes: - pos_prompt: - class_type: CLIPTextEncode - title: "CLIP Text Encode (Positive)" - neg_prompt: - class_type: CLIPTextEncode - title: "CLIP Text Encode (Negative)" ksampler: class_type: KSampler title: "KSampler" @@ -25,8 +19,6 @@ connections: to: "save_image:images" ui_map: - positive_prompt: "pos_prompt:text" - negative_prompt: "neg_prompt:text" seed: "ksampler:seed" steps: "ksampler:steps" cfg: "ksampler:cfg" diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/anima.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/anima.yaml index e002ca673eb428ed43d217ba3b4432135b71cc65..8d7f75deafd6c122a110bb9438dbe9fc69875c9f 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/anima.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/anima.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load Diffusion Model" @@ -57,6 +63,8 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" vae_name: "vae_loader:vae_name" clip_name: "clip_loader:clip_name" \ No newline at end of file diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/auraflow.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/auraflow.yaml index 6d1bc30e9723a641d02f724757f7e48799615aae..f9c3c5c662bd5f5dc588eca7d183cdec178ea48c 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/auraflow.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/auraflow.yaml @@ -1,48 +1,56 @@ -nodes: - ckpt_loader: - class_type: CheckpointLoaderSimple - title: "Load Checkpoint" - -connections: - - from: "ckpt_loader:0" - to: "ksampler:model" - - from: "ckpt_loader:1" - to: "pos_prompt:clip" - - from: "ckpt_loader:1" - to: "neg_prompt:clip" - - from: "pos_prompt:0" - to: "ksampler:positive" - - from: "neg_prompt:0" - to: "ksampler:negative" - - from: "ckpt_loader:2" - to: "vae_decode:vae" - - from: "ckpt_loader:2" - to: "vae_encode:vae" - -dynamic_vae_chains: - vae_chain: - targets: - - "vae_decode:vae" - - "vae_encode:vae" - -dynamic_lora_chains: - lora_chain: - template: "LoraLoader" - start: "ckpt_loader" - output_map: - "0": "model" - "1": "clip" - input_map: - "model": "model" - "clip": "clip" - end_input_map: - "model": ["ksampler:model"] - "clip": ["pos_prompt:clip", "neg_prompt:clip"] - -dynamic_conditioning_chains: - conditioning_chain: - ksampler_node: "ksampler" - clip_source: "ckpt_loader:1" - -ui_map: - model_name: "ckpt_loader:ckpt_name" +nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" + ckpt_loader: + class_type: CheckpointLoaderSimple + title: "Load Checkpoint" + +connections: + - from: "ckpt_loader:0" + to: "ksampler:model" + - from: "ckpt_loader:1" + to: "pos_prompt:clip" + - from: "ckpt_loader:1" + to: "neg_prompt:clip" + - from: "pos_prompt:0" + to: "ksampler:positive" + - from: "neg_prompt:0" + to: "ksampler:negative" + - from: "ckpt_loader:2" + to: "vae_decode:vae" + - from: "ckpt_loader:2" + to: "vae_encode:vae" + +dynamic_vae_chains: + vae_chain: + targets: + - "vae_decode:vae" + - "vae_encode:vae" + +dynamic_lora_chains: + lora_chain: + template: "LoraLoader" + start: "ckpt_loader" + output_map: + "0": "model" + "1": "clip" + input_map: + "model": "model" + "clip": "clip" + end_input_map: + "model": ["ksampler:model"] + "clip": ["pos_prompt:clip", "neg_prompt:clip"] + +dynamic_conditioning_chains: + conditioning_chain: + ksampler_node: "ksampler" + clip_source: "ckpt_loader:1" + +ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" + model_name: "ckpt_loader:ckpt_name" diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/boogu-image.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/boogu-image.yaml index baaf33c19c26e8503f2eeb44440b11dfd8e87349..b4b7d2717c064138a87d7d796e10cc014c353fc2 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/boogu-image.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/boogu-image.yaml @@ -1,58 +1,66 @@ -nodes: - unet_loader: - class_type: UNETLoader - title: "Load Diffusion Model" - params: - weight_dtype: "default" - clip_loader: - class_type: CLIPLoader - title: "Load CLIP" - params: - type: "boogu" - device: "default" - vae_loader: - class_type: VAELoader - title: "Load VAE" - -connections: - - from: "unet_loader:0" - to: "ksampler:model" - - from: "clip_loader:0" - to: "pos_prompt:clip" - - from: "clip_loader:0" - to: "neg_prompt:clip" - - from: "pos_prompt:0" - to: "ksampler:positive" - - from: "neg_prompt:0" - to: "ksampler:negative" - - from: "vae_loader:0" - to: "vae_decode:vae" - - from: "vae_loader:0" - to: "vae_encode:vae" - -dynamic_lora_chains: - lora_chain: - template: "LoraLoader" - output_map: - "unet_loader:0": "model" - "clip_loader:0": "clip" - input_map: - "model": "model" - "clip": "clip" - end_input_map: - "model": ["ksampler:model"] - "clip": ["pos_prompt:clip", "neg_prompt:clip"] - -dynamic_conditioning_chains: - conditioning_chain: - ksampler_node: "ksampler" - clip_source: "clip_loader:0" - -dynamic_pid_chains: - pid_chain: - ksampler_node: "ksampler" - -ui_map: - unet_name: "unet_loader:unet_name" - clip_name: "clip_loader:clip_name" - vae_name: "vae_loader:vae_name" +nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" + unet_loader: + class_type: UNETLoader + title: "Load Diffusion Model" + params: + weight_dtype: "default" + clip_loader: + class_type: CLIPLoader + title: "Load CLIP" + params: + type: "boogu" + device: "default" + vae_loader: + class_type: VAELoader + title: "Load VAE" + +connections: + - from: "unet_loader:0" + to: "ksampler:model" + - from: "clip_loader:0" + to: "pos_prompt:clip" + - from: "clip_loader:0" + to: "neg_prompt:clip" + - from: "pos_prompt:0" + to: "ksampler:positive" + - from: "neg_prompt:0" + to: "ksampler:negative" + - from: "vae_loader:0" + to: "vae_decode:vae" + - from: "vae_loader:0" + to: "vae_encode:vae" + +dynamic_lora_chains: + lora_chain: + template: "LoraLoader" + output_map: + "unet_loader:0": "model" + "clip_loader:0": "clip" + input_map: + "model": "model" + "clip": "clip" + end_input_map: + "model": ["ksampler:model"] + "clip": ["pos_prompt:clip", "neg_prompt:clip"] + +dynamic_conditioning_chains: + conditioning_chain: + ksampler_node: "ksampler" + clip_source: "clip_loader:0" + +dynamic_pid_chains: + pid_chain: + ksampler_node: "ksampler" + +ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" + unet_name: "unet_loader:unet_name" + clip_name: "clip_loader:clip_name" + vae_name: "vae_loader:vae_name" diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/chroma1-radiance.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/chroma1-radiance.yaml index 0b9a569f276b6ac2a909f9b06ee90e0f97eadf9a..8c6e270451db8b7763eb224c42ca5221c438b53f 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/chroma1-radiance.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/chroma1-radiance.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load Diffusion Model" @@ -55,5 +61,7 @@ dynamic_conditioning_chains: clip_source: "t5_tokenizer:0" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" clip_name: "clip_loader:clip_name" \ No newline at end of file diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/chroma1.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/chroma1.yaml index fc0a05170e84f454133d603f85210a3c21456771..4fcb990b75599a46acadb816a264e5217e4f87a3 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/chroma1.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/chroma1.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load Diffusion Model" @@ -60,6 +66,8 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" vae_name: "vae_loader:vae_name" clip_name: "clip_loader:clip_name" \ No newline at end of file diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/cosmos-predict2.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/cosmos-predict2.yaml index d2c9c9e6539f88ab28cca210f6997c43851e7a0e..88f876db099dc3f56194df557596047f0516a5e5 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/cosmos-predict2.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/cosmos-predict2.yaml @@ -1,47 +1,55 @@ -nodes: - unet_loader: - class_type: UNETLoader - title: "Load Diffusion Model" - params: - weight_dtype: "default" - vae_loader: - class_type: VAELoader - title: "Load VAE" - clip_loader: - class_type: CLIPLoader - title: "Load CLIP" - params: - type: "cosmos" - device: "default" - -connections: - - from: "unet_loader:0" - to: "ksampler:model" - - from: "clip_loader:0" - to: "pos_prompt:clip" - - from: "clip_loader:0" - to: "neg_prompt:clip" - - from: "pos_prompt:0" - to: "ksampler:positive" - - from: "neg_prompt:0" - to: "ksampler:negative" - - from: "vae_loader:0" - to: "vae_decode:vae" - - from: "vae_loader:0" - to: "vae_encode:vae" - -dynamic_vae_chains: - vae_chain: - targets: - - "vae_decode:vae" - - "vae_encode:vae" - -dynamic_conditioning_chains: - conditioning_chain: - ksampler_node: "ksampler" - clip_source: "clip_loader:0" - -ui_map: - unet_name: "unet_loader:unet_name" - vae_name: "vae_loader:vae_name" - clip_name: "clip_loader:clip_name" +nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" + unet_loader: + class_type: UNETLoader + title: "Load Diffusion Model" + params: + weight_dtype: "default" + vae_loader: + class_type: VAELoader + title: "Load VAE" + clip_loader: + class_type: CLIPLoader + title: "Load CLIP" + params: + type: "cosmos" + device: "default" + +connections: + - from: "unet_loader:0" + to: "ksampler:model" + - from: "clip_loader:0" + to: "pos_prompt:clip" + - from: "clip_loader:0" + to: "neg_prompt:clip" + - from: "pos_prompt:0" + to: "ksampler:positive" + - from: "neg_prompt:0" + to: "ksampler:negative" + - from: "vae_loader:0" + to: "vae_decode:vae" + - from: "vae_loader:0" + to: "vae_encode:vae" + +dynamic_vae_chains: + vae_chain: + targets: + - "vae_decode:vae" + - "vae_encode:vae" + +dynamic_conditioning_chains: + conditioning_chain: + ksampler_node: "ksampler" + clip_source: "clip_loader:0" + +ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" + unet_name: "unet_loader:unet_name" + vae_name: "vae_loader:vae_name" + clip_name: "clip_loader:clip_name" diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/ernie-image.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/ernie-image.yaml index 4d8f8154ff98d042e736495e470e51043659e9b4..277d4849bfc0cbcf57974133597b8d293e59707d 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/ernie-image.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/ernie-image.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load Diffusion Model" @@ -53,6 +59,8 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" clip_name: "clip_loader:clip_name" vae_name: "vae_loader:vae_name" \ No newline at end of file diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/flux1.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/flux1.yaml index ab4c54cd878ee667df8be8225a24dbbd8a4a0af3..fcfdedb95e08e6280b2ffe72108ec80331ee3211 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/flux1.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/flux1.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load FLUX UNET" @@ -61,6 +67,8 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" vae_name: "vae_loader:vae_name" clip1_name: "clip_loader:clip_name1" diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/hidream-i1.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/hidream-i1.yaml index 657df564f7e0410c6fedb2b65f81ede31dc8c7aa..e03b350ce8e09086ef57bb4f3a52333e93c2c303 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/hidream-i1.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/hidream-i1.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load HiDream-I1 UNET" @@ -49,6 +55,8 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" vae_name: "vae_loader:vae_name" clip1_name: "clip_loader:clip_name1" diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/hidream-o1.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/hidream-o1.yaml index 8b2f1f0f4a1dc9a9b1f227ba432f4ed1687c498e..76b36f6f5130f3d63961be28a698e6c78d92a601 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/hidream-o1.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/hidream-o1.yaml @@ -1,68 +1,76 @@ -nodes: - ckpt_loader: - class_type: CheckpointLoaderSimple - title: "Load Checkpoint" - - model_noise_scale: - class_type: ModelNoiseScale - title: "ModelNoiseScale" - params: - noise_scale: 8 - -connections: - - from: "ckpt_loader:0" - to: "model_noise_scale:model" - - - from: "model_noise_scale:0" - to: "ksampler:model" - - - from: "ckpt_loader:1" - to: "pos_prompt:clip" - - from: "ckpt_loader:1" - to: "neg_prompt:clip" - - - from: "pos_prompt:0" - to: "ksampler:positive" - - from: "neg_prompt:0" - to: "ksampler:negative" - - - from: "ckpt_loader:2" - to: "vae_decode:vae" - - from: "ckpt_loader:2" - to: "vae_encode:vae" - -dynamic_vae_chains: - vae_chain: - targets: - - "vae_decode:vae" - - "vae_encode:vae" - -dynamic_lora_chains: - lora_chain: - template: "LoraLoader" - start: "ckpt_loader" - output_map: - "0": "model" - "1": "clip" - input_map: - "model": "model" - "clip": "clip" - end_input_map: - "model": ["model_noise_scale:model"] - "clip": ["pos_prompt:clip", "neg_prompt:clip"] - -dynamic_hidream_o1_smoothing_chains: - hidream_o1_smoothing_chain: - target_node: "ksampler" - -dynamic_conditioning_chains: - conditioning_chain: - ksampler_node: "ksampler" - clip_source: "ckpt_loader:1" - -dynamic_hidream_o1_reference_chains: - hidream_o1_reference_chain: - ksampler_node: "ksampler" - -ui_map: +nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" + ckpt_loader: + class_type: CheckpointLoaderSimple + title: "Load Checkpoint" + + model_noise_scale: + class_type: ModelNoiseScale + title: "ModelNoiseScale" + params: + noise_scale: 8 + +connections: + - from: "ckpt_loader:0" + to: "model_noise_scale:model" + + - from: "model_noise_scale:0" + to: "ksampler:model" + + - from: "ckpt_loader:1" + to: "pos_prompt:clip" + - from: "ckpt_loader:1" + to: "neg_prompt:clip" + + - from: "pos_prompt:0" + to: "ksampler:positive" + - from: "neg_prompt:0" + to: "ksampler:negative" + + - from: "ckpt_loader:2" + to: "vae_decode:vae" + - from: "ckpt_loader:2" + to: "vae_encode:vae" + +dynamic_vae_chains: + vae_chain: + targets: + - "vae_decode:vae" + - "vae_encode:vae" + +dynamic_lora_chains: + lora_chain: + template: "LoraLoader" + start: "ckpt_loader" + output_map: + "0": "model" + "1": "clip" + input_map: + "model": "model" + "clip": "clip" + end_input_map: + "model": ["model_noise_scale:model"] + "clip": ["pos_prompt:clip", "neg_prompt:clip"] + +dynamic_hidream_o1_smoothing_chains: + hidream_o1_smoothing_chain: + target_node: "ksampler" + +dynamic_conditioning_chains: + conditioning_chain: + ksampler_node: "ksampler" + clip_source: "ckpt_loader:1" + +dynamic_hidream_o1_reference_chains: + hidream_o1_reference_chain: + ksampler_node: "ksampler" + +ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" model_name: "ckpt_loader:ckpt_name" \ No newline at end of file diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/hunyuanimage.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/hunyuanimage.yaml index 7fa9a42af9a6be0ff527e532026bd33309fc9373..7a34f5721cb97c62b39b9aa296c58a2da5aeb02b 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/hunyuanimage.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/hunyuanimage.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load Hunyuan UNET" @@ -36,6 +42,8 @@ dynamic_conditioning_chains: clip_source: "clip_loader:0" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" vae_name: "vae_loader:vae_name" clip1_name: "clip_loader:clip_name1" diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/ideogram-4.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/ideogram-4.yaml index 54cb4df812a3fa392106984ca90cd02f23e1923b..7d985af16f2efba48a970292fd4e65b9c4727c5e 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/ideogram-4.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/ideogram-4.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load Diffusion Model" @@ -95,6 +101,8 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" unet_uncond_name: "unet_uncond_loader:unet_name" clip_name: "clip_loader:clip_name" diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/joyai-image.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/joyai-image.yaml index 01afde5de910dbed134695b560b6ffab4429a587..b8e2009f1225b3ab016143f3273c0a501354a501 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/joyai-image.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/joyai-image.yaml @@ -1,86 +1,86 @@ -nodes: - unet_loader: - class_type: UNETLoader - title: "Load Diffusion Model" - params: - weight_dtype: "default" - vae_loader: - class_type: VAELoader - title: "Load VAE" - clip_loader: - class_type: CLIPLoader - title: "Load CLIP" - params: - type: "joyimage" - device: "default" - - pos_prompt: - class_type: TextEncodeJoyImageEdit - title: "TextEncodeJoyImageEdit (Positive)" - neg_prompt: - class_type: TextEncodeJoyImageEdit - title: "TextEncodeJoyImageEdit (Negative)" - - cfg_norm: - class_type: CFGNorm - title: "CFGNorm" - params: - strength: 1.0 - pre_cfg: true - -connections: - - from: "unet_loader:0" - to: "cfg_norm:model" - - from: "cfg_norm:0" - to: "ksampler:model" - - - from: "clip_loader:0" - to: "pos_prompt:clip" - - from: "clip_loader:0" - to: "neg_prompt:clip" - - - from: "pos_prompt:0" - to: "ksampler:positive" - - from: "neg_prompt:0" - to: "ksampler:negative" - - - from: "vae_loader:0" - to: "vae_decode:vae" - - from: "vae_loader:0" - to: "vae_encode:vae" - -dynamic_lora_chains: - lora_chain: - template: "LoraLoader" - output_map: - "unet_loader:0": "model" - "clip_loader:0": "clip" - input_map: - "model": "model" - "clip": "clip" - end_input_map: - "model": ["cfg_norm:model"] - "clip": ["pos_prompt:clip", "neg_prompt:clip"] - -dynamic_conditioning_chains: - conditioning_chain: - ksampler_node: "ksampler" - clip_source: "clip_loader:0" - -dynamic_pid_chains: - pid_chain: - ksampler_node: "ksampler" - -dynamic_joyai_reference_chains: - joyai_reference_chain: - pos_prompt_node: "pos_prompt" - neg_prompt_node: "neg_prompt" - vae_node: "vae_loader" - -ui_map: - unet_name: "unet_loader:unet_name" - vae_name: "vae_loader:vae_name" - clip_name: "clip_loader:clip_name" - positive_prompt: "pos_prompt:prompt" - negative_prompt: "neg_prompt:prompt" - +nodes: + unet_loader: + class_type: UNETLoader + title: "Load Diffusion Model" + params: + weight_dtype: "default" + vae_loader: + class_type: VAELoader + title: "Load VAE" + clip_loader: + class_type: CLIPLoader + title: "Load CLIP" + params: + type: "joyimage" + device: "default" + + pos_prompt: + class_type: TextEncodeJoyImageEdit + title: "TextEncodeJoyImageEdit (Positive)" + neg_prompt: + class_type: TextEncodeJoyImageEdit + title: "TextEncodeJoyImageEdit (Negative)" + + cfg_norm: + class_type: CFGNorm + title: "CFGNorm" + params: + strength: 1.0 + pre_cfg: true + +connections: + - from: "unet_loader:0" + to: "cfg_norm:model" + - from: "cfg_norm:0" + to: "ksampler:model" + + - from: "clip_loader:0" + to: "pos_prompt:clip" + - from: "clip_loader:0" + to: "neg_prompt:clip" + + - from: "pos_prompt:0" + to: "ksampler:positive" + - from: "neg_prompt:0" + to: "ksampler:negative" + + - from: "vae_loader:0" + to: "vae_decode:vae" + - from: "vae_loader:0" + to: "vae_encode:vae" + +dynamic_lora_chains: + lora_chain: + template: "LoraLoader" + output_map: + "unet_loader:0": "model" + "clip_loader:0": "clip" + input_map: + "model": "model" + "clip": "clip" + end_input_map: + "model": ["cfg_norm:model"] + "clip": ["pos_prompt:clip", "neg_prompt:clip"] + +dynamic_conditioning_chains: + conditioning_chain: + ksampler_node: "ksampler" + clip_source: "clip_loader:0" + +dynamic_pid_chains: + pid_chain: + ksampler_node: "ksampler" + +dynamic_joyai_reference_chains: + joyai_reference_chain: + pos_prompt_node: "pos_prompt" + neg_prompt_node: "neg_prompt" + vae_node: "vae_loader" + +ui_map: + unet_name: "unet_loader:unet_name" + vae_name: "vae_loader:vae_name" + clip_name: "clip_loader:clip_name" + positive_prompt: "pos_prompt:prompt" + negative_prompt: "neg_prompt:prompt" + diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/kandinsky-5.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/kandinsky-5.yaml index eff57c82ccd76d84d63b913a4a4b6d8d794b5e6c..35b452e8eceb2235d56d6c994ed3b54c61905b78 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/kandinsky-5.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/kandinsky-5.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load Diffusion Model" @@ -66,6 +72,8 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" vae_name: "vae_loader:vae_name" clip1_name: "clip_loader:clip_name1" diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/krea-2.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/krea-2.yaml index 2a4b78b194be5a35c162484b8c19b9855f28e57f..7d34b6fc33de10859c65f53a640e6e5d6abaad82 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/krea-2.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/krea-2.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load Diffusion Model" @@ -58,6 +64,8 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" clip_name: "clip_loader:clip_name" vae_name: "vae_loader:vae_name" \ No newline at end of file diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/lens.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/lens.yaml index 1b68ce8a158c2dba2cae5abd8d7df4a29da00299..24dde3f4ffbb15808c356357e3253587420467d8 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/lens.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/lens.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load Diffusion Model" @@ -53,6 +59,8 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" clip_name: "clip_loader:clip_name" vae_name: "vae_loader:vae_name" \ No newline at end of file diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/longcat-image.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/longcat-image.yaml index 46b9c34b77de33b83fc99476ead755c528604de2..b53f5f74639d42624ed831087c1ce4bcdac9e61b 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/longcat-image.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/longcat-image.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load Diffusion Model" @@ -82,6 +88,8 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" vae_name: "vae_loader:vae_name" clip_name: "clip_loader:clip_name" \ No newline at end of file diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/lumina.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/lumina.yaml index 3170507a36c78b6d98f89007bbcd0f3ea203c183..573198cc684c80c374b72035810403d26626bb39 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/lumina.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/lumina.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" ckpt_loader: class_type: CheckpointLoaderSimple title: "Load Checkpoint" @@ -58,4 +64,6 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" model_name: "ckpt_loader:ckpt_name" \ No newline at end of file diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/mage-flow.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/mage-flow.yaml new file mode 100644 index 0000000000000000000000000000000000000000..20621c282a1456bc56c3aab4d8bb5fc97fef94f4 --- /dev/null +++ b/core/pipelines/workflow_recipes/_partials/conditioning/mage-flow.yaml @@ -0,0 +1,77 @@ +nodes: + unet_loader: + class_type: UNETLoader + title: "Load Diffusion Model" + params: + weight_dtype: "default" + vae_loader: + class_type: VAELoader + title: "Load VAE" + clip_loader: + class_type: CLIPLoader + title: "Load CLIP" + params: + type: "mage" + device: "default" + text_encode_latent: + class_type: TextEncodeMageFlowEdit + title: "TextEncodeMageFlowEdit" + +connections: + - from: "unet_loader:0" + to: "ksampler:model" + - from: "clip_loader:0" + to: "text_encode_latent:clip" + - from: "vae_loader:0" + to: "vae_decode:vae" + - from: "vae_loader:0" + to: "vae_encode:vae" + - from: "text_encode_latent:0" + to: "ksampler:positive" + - from: "text_encode_latent:1" + to: "ksampler:negative" + - from: "text_encode_latent:2" + to: "ksampler:latent_image" + +dynamic_lora_chains: + lora_chain: + template: "LoraLoader" + output_map: + "unet_loader:0": "model" + "clip_loader:0": "clip" + input_map: + "model": "model" + "clip": "clip" + end_input_map: + "model": ["ksampler:model"] + "clip": ["text_encode_latent:clip"] + +dynamic_controlnet_chains: + controlnet_chain: + template: "ControlNetApplyAdvanced" + ksampler_node: "ksampler" + vae_source: "vae_loader:0" + +dynamic_conditioning_chains: + conditioning_chain: + ksampler_node: "ksampler" + clip_source: "clip_loader:0" + +dynamic_pid_chains: + pid_chain: + ksampler_node: "ksampler" + +dynamic_reference_image_chains: + reference_image_chain: + text_encode_node: "text_encode_latent" + vae_node: "vae_loader" + +ui_map: + unet_name: "unet_loader:unet_name" + vae_name: "vae_loader:vae_name" + clip_name: "clip_loader:clip_name" + positive_prompt: "text_encode_latent:prompt" + negative_prompt: "text_encode_latent:negative_prompt" + width: "text_encode_latent:width" + height: "text_encode_latent:height" + batch_size: "text_encode_latent:batch_size" diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/newbie-image.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/newbie-image.yaml index 339464ca0118ff49e00cea884da8f189610b5cda..045657df6e9661c8b48e34b3cca079dfed4c05cc 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/newbie-image.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/newbie-image.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load Diffusion Model" @@ -63,6 +69,8 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" vae_name: "vae_loader:vae_name" clip1_name: "clip_loader:clip_name1" diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/omnigen2.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/omnigen2.yaml index 6f74bd8cb856d945d478119c0bc0f7bd358191a9..f9024b25c959df8cb58d2f78fc4faef4594053b8 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/omnigen2.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/omnigen2.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load Diffusion Model" @@ -58,6 +64,8 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" vae_name: "vae_loader:vae_name" clip_name: "clip_loader:clip_name" \ No newline at end of file diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/ovis-image.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/ovis-image.yaml index 56c62007afc81db545fbe3975aab4cc8fa8384c6..50cc11554435f7d09c39b27c5a21edd5d71c0858 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/ovis-image.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/ovis-image.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load Diffusion Model" @@ -49,6 +55,8 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" vae_name: "vae_loader:vae_name" clip_name: "clip_loader:clip_name" \ No newline at end of file diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/pixeldit.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/pixeldit.yaml index 0b2ca187c0ee2105365ac55993614896a09fb2a7..ccc711d9af804269d4933654f3ffb052fdb45398 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/pixeldit.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/pixeldit.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load Diffusion Model" @@ -38,6 +44,8 @@ dynamic_conditioning_chains: clip_source: "clip_loader:0" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" vae_name: "vae_loader:vae_name" clip_name: "clip_loader:clip_name" \ No newline at end of file diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/qwen-image.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/qwen-image.yaml index 780a92a12d74fe8e987084a72a584c3c2ba15187..dea187d26ff7cf275c2004d3cc99fb1a5827b41a 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/qwen-image.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/qwen-image.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load Qwen UNET" @@ -70,6 +76,8 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" vae_name: "vae_loader:vae_name" clip_name: "clip_loader:clip_name" \ No newline at end of file diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/sd15.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/sd15.yaml index 03858047f4a66d9a6fc83ab5b9c835b3580e199c..c2eda2b4f259a89065186af0cd538813627f04e6 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/sd15.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/sd15.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" ckpt_loader: class_type: CheckpointLoaderSimple title: "Load Checkpoint" @@ -65,5 +71,7 @@ dynamic_conditioning_chains: clip_source: "clip_set_last_layer:0" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" model_name: "ckpt_loader:ckpt_name" clip_skip: "clip_set_last_layer:stop_at_clip_layer" \ No newline at end of file diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/sd35.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/sd35.yaml index 65b9caafc08147ebd91e0483eb1b3fed4844b5fc..87a66d63cda04dd963824fedaa12e42ecd384625 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/sd35.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/sd35.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" ckpt_loader: class_type: CheckpointLoaderSimple title: "Load Checkpoint" @@ -59,4 +65,6 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" model_name: "ckpt_loader:ckpt_name" \ No newline at end of file diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/sdxl.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/sdxl.yaml index db0195ec410a7c4cbdfbc14fba051e525d313c7e..3bff063c0d2d1373075c23862abab6121a83d68d 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/sdxl.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/sdxl.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" ckpt_loader: class_type: CheckpointLoaderSimple title: "Load Checkpoint" @@ -64,4 +70,6 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" model_name: "ckpt_loader:ckpt_name" \ No newline at end of file diff --git a/core/pipelines/workflow_recipes/_partials/conditioning/z-image.yaml b/core/pipelines/workflow_recipes/_partials/conditioning/z-image.yaml index d6e2f23e4a79bde95d8a8c397ba86f303876337f..66ac4fe5aac7e5346a443af389a0d5e556a4a149 100644 --- a/core/pipelines/workflow_recipes/_partials/conditioning/z-image.yaml +++ b/core/pipelines/workflow_recipes/_partials/conditioning/z-image.yaml @@ -1,4 +1,10 @@ nodes: + pos_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Positive)" + neg_prompt: + class_type: CLIPTextEncode + title: "CLIP Text Encode (Negative)" unet_loader: class_type: UNETLoader title: "Load Diffusion Model" @@ -64,6 +70,8 @@ dynamic_pid_chains: ksampler_node: "ksampler" ui_map: + positive_prompt: "pos_prompt:text" + negative_prompt: "neg_prompt:text" unet_name: "unet_loader:unet_name" vae_name: "vae_loader:vae_name" clip_name: "clip_loader:clip_name" \ No newline at end of file diff --git a/core/pipelines/workflow_recipes/_partials/input/txt2img_hidream_o1_latent.yaml b/core/pipelines/workflow_recipes/_partials/input/txt2img_hidream_o1_latent.yaml index bcdb9a7c5fd77a46f656a30f8a2b3b45a68b5625..153f2de21ec173a90c0b7b2d4f53424a31c71462 100644 --- a/core/pipelines/workflow_recipes/_partials/input/txt2img_hidream_o1_latent.yaml +++ b/core/pipelines/workflow_recipes/_partials/input/txt2img_hidream_o1_latent.yaml @@ -1,11 +1,11 @@ -nodes: - latent_source: - class_type: "EmptyHiDreamO1LatentImage" - title: "Empty HiDream-O1 Latent Image" - -connections: [] - -ui_map: - width: "latent_source:width" - height: "latent_source:height" - batch_size: "latent_source:batch_size" +nodes: + latent_source: + class_type: "EmptyHiDreamO1LatentImage" + title: "Empty HiDream-O1 Latent Image" + +connections: [] + +ui_map: + width: "latent_source:width" + height: "latent_source:height" + batch_size: "latent_source:batch_size" diff --git a/core/pipelines/workflow_recipes/_partials/input/txt2img_none.yaml b/core/pipelines/workflow_recipes/_partials/input/txt2img_none.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e3032a53a91501210c00f44afb1dfa9dea9c5ef9 --- /dev/null +++ b/core/pipelines/workflow_recipes/_partials/input/txt2img_none.yaml @@ -0,0 +1,5 @@ +nodes: {} + +connections: [] + +ui_map: {} diff --git a/ui/events/chain_handlers.py b/ui/events/chain_handlers.py index de0d61c93f4b55cb3a0adce885eb3cd54958008f..7026ebd16ef50c0a9695dc2ae6c9e3718f2d300e 100644 --- a/ui/events/chain_handlers.py +++ b/ui/events/chain_handlers.py @@ -748,6 +748,39 @@ def create_joyai_reference_event_handlers(prefix, ui_components): del_button.click(fn=del_ref_row, inputs=[count_state], outputs=del_outputs, show_progress=False) +def create_reference_image_event_handlers(prefix, ui_components): + ref_rows = ui_components.get(f'reference_image_rows_{prefix}') + if not ref_rows: return + count_state = ui_components[f'reference_image_count_state_{prefix}'] + add_button = ui_components[f'add_reference_image_button_{prefix}'] + del_button = ui_components[f'delete_reference_image_button_{prefix}'] + images = ui_components[f'reference_image_images_{prefix}'] + + def add_ref_row(c): + c += 1 + return { + count_state: c, + ref_rows[c - 1]: gr.update(visible=True), + add_button: gr.update(visible=c < 10), + del_button: gr.update(visible=True), + } + + def del_ref_row(c): + c -= 1 + return { + count_state: c, + ref_rows[c]: gr.update(visible=False), + images[c]: None, + add_button: gr.update(visible=True), + del_button: gr.update(visible=c > 0), + } + + add_outputs = [count_state, add_button, del_button] + ref_rows + del_outputs = [count_state, add_button, del_button] + ref_rows + images + add_button.click(fn=add_ref_row, inputs=[count_state], outputs=add_outputs, show_progress=False) + del_button.click(fn=del_ref_row, inputs=[count_state], outputs=del_outputs, show_progress=False) + + def create_embedding_event_handlers(prefix, ui_components): rows = ui_components.get(f'embedding_rows_{prefix}') if not rows: return diff --git a/ui/events/change_handlers.py b/ui/events/change_handlers.py index 0a55b8199b03d318b24392d9ce2816253cf4d2e8..543801e75b02dd6c8805d166b3e45bf5823e4c10 100644 --- a/ui/events/change_handlers.py +++ b/ui/events/change_handlers.py @@ -17,7 +17,7 @@ from .config_loaders import ( load_ipadapter_config ) -def make_update_fn(m_comp, cat_comp, cs_comp, ar_comp, width_comp, height_comp, cn_types, cn_series, cn_filepaths, anima_cn_types, anima_cn_series, anima_cn_filepaths, diffsynth_cn_types, diffsynth_cn_series, diffsynth_cn_filepaths, krea2_cn_types, krea2_cn_series, krea2_cn_filepaths, ipa_preset, lora_acc, cn_acc, anima_cn_acc, diffsynth_cn_acc, krea2_cn_acc, ipa_acc, sd3_ipa_acc, flux1_ipa_acc, style_acc, embed_acc, cond_acc, ref_latent_acc, hidream_o1_ref_acc, guidance_comp, prompt_comp, neg_prompt_comp, steps_comp, cfg_comp, sampler_comp, scheduler_comp, pid_acc=None, vae_acc=None, joyai_ref_acc=None): +def make_update_fn(m_comp, cat_comp, cs_comp, ar_comp, width_comp, height_comp, cn_types, cn_series, cn_filepaths, anima_cn_types, anima_cn_series, anima_cn_filepaths, diffsynth_cn_types, diffsynth_cn_series, diffsynth_cn_filepaths, krea2_cn_types, krea2_cn_series, krea2_cn_filepaths, ipa_preset, lora_acc, cn_acc, anima_cn_acc, diffsynth_cn_acc, krea2_cn_acc, ipa_acc, sd3_ipa_acc, flux1_ipa_acc, style_acc, embed_acc, cond_acc, ref_latent_acc, hidream_o1_ref_acc, guidance_comp, prompt_comp, neg_prompt_comp, steps_comp, cfg_comp, sampler_comp, scheduler_comp, pid_acc=None, vae_acc=None, joyai_ref_acc=None, ref_img_acc=None): def update_fn(*args): arch = args[0] category = args[1] @@ -69,6 +69,7 @@ def make_update_fn(m_comp, cat_comp, cs_comp, ar_comp, width_comp, height_comp, if ref_latent_acc: updates[ref_latent_acc] = gr.update(visible=('reference_latent' in enabled_chains)) if hidream_o1_ref_acc: updates[hidream_o1_ref_acc] = gr.update(visible=('hidream_o1_reference' in enabled_chains)) if joyai_ref_acc: updates[joyai_ref_acc] = gr.update(visible=('joyai_reference' in enabled_chains)) + if ref_img_acc: updates[ref_img_acc] = gr.update(visible=('reference_image' in enabled_chains)) if pid_acc: updates[pid_acc] = gr.update(visible=('pid' in enabled_chains)) if vae_acc: updates[vae_acc] = gr.update(visible=('vae' in enabled_chains)) @@ -143,7 +144,7 @@ def make_update_fn(m_comp, cat_comp, cs_comp, ar_comp, width_comp, height_comp, return update_fn -def make_model_change_fn(cat_comp_ref, cs_comp, ar_comp, width_comp, height_comp, cn_types, cn_series, cn_filepaths, anima_cn_types, anima_cn_series, anima_cn_filepaths, diffsynth_cn_types, diffsynth_cn_series, diffsynth_cn_filepaths, krea2_cn_types, krea2_cn_series, krea2_cn_filepaths, arch_comp_ref, ipa_preset, lora_acc, cn_acc, anima_cn_acc, diffsynth_cn_acc, krea2_cn_acc, ipa_acc, sd3_ipa_acc, flux1_ipa_acc, style_acc, embed_acc, cond_acc, ref_latent_acc, hidream_o1_ref_acc, guidance_comp, prompt_comp, neg_prompt_comp, steps_comp, cfg_comp, sampler_comp, scheduler_comp, pid_acc=None, vae_acc=None, joyai_ref_acc=None): +def make_model_change_fn(cat_comp_ref, cs_comp, ar_comp, width_comp, height_comp, cn_types, cn_series, cn_filepaths, anima_cn_types, anima_cn_series, anima_cn_filepaths, diffsynth_cn_types, diffsynth_cn_series, diffsynth_cn_filepaths, krea2_cn_types, krea2_cn_series, krea2_cn_filepaths, arch_comp_ref, ipa_preset, lora_acc, cn_acc, anima_cn_acc, diffsynth_cn_acc, krea2_cn_acc, ipa_acc, sd3_ipa_acc, flux1_ipa_acc, style_acc, embed_acc, cond_acc, ref_latent_acc, hidream_o1_ref_acc, guidance_comp, prompt_comp, neg_prompt_comp, steps_comp, cfg_comp, sampler_comp, scheduler_comp, pid_acc=None, vae_acc=None, joyai_ref_acc=None, ref_img_acc=None): def change_fn(*args): model_name = args[0] idx = 1 @@ -200,9 +201,9 @@ def make_model_change_fn(cat_comp_ref, cs_comp, ar_comp, width_comp, height_comp if ref_latent_acc: updates[ref_latent_acc] = gr.update(visible=('reference_latent' in enabled_chains)) if hidream_o1_ref_acc: updates[hidream_o1_ref_acc] = gr.update(visible=('hidream_o1_reference' in enabled_chains)) if joyai_ref_acc: updates[joyai_ref_acc] = gr.update(visible=('joyai_reference' in enabled_chains)) + if ref_img_acc: updates[ref_img_acc] = gr.update(visible=('reference_image' in enabled_chains)) if pid_acc: updates[pid_acc] = gr.update(visible=('pid' in enabled_chains)) if vae_acc: updates[vae_acc] = gr.update(visible=('vae' in enabled_chains)) - if vae_acc: updates[vae_acc] = gr.update(visible=('vae' in enabled_chains)) if cs_comp: updates[cs_comp] = gr.update(visible=(arch_model_type == "sd15")) diff --git a/ui/events/main.py b/ui/events/main.py index f6a5b381dfba9d431474b2540ff182ba2a61b20f..3811e37ae30fe5b734936ce9237248ce78d5bca5 100644 --- a/ui/events/main.py +++ b/ui/events/main.py @@ -13,7 +13,8 @@ from .chain_handlers import ( create_style_event_handlers, create_reference_latent_event_handlers, create_hidream_o1_reference_event_handlers, - create_joyai_reference_event_handlers + create_joyai_reference_event_handlers, + create_reference_image_event_handlers ) from .change_handlers import ( make_update_fn, @@ -68,6 +69,7 @@ def attach_event_handlers(ui_components, demo): ref_latent_accordion = ui_components.get(f'reference_latent_accordion_{prefix}') hidream_o1_ref_accordion = ui_components.get(f'hidream_o1_reference_accordion_{prefix}') joyai_ref_accordion = ui_components.get(f'joyai_reference_accordion_{prefix}') + ref_img_accordion = ui_components.get(f'reference_image_accordion_{prefix}') pid_accordion = ui_components.get(f'pid_accordion_{prefix}') vae_accordion = ui_components.get(f'vae_accordion_{prefix}') @@ -106,6 +108,7 @@ def attach_event_handlers(ui_components, demo): if ref_latent_accordion: outputs.append(ref_latent_accordion) if hidream_o1_ref_accordion: outputs.append(hidream_o1_ref_accordion) if joyai_ref_accordion: outputs.append(joyai_ref_accordion) + if ref_img_accordion: outputs.append(ref_img_accordion) if pid_accordion: outputs.append(pid_accordion) if vae_accordion: outputs.append(vae_accordion) if ipa_preset_list: outputs.append(ipa_preset_list) @@ -120,7 +123,7 @@ def attach_event_handlers(ui_components, demo): krea2_cn_types_list, krea2_cn_series_list, krea2_cn_filepaths_list, ipa_preset_list, lora_accordion, cn_accordion, anima_cn_accordion, diffsynth_cn_accordion, krea2_cn_accordion, ipa_accordion, sd3_ipa_accordion, flux1_ipa_accordion, style_accordion, embedding_accordion, conditioning_accordion, ref_latent_accordion, hidream_o1_ref_accordion, guidance_comp, prompt_comp, neg_prompt_comp, steps_comp, cfg_comp, sampler_comp, scheduler_comp, - pid_acc=pid_accordion, vae_acc=vae_accordion, joyai_ref_acc=joyai_ref_accordion + pid_acc=pid_accordion, vae_acc=vae_accordion, joyai_ref_acc=joyai_ref_accordion, ref_img_acc=ref_img_accordion ) inputs = [arch_comp, cat_comp] if aspect_ratio_comp: @@ -153,6 +156,7 @@ def attach_event_handlers(ui_components, demo): if ref_latent_accordion: outputs2.append(ref_latent_accordion) if hidream_o1_ref_accordion: outputs2.append(hidream_o1_ref_accordion) if joyai_ref_accordion: outputs2.append(joyai_ref_accordion) + if ref_img_accordion: outputs2.append(ref_img_accordion) if pid_accordion: outputs2.append(pid_accordion) if vae_accordion: outputs2.append(vae_accordion) if ipa_preset_list: outputs2.append(ipa_preset_list) @@ -172,7 +176,7 @@ def attach_event_handlers(ui_components, demo): krea2_cn_types_list, krea2_cn_series_list, krea2_cn_filepaths_list, arch_comp, ipa_preset_list, lora_accordion, cn_accordion, anima_cn_accordion, diffsynth_cn_accordion, krea2_cn_accordion, ipa_accordion, sd3_ipa_accordion, flux1_ipa_accordion, style_accordion, embedding_accordion, conditioning_accordion, ref_latent_accordion, hidream_o1_ref_accordion, guidance_comp, prompt_comp, neg_prompt_comp, steps_comp, cfg_comp, sampler_comp, scheduler_comp, - pid_acc=pid_accordion, vae_acc=vae_accordion, joyai_ref_acc=joyai_ref_accordion + pid_acc=pid_accordion, vae_acc=vae_accordion, joyai_ref_acc=joyai_ref_accordion, ref_img_acc=ref_img_accordion ) model_comp.change(fn=change_fn, inputs=inputs2, outputs=outputs2) @@ -190,6 +194,7 @@ def attach_event_handlers(ui_components, demo): create_reference_latent_event_handlers(prefix, ui_components) create_hidream_o1_reference_event_handlers(prefix, ui_components) create_joyai_reference_event_handlers(prefix, ui_components) + create_reference_image_event_handlers(prefix, ui_components) create_run_event(prefix, task_type, ui_components) if 'view_mode_inpaint' in ui_components: diff --git a/ui/events/run_handlers.py b/ui/events/run_handlers.py index b112cbb570302f24bd28800029635c8ac29af459..59ef2a2e78c7f7de878c230ca13400e6f93d03a0 100644 --- a/ui/events/run_handlers.py +++ b/ui/events/run_handlers.py @@ -53,6 +53,7 @@ def create_run_event(prefix: str, task_type: str, ui_components: dict): reference_latent_data_components = ui_components.get(f'all_reference_latent_components_flat_{prefix}', []) hidream_o1_reference_data_components = ui_components.get(f'all_hidream_o1_reference_components_flat_{prefix}', []) joyai_reference_data_components = ui_components.get(f'all_joyai_reference_components_flat_{prefix}', []) + reference_image_data_components = ui_components.get(f'all_reference_image_components_flat_{prefix}', []) run_inputs_map['vae_source'] = ui_components.get(f'vae_source_{prefix}') run_inputs_map['vae_id'] = ui_components.get(f'vae_id_{prefix}') @@ -63,7 +64,7 @@ def create_run_event(prefix: str, task_type: str, ui_components: dict): all_chains = [ lora_data_components, controlnet_data_components, anima_controlnet_lllite_data_components, diffsynth_controlnet_data_components, krea2_controlnet_data_components, ipadapter_data_components, sd3_ipadapter_data_components, flux1_ipadapter_data_components, style_data_components, - embedding_data_components, conditioning_data_components, reference_latent_data_components, hidream_o1_reference_data_components, joyai_reference_data_components + embedding_data_components, conditioning_data_components, reference_latent_data_components, hidream_o1_reference_data_components, joyai_reference_data_components, reference_image_data_components ] for chain in all_chains: if chain: @@ -94,6 +95,7 @@ def create_run_event(prefix: str, task_type: str, ui_components: dict): assign_chain_data('reference_latent_data', reference_latent_data_components) assign_chain_data('hidream_o1_reference_data', hidream_o1_reference_data_components) assign_chain_data('joyai_reference_data', joyai_reference_data_components) + assign_chain_data('reference_image_data', reference_image_data_components) return ui_dict diff --git a/ui/shared/hires_fix_ui.py b/ui/shared/hires_fix_ui.py index 03a1db6100402a1ccd184efbf4afe18369877766..42ea68ca8e0b71c29e7330ecaf62b4b7839b4c60 100644 --- a/ui/shared/hires_fix_ui.py +++ b/ui/shared/hires_fix_ui.py @@ -7,7 +7,7 @@ from .ui_components import ( create_conditioning_ui, create_vae_override_ui, create_model_architecture_filter_ui, create_category_filter_ui, create_sd3_ipadapter_ui, create_flux1_ipadapter_ui, create_style_ui, - create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui + create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui, create_reference_image_ui ) default_vals = MODEL_DEFAULTS_CONFIG.get('Default', {}) @@ -102,6 +102,7 @@ def create_ui(): components.update(create_reference_latent_ui(prefix)) components.update(create_hidream_o1_reference_ui(prefix)) components.update(create_joyai_reference_ui(prefix)) + components.update(create_reference_image_ui(prefix)) components.update(create_vae_override_ui(prefix)) return components \ No newline at end of file diff --git a/ui/shared/img2img_ui.py b/ui/shared/img2img_ui.py index 6ddbedff325d00691770d2e53217fbca27396141..68ece6ecc32d94135c8b7f30969c8892c4ffebf4 100644 --- a/ui/shared/img2img_ui.py +++ b/ui/shared/img2img_ui.py @@ -7,7 +7,7 @@ from .ui_components import ( create_conditioning_ui, create_vae_override_ui, create_model_architecture_filter_ui, create_category_filter_ui, create_sd3_ipadapter_ui, create_flux1_ipadapter_ui, create_style_ui, - create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui + create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui, create_reference_image_ui ) default_vals = MODEL_DEFAULTS_CONFIG.get('Default', {}) @@ -83,6 +83,7 @@ def create_ui(): components.update(create_reference_latent_ui(prefix)) components.update(create_hidream_o1_reference_ui(prefix)) components.update(create_joyai_reference_ui(prefix)) + components.update(create_reference_image_ui(prefix)) components.update(create_vae_override_ui(prefix)) return components \ No newline at end of file diff --git a/ui/shared/inpaint_ui.py b/ui/shared/inpaint_ui.py index d804aeb7aaeed52b691656a5d803e783d3bb7d4d..19e779ab9e7fbbc327b091781a94f093d43a4b74 100644 --- a/ui/shared/inpaint_ui.py +++ b/ui/shared/inpaint_ui.py @@ -6,7 +6,7 @@ from .ui_components import ( create_conditioning_ui, create_vae_override_ui, create_model_architecture_filter_ui, create_category_filter_ui, create_sd3_ipadapter_ui, create_flux1_ipadapter_ui, create_style_ui, - create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui + create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui, create_reference_image_ui ) default_vals = MODEL_DEFAULTS_CONFIG.get('Default', {}) @@ -115,6 +115,7 @@ def create_ui(): components.update(create_reference_latent_ui(prefix)) components.update(create_hidream_o1_reference_ui(prefix)) components.update(create_joyai_reference_ui(prefix)) + components.update(create_reference_image_ui(prefix)) components.update(create_vae_override_ui(prefix)) components[f'accordion_wrapper_{prefix}'] = accordion_wrapper diff --git a/ui/shared/outpaint_ui.py b/ui/shared/outpaint_ui.py index 1b7debc38f145b35fce680b417f395e27b6e094e..afb4b0820dbd07e1dc1807d05022e706f7d345f2 100644 --- a/ui/shared/outpaint_ui.py +++ b/ui/shared/outpaint_ui.py @@ -7,7 +7,7 @@ from .ui_components import ( create_conditioning_ui, create_vae_override_ui, create_model_architecture_filter_ui, create_category_filter_ui, create_sd3_ipadapter_ui, create_flux1_ipadapter_ui, create_style_ui, - create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui + create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui, create_reference_image_ui ) default_vals = MODEL_DEFAULTS_CONFIG.get('Default', {}) @@ -98,6 +98,7 @@ def create_ui(): components.update(create_reference_latent_ui(prefix)) components.update(create_hidream_o1_reference_ui(prefix)) components.update(create_joyai_reference_ui(prefix)) + components.update(create_reference_image_ui(prefix)) components.update(create_vae_override_ui(prefix)) return components \ No newline at end of file diff --git a/ui/shared/txt2img_ui.py b/ui/shared/txt2img_ui.py index fe31a58165702c2ac2f5129cafa314bb668638bf..594a8a8f4f50ab56016a46fc55506a026b91d9a2 100644 --- a/ui/shared/txt2img_ui.py +++ b/ui/shared/txt2img_ui.py @@ -6,7 +6,7 @@ from .ui_components import ( create_conditioning_ui, create_vae_override_ui, create_model_architecture_filter_ui, create_category_filter_ui, create_sd3_ipadapter_ui, create_flux1_ipadapter_ui, create_style_ui, - create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui, + create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui, create_reference_image_ui, create_pid_ui ) @@ -55,6 +55,7 @@ def create_ui(): components.update(create_reference_latent_ui(prefix)) components.update(create_hidream_o1_reference_ui(prefix)) components.update(create_joyai_reference_ui(prefix)) + components.update(create_reference_image_ui(prefix)) components.update(create_vae_override_ui(prefix)) components.update(create_pid_ui(prefix)) diff --git a/ui/shared/ui_components.py b/ui/shared/ui_components.py index 4d1fa00c7117159c6f464395e991919018051802..0103fdb4171790ec256ed64e58df9e14efca1d9e 100644 --- a/ui/shared/ui_components.py +++ b/ui/shared/ui_components.py @@ -725,6 +725,35 @@ def create_joyai_reference_ui(prefix: str, max_units=2): return components +def create_reference_image_ui(prefix: str, max_units=10): + components = {} + key = lambda name: f"{name}_{prefix}" + + with gr.Accordion("Mage-Flow Reference Edit Settings", open=False, visible=('reference_image' in default_enabled_chains)) as ref_accordion: + components[key('reference_image_accordion')] = ref_accordion + gr.Markdown("💡 **Tip:** (Mage-Flow-Edit-Turbo/Mage-Flow-Edit recommended) For multimodal models, this feature enables powerful editing and combining capabilities. In txt2img mode, adding a single reference image performs an **Image Edit**, while adding multiple images performs an **Image Combine**.") + + ref_image_groups = [] + ref_image_inputs = [] + with gr.Row(): + for i in range(max_units): + with gr.Column(visible=(i < 1), min_width=160) as img_col: + img_comp = gr.Image(type="pil", label=f"Ref. {i+1}", sources=["upload"], height=150) + ref_image_groups.append(img_col) + ref_image_inputs.append(img_comp) + + components[key('reference_image_rows')] = ref_image_groups + components[key('reference_image_images')] = ref_image_inputs + + with gr.Row(): + components[key('add_reference_image_button')] = gr.Button("✚ Add Reference Image") + components[key('delete_reference_image_button')] = gr.Button("➖ Delete Reference Image", visible=False) + components[key('reference_image_count_state')] = gr.State(1) + + components[key('all_reference_image_components_flat')] = ref_image_inputs + + return components + def create_pid_ui(prefix: str): components = {} key = lambda name: f"{name}_{prefix}" diff --git a/yaml/constants.yaml b/yaml/constants.yaml index cd550d7ba2e2711dc115752cfd968d21cc347a6d..8d47f057601d14ccd20cf7f19b39ac8dfc098e9c 100644 --- a/yaml/constants.yaml +++ b/yaml/constants.yaml @@ -15,6 +15,14 @@ RESOLUTION_MAP: "3:4 (Classic Portrait)": [896, 1152] "3:2 (Photography)": [1216, 832] "2:3 (Photography Portrait)": [832, 1216] + mage-flow: + "1:1 (Square)": [1024, 1024] + "16:9 (Landscape)": [1344, 768] + "9:16 (Portrait)": [768, 1344] + "4:3 (Classic)": [1152, 896] + "3:4 (Classic Portrait)": [896, 1152] + "3:2 (Photography)": [1216, 832] + "2:3 (Photography Portrait)": [832, 1216] joyai-image: "1:1 (Square)": [1024, 1024] "16:9 (Landscape)": [1344, 768] @@ -241,8 +249,9 @@ RESOLUTION_MAP: "2:3 (Portrait)": [512, 768] MULTIPLIERS_MAP: - joyai-image: 1 krea-2: 1 + mage-flow: 1 + joyai-image: 1 boogu-image: 1 pixeldit: 1 ideogram-4: 1 diff --git a/yaml/file_list.yaml b/yaml/file_list.yaml index ddf233e6e635843d59b9a072e176e4bf952f066b..210eb3d785df029dfe2e102eb76c2e84d552cfa8 100644 --- a/yaml/file_list.yaml +++ b/yaml/file_list.yaml @@ -405,6 +405,23 @@ file: source: "hf" repo_id: "Comfy-Org/Krea-2" repository_file_path: "diffusion_models/krea2_raw_fp8_scaled.safetensors" + # Mage-Flow + - filename: "mage_flow_turbo_int8_convrot.safetensors" + source: "hf" + repo_id: "Comfy-Org/Mage-Flow" + repository_file_path: "diffusion_models/mage_flow_turbo_int8_convrot.safetensors" + - filename: "mage_flow_int8_convrot.safetensors" + source: "hf" + repo_id: "Comfy-Org/Mage-Flow" + repository_file_path: "diffusion_models/mage_flow_int8_convrot.safetensors" + - filename: "mage_flow_edit_turbo_int8_convrot.safetensors" + source: "hf" + repo_id: "Comfy-Org/Mage-Flow" + repository_file_path: "diffusion_models/mage_flow_edit_turbo_int8_convrot.safetensors" + - filename: "mage_flow_edit_int8_convrot.safetensors" + source: "hf" + repo_id: "Comfy-Org/Mage-Flow" + repository_file_path: "diffusion_models/mage_flow_edit_int8_convrot.safetensors" # JoyAI-Image - filename: "joyai_image_edit_int8_convrot.safetensors" source: "hf" @@ -916,4 +933,8 @@ file: - filename: "flux2-vae.safetensors" source: "hf" repo_id: "Comfy-Org/flux2-dev" - repository_file_path: "split_files/vae/flux2-vae.safetensors" \ No newline at end of file + repository_file_path: "split_files/vae/flux2-vae.safetensors" + - filename: "mage_flow_vae_bf16.safetensors" + source: "hf" + repo_id: "Comfy-Org/Mage-Flow" + repository_file_path: "vae/mage_flow_vae_bf16.safetensors" \ No newline at end of file diff --git a/yaml/image_gen_features.yaml b/yaml/image_gen_features.yaml index ed2d9bd2decdb513d2ff0b32387273e6a7cbcdf9..79feba5c3189f5d49ef669e40b96c5b49a50575e 100644 --- a/yaml/image_gen_features.yaml +++ b/yaml/image_gen_features.yaml @@ -8,6 +8,10 @@ default: - conditioning - vae +mage-flow: + enabled_chains: + - reference_image + joyai-image: enabled_chains: - joyai_reference diff --git a/yaml/injectors.yaml b/yaml/injectors.yaml index a16caef55710ee1777f45cabeafd9caef9849909..5cbf1a44463750a57ceac8d9eb7879a86442ce51 100644 --- a/yaml/injectors.yaml +++ b/yaml/injectors.yaml @@ -31,6 +31,8 @@ injector_definitions: module: "chain_injectors.hidream_o1_reference_injector" dynamic_joyai_reference_chains: module: "chain_injectors.joyai_reference_injector" + dynamic_reference_image_chains: + module: "chain_injectors.reference_image_injector" dynamic_pid_chains: module: "chain_injectors.pid_injector" @@ -51,4 +53,5 @@ injector_order: - dynamic_hidream_o1_smoothing_chains - dynamic_hidream_o1_reference_chains - dynamic_joyai_reference_chains + - dynamic_reference_image_chains - dynamic_pid_chains \ No newline at end of file diff --git a/yaml/model_architectures.yaml b/yaml/model_architectures.yaml index ca9069266a1c52cfcf3bdb8aed89d591e4aba568..6080ad03d3a8a99e96c692b0e2c785ee9d35f4b0 100644 --- a/yaml/model_architectures.yaml +++ b/yaml/model_architectures.yaml @@ -1,5 +1,6 @@ architecture_order: - "Krea-2" + - "Mage-Flow" - "JoyAI-Image" - "Boogu-Image" - "PixelDiT" @@ -32,6 +33,9 @@ architecture_order: architectures: Krea-2: model_type: "krea-2" + "Mage-Flow": + model_type: "mage-flow" + controlnet_key: "Mage-Flow" "JoyAI-Image": model_type: "joyai-image" "Boogu-Image": diff --git a/yaml/model_defaults.yaml b/yaml/model_defaults.yaml index a053321a8ccf463ab8822e1970d0fb913872a754..982f9cf14b3248c4e037f2c81fdafa2afec8be08 100644 --- a/yaml/model_defaults.yaml +++ b/yaml/model_defaults.yaml @@ -6,6 +6,19 @@ Default: positive_prompt: "" negative_prompt: "" +Mage-Flow: + _defaults: + steps: 30 + cfg: 5.0 + sampler_name: "euler" + scheduler: "simple" + "Mage-Flow-Turbo": + steps: 4 + cfg: 1.0 + "Mage-Flow-Edit-Turbo": + steps: 4 + cfg: 1.0 + Krea-2: _defaults: steps: 52 diff --git a/yaml/model_list.yaml b/yaml/model_list.yaml index 1006723821ca27d7de9a4c9bca7de21cc30a1f1e..a534b2ccb584bd249cf29def5b408be9ede44379 100644 --- a/yaml/model_list.yaml +++ b/yaml/model_list.yaml @@ -12,6 +12,29 @@ Checkpoint: unet: "krea2_raw_fp8_scaled.safetensors" clip: "qwen3vl_4b_fp8_scaled.safetensors" vae: "qwen_image_vae.safetensors" + Mage-Flow: + latent_type: none + models: + - display_name: "Mage-Flow-Turbo" + components: + unet: "mage_flow_turbo_int8_convrot.safetensors" + clip: "qwen3vl_4b_fp8_scaled.safetensors" + vae: "mage_flow_vae_bf16.safetensors" + - display_name: "Mage-Flow" + components: + unet: "mage_flow_int8_convrot.safetensors" + clip: "qwen3vl_4b_fp8_scaled.safetensors" + vae: "mage_flow_vae_bf16.safetensors" + - display_name: "Mage-Flow-Edit-Turbo" + components: + unet: "mage_flow_edit_turbo_int8_convrot.safetensors" + clip: "qwen3vl_4b_fp8_scaled.safetensors" + vae: "mage_flow_vae_bf16.safetensors" + - display_name: "Mage-Flow-Edit" + components: + unet: "mage_flow_edit_int8_convrot.safetensors" + clip: "qwen3vl_4b_fp8_scaled.safetensors" + vae: "mage_flow_vae_bf16.safetensors" JoyAI-Image: latent_type: sd3_latent models: