RioShiina commited on
Commit
b4cd781
·
verified ·
1 Parent(s): 26d09bf

Add Krea-2 Reference Edit injector.

Browse files
README.md CHANGED
@@ -107,6 +107,7 @@ models:
107
  - OnomaAIResearch/Illustrious-XL-v1.0
108
  - OnomaAIResearch/Illustrious-XL-v1.1
109
  - OnomaAIResearch/Illustrious-XL-v2.0
 
110
  - Patil/Krea-2-depth-controlnet
111
  - RedRayz/hikari_noob_v-pred_1.2.4
112
  - Shakker-Labs/FLUX.1-dev-ControlNet-Union-Pro-2.0
 
107
  - OnomaAIResearch/Illustrious-XL-v1.0
108
  - OnomaAIResearch/Illustrious-XL-v1.1
109
  - OnomaAIResearch/Illustrious-XL-v2.0
110
+ - ostris/krea2_turbo_style_reference
111
  - Patil/Krea-2-depth-controlnet
112
  - RedRayz/hikari_noob_v-pred_1.2.4
113
  - Shakker-Labs/FLUX.1-dev-ControlNet-Union-Pro-2.0
chain_injectors/krea2_identity_edit_injector.py CHANGED
@@ -115,10 +115,24 @@ def inject(assembler, chain_definition, chain_items):
115
  pos_text = ""
116
  if pos_prompt_id and pos_prompt_id in assembler.workflow:
117
  pos_text = assembler.workflow[pos_prompt_id]['inputs'].get('text', '')
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
  neg_text = ""
120
  if neg_prompt_id and neg_prompt_id in assembler.workflow:
121
  neg_text = assembler.workflow[neg_prompt_id]['inputs'].get('text', '')
 
 
122
 
123
  pos_grounded_id = assembler._get_unique_id()
124
  pos_grounded_node = assembler._get_node_template("Krea2EditGroundedEncode")
 
115
  pos_text = ""
116
  if pos_prompt_id and pos_prompt_id in assembler.workflow:
117
  pos_text = assembler.workflow[pos_prompt_id]['inputs'].get('text', '')
118
+ elif hasattr(assembler, 'ui_values') and isinstance(assembler.ui_values, dict):
119
+ pos_text = assembler.ui_values.get('positive_prompt') or assembler.ui_values.get('prompt') or ''
120
+
121
+ if not pos_text:
122
+ for node_id, node in assembler.workflow.items():
123
+ if isinstance(node, dict):
124
+ cls = node.get('class_type', '')
125
+ if cls in ['Krea2EditGroundedEncode', 'TextEncodeQwenImageEditPlus', 'CLIPTextEncode']:
126
+ t = node.get('inputs', {}).get('prompt') or node.get('inputs', {}).get('text')
127
+ if t:
128
+ pos_text = t
129
+ break
130
 
131
  neg_text = ""
132
  if neg_prompt_id and neg_prompt_id in assembler.workflow:
133
  neg_text = assembler.workflow[neg_prompt_id]['inputs'].get('text', '')
134
+ elif hasattr(assembler, 'ui_values') and isinstance(assembler.ui_values, dict):
135
+ neg_text = assembler.ui_values.get('negative_prompt') or assembler.ui_values.get('neg_prompt') or ''
136
 
137
  pos_grounded_id = assembler._get_unique_id()
138
  pos_grounded_node = assembler._get_node_template("Krea2EditGroundedEncode")
chain_injectors/krea2_reference_edit_injector.py ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from utils.app_utils import ensure_file_downloaded
3
+
4
+ def create_node(assembler, class_type, title):
5
+ try:
6
+ node = assembler._get_node_template(class_type)
7
+ except Exception:
8
+ node = {
9
+ "inputs": {},
10
+ "class_type": class_type,
11
+ "_meta": {"title": title}
12
+ }
13
+ node['_meta']['title'] = title
14
+ return node
15
+
16
+ def inject(assembler, chain_definition, chain_items):
17
+ if not chain_items:
18
+ return
19
+
20
+ valid_images = []
21
+ for item in chain_items:
22
+ if not item:
23
+ continue
24
+ img_path = item
25
+ if isinstance(item, dict):
26
+ img_path = item.get('image') or item.get('filename') or item.get('path')
27
+ if img_path:
28
+ valid_images.append(img_path)
29
+
30
+ if not valid_images:
31
+ return
32
+
33
+ valid_images = valid_images[:3]
34
+
35
+ lora_filename = "krea2_style_reference.safetensors"
36
+ try:
37
+ ensure_file_downloaded(lora_filename)
38
+ except Exception as e:
39
+ print(f"Warning: Failed to ensure '{lora_filename}' downloaded: {e}")
40
+
41
+ ksampler_name = chain_definition.get('ksampler_node', 'ksampler')
42
+ pos_prompt_name = chain_definition.get('pos_prompt_node', 'pos_prompt')
43
+ neg_prompt_name = chain_definition.get('neg_prompt_node', 'neg_prompt')
44
+ clip_loader_name = chain_definition.get('clip_loader_node', 'clip_loader')
45
+ vae_loader_name = chain_definition.get('vae_loader_node', 'vae_loader')
46
+
47
+ if ksampler_name not in assembler.node_map:
48
+ print(f"Warning: Target node '{ksampler_name}' for Krea2 Style Reference Edit chain not found. Skipping.")
49
+ return
50
+
51
+ ksampler_id = assembler.node_map[ksampler_name]
52
+
53
+ if 'model' not in assembler.workflow[ksampler_id]['inputs']:
54
+ print(f"Warning: KSampler node '{ksampler_name}' is missing 'model' input. Skipping.")
55
+ return
56
+
57
+ current_model_connection = assembler.workflow[ksampler_id]['inputs']['model']
58
+
59
+ vae_connection = None
60
+ if vae_loader_name in assembler.node_map:
61
+ vae_connection = [assembler.node_map[vae_loader_name], 0]
62
+ else:
63
+ for node_id, node in assembler.workflow.items():
64
+ if isinstance(node, dict) and node.get('class_type') == 'VAELoader':
65
+ vae_connection = [node_id, 0]
66
+ break
67
+
68
+ clip_connection = None
69
+ if clip_loader_name in assembler.node_map:
70
+ clip_connection = [assembler.node_map[clip_loader_name], 0]
71
+ elif pos_prompt_name in assembler.node_map:
72
+ pos_id = assembler.node_map[pos_prompt_name]
73
+ clip_connection = assembler.workflow[pos_id]['inputs'].get('clip')
74
+
75
+ scaled_image_ids = []
76
+ for i, img_filename in enumerate(valid_images):
77
+ load_id = assembler._get_unique_id()
78
+ load_node = create_node(assembler, "LoadImage", f"Load Reference Image {i+1}")
79
+ load_node['inputs']['image'] = img_filename
80
+ assembler.workflow[load_id] = load_node
81
+
82
+ scale_id = assembler._get_unique_id()
83
+ scale_node = create_node(assembler, "ImageScaleToTotalPixels", f"Scale Reference {i+1}")
84
+ scale_node['inputs']['upscale_method'] = "nearest-exact"
85
+ scale_node['inputs']['megapixels'] = 1
86
+ scale_node['inputs']['resolution_steps'] = 1
87
+ scale_node['inputs']['image'] = [load_id, 0]
88
+ assembler.workflow[scale_id] = scale_node
89
+ scaled_image_ids.append(scale_id)
90
+
91
+ lora_loader_id = assembler._get_unique_id()
92
+ lora_loader_node = create_node(assembler, "LoraLoaderModelOnly", "Load LoRA (Krea2 Style Reference)")
93
+ lora_loader_node['inputs']['lora_name'] = lora_filename
94
+ lora_loader_node['inputs']['strength_model'] = 1.0
95
+ lora_loader_node['inputs']['model'] = current_model_connection
96
+ assembler.workflow[lora_loader_id] = lora_loader_node
97
+
98
+ assembler.workflow[ksampler_id]['inputs']['model'] = [lora_loader_id, 0]
99
+
100
+ pos_prompt_id = assembler.node_map.get(pos_prompt_name)
101
+ neg_prompt_id = assembler.node_map.get(neg_prompt_name)
102
+
103
+ pos_text = ""
104
+ if pos_prompt_id and pos_prompt_id in assembler.workflow:
105
+ pos_text = assembler.workflow[pos_prompt_id]['inputs'].get('text', '')
106
+ elif hasattr(assembler, 'ui_values') and isinstance(assembler.ui_values, dict):
107
+ pos_text = assembler.ui_values.get('positive_prompt') or assembler.ui_values.get('prompt') or ''
108
+
109
+ if not pos_text:
110
+ for node_id, node in assembler.workflow.items():
111
+ if isinstance(node, dict):
112
+ cls = node.get('class_type', '')
113
+ if cls in ['Krea2EditGroundedEncode', 'TextEncodeQwenImageEditPlus', 'CLIPTextEncode']:
114
+ t = node.get('inputs', {}).get('prompt') or node.get('inputs', {}).get('text')
115
+ if t:
116
+ pos_text = t
117
+ break
118
+
119
+ neg_text = ""
120
+ if neg_prompt_id and neg_prompt_id in assembler.workflow:
121
+ neg_text = assembler.workflow[neg_prompt_id]['inputs'].get('text', '')
122
+ elif hasattr(assembler, 'ui_values') and isinstance(assembler.ui_values, dict):
123
+ neg_text = assembler.ui_values.get('negative_prompt') or assembler.ui_values.get('neg_prompt') or ''
124
+
125
+ pos_encode_id = assembler._get_unique_id()
126
+ pos_encode_node = create_node(assembler, "TextEncodeQwenImageEditPlus", "TextEncodeQwenImageEditPlus (Positive)")
127
+ pos_encode_node['inputs']['prompt'] = pos_text
128
+ if clip_connection:
129
+ pos_encode_node['inputs']['clip'] = clip_connection
130
+ if vae_connection:
131
+ pos_encode_node['inputs']['vae'] = vae_connection
132
+ for idx, s_id in enumerate(scaled_image_ids):
133
+ pos_encode_node['inputs'][f"image{idx+1}"] = [s_id, 0]
134
+ assembler.workflow[pos_encode_id] = pos_encode_node
135
+
136
+ neg_encode_id = assembler._get_unique_id()
137
+ neg_encode_node = create_node(assembler, "TextEncodeQwenImageEditPlus", "TextEncodeQwenImageEditPlus (Negative)")
138
+ neg_encode_node['inputs']['prompt'] = neg_text
139
+ if clip_connection:
140
+ neg_encode_node['inputs']['clip'] = clip_connection
141
+ if vae_connection:
142
+ neg_encode_node['inputs']['vae'] = vae_connection
143
+ for idx, s_id in enumerate(scaled_image_ids):
144
+ neg_encode_node['inputs'][f"image{idx+1}"] = [s_id, 0]
145
+ assembler.workflow[neg_encode_id] = neg_encode_node
146
+
147
+ pos_ref_id = assembler._get_unique_id()
148
+ pos_ref_node = create_node(assembler, "FluxKontextMultiReferenceLatentMethod", "Edit Model Reference Method")
149
+ pos_ref_node['inputs']['reference_latents_method'] = "index_timestep_zero"
150
+ pos_ref_node['inputs']['conditioning'] = [pos_encode_id, 0]
151
+ assembler.workflow[pos_ref_id] = pos_ref_node
152
+
153
+ neg_ref_id = assembler._get_unique_id()
154
+ neg_ref_node = create_node(assembler, "FluxKontextMultiReferenceLatentMethod", "Edit Model Reference Method")
155
+ neg_ref_node['inputs']['reference_latents_method'] = "index_timestep_zero"
156
+ neg_ref_node['inputs']['conditioning'] = [neg_encode_id, 0]
157
+ assembler.workflow[neg_ref_id] = neg_ref_node
158
+
159
+ assembler.workflow[ksampler_id]['inputs']['positive'] = [pos_ref_id, 0]
160
+ assembler.workflow[ksampler_id]['inputs']['negative'] = [neg_ref_id, 0]
161
+
162
+ if pos_prompt_id and pos_prompt_id in assembler.workflow:
163
+ del assembler.workflow[pos_prompt_id]
164
+
165
+ if neg_prompt_id and neg_prompt_id in assembler.workflow:
166
+ del assembler.workflow[neg_prompt_id]
167
+
168
+ print(f"Krea2 Style Reference Edit injector applied with {len(valid_images)} reference image(s). Original CLIPTextEncode nodes replaced.")
chain_injectors/qwen_image_edit_injector.py CHANGED
@@ -70,10 +70,24 @@ def inject(assembler, chain_definition, chain_items):
70
  pos_text = ""
71
  if pos_prompt_id and pos_prompt_id in assembler.workflow:
72
  pos_text = assembler.workflow[pos_prompt_id]['inputs'].get('text', '')
 
 
 
 
 
 
 
 
 
 
 
 
73
 
74
  neg_text = ""
75
  if neg_prompt_id and neg_prompt_id in assembler.workflow:
76
  neg_text = assembler.workflow[neg_prompt_id]['inputs'].get('text', '')
 
 
77
 
78
  scaled_image_ids = []
79
  for i, img_filename in enumerate(valid_images):
 
70
  pos_text = ""
71
  if pos_prompt_id and pos_prompt_id in assembler.workflow:
72
  pos_text = assembler.workflow[pos_prompt_id]['inputs'].get('text', '')
73
+ elif hasattr(assembler, 'ui_values') and isinstance(assembler.ui_values, dict):
74
+ pos_text = assembler.ui_values.get('positive_prompt') or assembler.ui_values.get('prompt') or ''
75
+
76
+ if not pos_text:
77
+ for node_id, node in assembler.workflow.items():
78
+ if isinstance(node, dict):
79
+ cls = node.get('class_type', '')
80
+ if cls in ['Krea2EditGroundedEncode', 'TextEncodeQwenImageEditPlus', 'CLIPTextEncode']:
81
+ t = node.get('inputs', {}).get('prompt') or node.get('inputs', {}).get('text')
82
+ if t:
83
+ pos_text = t
84
+ break
85
 
86
  neg_text = ""
87
  if neg_prompt_id and neg_prompt_id in assembler.workflow:
88
  neg_text = assembler.workflow[neg_prompt_id]['inputs'].get('text', '')
89
+ elif hasattr(assembler, 'ui_values') and isinstance(assembler.ui_values, dict):
90
+ neg_text = assembler.ui_values.get('negative_prompt') or assembler.ui_values.get('neg_prompt') or ''
91
 
92
  scaled_image_ids = []
93
  for i, img_filename in enumerate(valid_images):
core/pipelines/pipeline_input_processor.py CHANGED
@@ -368,6 +368,17 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
368
  temp_files_to_clean.append(temp_path)
369
  active_krea2_identity_edit.append(os.path.basename(temp_path))
370
 
 
 
 
 
 
 
 
 
 
 
 
371
  qwen_image_edit_data = ui_inputs.get('qwen_image_edit_data', [])
372
  active_qwen_image_edit = []
373
  if qwen_image_edit_data:
@@ -433,6 +444,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
433
  "active_hidream_o1_reference": active_hidream_o1_reference,
434
  "active_joyai_reference": active_joyai_reference,
435
  "active_krea2_identity_edit": active_krea2_identity_edit,
 
436
  "active_qwen_image_edit": active_qwen_image_edit,
437
  "active_reference_images": active_reference_images,
438
  "active_conditioning": active_conditioning,
 
368
  temp_files_to_clean.append(temp_path)
369
  active_krea2_identity_edit.append(os.path.basename(temp_path))
370
 
371
+ krea2_reference_edit_data = ui_inputs.get('krea2_reference_edit_data', [])
372
+ active_krea2_reference_edit = []
373
+ if krea2_reference_edit_data:
374
+ for img in krea2_reference_edit_data:
375
+ if img:
376
+ if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR)
377
+ temp_path = os.path.join(INPUT_DIR, f"temp_krea2_reference_ref_{random.randint(1000, 9999)}.png")
378
+ img.save(temp_path, "PNG")
379
+ temp_files_to_clean.append(temp_path)
380
+ active_krea2_reference_edit.append(os.path.basename(temp_path))
381
+
382
  qwen_image_edit_data = ui_inputs.get('qwen_image_edit_data', [])
383
  active_qwen_image_edit = []
384
  if qwen_image_edit_data:
 
444
  "active_hidream_o1_reference": active_hidream_o1_reference,
445
  "active_joyai_reference": active_joyai_reference,
446
  "active_krea2_identity_edit": active_krea2_identity_edit,
447
+ "active_krea2_reference_edit": active_krea2_reference_edit,
448
  "active_qwen_image_edit": active_qwen_image_edit,
449
  "active_reference_images": active_reference_images,
450
  "active_conditioning": active_conditioning,
core/pipelines/sd_image_pipeline.py CHANGED
@@ -35,7 +35,8 @@ class SdImagePipeline(BasePipeline):
35
  decoded_images_tensor = WorkflowExecutor.execute_workflow(workflow, initial_objects=initial_objects)
36
 
37
  output_images = []
38
- start_seed = ui_inputs['seed'] if ui_inputs['seed'] != -1 else random.randint(0, 2**64 - 1)
 
39
  for i in range(decoded_images_tensor.shape[0]):
40
  img_tensor = decoded_images_tensor[i]
41
  pil_image = Image.fromarray((img_tensor.cpu().numpy() * 255.0).astype("uint8"))
@@ -118,6 +119,7 @@ class SdImagePipeline(BasePipeline):
118
  active_hidream_o1_reference = processed["active_hidream_o1_reference"]
119
  active_joyai_reference = processed.get("active_joyai_reference", [])
120
  active_krea2_identity_edit = processed.get("active_krea2_identity_edit", [])
 
121
  active_qwen_image_edit = processed.get("active_qwen_image_edit", [])
122
  active_reference_images = processed.get("active_reference_images", [])
123
  active_conditioning = processed["active_conditioning"]
@@ -126,7 +128,8 @@ class SdImagePipeline(BasePipeline):
126
 
127
  progress(0.8, desc="Assembling workflow...")
128
 
129
- if ui_inputs.get('seed') == -1:
 
130
  ui_inputs['seed'] = random.randint(0, 2**32 - 1)
131
 
132
  model_info = ALL_MODEL_MAP[model_display_name]
@@ -178,6 +181,7 @@ class SdImagePipeline(BasePipeline):
178
  "hidream_o1_reference_chain": active_hidream_o1_reference,
179
  "joyai_reference_chain": active_joyai_reference,
180
  "krea2_identity_edit_chain": active_krea2_identity_edit,
 
181
  "qwen_image_edit_chain": active_qwen_image_edit,
182
  "reference_image_chain": active_reference_images,
183
  "vae_chain": [ui_inputs.get('vae_name')] if ui_inputs.get('vae_name') else [],
 
35
  decoded_images_tensor = WorkflowExecutor.execute_workflow(workflow, initial_objects=initial_objects)
36
 
37
  output_images = []
38
+ raw_seed = ui_inputs.get('seed')
39
+ start_seed = int(raw_seed) if (raw_seed is not None and raw_seed != -1) else random.randint(0, 2**64 - 1)
40
  for i in range(decoded_images_tensor.shape[0]):
41
  img_tensor = decoded_images_tensor[i]
42
  pil_image = Image.fromarray((img_tensor.cpu().numpy() * 255.0).astype("uint8"))
 
119
  active_hidream_o1_reference = processed["active_hidream_o1_reference"]
120
  active_joyai_reference = processed.get("active_joyai_reference", [])
121
  active_krea2_identity_edit = processed.get("active_krea2_identity_edit", [])
122
+ active_krea2_reference_edit = processed.get("active_krea2_reference_edit", [])
123
  active_qwen_image_edit = processed.get("active_qwen_image_edit", [])
124
  active_reference_images = processed.get("active_reference_images", [])
125
  active_conditioning = processed["active_conditioning"]
 
128
 
129
  progress(0.8, desc="Assembling workflow...")
130
 
131
+ seed_val = ui_inputs.get('seed')
132
+ if seed_val is None or seed_val == -1:
133
  ui_inputs['seed'] = random.randint(0, 2**32 - 1)
134
 
135
  model_info = ALL_MODEL_MAP[model_display_name]
 
181
  "hidream_o1_reference_chain": active_hidream_o1_reference,
182
  "joyai_reference_chain": active_joyai_reference,
183
  "krea2_identity_edit_chain": active_krea2_identity_edit,
184
+ "krea2_reference_edit_chain": active_krea2_reference_edit,
185
  "qwen_image_edit_chain": active_qwen_image_edit,
186
  "reference_image_chain": active_reference_images,
187
  "vae_chain": [ui_inputs.get('vae_name')] if ui_inputs.get('vae_name') else [],
core/pipelines/workflow_recipes/_partials/conditioning/krea-2.yaml CHANGED
@@ -62,6 +62,14 @@ dynamic_krea2_identity_edit_chains:
62
  clip_loader_node: "clip_loader"
63
  vae_loader_node: "vae_loader"
64
 
 
 
 
 
 
 
 
 
65
  dynamic_conditioning_chains:
66
  conditioning_chain:
67
  ksampler_node: "ksampler"
 
62
  clip_loader_node: "clip_loader"
63
  vae_loader_node: "vae_loader"
64
 
65
+ dynamic_krea2_reference_edit_chains:
66
+ krea2_reference_edit_chain:
67
+ ksampler_node: "ksampler"
68
+ pos_prompt_node: "pos_prompt"
69
+ neg_prompt_node: "neg_prompt"
70
+ clip_loader_node: "clip_loader"
71
+ vae_loader_node: "vae_loader"
72
+
73
  dynamic_conditioning_chains:
74
  conditioning_chain:
75
  ksampler_node: "ksampler"
core/workflow_assembler.py CHANGED
@@ -127,6 +127,7 @@ class WorkflowAssembler:
127
  return merged_recipe
128
 
129
  def assemble(self, ui_values):
 
130
  for name, details in self.recipe['nodes'].items():
131
  class_type = details['class_type']
132
  template = self._get_node_template(class_type)
 
127
  return merged_recipe
128
 
129
  def assemble(self, ui_values):
130
+ self.ui_values = ui_values
131
  for name, details in self.recipe['nodes'].items():
132
  class_type = details['class_type']
133
  template = self._get_node_template(class_type)
requirements.txt CHANGED
@@ -1,5 +1,5 @@
1
- comfyui-frontend-package==1.47.10
2
- comfyui-workflow-templates==0.11.19
3
  comfyui-embedded-docs==0.5.9
4
  torch
5
  torchsde
@@ -22,7 +22,7 @@ alembic
22
  SQLAlchemy>=2.0.0
23
  filelock
24
  av>=16.0.0
25
- comfy-kitchen==0.2.24
26
  comfy-aimdo==0.4.10
27
  requests
28
  simpleeval>=1.0.0
 
1
+ comfyui-frontend-package==1.47.11
2
+ comfyui-workflow-templates==0.11.20
3
  comfyui-embedded-docs==0.5.9
4
  torch
5
  torchsde
 
22
  SQLAlchemy>=2.0.0
23
  filelock
24
  av>=16.0.0
25
+ comfy-kitchen==0.2.25
26
  comfy-aimdo==0.4.10
27
  requests
28
  simpleeval>=1.0.0
ui/events/chain_handlers.py CHANGED
@@ -900,6 +900,39 @@ def create_qwen_image_edit_event_handlers(prefix, ui_components):
900
  del_button = ui_components[f'delete_qwen_image_edit_button_{prefix}']
901
  images = ui_components[f'qwen_image_edit_images_{prefix}']
902
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
903
  def add_ref_row(c):
904
  c += 1
905
  return {
 
900
  del_button = ui_components[f'delete_qwen_image_edit_button_{prefix}']
901
  images = ui_components[f'qwen_image_edit_images_{prefix}']
902
 
903
+ def add_ref_row(c):
904
+ c += 1
905
+ return {
906
+ count_state: c,
907
+ ref_rows[c - 1]: gr.update(visible=True),
908
+ add_button: gr.update(visible=c < 3),
909
+ del_button: gr.update(visible=True),
910
+ }
911
+
912
+ def del_ref_row(c):
913
+ c -= 1
914
+ return {
915
+ count_state: c,
916
+ ref_rows[c]: gr.update(visible=False),
917
+ images[c]: None,
918
+ add_button: gr.update(visible=True),
919
+ del_button: gr.update(visible=c > 0),
920
+ }
921
+
922
+ add_outputs = [count_state, add_button, del_button] + ref_rows
923
+ del_outputs = [count_state, add_button, del_button] + ref_rows + images
924
+ add_button.click(fn=add_ref_row, inputs=[count_state], outputs=add_outputs, show_progress=False)
925
+ del_button.click(fn=del_ref_row, inputs=[count_state], outputs=del_outputs, show_progress=False)
926
+
927
+
928
+ def create_krea2_reference_edit_event_handlers(prefix, ui_components):
929
+ ref_rows = ui_components.get(f'krea2_reference_edit_rows_{prefix}')
930
+ if not ref_rows: return
931
+ count_state = ui_components[f'krea2_reference_edit_count_state_{prefix}']
932
+ add_button = ui_components[f'add_krea2_reference_edit_button_{prefix}']
933
+ del_button = ui_components[f'delete_krea2_reference_edit_button_{prefix}']
934
+ images = ui_components[f'krea2_reference_edit_images_{prefix}']
935
+
936
  def add_ref_row(c):
937
  c += 1
938
  return {
ui/events/change_handlers.py CHANGED
@@ -17,7 +17,7 @@ from .config_loaders import (
17
  load_ipadapter_config
18
  )
19
 
20
- 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, krea2_identity_edit_acc=None, qwen_image_edit_acc=None, ref_img_acc=None):
21
  def update_fn(*args):
22
  arch = args[0]
23
  category = args[1]
@@ -70,6 +70,7 @@ def make_update_fn(m_comp, cat_comp, cs_comp, ar_comp, width_comp, height_comp,
70
  if hidream_o1_ref_acc: updates[hidream_o1_ref_acc] = gr.update(visible=('hidream_o1_reference' in enabled_chains))
71
  if joyai_ref_acc: updates[joyai_ref_acc] = gr.update(visible=('joyai_reference' in enabled_chains))
72
  if krea2_identity_edit_acc: updates[krea2_identity_edit_acc] = gr.update(visible=('krea2_identity_edit' in enabled_chains))
 
73
  if qwen_image_edit_acc: updates[qwen_image_edit_acc] = gr.update(visible=('qwen_image_edit' in enabled_chains))
74
  if ref_img_acc: updates[ref_img_acc] = gr.update(visible=('reference_image' in enabled_chains))
75
  if pid_acc: updates[pid_acc] = gr.update(visible=('pid' in enabled_chains))
@@ -146,7 +147,7 @@ def make_update_fn(m_comp, cat_comp, cs_comp, ar_comp, width_comp, height_comp,
146
  return update_fn
147
 
148
 
149
- 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, krea2_identity_edit_acc=None, qwen_image_edit_acc=None, ref_img_acc=None):
150
  def change_fn(*args):
151
  model_name = args[0]
152
  idx = 1
@@ -204,6 +205,7 @@ def make_model_change_fn(cat_comp_ref, cs_comp, ar_comp, width_comp, height_comp
204
  if hidream_o1_ref_acc: updates[hidream_o1_ref_acc] = gr.update(visible=('hidream_o1_reference' in enabled_chains))
205
  if joyai_ref_acc: updates[joyai_ref_acc] = gr.update(visible=('joyai_reference' in enabled_chains))
206
  if krea2_identity_edit_acc: updates[krea2_identity_edit_acc] = gr.update(visible=('krea2_identity_edit' in enabled_chains))
 
207
  if qwen_image_edit_acc: updates[qwen_image_edit_acc] = gr.update(visible=('qwen_image_edit' in enabled_chains))
208
  if ref_img_acc: updates[ref_img_acc] = gr.update(visible=('reference_image' in enabled_chains))
209
  if pid_acc: updates[pid_acc] = gr.update(visible=('pid' in enabled_chains))
 
17
  load_ipadapter_config
18
  )
19
 
20
+ 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, krea2_identity_edit_acc=None, krea2_reference_edit_acc=None, qwen_image_edit_acc=None, ref_img_acc=None):
21
  def update_fn(*args):
22
  arch = args[0]
23
  category = args[1]
 
70
  if hidream_o1_ref_acc: updates[hidream_o1_ref_acc] = gr.update(visible=('hidream_o1_reference' in enabled_chains))
71
  if joyai_ref_acc: updates[joyai_ref_acc] = gr.update(visible=('joyai_reference' in enabled_chains))
72
  if krea2_identity_edit_acc: updates[krea2_identity_edit_acc] = gr.update(visible=('krea2_identity_edit' in enabled_chains))
73
+ if krea2_reference_edit_acc: updates[krea2_reference_edit_acc] = gr.update(visible=('krea2_reference_edit' in enabled_chains))
74
  if qwen_image_edit_acc: updates[qwen_image_edit_acc] = gr.update(visible=('qwen_image_edit' in enabled_chains))
75
  if ref_img_acc: updates[ref_img_acc] = gr.update(visible=('reference_image' in enabled_chains))
76
  if pid_acc: updates[pid_acc] = gr.update(visible=('pid' in enabled_chains))
 
147
  return update_fn
148
 
149
 
150
+ 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, krea2_identity_edit_acc=None, krea2_reference_edit_acc=None, qwen_image_edit_acc=None, ref_img_acc=None):
151
  def change_fn(*args):
152
  model_name = args[0]
153
  idx = 1
 
205
  if hidream_o1_ref_acc: updates[hidream_o1_ref_acc] = gr.update(visible=('hidream_o1_reference' in enabled_chains))
206
  if joyai_ref_acc: updates[joyai_ref_acc] = gr.update(visible=('joyai_reference' in enabled_chains))
207
  if krea2_identity_edit_acc: updates[krea2_identity_edit_acc] = gr.update(visible=('krea2_identity_edit' in enabled_chains))
208
+ if krea2_reference_edit_acc: updates[krea2_reference_edit_acc] = gr.update(visible=('krea2_reference_edit' in enabled_chains))
209
  if qwen_image_edit_acc: updates[qwen_image_edit_acc] = gr.update(visible=('qwen_image_edit' in enabled_chains))
210
  if ref_img_acc: updates[ref_img_acc] = gr.update(visible=('reference_image' in enabled_chains))
211
  if pid_acc: updates[pid_acc] = gr.update(visible=('pid' in enabled_chains))
ui/events/main.py CHANGED
@@ -15,6 +15,7 @@ from .chain_handlers import (
15
  create_hidream_o1_reference_event_handlers,
16
  create_joyai_reference_event_handlers,
17
  create_krea2_identity_edit_event_handlers,
 
18
  create_qwen_image_edit_event_handlers,
19
  create_reference_image_event_handlers
20
  )
@@ -72,6 +73,7 @@ def attach_event_handlers(ui_components, demo):
72
  hidream_o1_ref_accordion = ui_components.get(f'hidream_o1_reference_accordion_{prefix}')
73
  joyai_ref_accordion = ui_components.get(f'joyai_reference_accordion_{prefix}')
74
  krea2_identity_edit_accordion = ui_components.get(f'krea2_identity_edit_accordion_{prefix}')
 
75
  qwen_image_edit_accordion = ui_components.get(f'qwen_image_edit_accordion_{prefix}')
76
  ref_img_accordion = ui_components.get(f'reference_image_accordion_{prefix}')
77
  pid_accordion = ui_components.get(f'pid_accordion_{prefix}')
@@ -113,6 +115,7 @@ def attach_event_handlers(ui_components, demo):
113
  if hidream_o1_ref_accordion: outputs.append(hidream_o1_ref_accordion)
114
  if joyai_ref_accordion: outputs.append(joyai_ref_accordion)
115
  if krea2_identity_edit_accordion: outputs.append(krea2_identity_edit_accordion)
 
116
  if qwen_image_edit_accordion: outputs.append(qwen_image_edit_accordion)
117
  if ref_img_accordion: outputs.append(ref_img_accordion)
118
  if pid_accordion: outputs.append(pid_accordion)
@@ -129,7 +132,7 @@ def attach_event_handlers(ui_components, demo):
129
  krea2_cn_types_list, krea2_cn_series_list, krea2_cn_filepaths_list,
130
  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,
131
  ref_latent_accordion, hidream_o1_ref_accordion, guidance_comp, prompt_comp, neg_prompt_comp, steps_comp, cfg_comp, sampler_comp, scheduler_comp,
132
- pid_acc=pid_accordion, vae_acc=vae_accordion, joyai_ref_acc=joyai_ref_accordion, krea2_identity_edit_acc=krea2_identity_edit_accordion, qwen_image_edit_acc=qwen_image_edit_accordion, ref_img_acc=ref_img_accordion
133
  )
134
  inputs = [arch_comp, cat_comp]
135
  if aspect_ratio_comp:
@@ -163,6 +166,7 @@ def attach_event_handlers(ui_components, demo):
163
  if hidream_o1_ref_accordion: outputs2.append(hidream_o1_ref_accordion)
164
  if joyai_ref_accordion: outputs2.append(joyai_ref_accordion)
165
  if krea2_identity_edit_accordion: outputs2.append(krea2_identity_edit_accordion)
 
166
  if qwen_image_edit_accordion: outputs2.append(qwen_image_edit_accordion)
167
  if ref_img_accordion: outputs2.append(ref_img_accordion)
168
  if pid_accordion: outputs2.append(pid_accordion)
@@ -184,7 +188,7 @@ def attach_event_handlers(ui_components, demo):
184
  krea2_cn_types_list, krea2_cn_series_list, krea2_cn_filepaths_list,
185
  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,
186
  ref_latent_accordion, hidream_o1_ref_accordion, guidance_comp, prompt_comp, neg_prompt_comp, steps_comp, cfg_comp, sampler_comp, scheduler_comp,
187
- pid_acc=pid_accordion, vae_acc=vae_accordion, joyai_ref_acc=joyai_ref_accordion, krea2_identity_edit_acc=krea2_identity_edit_accordion, qwen_image_edit_acc=qwen_image_edit_accordion, ref_img_acc=ref_img_accordion
188
  )
189
  model_comp.change(fn=change_fn, inputs=inputs2, outputs=outputs2)
190
 
@@ -203,6 +207,7 @@ def attach_event_handlers(ui_components, demo):
203
  create_hidream_o1_reference_event_handlers(prefix, ui_components)
204
  create_joyai_reference_event_handlers(prefix, ui_components)
205
  create_krea2_identity_edit_event_handlers(prefix, ui_components)
 
206
  create_qwen_image_edit_event_handlers(prefix, ui_components)
207
  create_reference_image_event_handlers(prefix, ui_components)
208
  create_run_event(prefix, task_type, ui_components)
 
15
  create_hidream_o1_reference_event_handlers,
16
  create_joyai_reference_event_handlers,
17
  create_krea2_identity_edit_event_handlers,
18
+ create_krea2_reference_edit_event_handlers,
19
  create_qwen_image_edit_event_handlers,
20
  create_reference_image_event_handlers
21
  )
 
73
  hidream_o1_ref_accordion = ui_components.get(f'hidream_o1_reference_accordion_{prefix}')
74
  joyai_ref_accordion = ui_components.get(f'joyai_reference_accordion_{prefix}')
75
  krea2_identity_edit_accordion = ui_components.get(f'krea2_identity_edit_accordion_{prefix}')
76
+ krea2_reference_edit_accordion = ui_components.get(f'krea2_reference_edit_accordion_{prefix}')
77
  qwen_image_edit_accordion = ui_components.get(f'qwen_image_edit_accordion_{prefix}')
78
  ref_img_accordion = ui_components.get(f'reference_image_accordion_{prefix}')
79
  pid_accordion = ui_components.get(f'pid_accordion_{prefix}')
 
115
  if hidream_o1_ref_accordion: outputs.append(hidream_o1_ref_accordion)
116
  if joyai_ref_accordion: outputs.append(joyai_ref_accordion)
117
  if krea2_identity_edit_accordion: outputs.append(krea2_identity_edit_accordion)
118
+ if krea2_reference_edit_accordion: outputs.append(krea2_reference_edit_accordion)
119
  if qwen_image_edit_accordion: outputs.append(qwen_image_edit_accordion)
120
  if ref_img_accordion: outputs.append(ref_img_accordion)
121
  if pid_accordion: outputs.append(pid_accordion)
 
132
  krea2_cn_types_list, krea2_cn_series_list, krea2_cn_filepaths_list,
133
  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,
134
  ref_latent_accordion, hidream_o1_ref_accordion, guidance_comp, prompt_comp, neg_prompt_comp, steps_comp, cfg_comp, sampler_comp, scheduler_comp,
135
+ pid_acc=pid_accordion, vae_acc=vae_accordion, joyai_ref_acc=joyai_ref_accordion, krea2_identity_edit_acc=krea2_identity_edit_accordion, krea2_reference_edit_acc=krea2_reference_edit_accordion, qwen_image_edit_acc=qwen_image_edit_accordion, ref_img_acc=ref_img_accordion
136
  )
137
  inputs = [arch_comp, cat_comp]
138
  if aspect_ratio_comp:
 
166
  if hidream_o1_ref_accordion: outputs2.append(hidream_o1_ref_accordion)
167
  if joyai_ref_accordion: outputs2.append(joyai_ref_accordion)
168
  if krea2_identity_edit_accordion: outputs2.append(krea2_identity_edit_accordion)
169
+ if krea2_reference_edit_accordion: outputs2.append(krea2_reference_edit_accordion)
170
  if qwen_image_edit_accordion: outputs2.append(qwen_image_edit_accordion)
171
  if ref_img_accordion: outputs2.append(ref_img_accordion)
172
  if pid_accordion: outputs2.append(pid_accordion)
 
188
  krea2_cn_types_list, krea2_cn_series_list, krea2_cn_filepaths_list,
189
  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,
190
  ref_latent_accordion, hidream_o1_ref_accordion, guidance_comp, prompt_comp, neg_prompt_comp, steps_comp, cfg_comp, sampler_comp, scheduler_comp,
191
+ pid_acc=pid_accordion, vae_acc=vae_accordion, joyai_ref_acc=joyai_ref_accordion, krea2_identity_edit_acc=krea2_identity_edit_accordion, krea2_reference_edit_acc=krea2_reference_edit_accordion, qwen_image_edit_acc=qwen_image_edit_accordion, ref_img_acc=ref_img_accordion
192
  )
193
  model_comp.change(fn=change_fn, inputs=inputs2, outputs=outputs2)
194
 
 
207
  create_hidream_o1_reference_event_handlers(prefix, ui_components)
208
  create_joyai_reference_event_handlers(prefix, ui_components)
209
  create_krea2_identity_edit_event_handlers(prefix, ui_components)
210
+ create_krea2_reference_edit_event_handlers(prefix, ui_components)
211
  create_qwen_image_edit_event_handlers(prefix, ui_components)
212
  create_reference_image_event_handlers(prefix, ui_components)
213
  create_run_event(prefix, task_type, ui_components)
ui/events/run_handlers.py CHANGED
@@ -54,6 +54,7 @@ def create_run_event(prefix: str, task_type: str, ui_components: dict):
54
  hidream_o1_reference_data_components = ui_components.get(f'all_hidream_o1_reference_components_flat_{prefix}', [])
55
  joyai_reference_data_components = ui_components.get(f'all_joyai_reference_components_flat_{prefix}', [])
56
  krea2_identity_edit_data_components = ui_components.get(f'all_krea2_identity_edit_components_flat_{prefix}', [])
 
57
  qwen_image_edit_data_components = ui_components.get(f'all_qwen_image_edit_components_flat_{prefix}', [])
58
  reference_image_data_components = ui_components.get(f'all_reference_image_components_flat_{prefix}', [])
59
 
@@ -66,7 +67,7 @@ def create_run_event(prefix: str, task_type: str, ui_components: dict):
66
  all_chains = [
67
  lora_data_components, controlnet_data_components, anima_controlnet_lllite_data_components, diffsynth_controlnet_data_components, krea2_controlnet_data_components, ipadapter_data_components,
68
  sd3_ipadapter_data_components, flux1_ipadapter_data_components, style_data_components,
69
- embedding_data_components, conditioning_data_components, reference_latent_data_components, hidream_o1_reference_data_components, joyai_reference_data_components, krea2_identity_edit_data_components, qwen_image_edit_data_components, reference_image_data_components
70
  ]
71
  for chain in all_chains:
72
  if chain:
@@ -98,6 +99,7 @@ def create_run_event(prefix: str, task_type: str, ui_components: dict):
98
  assign_chain_data('hidream_o1_reference_data', hidream_o1_reference_data_components)
99
  assign_chain_data('joyai_reference_data', joyai_reference_data_components)
100
  assign_chain_data('krea2_identity_edit_data', krea2_identity_edit_data_components)
 
101
  assign_chain_data('qwen_image_edit_data', qwen_image_edit_data_components)
102
  assign_chain_data('reference_image_data', reference_image_data_components)
103
 
 
54
  hidream_o1_reference_data_components = ui_components.get(f'all_hidream_o1_reference_components_flat_{prefix}', [])
55
  joyai_reference_data_components = ui_components.get(f'all_joyai_reference_components_flat_{prefix}', [])
56
  krea2_identity_edit_data_components = ui_components.get(f'all_krea2_identity_edit_components_flat_{prefix}', [])
57
+ krea2_reference_edit_data_components = ui_components.get(f'all_krea2_reference_edit_components_flat_{prefix}', [])
58
  qwen_image_edit_data_components = ui_components.get(f'all_qwen_image_edit_components_flat_{prefix}', [])
59
  reference_image_data_components = ui_components.get(f'all_reference_image_components_flat_{prefix}', [])
60
 
 
67
  all_chains = [
68
  lora_data_components, controlnet_data_components, anima_controlnet_lllite_data_components, diffsynth_controlnet_data_components, krea2_controlnet_data_components, ipadapter_data_components,
69
  sd3_ipadapter_data_components, flux1_ipadapter_data_components, style_data_components,
70
+ embedding_data_components, conditioning_data_components, reference_latent_data_components, hidream_o1_reference_data_components, joyai_reference_data_components, krea2_identity_edit_data_components, krea2_reference_edit_data_components, qwen_image_edit_data_components, reference_image_data_components
71
  ]
72
  for chain in all_chains:
73
  if chain:
 
99
  assign_chain_data('hidream_o1_reference_data', hidream_o1_reference_data_components)
100
  assign_chain_data('joyai_reference_data', joyai_reference_data_components)
101
  assign_chain_data('krea2_identity_edit_data', krea2_identity_edit_data_components)
102
+ assign_chain_data('krea2_reference_edit_data', krea2_reference_edit_data_components)
103
  assign_chain_data('qwen_image_edit_data', qwen_image_edit_data_components)
104
  assign_chain_data('reference_image_data', reference_image_data_components)
105
 
ui/shared/hires_fix_ui.py CHANGED
@@ -7,7 +7,7 @@ from .ui_components import (
7
  create_conditioning_ui, create_vae_override_ui,
8
  create_model_architecture_filter_ui, create_category_filter_ui,
9
  create_sd3_ipadapter_ui, create_flux1_ipadapter_ui, create_style_ui,
10
- create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui, create_reference_image_ui, create_krea2_identity_edit_ui, create_qwen_image_edit_ui
11
  )
12
 
13
  default_vals = MODEL_DEFAULTS_CONFIG.get('Default', {})
@@ -103,6 +103,7 @@ def create_ui():
103
  components.update(create_hidream_o1_reference_ui(prefix))
104
  components.update(create_joyai_reference_ui(prefix))
105
  components.update(create_krea2_identity_edit_ui(prefix))
 
106
  components.update(create_qwen_image_edit_ui(prefix))
107
  components.update(create_reference_image_ui(prefix))
108
  components.update(create_vae_override_ui(prefix))
 
7
  create_conditioning_ui, create_vae_override_ui,
8
  create_model_architecture_filter_ui, create_category_filter_ui,
9
  create_sd3_ipadapter_ui, create_flux1_ipadapter_ui, create_style_ui,
10
+ create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui, create_reference_image_ui, create_krea2_identity_edit_ui, create_krea2_reference_edit_ui, create_qwen_image_edit_ui
11
  )
12
 
13
  default_vals = MODEL_DEFAULTS_CONFIG.get('Default', {})
 
103
  components.update(create_hidream_o1_reference_ui(prefix))
104
  components.update(create_joyai_reference_ui(prefix))
105
  components.update(create_krea2_identity_edit_ui(prefix))
106
+ components.update(create_krea2_reference_edit_ui(prefix))
107
  components.update(create_qwen_image_edit_ui(prefix))
108
  components.update(create_reference_image_ui(prefix))
109
  components.update(create_vae_override_ui(prefix))
ui/shared/img2img_ui.py CHANGED
@@ -7,7 +7,7 @@ from .ui_components import (
7
  create_conditioning_ui, create_vae_override_ui,
8
  create_model_architecture_filter_ui, create_category_filter_ui,
9
  create_sd3_ipadapter_ui, create_flux1_ipadapter_ui, create_style_ui,
10
- create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui, create_reference_image_ui, create_krea2_identity_edit_ui, create_qwen_image_edit_ui
11
  )
12
 
13
  default_vals = MODEL_DEFAULTS_CONFIG.get('Default', {})
@@ -84,6 +84,7 @@ def create_ui():
84
  components.update(create_hidream_o1_reference_ui(prefix))
85
  components.update(create_joyai_reference_ui(prefix))
86
  components.update(create_krea2_identity_edit_ui(prefix))
 
87
  components.update(create_qwen_image_edit_ui(prefix))
88
  components.update(create_reference_image_ui(prefix))
89
  components.update(create_vae_override_ui(prefix))
 
7
  create_conditioning_ui, create_vae_override_ui,
8
  create_model_architecture_filter_ui, create_category_filter_ui,
9
  create_sd3_ipadapter_ui, create_flux1_ipadapter_ui, create_style_ui,
10
+ create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui, create_reference_image_ui, create_krea2_identity_edit_ui, create_krea2_reference_edit_ui, create_qwen_image_edit_ui
11
  )
12
 
13
  default_vals = MODEL_DEFAULTS_CONFIG.get('Default', {})
 
84
  components.update(create_hidream_o1_reference_ui(prefix))
85
  components.update(create_joyai_reference_ui(prefix))
86
  components.update(create_krea2_identity_edit_ui(prefix))
87
+ components.update(create_krea2_reference_edit_ui(prefix))
88
  components.update(create_qwen_image_edit_ui(prefix))
89
  components.update(create_reference_image_ui(prefix))
90
  components.update(create_vae_override_ui(prefix))
ui/shared/inpaint_ui.py CHANGED
@@ -6,7 +6,7 @@ from .ui_components import (
6
  create_conditioning_ui, create_vae_override_ui,
7
  create_model_architecture_filter_ui, create_category_filter_ui,
8
  create_sd3_ipadapter_ui, create_flux1_ipadapter_ui, create_style_ui,
9
- create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui, create_reference_image_ui, create_krea2_identity_edit_ui, create_qwen_image_edit_ui
10
  )
11
 
12
  default_vals = MODEL_DEFAULTS_CONFIG.get('Default', {})
@@ -116,6 +116,7 @@ def create_ui():
116
  components.update(create_hidream_o1_reference_ui(prefix))
117
  components.update(create_joyai_reference_ui(prefix))
118
  components.update(create_krea2_identity_edit_ui(prefix))
 
119
  components.update(create_qwen_image_edit_ui(prefix))
120
  components.update(create_reference_image_ui(prefix))
121
  components.update(create_vae_override_ui(prefix))
 
6
  create_conditioning_ui, create_vae_override_ui,
7
  create_model_architecture_filter_ui, create_category_filter_ui,
8
  create_sd3_ipadapter_ui, create_flux1_ipadapter_ui, create_style_ui,
9
+ create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui, create_reference_image_ui, create_krea2_identity_edit_ui, create_krea2_reference_edit_ui, create_qwen_image_edit_ui
10
  )
11
 
12
  default_vals = MODEL_DEFAULTS_CONFIG.get('Default', {})
 
116
  components.update(create_hidream_o1_reference_ui(prefix))
117
  components.update(create_joyai_reference_ui(prefix))
118
  components.update(create_krea2_identity_edit_ui(prefix))
119
+ components.update(create_krea2_reference_edit_ui(prefix))
120
  components.update(create_qwen_image_edit_ui(prefix))
121
  components.update(create_reference_image_ui(prefix))
122
  components.update(create_vae_override_ui(prefix))
ui/shared/outpaint_ui.py CHANGED
@@ -7,7 +7,7 @@ from .ui_components import (
7
  create_conditioning_ui, create_vae_override_ui,
8
  create_model_architecture_filter_ui, create_category_filter_ui,
9
  create_sd3_ipadapter_ui, create_flux1_ipadapter_ui, create_style_ui,
10
- create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui, create_reference_image_ui, create_krea2_identity_edit_ui, create_qwen_image_edit_ui
11
  )
12
 
13
  default_vals = MODEL_DEFAULTS_CONFIG.get('Default', {})
@@ -99,6 +99,7 @@ def create_ui():
99
  components.update(create_hidream_o1_reference_ui(prefix))
100
  components.update(create_joyai_reference_ui(prefix))
101
  components.update(create_krea2_identity_edit_ui(prefix))
 
102
  components.update(create_qwen_image_edit_ui(prefix))
103
  components.update(create_reference_image_ui(prefix))
104
  components.update(create_vae_override_ui(prefix))
 
7
  create_conditioning_ui, create_vae_override_ui,
8
  create_model_architecture_filter_ui, create_category_filter_ui,
9
  create_sd3_ipadapter_ui, create_flux1_ipadapter_ui, create_style_ui,
10
+ create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui, create_reference_image_ui, create_krea2_identity_edit_ui, create_krea2_reference_edit_ui, create_qwen_image_edit_ui
11
  )
12
 
13
  default_vals = MODEL_DEFAULTS_CONFIG.get('Default', {})
 
99
  components.update(create_hidream_o1_reference_ui(prefix))
100
  components.update(create_joyai_reference_ui(prefix))
101
  components.update(create_krea2_identity_edit_ui(prefix))
102
+ components.update(create_krea2_reference_edit_ui(prefix))
103
  components.update(create_qwen_image_edit_ui(prefix))
104
  components.update(create_reference_image_ui(prefix))
105
  components.update(create_vae_override_ui(prefix))
ui/shared/txt2img_ui.py CHANGED
@@ -6,7 +6,7 @@ from .ui_components import (
6
  create_conditioning_ui, create_vae_override_ui,
7
  create_model_architecture_filter_ui, create_category_filter_ui,
8
  create_sd3_ipadapter_ui, create_flux1_ipadapter_ui, create_style_ui,
9
- create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui, create_reference_image_ui, create_krea2_identity_edit_ui, create_qwen_image_edit_ui,
10
  create_pid_ui
11
  )
12
 
@@ -56,6 +56,7 @@ def create_ui():
56
  components.update(create_hidream_o1_reference_ui(prefix))
57
  components.update(create_joyai_reference_ui(prefix))
58
  components.update(create_krea2_identity_edit_ui(prefix))
 
59
  components.update(create_qwen_image_edit_ui(prefix))
60
  components.update(create_reference_image_ui(prefix))
61
  components.update(create_vae_override_ui(prefix))
 
6
  create_conditioning_ui, create_vae_override_ui,
7
  create_model_architecture_filter_ui, create_category_filter_ui,
8
  create_sd3_ipadapter_ui, create_flux1_ipadapter_ui, create_style_ui,
9
+ create_reference_latent_ui, create_hidream_o1_reference_ui, create_joyai_reference_ui, create_reference_image_ui, create_krea2_identity_edit_ui, create_krea2_reference_edit_ui, create_qwen_image_edit_ui,
10
  create_pid_ui
11
  )
12
 
 
56
  components.update(create_hidream_o1_reference_ui(prefix))
57
  components.update(create_joyai_reference_ui(prefix))
58
  components.update(create_krea2_identity_edit_ui(prefix))
59
+ components.update(create_krea2_reference_edit_ui(prefix))
60
  components.update(create_qwen_image_edit_ui(prefix))
61
  components.update(create_reference_image_ui(prefix))
62
  components.update(create_vae_override_ui(prefix))
ui/shared/ui_components.py CHANGED
@@ -775,7 +775,7 @@ def create_krea2_identity_edit_ui(prefix: str, max_units=2):
775
  components = {}
776
  key = lambda name: f"{name}_{prefix}"
777
 
778
- with gr.Accordion("Krea-2 Identity Edit Setting", open=False, visible=('krea2_identity_edit' in default_enabled_chains)) as ref_accordion:
779
  components[key('krea2_identity_edit_accordion')] = ref_accordion
780
  gr.Markdown("💡 **Tip:** Processed using the [lbouaraba/comfyui-krea2edit](https://github.com/lbouaraba/comfyui-krea2edit) node. (Krea-2-Turbo recommended, Krea-2-Raw need set ZeroGPU Duration (s) to 120 ) In txt2img mode, adding a single reference image performs an **Image Edit**, while adding multiple images performs an **Image Combine**.")
781
 
@@ -827,4 +827,33 @@ def create_qwen_image_edit_ui(prefix: str, max_units=3):
827
 
828
  components[key('all_qwen_image_edit_components_flat')] = ref_image_inputs
829
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
830
  return components
 
775
  components = {}
776
  key = lambda name: f"{name}_{prefix}"
777
 
778
+ with gr.Accordion("Krea2 Identity Edit Settings", open=False, visible=('krea2_identity_edit' in default_enabled_chains)) as ref_accordion:
779
  components[key('krea2_identity_edit_accordion')] = ref_accordion
780
  gr.Markdown("💡 **Tip:** Processed using the [lbouaraba/comfyui-krea2edit](https://github.com/lbouaraba/comfyui-krea2edit) node. (Krea-2-Turbo recommended, Krea-2-Raw need set ZeroGPU Duration (s) to 120 ) In txt2img mode, adding a single reference image performs an **Image Edit**, while adding multiple images performs an **Image Combine**.")
781
 
 
827
 
828
  components[key('all_qwen_image_edit_components_flat')] = ref_image_inputs
829
 
830
+ return components
831
+
832
+ def create_krea2_reference_edit_ui(prefix: str, max_units=3):
833
+ components = {}
834
+ key = lambda name: f"{name}_{prefix}"
835
+
836
+ with gr.Accordion("Krea2 Style Reference Edit Settings", open=False, visible=('krea2_reference_edit' in default_enabled_chains)) as ref_accordion:
837
+ components[key('krea2_reference_edit_accordion')] = ref_accordion
838
+ gr.Markdown("💡 **Tip:** (Krea-2-Turbo recommended) Add style reference images to perform style reference editing.")
839
+
840
+ ref_image_groups = []
841
+ ref_image_inputs = []
842
+ with gr.Row():
843
+ for i in range(max_units):
844
+ with gr.Column(visible=(i < 1), min_width=160) as img_col:
845
+ img_comp = gr.Image(type="pil", label=f"Ref. {i+1}", sources=["upload"], height=150)
846
+ ref_image_groups.append(img_col)
847
+ ref_image_inputs.append(img_comp)
848
+
849
+ components[key('krea2_reference_edit_rows')] = ref_image_groups
850
+ components[key('krea2_reference_edit_images')] = ref_image_inputs
851
+
852
+ with gr.Row():
853
+ components[key('add_krea2_reference_edit_button')] = gr.Button("✚ Add Reference Image")
854
+ components[key('delete_krea2_reference_edit_button')] = gr.Button("➖ Delete Reference Image", visible=False)
855
+ components[key('krea2_reference_edit_count_state')] = gr.State(1)
856
+
857
+ components[key('all_krea2_reference_edit_components_flat')] = ref_image_inputs
858
+
859
  return components
yaml/file_list.yaml CHANGED
@@ -414,6 +414,10 @@ file:
414
  source: "hf"
415
  repo_id: "Comfy-Org/Mage-Flow"
416
  repository_file_path: "diffusion_models/mage_flow_int8_convrot.safetensors"
 
 
 
 
417
  - filename: "mage_flow_edit_turbo_int8_convrot.safetensors"
418
  source: "hf"
419
  repo_id: "Comfy-Org/Mage-Flow"
@@ -422,6 +426,10 @@ file:
422
  source: "hf"
423
  repo_id: "Comfy-Org/Mage-Flow"
424
  repository_file_path: "diffusion_models/mage_flow_edit_int8_convrot.safetensors"
 
 
 
 
425
  # JoyAI-Image
426
  - filename: "joyai_image_edit_int8_convrot.safetensors"
427
  source: "hf"
@@ -771,6 +779,11 @@ file:
771
  source: "hf"
772
  repo_id: "conradlocke/krea2-identity-edit"
773
  repository_file_path: "krea2_identity_edit_v1_2.safetensors"
 
 
 
 
 
774
  # Krea2 ControlNet
775
  - filename: "depth-control-lora.safetensors"
776
  source: "hf"
 
414
  source: "hf"
415
  repo_id: "Comfy-Org/Mage-Flow"
416
  repository_file_path: "diffusion_models/mage_flow_int8_convrot.safetensors"
417
+ - filename: "mage_flow_base_bf16.safetensors"
418
+ source: "hf"
419
+ repo_id: "Comfy-Org/Mage-Flow"
420
+ repository_file_path: "diffusion_models/mage_flow_base_bf16.safetensors"
421
  - filename: "mage_flow_edit_turbo_int8_convrot.safetensors"
422
  source: "hf"
423
  repo_id: "Comfy-Org/Mage-Flow"
 
426
  source: "hf"
427
  repo_id: "Comfy-Org/Mage-Flow"
428
  repository_file_path: "diffusion_models/mage_flow_edit_int8_convrot.safetensors"
429
+ - filename: "mage_flow_edit_base_bf16.safetensors"
430
+ source: "hf"
431
+ repo_id: "Comfy-Org/Mage-Flow"
432
+ repository_file_path: "diffusion_models/mage_flow_edit_base_bf16.safetensors"
433
  # JoyAI-Image
434
  - filename: "joyai_image_edit_int8_convrot.safetensors"
435
  source: "hf"
 
779
  source: "hf"
780
  repo_id: "conradlocke/krea2-identity-edit"
781
  repository_file_path: "krea2_identity_edit_v1_2.safetensors"
782
+ # Krea2 Style Reference Edit
783
+ - filename: "krea2_style_reference.safetensors"
784
+ source: "hf"
785
+ repo_id: "ostris/krea2_turbo_style_reference"
786
+ repository_file_path: "krea2_style_reference.safetensors"
787
  # Krea2 ControlNet
788
  - filename: "depth-control-lora.safetensors"
789
  source: "hf"
yaml/image_gen_features.yaml CHANGED
@@ -21,6 +21,7 @@ krea-2:
21
  - lora
22
  - krea2_controlnet
23
  - krea2_identity_edit
 
24
  - pid
25
 
26
  boogu-image:
 
21
  - lora
22
  - krea2_controlnet
23
  - krea2_identity_edit
24
+ - krea2_reference_edit
25
  - pid
26
 
27
  boogu-image:
yaml/injectors.yaml CHANGED
@@ -33,6 +33,8 @@ injector_definitions:
33
  module: "chain_injectors.joyai_reference_injector"
34
  dynamic_krea2_identity_edit_chains:
35
  module: "chain_injectors.krea2_identity_edit_injector"
 
 
36
  dynamic_qwen_image_edit_chains:
37
  module: "chain_injectors.qwen_image_edit_injector"
38
  dynamic_reference_image_chains:
@@ -54,6 +56,7 @@ injector_order:
54
  - dynamic_controlnet_chains
55
  - dynamic_krea2_controlnet_chains
56
  - dynamic_krea2_identity_edit_chains
 
57
  - dynamic_qwen_image_edit_chains
58
  - dynamic_anima_controlnet_lllite_chains
59
  - dynamic_hidream_o1_smoothing_chains
 
33
  module: "chain_injectors.joyai_reference_injector"
34
  dynamic_krea2_identity_edit_chains:
35
  module: "chain_injectors.krea2_identity_edit_injector"
36
+ dynamic_krea2_reference_edit_chains:
37
+ module: "chain_injectors.krea2_reference_edit_injector"
38
  dynamic_qwen_image_edit_chains:
39
  module: "chain_injectors.qwen_image_edit_injector"
40
  dynamic_reference_image_chains:
 
56
  - dynamic_controlnet_chains
57
  - dynamic_krea2_controlnet_chains
58
  - dynamic_krea2_identity_edit_chains
59
+ - dynamic_krea2_reference_edit_chains
60
  - dynamic_qwen_image_edit_chains
61
  - dynamic_anima_controlnet_lllite_chains
62
  - dynamic_hidream_o1_smoothing_chains
yaml/model_list.yaml CHANGED
@@ -25,6 +25,11 @@ Checkpoint:
25
  unet: "mage_flow_int8_convrot.safetensors"
26
  clip: "qwen3vl_4b_fp8_scaled.safetensors"
27
  vae: "mage_flow_vae_bf16.safetensors"
 
 
 
 
 
28
  - display_name: "Mage-Flow-Edit-Turbo"
29
  components:
30
  unet: "mage_flow_edit_turbo_int8_convrot.safetensors"
@@ -35,6 +40,11 @@ Checkpoint:
35
  unet: "mage_flow_edit_int8_convrot.safetensors"
36
  clip: "qwen3vl_4b_fp8_scaled.safetensors"
37
  vae: "mage_flow_vae_bf16.safetensors"
 
 
 
 
 
38
  JoyAI-Image:
39
  latent_type: sd3_latent
40
  models:
 
25
  unet: "mage_flow_int8_convrot.safetensors"
26
  clip: "qwen3vl_4b_fp8_scaled.safetensors"
27
  vae: "mage_flow_vae_bf16.safetensors"
28
+ - display_name: "Mage-Flow-Base"
29
+ components:
30
+ unet: "mage_flow_base_bf16.safetensors"
31
+ clip: "qwen3vl_4b_fp8_scaled.safetensors"
32
+ vae: "mage_flow_vae_bf16.safetensors"
33
  - display_name: "Mage-Flow-Edit-Turbo"
34
  components:
35
  unet: "mage_flow_edit_turbo_int8_convrot.safetensors"
 
40
  unet: "mage_flow_edit_int8_convrot.safetensors"
41
  clip: "qwen3vl_4b_fp8_scaled.safetensors"
42
  vae: "mage_flow_vae_bf16.safetensors"
43
+ - display_name: "Mage-Flow-Edit-Base"
44
+ components:
45
+ unet: "mage_flow_edit_base_bf16.safetensors"
46
+ clip: "qwen3vl_4b_fp8_scaled.safetensors"
47
+ vae: "mage_flow_vae_bf16.safetensors"
48
  JoyAI-Image:
49
  latent_type: sd3_latent
50
  models: