Spaces:
Running on Zero
Running on Zero
Upgrade to Gradio 6
Browse files- .gitignore +15 -0
- README.md +0 -1
- app.py +5 -6
- core/pipelines/pipeline_input_processor.py +28 -21
- core/pipelines/sd_image_pipeline.py +8 -5
- core/pipelines/workflow_recipes/_partials/conditioning/flux1.yaml +3 -2
- core/settings.py +12 -2
- mcp_tools/common.py +2 -1
- mcp_tools/get_feature_list.py +27 -5
- mcp_tools/mcp_gradio_integration.py +2 -0
- requirements.txt +1 -1
- ui/events/change_handlers.py +36 -12
- ui/events/main.py +176 -13
- ui/events/run_handlers.py +53 -18
- ui/{shared/inpaint_ui.py → imagegen_ui.py} +197 -125
- ui/layout.py +4 -20
- ui/shared/hires_fix_ui.py +0 -111
- ui/shared/img2img_ui.py +0 -92
- ui/shared/outpaint_ui.py +0 -107
- ui/shared/txt2img_ui.py +0 -66
- ui/shared/ui_components.py +1 -2
- yaml/chain_features.yaml +0 -128
- yaml/{image_gen_features.yaml → model_architecture_features.yaml} +199 -199
- yaml/task_features.yaml +125 -0
.gitignore
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
__pycache__/
|
| 2 |
+
*.py[cod]
|
| 3 |
+
*$py.class
|
| 4 |
+
|
| 5 |
+
# Environments & IDE
|
| 6 |
+
.env
|
| 7 |
+
.venv/
|
| 8 |
+
env/
|
| 9 |
+
venv/
|
| 10 |
+
.idea/
|
| 11 |
+
.vscode/
|
| 12 |
+
|
| 13 |
+
# Temporary files
|
| 14 |
+
*.tmp
|
| 15 |
+
*.temp
|
README.md
CHANGED
|
@@ -4,7 +4,6 @@ emoji: 🖼
|
|
| 4 |
colorFrom: purple
|
| 5 |
colorTo: red
|
| 6 |
sdk: gradio
|
| 7 |
-
sdk_version: "5.50.0"
|
| 8 |
app_file: app.py
|
| 9 |
python_version: 3.12
|
| 10 |
short_description: Multi-task image generator with dynamic, chainable workflows
|
|
|
|
| 4 |
colorFrom: purple
|
| 5 |
colorTo: red
|
| 6 |
sdk: gradio
|
|
|
|
| 7 |
app_file: app.py
|
| 8 |
python_version: 3.12
|
| 9 |
short_description: Multi-task image generator with dynamic, chainable workflows
|
app.py
CHANGED
|
@@ -49,7 +49,7 @@ def dummy_gpu_for_startup():
|
|
| 49 |
return "Startup check passed."
|
| 50 |
|
| 51 |
|
| 52 |
-
def
|
| 53 |
from comfy_integration import setup as setup_comfyui
|
| 54 |
from utils.app_utils import load_ipadapter_presets
|
| 55 |
|
|
@@ -80,7 +80,6 @@ def main():
|
|
| 80 |
load_ipadapter_presets()
|
| 81 |
print("--- ✅ IPAdapter setup complete. ---")
|
| 82 |
|
| 83 |
-
|
| 84 |
print("--- Environment configured. Proceeding with module imports. ---")
|
| 85 |
from ui.layout import build_ui
|
| 86 |
from ui.events import attach_event_handlers
|
|
@@ -90,10 +89,10 @@ def main():
|
|
| 90 |
print(f"✅ Working directory is stable: {os.getcwd()}")
|
| 91 |
|
| 92 |
demo = build_ui(attach_event_handlers)
|
|
|
|
| 93 |
|
| 94 |
-
|
| 95 |
-
demo.queue().launch(mcp_server=True)
|
| 96 |
-
|
| 97 |
|
| 98 |
if __name__ == "__main__":
|
| 99 |
-
|
|
|
|
|
|
| 49 |
return "Startup check passed."
|
| 50 |
|
| 51 |
|
| 52 |
+
def create_app():
|
| 53 |
from comfy_integration import setup as setup_comfyui
|
| 54 |
from utils.app_utils import load_ipadapter_presets
|
| 55 |
|
|
|
|
| 80 |
load_ipadapter_presets()
|
| 81 |
print("--- ✅ IPAdapter setup complete. ---")
|
| 82 |
|
|
|
|
| 83 |
print("--- Environment configured. Proceeding with module imports. ---")
|
| 84 |
from ui.layout import build_ui
|
| 85 |
from ui.events import attach_event_handlers
|
|
|
|
| 89 |
print(f"✅ Working directory is stable: {os.getcwd()}")
|
| 90 |
|
| 91 |
demo = build_ui(attach_event_handlers)
|
| 92 |
+
return demo
|
| 93 |
|
| 94 |
+
demo = create_app()
|
|
|
|
|
|
|
| 95 |
|
| 96 |
if __name__ == "__main__":
|
| 97 |
+
print("--- Launching Gradio Interface ---")
|
| 98 |
+
demo.queue().launch(mcp_server=True, footer_links=["api", "gradio", "settings"])
|
core/pipelines/pipeline_input_processor.py
CHANGED
|
@@ -5,7 +5,10 @@ import gradio as gr
|
|
| 5 |
from PIL import Image, ImageChops
|
| 6 |
from typing import Dict, Any, List
|
| 7 |
|
| 8 |
-
from core.settings import
|
|
|
|
|
|
|
|
|
|
| 9 |
from utils.app_utils import (
|
| 10 |
sanitize_filename,
|
| 11 |
get_lora_path,
|
|
@@ -21,6 +24,10 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 21 |
task_type = ui_inputs['task_type']
|
| 22 |
temp_files_to_clean = []
|
| 23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
multiplier = MULTIPLIERS_MAP.get(workflow_model_type, 8)
|
| 25 |
img_w, img_h = 0, 0
|
| 26 |
if task_type == 'txt2img':
|
|
@@ -53,7 +60,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 53 |
|
| 54 |
lora_data = ui_inputs.get('lora_data', [])
|
| 55 |
active_loras_for_gpu, active_loras_for_meta = [], []
|
| 56 |
-
if lora_data:
|
| 57 |
sources, ids, scales, files = lora_data[0::4], lora_data[1::4], lora_data[2::4], lora_data[3::4]
|
| 58 |
for i, (source, lora_id, scale, _) in enumerate(zip(sources, ids, scales, files)):
|
| 59 |
if scale > 0 and lora_id and lora_id.strip():
|
|
@@ -145,7 +152,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 145 |
|
| 146 |
embedding_data = ui_inputs.get('embedding_data', [])
|
| 147 |
embedding_filenames = []
|
| 148 |
-
if embedding_data:
|
| 149 |
emb_sources, emb_ids, emb_files = embedding_data[0::3], embedding_data[1::3], embedding_data[2::3]
|
| 150 |
for i, (source, emb_id, _) in enumerate(zip(emb_sources, emb_ids, emb_files)):
|
| 151 |
if emb_id and emb_id.strip():
|
|
@@ -165,7 +172,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 165 |
|
| 166 |
controlnet_data = ui_inputs.get('controlnet_data', [])
|
| 167 |
active_controlnets = []
|
| 168 |
-
if controlnet_data:
|
| 169 |
(cn_images, _, _, cn_strengths, cn_filepaths) = [controlnet_data[i::5] for i in range(5)]
|
| 170 |
for i in range(len(cn_images)):
|
| 171 |
if cn_images[i] and cn_strengths[i] > 0 and cn_filepaths[i] and cn_filepaths[i] != "None":
|
|
@@ -181,7 +188,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 181 |
|
| 182 |
anima_controlnet_lllite_data = ui_inputs.get('anima_controlnet_lllite_data', [])
|
| 183 |
active_anima_controlnets = []
|
| 184 |
-
if anima_controlnet_lllite_data:
|
| 185 |
(cn_images, _, _, cn_strengths, cn_filepaths, cn_starts, cn_ends) = [anima_controlnet_lllite_data[i::7] for i in range(7)]
|
| 186 |
for i in range(len(cn_images)):
|
| 187 |
if cn_images[i] and cn_strengths[i] > 0 and cn_filepaths[i] and cn_filepaths[i] != "None":
|
|
@@ -197,7 +204,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 197 |
|
| 198 |
diffsynth_controlnet_data = ui_inputs.get('diffsynth_controlnet_data', [])
|
| 199 |
active_diffsynth_controlnets = []
|
| 200 |
-
if diffsynth_controlnet_data:
|
| 201 |
(cn_images, _, _, cn_strengths, cn_filepaths) = [diffsynth_controlnet_data[i::5] for i in range(5)]
|
| 202 |
for i in range(len(cn_images)):
|
| 203 |
if cn_images[i] and cn_strengths[i] > 0 and cn_filepaths[i] and cn_filepaths[i] != "None":
|
|
@@ -213,7 +220,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 213 |
|
| 214 |
krea2_controlnet_data = ui_inputs.get('krea2_controlnet_data', [])
|
| 215 |
active_krea2_controlnets = []
|
| 216 |
-
if krea2_controlnet_data:
|
| 217 |
(cn_images, _, _, cn_strengths, cn_filepaths) = [krea2_controlnet_data[i::5] for i in range(5)]
|
| 218 |
for i in range(len(cn_images)):
|
| 219 |
if cn_images[i] and cn_strengths[i] > 0 and cn_filepaths[i] and cn_filepaths[i] != "None":
|
|
@@ -229,7 +236,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 229 |
|
| 230 |
ipadapter_data = ui_inputs.get('ipadapter_data', [])
|
| 231 |
active_ipadapters = []
|
| 232 |
-
if ipadapter_data:
|
| 233 |
num_ipa_units = (len(ipadapter_data) - 5) // 3
|
| 234 |
final_preset, final_weight, final_lora_strength, final_embeds_scaling, final_combine_method = ipadapter_data[-5:]
|
| 235 |
ipa_images, ipa_weights, ipa_lora_strengths = [ipadapter_data[i*num_ipa_units:(i+1)*num_ipa_units] for i in range(3)]
|
|
@@ -260,7 +267,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 260 |
|
| 261 |
flux1_ipadapter_data = ui_inputs.get('flux1_ipadapter_data', [])
|
| 262 |
active_flux1_ipadapters = []
|
| 263 |
-
if flux1_ipadapter_data:
|
| 264 |
num_units = len(flux1_ipadapter_data) // 4
|
| 265 |
f_images = flux1_ipadapter_data[0*num_units : 1*num_units]
|
| 266 |
f_weights = flux1_ipadapter_data[1*num_units : 2*num_units]
|
|
@@ -289,7 +296,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 289 |
|
| 290 |
sd3_ipadapter_data = ui_inputs.get('sd3_ipadapter_chain', [])
|
| 291 |
active_sd3_ipadapters = []
|
| 292 |
-
if sd3_ipadapter_data:
|
| 293 |
num_units = len(sd3_ipadapter_data) // 4
|
| 294 |
s_images = sd3_ipadapter_data[0*num_units : 1*num_units]
|
| 295 |
s_weights = sd3_ipadapter_data[1*num_units : 2*num_units]
|
|
@@ -311,7 +318,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 311 |
|
| 312 |
style_data = ui_inputs.get('style_data', [])
|
| 313 |
active_styles = []
|
| 314 |
-
if style_data:
|
| 315 |
num_units = len(style_data) // 2
|
| 316 |
st_images = style_data[0*num_units : 1*num_units]
|
| 317 |
st_strengths = style_data[1*num_units : 2*num_units]
|
|
@@ -331,7 +338,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 331 |
|
| 332 |
reference_latent_data = ui_inputs.get('reference_latent_data', [])
|
| 333 |
active_reference_latents = []
|
| 334 |
-
if reference_latent_data:
|
| 335 |
for img in reference_latent_data:
|
| 336 |
if img:
|
| 337 |
if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR)
|
|
@@ -342,7 +349,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 342 |
|
| 343 |
hidream_o1_reference_data = ui_inputs.get('hidream_o1_reference_data', [])
|
| 344 |
active_hidream_o1_reference = []
|
| 345 |
-
if hidream_o1_reference_data:
|
| 346 |
for img in hidream_o1_reference_data:
|
| 347 |
if img:
|
| 348 |
if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR)
|
|
@@ -353,7 +360,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 353 |
|
| 354 |
joyai_reference_data = ui_inputs.get('joyai_reference_data', [])
|
| 355 |
active_joyai_reference = []
|
| 356 |
-
if joyai_reference_data:
|
| 357 |
for img in joyai_reference_data:
|
| 358 |
if img:
|
| 359 |
if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR)
|
|
@@ -364,7 +371,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 364 |
|
| 365 |
krea2_identity_edit_data = ui_inputs.get('krea2_identity_edit_data', [])
|
| 366 |
active_krea2_identity_edit = []
|
| 367 |
-
if krea2_identity_edit_data:
|
| 368 |
for img in krea2_identity_edit_data:
|
| 369 |
if img:
|
| 370 |
if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR)
|
|
@@ -375,7 +382,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 375 |
|
| 376 |
krea2_reference_edit_data = ui_inputs.get('krea2_reference_edit_data', [])
|
| 377 |
active_krea2_reference_edit = []
|
| 378 |
-
if krea2_reference_edit_data:
|
| 379 |
for img in krea2_reference_edit_data:
|
| 380 |
if img:
|
| 381 |
if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR)
|
|
@@ -386,7 +393,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 386 |
|
| 387 |
qwen_image_edit_data = ui_inputs.get('qwen_image_edit_data', [])
|
| 388 |
active_qwen_image_edit = []
|
| 389 |
-
if qwen_image_edit_data:
|
| 390 |
for img in qwen_image_edit_data:
|
| 391 |
if img:
|
| 392 |
if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR)
|
|
@@ -397,7 +404,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 397 |
|
| 398 |
boogu_edit_data = ui_inputs.get('boogu_edit_data', [])
|
| 399 |
active_boogu_edit = []
|
| 400 |
-
if boogu_edit_data:
|
| 401 |
for img in boogu_edit_data:
|
| 402 |
if img:
|
| 403 |
if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR)
|
|
@@ -408,7 +415,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 408 |
|
| 409 |
reference_image_data = ui_inputs.get('reference_image_data', [])
|
| 410 |
active_reference_images = []
|
| 411 |
-
if reference_image_data:
|
| 412 |
for img in reference_image_data:
|
| 413 |
if img:
|
| 414 |
if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR)
|
|
@@ -420,7 +427,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 420 |
vae_source = ui_inputs.get('vae_source')
|
| 421 |
vae_id = ui_inputs.get('vae_id')
|
| 422 |
vae_name_override = None
|
| 423 |
-
if vae_source and vae_source != "None":
|
| 424 |
if vae_source == "File":
|
| 425 |
vae_name_override = sanitize_filename(vae_id)
|
| 426 |
local_path = os.path.join(VAE_DIR, vae_name_override)
|
|
@@ -435,7 +442,7 @@ def process_pipeline_inputs(ui_inputs: Dict[str, Any], progress: gr.Progress, wo
|
|
| 435 |
|
| 436 |
conditioning_data = ui_inputs.get('conditioning_data', [])
|
| 437 |
active_conditioning = []
|
| 438 |
-
if conditioning_data:
|
| 439 |
num_units = len(conditioning_data) // 6
|
| 440 |
prompts, widths, heights, xs, ys, strengths = [conditioning_data[i*num_units : (i+1)*num_units] for i in range(6)]
|
| 441 |
for i in range(num_units):
|
|
|
|
| 5 |
from PIL import Image, ImageChops
|
| 6 |
from typing import Dict, Any, List
|
| 7 |
|
| 8 |
+
from core.settings import (
|
| 9 |
+
INPUT_DIR, MULTIPLIERS_MAP, LORA_DIR, EMBEDDING_DIR, VAE_DIR,
|
| 10 |
+
FEATURES_CONFIG, TASK_FEATURES_CONFIG
|
| 11 |
+
)
|
| 12 |
from utils.app_utils import (
|
| 13 |
sanitize_filename,
|
| 14 |
get_lora_path,
|
|
|
|
| 24 |
task_type = ui_inputs['task_type']
|
| 25 |
temp_files_to_clean = []
|
| 26 |
|
| 27 |
+
arch_enabled_chains = FEATURES_CONFIG.get(workflow_model_type, {}).get('enabled_chains', [])
|
| 28 |
+
task_enabled_chains = TASK_FEATURES_CONFIG.get(task_type, {}).get('enabled_chains', [])
|
| 29 |
+
enabled_chains = set([c for c in arch_enabled_chains if c in task_enabled_chains])
|
| 30 |
+
|
| 31 |
multiplier = MULTIPLIERS_MAP.get(workflow_model_type, 8)
|
| 32 |
img_w, img_h = 0, 0
|
| 33 |
if task_type == 'txt2img':
|
|
|
|
| 60 |
|
| 61 |
lora_data = ui_inputs.get('lora_data', [])
|
| 62 |
active_loras_for_gpu, active_loras_for_meta = [], []
|
| 63 |
+
if 'lora' in enabled_chains and lora_data:
|
| 64 |
sources, ids, scales, files = lora_data[0::4], lora_data[1::4], lora_data[2::4], lora_data[3::4]
|
| 65 |
for i, (source, lora_id, scale, _) in enumerate(zip(sources, ids, scales, files)):
|
| 66 |
if scale > 0 and lora_id and lora_id.strip():
|
|
|
|
| 152 |
|
| 153 |
embedding_data = ui_inputs.get('embedding_data', [])
|
| 154 |
embedding_filenames = []
|
| 155 |
+
if 'embedding' in enabled_chains and embedding_data:
|
| 156 |
emb_sources, emb_ids, emb_files = embedding_data[0::3], embedding_data[1::3], embedding_data[2::3]
|
| 157 |
for i, (source, emb_id, _) in enumerate(zip(emb_sources, emb_ids, emb_files)):
|
| 158 |
if emb_id and emb_id.strip():
|
|
|
|
| 172 |
|
| 173 |
controlnet_data = ui_inputs.get('controlnet_data', [])
|
| 174 |
active_controlnets = []
|
| 175 |
+
if 'controlnet' in enabled_chains and controlnet_data:
|
| 176 |
(cn_images, _, _, cn_strengths, cn_filepaths) = [controlnet_data[i::5] for i in range(5)]
|
| 177 |
for i in range(len(cn_images)):
|
| 178 |
if cn_images[i] and cn_strengths[i] > 0 and cn_filepaths[i] and cn_filepaths[i] != "None":
|
|
|
|
| 188 |
|
| 189 |
anima_controlnet_lllite_data = ui_inputs.get('anima_controlnet_lllite_data', [])
|
| 190 |
active_anima_controlnets = []
|
| 191 |
+
if 'anima_controlnet_lllite' in enabled_chains and anima_controlnet_lllite_data:
|
| 192 |
(cn_images, _, _, cn_strengths, cn_filepaths, cn_starts, cn_ends) = [anima_controlnet_lllite_data[i::7] for i in range(7)]
|
| 193 |
for i in range(len(cn_images)):
|
| 194 |
if cn_images[i] and cn_strengths[i] > 0 and cn_filepaths[i] and cn_filepaths[i] != "None":
|
|
|
|
| 204 |
|
| 205 |
diffsynth_controlnet_data = ui_inputs.get('diffsynth_controlnet_data', [])
|
| 206 |
active_diffsynth_controlnets = []
|
| 207 |
+
if 'diffsynth_controlnet' in enabled_chains and diffsynth_controlnet_data:
|
| 208 |
(cn_images, _, _, cn_strengths, cn_filepaths) = [diffsynth_controlnet_data[i::5] for i in range(5)]
|
| 209 |
for i in range(len(cn_images)):
|
| 210 |
if cn_images[i] and cn_strengths[i] > 0 and cn_filepaths[i] and cn_filepaths[i] != "None":
|
|
|
|
| 220 |
|
| 221 |
krea2_controlnet_data = ui_inputs.get('krea2_controlnet_data', [])
|
| 222 |
active_krea2_controlnets = []
|
| 223 |
+
if 'krea2_controlnet' in enabled_chains and krea2_controlnet_data:
|
| 224 |
(cn_images, _, _, cn_strengths, cn_filepaths) = [krea2_controlnet_data[i::5] for i in range(5)]
|
| 225 |
for i in range(len(cn_images)):
|
| 226 |
if cn_images[i] and cn_strengths[i] > 0 and cn_filepaths[i] and cn_filepaths[i] != "None":
|
|
|
|
| 236 |
|
| 237 |
ipadapter_data = ui_inputs.get('ipadapter_data', [])
|
| 238 |
active_ipadapters = []
|
| 239 |
+
if 'ipadapter' in enabled_chains and ipadapter_data:
|
| 240 |
num_ipa_units = (len(ipadapter_data) - 5) // 3
|
| 241 |
final_preset, final_weight, final_lora_strength, final_embeds_scaling, final_combine_method = ipadapter_data[-5:]
|
| 242 |
ipa_images, ipa_weights, ipa_lora_strengths = [ipadapter_data[i*num_ipa_units:(i+1)*num_ipa_units] for i in range(3)]
|
|
|
|
| 267 |
|
| 268 |
flux1_ipadapter_data = ui_inputs.get('flux1_ipadapter_data', [])
|
| 269 |
active_flux1_ipadapters = []
|
| 270 |
+
if 'flux1_ipadapter' in enabled_chains and flux1_ipadapter_data:
|
| 271 |
num_units = len(flux1_ipadapter_data) // 4
|
| 272 |
f_images = flux1_ipadapter_data[0*num_units : 1*num_units]
|
| 273 |
f_weights = flux1_ipadapter_data[1*num_units : 2*num_units]
|
|
|
|
| 296 |
|
| 297 |
sd3_ipadapter_data = ui_inputs.get('sd3_ipadapter_chain', [])
|
| 298 |
active_sd3_ipadapters = []
|
| 299 |
+
if 'sd3_ipadapter' in enabled_chains and sd3_ipadapter_data:
|
| 300 |
num_units = len(sd3_ipadapter_data) // 4
|
| 301 |
s_images = sd3_ipadapter_data[0*num_units : 1*num_units]
|
| 302 |
s_weights = sd3_ipadapter_data[1*num_units : 2*num_units]
|
|
|
|
| 318 |
|
| 319 |
style_data = ui_inputs.get('style_data', [])
|
| 320 |
active_styles = []
|
| 321 |
+
if 'style' in enabled_chains and style_data:
|
| 322 |
num_units = len(style_data) // 2
|
| 323 |
st_images = style_data[0*num_units : 1*num_units]
|
| 324 |
st_strengths = style_data[1*num_units : 2*num_units]
|
|
|
|
| 338 |
|
| 339 |
reference_latent_data = ui_inputs.get('reference_latent_data', [])
|
| 340 |
active_reference_latents = []
|
| 341 |
+
if 'reference_latent' in enabled_chains and reference_latent_data:
|
| 342 |
for img in reference_latent_data:
|
| 343 |
if img:
|
| 344 |
if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR)
|
|
|
|
| 349 |
|
| 350 |
hidream_o1_reference_data = ui_inputs.get('hidream_o1_reference_data', [])
|
| 351 |
active_hidream_o1_reference = []
|
| 352 |
+
if 'hidream_o1_reference' in enabled_chains and hidream_o1_reference_data:
|
| 353 |
for img in hidream_o1_reference_data:
|
| 354 |
if img:
|
| 355 |
if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR)
|
|
|
|
| 360 |
|
| 361 |
joyai_reference_data = ui_inputs.get('joyai_reference_data', [])
|
| 362 |
active_joyai_reference = []
|
| 363 |
+
if 'joyai_image' in enabled_chains and joyai_reference_data:
|
| 364 |
for img in joyai_reference_data:
|
| 365 |
if img:
|
| 366 |
if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR)
|
|
|
|
| 371 |
|
| 372 |
krea2_identity_edit_data = ui_inputs.get('krea2_identity_edit_data', [])
|
| 373 |
active_krea2_identity_edit = []
|
| 374 |
+
if 'krea2_identity_edit' in enabled_chains and krea2_identity_edit_data:
|
| 375 |
for img in krea2_identity_edit_data:
|
| 376 |
if img:
|
| 377 |
if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR)
|
|
|
|
| 382 |
|
| 383 |
krea2_reference_edit_data = ui_inputs.get('krea2_reference_edit_data', [])
|
| 384 |
active_krea2_reference_edit = []
|
| 385 |
+
if 'krea2_style_reference' in enabled_chains and krea2_reference_edit_data:
|
| 386 |
for img in krea2_reference_edit_data:
|
| 387 |
if img:
|
| 388 |
if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR)
|
|
|
|
| 393 |
|
| 394 |
qwen_image_edit_data = ui_inputs.get('qwen_image_edit_data', [])
|
| 395 |
active_qwen_image_edit = []
|
| 396 |
+
if 'qwen_image_edit' in enabled_chains and qwen_image_edit_data:
|
| 397 |
for img in qwen_image_edit_data:
|
| 398 |
if img:
|
| 399 |
if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR)
|
|
|
|
| 404 |
|
| 405 |
boogu_edit_data = ui_inputs.get('boogu_edit_data', [])
|
| 406 |
active_boogu_edit = []
|
| 407 |
+
if 'boogu_image_edit' in enabled_chains and boogu_edit_data:
|
| 408 |
for img in boogu_edit_data:
|
| 409 |
if img:
|
| 410 |
if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR)
|
|
|
|
| 415 |
|
| 416 |
reference_image_data = ui_inputs.get('reference_image_data', [])
|
| 417 |
active_reference_images = []
|
| 418 |
+
if 'reference_image' in enabled_chains and reference_image_data:
|
| 419 |
for img in reference_image_data:
|
| 420 |
if img:
|
| 421 |
if not os.path.exists(INPUT_DIR): os.makedirs(INPUT_DIR)
|
|
|
|
| 427 |
vae_source = ui_inputs.get('vae_source')
|
| 428 |
vae_id = ui_inputs.get('vae_id')
|
| 429 |
vae_name_override = None
|
| 430 |
+
if 'vae' in enabled_chains and vae_source and vae_source != "None":
|
| 431 |
if vae_source == "File":
|
| 432 |
vae_name_override = sanitize_filename(vae_id)
|
| 433 |
local_path = os.path.join(VAE_DIR, vae_name_override)
|
|
|
|
| 442 |
|
| 443 |
conditioning_data = ui_inputs.get('conditioning_data', [])
|
| 444 |
active_conditioning = []
|
| 445 |
+
if 'conditioning' in enabled_chains and conditioning_data:
|
| 446 |
num_units = len(conditioning_data) // 6
|
| 447 |
prompts, widths, heights, xs, ys, strengths = [conditioning_data[i*num_units : (i+1)*num_units] for i in range(6)]
|
| 448 |
for i in range(num_units):
|
core/pipelines/sd_image_pipeline.py
CHANGED
|
@@ -70,7 +70,11 @@ class SdImagePipeline(BasePipeline):
|
|
| 70 |
|
| 71 |
required_models = self.get_required_models(model_display_name=model_display_name)
|
| 72 |
|
| 73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
if is_pid_enabled:
|
| 75 |
import yaml
|
| 76 |
pid_config_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), 'yaml', 'pid.yaml')
|
|
@@ -149,7 +153,7 @@ class SdImagePipeline(BasePipeline):
|
|
| 149 |
assembler = WorkflowAssembler(recipe_path, dynamic_values=dynamic_values)
|
| 150 |
|
| 151 |
hidream_o1_smoothing_data = []
|
| 152 |
-
if
|
| 153 |
hidream_o1_smoothing_data.append({})
|
| 154 |
|
| 155 |
workflow_inputs = {
|
|
@@ -159,8 +163,7 @@ class SdImagePipeline(BasePipeline):
|
|
| 159 |
"sampler_name": ui_inputs['sampler'], "scheduler": ui_inputs['scheduler'],
|
| 160 |
"batch_size": ui_inputs['batch_size'],
|
| 161 |
"denoise": ui_inputs['denoise'],
|
| 162 |
-
"vae_name": ui_inputs.get('vae_name'),
|
| 163 |
-
"guidance": ui_inputs.get('guidance', 3.5),
|
| 164 |
"lora_chain": active_loras_for_gpu,
|
| 165 |
"controlnet_chain": active_controlnets if not active_anima_controlnets else [],
|
| 166 |
"anima_controlnet_lllite_chain": active_anima_controlnets,
|
|
@@ -179,7 +182,7 @@ class SdImagePipeline(BasePipeline):
|
|
| 179 |
"qwen_image_edit_chain": active_qwen_image_edit,
|
| 180 |
"boogu_image_edit_chain": active_boogu_edit,
|
| 181 |
"reference_image_chain": active_reference_images,
|
| 182 |
-
"vae_chain": [ui_inputs.get('vae_name')] if ui_inputs.get('vae_name') else [],
|
| 183 |
"hidream_o1_smoothing_chain": hidream_o1_smoothing_data,
|
| 184 |
"pid_chain": [ui_inputs.get('pid_settings', 'OFF')] if is_pid_enabled else [],
|
| 185 |
"scheduler_width": ui_inputs.get('width', 1024),
|
|
|
|
| 70 |
|
| 71 |
required_models = self.get_required_models(model_display_name=model_display_name)
|
| 72 |
|
| 73 |
+
arch_enabled_chains = FEATURES_CONFIG.get(workflow_model_type, {}).get('enabled_chains', [])
|
| 74 |
+
task_enabled_chains = TASK_FEATURES_CONFIG.get(task_type, {}).get('enabled_chains', [])
|
| 75 |
+
enabled_chains = set([c for c in arch_enabled_chains if c in task_enabled_chains])
|
| 76 |
+
|
| 77 |
+
is_pid_enabled = (ui_inputs.get('pid_settings', 'OFF') == 'ON' and 'pid' in enabled_chains and task_type == 'txt2img')
|
| 78 |
if is_pid_enabled:
|
| 79 |
import yaml
|
| 80 |
pid_config_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), 'yaml', 'pid.yaml')
|
|
|
|
| 153 |
assembler = WorkflowAssembler(recipe_path, dynamic_values=dynamic_values)
|
| 154 |
|
| 155 |
hidream_o1_smoothing_data = []
|
| 156 |
+
if 'hidream_o1_smoothing' in enabled_chains and model_display_name == "HiDream-O1-Image":
|
| 157 |
hidream_o1_smoothing_data.append({})
|
| 158 |
|
| 159 |
workflow_inputs = {
|
|
|
|
| 163 |
"sampler_name": ui_inputs['sampler'], "scheduler": ui_inputs['scheduler'],
|
| 164 |
"batch_size": ui_inputs['batch_size'],
|
| 165 |
"denoise": ui_inputs['denoise'],
|
| 166 |
+
"vae_name": ui_inputs.get('vae_name') if 'vae' in enabled_chains else None,
|
|
|
|
| 167 |
"lora_chain": active_loras_for_gpu,
|
| 168 |
"controlnet_chain": active_controlnets if not active_anima_controlnets else [],
|
| 169 |
"anima_controlnet_lllite_chain": active_anima_controlnets,
|
|
|
|
| 182 |
"qwen_image_edit_chain": active_qwen_image_edit,
|
| 183 |
"boogu_image_edit_chain": active_boogu_edit,
|
| 184 |
"reference_image_chain": active_reference_images,
|
| 185 |
+
"vae_chain": [ui_inputs.get('vae_name')] if (ui_inputs.get('vae_name') and 'vae' in enabled_chains) else [],
|
| 186 |
"hidream_o1_smoothing_chain": hidream_o1_smoothing_data,
|
| 187 |
"pid_chain": [ui_inputs.get('pid_settings', 'OFF')] if is_pid_enabled else [],
|
| 188 |
"scheduler_width": ui_inputs.get('width', 1024),
|
core/pipelines/workflow_recipes/_partials/conditioning/flux1.yaml
CHANGED
|
@@ -22,6 +22,8 @@ nodes:
|
|
| 22 |
flux_guidance:
|
| 23 |
class_type: FluxGuidance
|
| 24 |
title: "FluxGuidance"
|
|
|
|
|
|
|
| 25 |
|
| 26 |
connections:
|
| 27 |
- from: "unet_loader:0"
|
|
@@ -72,5 +74,4 @@ ui_map:
|
|
| 72 |
unet_name: "unet_loader:unet_name"
|
| 73 |
vae_name: "vae_loader:vae_name"
|
| 74 |
clip1_name: "clip_loader:clip_name1"
|
| 75 |
-
clip2_name: "clip_loader:clip_name2"
|
| 76 |
-
guidance: "flux_guidance:guidance"
|
|
|
|
| 22 |
flux_guidance:
|
| 23 |
class_type: FluxGuidance
|
| 24 |
title: "FluxGuidance"
|
| 25 |
+
params:
|
| 26 |
+
guidance: 3.5
|
| 27 |
|
| 28 |
connections:
|
| 29 |
- from: "unet_loader:0"
|
|
|
|
| 74 |
unet_name: "unet_loader:unet_name"
|
| 75 |
vae_name: "vae_loader:vae_name"
|
| 76 |
clip1_name: "clip_loader:clip_name1"
|
| 77 |
+
clip2_name: "clip_loader:clip_name2"
|
|
|
core/settings.py
CHANGED
|
@@ -38,7 +38,8 @@ _FILE_LIST_PATH = os.path.join(_PROJECT_ROOT, 'yaml', 'file_list.yaml')
|
|
| 38 |
_IPADAPTER_LIST_PATH = os.path.join(_PROJECT_ROOT, 'yaml', 'ipadapter.yaml')
|
| 39 |
_CONSTANTS_PATH = os.path.join(_PROJECT_ROOT, 'yaml', 'constants.yaml')
|
| 40 |
_MODEL_ARCHITECTURES_PATH = os.path.join(_PROJECT_ROOT, 'yaml', 'model_architectures.yaml')
|
| 41 |
-
|
|
|
|
| 42 |
_MODEL_DEFAULTS_PATH = os.path.join(_PROJECT_ROOT, 'yaml', 'model_defaults.yaml')
|
| 43 |
|
| 44 |
def load_constants_from_yaml(filepath=_CONSTANTS_PATH):
|
|
@@ -55,13 +56,20 @@ def load_architectures_config(filepath=_MODEL_ARCHITECTURES_PATH):
|
|
| 55 |
with open(filepath, 'r', encoding='utf-8') as f:
|
| 56 |
return yaml.safe_load(f)
|
| 57 |
|
| 58 |
-
def load_features_config(filepath=
|
| 59 |
if not os.path.exists(filepath):
|
| 60 |
print(f"Warning: Features file not found at {filepath}.")
|
| 61 |
return {}
|
| 62 |
with open(filepath, 'r', encoding='utf-8') as f:
|
| 63 |
return yaml.safe_load(f)
|
| 64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
def load_model_defaults(filepath=_MODEL_DEFAULTS_PATH):
|
| 66 |
if not os.path.exists(filepath):
|
| 67 |
print(f"Warning: Model defaults file not found at {filepath}.")
|
|
@@ -195,6 +203,7 @@ try:
|
|
| 195 |
MULTIPLIERS_MAP = _constants.get('MULTIPLIERS_MAP', {})
|
| 196 |
ARCHITECTURES_CONFIG = load_architectures_config()
|
| 197 |
FEATURES_CONFIG = load_features_config()
|
|
|
|
| 198 |
MODEL_DEFAULTS_CONFIG = load_model_defaults()
|
| 199 |
except Exception as e:
|
| 200 |
print(f"FATAL: Could not load constants from YAML. Error: {e}")
|
|
@@ -204,4 +213,5 @@ except Exception as e:
|
|
| 204 |
MULTIPLIERS_MAP = {}
|
| 205 |
ARCHITECTURES_CONFIG = {}
|
| 206 |
FEATURES_CONFIG = {}
|
|
|
|
| 207 |
MODEL_DEFAULTS_CONFIG = {}
|
|
|
|
| 38 |
_IPADAPTER_LIST_PATH = os.path.join(_PROJECT_ROOT, 'yaml', 'ipadapter.yaml')
|
| 39 |
_CONSTANTS_PATH = os.path.join(_PROJECT_ROOT, 'yaml', 'constants.yaml')
|
| 40 |
_MODEL_ARCHITECTURES_PATH = os.path.join(_PROJECT_ROOT, 'yaml', 'model_architectures.yaml')
|
| 41 |
+
_MODEL_ARCH_FEATURES_PATH = os.path.join(_PROJECT_ROOT, 'yaml', 'model_architecture_features.yaml')
|
| 42 |
+
_TASK_FEATURES_PATH = os.path.join(_PROJECT_ROOT, 'yaml', 'task_features.yaml')
|
| 43 |
_MODEL_DEFAULTS_PATH = os.path.join(_PROJECT_ROOT, 'yaml', 'model_defaults.yaml')
|
| 44 |
|
| 45 |
def load_constants_from_yaml(filepath=_CONSTANTS_PATH):
|
|
|
|
| 56 |
with open(filepath, 'r', encoding='utf-8') as f:
|
| 57 |
return yaml.safe_load(f)
|
| 58 |
|
| 59 |
+
def load_features_config(filepath=_MODEL_ARCH_FEATURES_PATH):
|
| 60 |
if not os.path.exists(filepath):
|
| 61 |
print(f"Warning: Features file not found at {filepath}.")
|
| 62 |
return {}
|
| 63 |
with open(filepath, 'r', encoding='utf-8') as f:
|
| 64 |
return yaml.safe_load(f)
|
| 65 |
|
| 66 |
+
def load_task_features_config(filepath=_TASK_FEATURES_PATH):
|
| 67 |
+
if not os.path.exists(filepath):
|
| 68 |
+
print(f"Warning: Task features file not found at {filepath}.")
|
| 69 |
+
return {}
|
| 70 |
+
with open(filepath, 'r', encoding='utf-8') as f:
|
| 71 |
+
return yaml.safe_load(f)
|
| 72 |
+
|
| 73 |
def load_model_defaults(filepath=_MODEL_DEFAULTS_PATH):
|
| 74 |
if not os.path.exists(filepath):
|
| 75 |
print(f"Warning: Model defaults file not found at {filepath}.")
|
|
|
|
| 203 |
MULTIPLIERS_MAP = _constants.get('MULTIPLIERS_MAP', {})
|
| 204 |
ARCHITECTURES_CONFIG = load_architectures_config()
|
| 205 |
FEATURES_CONFIG = load_features_config()
|
| 206 |
+
TASK_FEATURES_CONFIG = load_task_features_config()
|
| 207 |
MODEL_DEFAULTS_CONFIG = load_model_defaults()
|
| 208 |
except Exception as e:
|
| 209 |
print(f"FATAL: Could not load constants from YAML. Error: {e}")
|
|
|
|
| 213 |
MULTIPLIERS_MAP = {}
|
| 214 |
ARCHITECTURES_CONFIG = {}
|
| 215 |
FEATURES_CONFIG = {}
|
| 216 |
+
TASK_FEATURES_CONFIG = {}
|
| 217 |
MODEL_DEFAULTS_CONFIG = {}
|
mcp_tools/common.py
CHANGED
|
@@ -20,8 +20,9 @@ _YAML_DIR = os.path.join(_PROJECT_ROOT, "yaml")
|
|
| 20 |
_MODEL_ARCHITECTURES_PATH = os.path.join(_YAML_DIR, "model_architectures.yaml")
|
| 21 |
_MODEL_LIST_PATH = os.path.join(_YAML_DIR, "model_list.yaml")
|
| 22 |
_MODEL_DEFAULTS_PATH = os.path.join(_YAML_DIR, "model_defaults.yaml")
|
| 23 |
-
_IMAGE_GEN_FEATURES_PATH = os.path.join(_YAML_DIR, "
|
| 24 |
_CHAIN_FEATURES_PATH = os.path.join(_YAML_DIR, "chain_features.yaml")
|
|
|
|
| 25 |
_CONSTANTS_PATH = os.path.join(_YAML_DIR, "constants.yaml")
|
| 26 |
|
| 27 |
|
|
|
|
| 20 |
_MODEL_ARCHITECTURES_PATH = os.path.join(_YAML_DIR, "model_architectures.yaml")
|
| 21 |
_MODEL_LIST_PATH = os.path.join(_YAML_DIR, "model_list.yaml")
|
| 22 |
_MODEL_DEFAULTS_PATH = os.path.join(_YAML_DIR, "model_defaults.yaml")
|
| 23 |
+
_IMAGE_GEN_FEATURES_PATH = os.path.join(_YAML_DIR, "model_architecture_features.yaml")
|
| 24 |
_CHAIN_FEATURES_PATH = os.path.join(_YAML_DIR, "chain_features.yaml")
|
| 25 |
+
_TASK_FEATURES_PATH = os.path.join(_YAML_DIR, "task_features.yaml")
|
| 26 |
_CONSTANTS_PATH = os.path.join(_YAML_DIR, "constants.yaml")
|
| 27 |
|
| 28 |
|
mcp_tools/get_feature_list.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
import os
|
| 2 |
from copy import deepcopy
|
| 3 |
-
from .common import _load_yaml, _CHAIN_FEATURES_PATH, _YAML_DIR
|
| 4 |
from .error_schema import make_not_found_error
|
| 5 |
|
| 6 |
|
|
@@ -79,14 +79,35 @@ def _get_default_example_chain_item(chain_name: str, chain_data: dict) -> dict:
|
|
| 79 |
return item
|
| 80 |
|
| 81 |
|
| 82 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
example_item = _get_default_example_chain_item(chain_name, chain_data)
|
| 84 |
entry = {
|
| 85 |
"feature_name": chain_name,
|
| 86 |
"chains": chain_data.get("chains", chain_name),
|
| 87 |
"display_name": chain_data.get("display_name", chain_name),
|
| 88 |
"description": chain_data.get("description", ""),
|
| 89 |
-
"supported_tasks":
|
| 90 |
"max_count": chain_data.get("max_count", 1),
|
| 91 |
"usage_guideline": chain_data.get("usage_guideline", ""),
|
| 92 |
"example_chain_item": example_item,
|
|
@@ -158,6 +179,7 @@ def handle_get_feature_list(feature_name: str | list[str] = "") -> list | dict:
|
|
| 158 |
returns complete feature details INCLUDING parameters_schema for the requested feature(s).
|
| 159 |
"""
|
| 160 |
chain_features = _load_yaml(_CHAIN_FEATURES_PATH)
|
|
|
|
| 161 |
|
| 162 |
targets = []
|
| 163 |
is_single_string_query = False
|
|
@@ -174,7 +196,7 @@ def handle_get_feature_list(feature_name: str | list[str] = "") -> list | dict:
|
|
| 174 |
# Case 1: Empty input -> return summary list of all features (without parameters_schema)
|
| 175 |
if not targets:
|
| 176 |
return [
|
| 177 |
-
_build_feature_entry(name, data, include_schema=False)
|
| 178 |
for name, data in chain_features.items()
|
| 179 |
]
|
| 180 |
|
|
@@ -200,7 +222,7 @@ def handle_get_feature_list(feature_name: str | list[str] = "") -> list | dict:
|
|
| 200 |
|
| 201 |
# Case 3: Return full info including parameters_schema
|
| 202 |
results = [
|
| 203 |
-
_build_feature_entry(target, chain_features[target], include_schema=True)
|
| 204 |
for target in resolved_targets
|
| 205 |
]
|
| 206 |
|
|
|
|
| 1 |
import os
|
| 2 |
from copy import deepcopy
|
| 3 |
+
from .common import _load_yaml, _CHAIN_FEATURES_PATH, _TASK_FEATURES_PATH, _YAML_DIR
|
| 4 |
from .error_schema import make_not_found_error
|
| 5 |
|
| 6 |
|
|
|
|
| 79 |
return item
|
| 80 |
|
| 81 |
|
| 82 |
+
def _get_supported_tasks_for_feature(chain_name: str, chain_data: dict, task_features: dict) -> list:
|
| 83 |
+
feat_chains = chain_data.get("chains", chain_name)
|
| 84 |
+
if isinstance(feat_chains, str):
|
| 85 |
+
target_chains = {feat_chains, chain_name}
|
| 86 |
+
elif isinstance(feat_chains, (list, tuple, set)):
|
| 87 |
+
target_chains = set(feat_chains) | {chain_name}
|
| 88 |
+
else:
|
| 89 |
+
target_chains = {chain_name}
|
| 90 |
+
|
| 91 |
+
supported = []
|
| 92 |
+
for task_name, task_data in task_features.items():
|
| 93 |
+
if not isinstance(task_data, dict):
|
| 94 |
+
continue
|
| 95 |
+
enabled_chains = task_data.get("enabled_chains", [])
|
| 96 |
+
if any(c in enabled_chains for c in target_chains):
|
| 97 |
+
supported.append(task_name)
|
| 98 |
+
return supported
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
def _build_feature_entry(chain_name: str, chain_data: dict, task_features: dict = None, include_schema: bool = False) -> dict:
|
| 102 |
+
if task_features is None:
|
| 103 |
+
task_features = _load_yaml(_TASK_FEATURES_PATH)
|
| 104 |
example_item = _get_default_example_chain_item(chain_name, chain_data)
|
| 105 |
entry = {
|
| 106 |
"feature_name": chain_name,
|
| 107 |
"chains": chain_data.get("chains", chain_name),
|
| 108 |
"display_name": chain_data.get("display_name", chain_name),
|
| 109 |
"description": chain_data.get("description", ""),
|
| 110 |
+
"supported_tasks": _get_supported_tasks_for_feature(chain_name, chain_data, task_features),
|
| 111 |
"max_count": chain_data.get("max_count", 1),
|
| 112 |
"usage_guideline": chain_data.get("usage_guideline", ""),
|
| 113 |
"example_chain_item": example_item,
|
|
|
|
| 179 |
returns complete feature details INCLUDING parameters_schema for the requested feature(s).
|
| 180 |
"""
|
| 181 |
chain_features = _load_yaml(_CHAIN_FEATURES_PATH)
|
| 182 |
+
task_features = _load_yaml(_TASK_FEATURES_PATH)
|
| 183 |
|
| 184 |
targets = []
|
| 185 |
is_single_string_query = False
|
|
|
|
| 196 |
# Case 1: Empty input -> return summary list of all features (without parameters_schema)
|
| 197 |
if not targets:
|
| 198 |
return [
|
| 199 |
+
_build_feature_entry(name, data, task_features, include_schema=False)
|
| 200 |
for name, data in chain_features.items()
|
| 201 |
]
|
| 202 |
|
|
|
|
| 222 |
|
| 223 |
# Case 3: Return full info including parameters_schema
|
| 224 |
results = [
|
| 225 |
+
_build_feature_entry(target, chain_features[target], task_features, include_schema=True)
|
| 226 |
for target in resolved_targets
|
| 227 |
]
|
| 228 |
|
mcp_tools/mcp_gradio_integration.py
CHANGED
|
@@ -56,6 +56,7 @@ def cleanup_dependencies_api_names(demo):
|
|
| 56 |
api_name = getattr(fn, "api_name", None)
|
| 57 |
if api_name not in HIGH_LEVEL_MCP_API_NAMES:
|
| 58 |
fn.show_api = False
|
|
|
|
| 59 |
|
| 60 |
deps = getattr(demo, "dependencies", None)
|
| 61 |
if deps is None and hasattr(demo, "config") and isinstance(demo.config, dict):
|
|
@@ -67,6 +68,7 @@ def cleanup_dependencies_api_names(demo):
|
|
| 67 |
api_name = dep.get("api_name")
|
| 68 |
if api_name not in HIGH_LEVEL_MCP_API_NAMES:
|
| 69 |
dep["show_api"] = False
|
|
|
|
| 70 |
|
| 71 |
print("[MCP Protection] Cleaned up demo dependencies. Suppressed atomic API endpoints.")
|
| 72 |
|
|
|
|
| 56 |
api_name = getattr(fn, "api_name", None)
|
| 57 |
if api_name not in HIGH_LEVEL_MCP_API_NAMES:
|
| 58 |
fn.show_api = False
|
| 59 |
+
fn.api_name = False
|
| 60 |
|
| 61 |
deps = getattr(demo, "dependencies", None)
|
| 62 |
if deps is None and hasattr(demo, "config") and isinstance(demo.config, dict):
|
|
|
|
| 68 |
api_name = dep.get("api_name")
|
| 69 |
if api_name not in HIGH_LEVEL_MCP_API_NAMES:
|
| 70 |
dep["show_api"] = False
|
| 71 |
+
dep["api_name"] = False
|
| 72 |
|
| 73 |
print("[MCP Protection] Cleaned up demo dependencies. Suppressed atomic API endpoints.")
|
| 74 |
|
requirements.txt
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
comfyui-frontend-package==1.49.6
|
| 2 |
-
comfyui-workflow-templates==0.11.
|
| 3 |
comfyui-embedded-docs==0.5.10
|
| 4 |
torch
|
| 5 |
torchsde
|
|
|
|
| 1 |
comfyui-frontend-package==1.49.6
|
| 2 |
+
comfyui-workflow-templates==0.11.44
|
| 3 |
comfyui-embedded-docs==0.5.10
|
| 4 |
torch
|
| 5 |
torchsde
|
ui/events/change_handlers.py
CHANGED
|
@@ -3,6 +3,7 @@ from core.settings import (
|
|
| 3 |
MODEL_TYPE_MAP,
|
| 4 |
MODEL_MAP_CHECKPOINT,
|
| 5 |
FEATURES_CONFIG,
|
|
|
|
| 6 |
ARCHITECTURES_CONFIG,
|
| 7 |
MODEL_DEFAULTS_CONFIG,
|
| 8 |
ARCH_CATEGORIES_MAP
|
|
@@ -17,7 +18,7 @@ from .config_loaders import (
|
|
| 17 |
load_ipadapter_config
|
| 18 |
)
|
| 19 |
|
| 20 |
-
def make_update_fn(m_comp, cat_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,
|
| 21 |
def update_fn(*args):
|
| 22 |
arch = args[0]
|
| 23 |
category = args[1]
|
|
@@ -53,7 +54,20 @@ def make_update_fn(m_comp, cat_comp, ar_comp, width_comp, height_comp, cn_types,
|
|
| 53 |
arch_model_type = architectures_dict.get(m_type, {}).get("model_type", m_type.lower().replace(" ", "").replace(".", ""))
|
| 54 |
|
| 55 |
arch_features = FEATURES_CONFIG.get(arch_model_type, {})
|
| 56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
|
| 58 |
if lora_acc: updates[lora_acc] = gr.update(visible=('lora' in enabled_chains))
|
| 59 |
if cn_acc: updates[cn_acc] = gr.update(visible=('controlnet' in enabled_chains))
|
|
@@ -76,9 +90,6 @@ def make_update_fn(m_comp, cat_comp, ar_comp, width_comp, height_comp, cn_types,
|
|
| 76 |
if ref_img_acc: updates[ref_img_acc] = gr.update(visible=('reference_image' in enabled_chains))
|
| 77 |
if pid_acc: updates[pid_acc] = gr.update(visible=('pid' in enabled_chains))
|
| 78 |
if vae_acc: updates[vae_acc] = gr.update(visible=('vae' in enabled_chains))
|
| 79 |
-
|
| 80 |
-
if guidance_comp:
|
| 81 |
-
updates[guidance_comp] = gr.update(visible=(arch_model_type == "flux1"))
|
| 82 |
|
| 83 |
if ar_comp:
|
| 84 |
res_key = arch_model_type
|
|
@@ -146,7 +157,7 @@ def make_update_fn(m_comp, cat_comp, ar_comp, width_comp, height_comp, cn_types,
|
|
| 146 |
return update_fn
|
| 147 |
|
| 148 |
|
| 149 |
-
def make_model_change_fn(cat_comp_ref, 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,
|
| 150 |
def change_fn(*args):
|
| 151 |
model_name = args[0]
|
| 152 |
idx = 1
|
|
@@ -187,7 +198,23 @@ def make_model_change_fn(cat_comp_ref, ar_comp, width_comp, height_comp, cn_type
|
|
| 187 |
arch_model_type = architectures_dict.get(m_type, {}).get("model_type", m_type.lower().replace(" ", "").replace(".", ""))
|
| 188 |
|
| 189 |
arch_features = FEATURES_CONFIG.get(arch_model_type, {})
|
| 190 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
|
| 192 |
if lora_acc: updates[lora_acc] = gr.update(visible=('lora' in enabled_chains))
|
| 193 |
if cn_acc: updates[cn_acc] = gr.update(visible=('controlnet' in enabled_chains))
|
|
@@ -210,9 +237,6 @@ def make_model_change_fn(cat_comp_ref, ar_comp, width_comp, height_comp, cn_type
|
|
| 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))
|
| 212 |
if vae_acc: updates[vae_acc] = gr.update(visible=('vae' in enabled_chains))
|
| 213 |
-
|
| 214 |
-
if guidance_comp:
|
| 215 |
-
updates[guidance_comp] = gr.update(visible=(arch_model_type == "flux1"))
|
| 216 |
|
| 217 |
if ar_comp:
|
| 218 |
res_key = arch_model_type
|
|
@@ -292,7 +316,7 @@ def initialize_all_cn_dropdowns(ui_components):
|
|
| 292 |
krea2_all_types, krea2_default_type, krea2_series_choices, krea2_default_series, krea2_filepath = get_krea2_cn_defaults()
|
| 293 |
|
| 294 |
updates = {}
|
| 295 |
-
for prefix in ["txt2img", "img2img", "inpaint", "outpaint", "hires_fix"]:
|
| 296 |
if f'controlnet_types_{prefix}' in ui_components:
|
| 297 |
for type_dd in ui_components[f'controlnet_types_{prefix}']:
|
| 298 |
updates[type_dd] = gr.update(choices=all_types, value=default_type)
|
|
@@ -348,7 +372,7 @@ def initialize_all_ipa_dropdowns(ui_components):
|
|
| 348 |
lora_strength_update = gr.update(visible=is_faceid_default)
|
| 349 |
|
| 350 |
updates = {}
|
| 351 |
-
for prefix in ["txt2img", "img2img", "inpaint", "outpaint", "hires_fix"]:
|
| 352 |
if f'ipadapter_final_preset_{prefix}' in ui_components:
|
| 353 |
for lora_strength_slider in ui_components[f'ipadapter_lora_strengths_{prefix}']:
|
| 354 |
updates[lora_strength_slider] = lora_strength_update
|
|
|
|
| 3 |
MODEL_TYPE_MAP,
|
| 4 |
MODEL_MAP_CHECKPOINT,
|
| 5 |
FEATURES_CONFIG,
|
| 6 |
+
TASK_FEATURES_CONFIG,
|
| 7 |
ARCHITECTURES_CONFIG,
|
| 8 |
MODEL_DEFAULTS_CONFIG,
|
| 9 |
ARCH_CATEGORIES_MAP
|
|
|
|
| 18 |
load_ipadapter_config
|
| 19 |
)
|
| 20 |
|
| 21 |
+
def make_update_fn(m_comp, cat_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, 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, boogu_edit_acc=None, ref_img_acc=None, task_type=None, type_comp=None):
|
| 22 |
def update_fn(*args):
|
| 23 |
arch = args[0]
|
| 24 |
category = args[1]
|
|
|
|
| 54 |
arch_model_type = architectures_dict.get(m_type, {}).get("model_type", m_type.lower().replace(" ", "").replace(".", ""))
|
| 55 |
|
| 56 |
arch_features = FEATURES_CONFIG.get(arch_model_type, {})
|
| 57 |
+
arch_enabled_chains = arch_features.get('enabled_chains', [])
|
| 58 |
+
|
| 59 |
+
# Determine current task type for task-level feature filtering
|
| 60 |
+
current_task = task_type # static task_type for standalone prefixes
|
| 61 |
+
if type_comp is not None:
|
| 62 |
+
# unified imagegen: task type comes from extra arg
|
| 63 |
+
type_arg_idx = 3 if ar_comp else 2
|
| 64 |
+
if len(args) > type_arg_idx:
|
| 65 |
+
type_val = args[type_arg_idx]
|
| 66 |
+
type_map = {'Txt2Img': 'txt2img', 'Img2Img': 'img2img', 'Inpaint': 'inpaint', 'Outpaint': 'outpaint', 'Hires. Fix': 'hires_fix'}
|
| 67 |
+
current_task = type_map.get(type_val, 'txt2img')
|
| 68 |
+
|
| 69 |
+
task_enabled_chains = TASK_FEATURES_CONFIG.get(current_task, {}).get('enabled_chains', []) if current_task else arch_enabled_chains
|
| 70 |
+
enabled_chains = [c for c in arch_enabled_chains if c in task_enabled_chains]
|
| 71 |
|
| 72 |
if lora_acc: updates[lora_acc] = gr.update(visible=('lora' in enabled_chains))
|
| 73 |
if cn_acc: updates[cn_acc] = gr.update(visible=('controlnet' in enabled_chains))
|
|
|
|
| 90 |
if ref_img_acc: updates[ref_img_acc] = gr.update(visible=('reference_image' in enabled_chains))
|
| 91 |
if pid_acc: updates[pid_acc] = gr.update(visible=('pid' in enabled_chains))
|
| 92 |
if vae_acc: updates[vae_acc] = gr.update(visible=('vae' in enabled_chains))
|
|
|
|
|
|
|
|
|
|
| 93 |
|
| 94 |
if ar_comp:
|
| 95 |
res_key = arch_model_type
|
|
|
|
| 157 |
return update_fn
|
| 158 |
|
| 159 |
|
| 160 |
+
def make_model_change_fn(cat_comp_ref, 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, 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, boogu_edit_acc=None, ref_img_acc=None, task_type=None, type_comp=None):
|
| 161 |
def change_fn(*args):
|
| 162 |
model_name = args[0]
|
| 163 |
idx = 1
|
|
|
|
| 198 |
arch_model_type = architectures_dict.get(m_type, {}).get("model_type", m_type.lower().replace(" ", "").replace(".", ""))
|
| 199 |
|
| 200 |
arch_features = FEATURES_CONFIG.get(arch_model_type, {})
|
| 201 |
+
arch_enabled_chains = arch_features.get('enabled_chains', [])
|
| 202 |
+
|
| 203 |
+
# Determine current task type for task-level feature filtering
|
| 204 |
+
current_task = task_type # static task_type for standalone prefixes
|
| 205 |
+
if type_comp is not None:
|
| 206 |
+
# unified imagegen: task type comes from extra arg after model, arch, cat, ar
|
| 207 |
+
type_arg_idx = 1
|
| 208 |
+
if arch_comp_ref: type_arg_idx += 1
|
| 209 |
+
if cat_comp_ref: type_arg_idx += 1
|
| 210 |
+
if ar_comp: type_arg_idx += 1
|
| 211 |
+
if len(args) > type_arg_idx:
|
| 212 |
+
type_val = args[type_arg_idx]
|
| 213 |
+
type_map = {'Txt2Img': 'txt2img', 'Img2Img': 'img2img', 'Inpaint': 'inpaint', 'Outpaint': 'outpaint', 'Hires. Fix': 'hires_fix'}
|
| 214 |
+
current_task = type_map.get(type_val, 'txt2img')
|
| 215 |
+
|
| 216 |
+
task_enabled_chains = TASK_FEATURES_CONFIG.get(current_task, {}).get('enabled_chains', []) if current_task else arch_enabled_chains
|
| 217 |
+
enabled_chains = [c for c in arch_enabled_chains if c in task_enabled_chains]
|
| 218 |
|
| 219 |
if lora_acc: updates[lora_acc] = gr.update(visible=('lora' in enabled_chains))
|
| 220 |
if cn_acc: updates[cn_acc] = gr.update(visible=('controlnet' in enabled_chains))
|
|
|
|
| 237 |
if ref_img_acc: updates[ref_img_acc] = gr.update(visible=('reference_image' in enabled_chains))
|
| 238 |
if pid_acc: updates[pid_acc] = gr.update(visible=('pid' in enabled_chains))
|
| 239 |
if vae_acc: updates[vae_acc] = gr.update(visible=('vae' in enabled_chains))
|
|
|
|
|
|
|
|
|
|
| 240 |
|
| 241 |
if ar_comp:
|
| 242 |
res_key = arch_model_type
|
|
|
|
| 316 |
krea2_all_types, krea2_default_type, krea2_series_choices, krea2_default_series, krea2_filepath = get_krea2_cn_defaults()
|
| 317 |
|
| 318 |
updates = {}
|
| 319 |
+
for prefix in ["imagegen", "txt2img", "img2img", "inpaint", "outpaint", "hires_fix"]:
|
| 320 |
if f'controlnet_types_{prefix}' in ui_components:
|
| 321 |
for type_dd in ui_components[f'controlnet_types_{prefix}']:
|
| 322 |
updates[type_dd] = gr.update(choices=all_types, value=default_type)
|
|
|
|
| 372 |
lora_strength_update = gr.update(visible=is_faceid_default)
|
| 373 |
|
| 374 |
updates = {}
|
| 375 |
+
for prefix in ["imagegen", "txt2img", "img2img", "inpaint", "outpaint", "hires_fix"]:
|
| 376 |
if f'ipadapter_final_preset_{prefix}' in ui_components:
|
| 377 |
for lora_strength_slider in ui_components[f'ipadapter_lora_strengths_{prefix}']:
|
| 378 |
updates[lora_strength_slider] = lora_strength_update
|
ui/events/main.py
CHANGED
|
@@ -29,15 +29,16 @@ from .change_handlers import (
|
|
| 29 |
from .run_handlers import create_run_event
|
| 30 |
|
| 31 |
def attach_event_handlers(ui_components, demo):
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
|
|
|
|
|
|
| 36 |
|
| 37 |
arch_comp = ui_components.get(f'model_arch_{prefix}')
|
| 38 |
cat_comp = ui_components.get(f'model_cat_{prefix}')
|
| 39 |
model_comp = ui_components.get(f'base_model_{prefix}')
|
| 40 |
-
guidance_comp = ui_components.get(f'guidance_{prefix}') or ui_components.get(f'{prefix}_guidance')
|
| 41 |
aspect_ratio_comp = ui_components.get(f'aspect_ratio_{prefix}') or ui_components.get(f'{prefix}_aspect_ratio_dropdown')
|
| 42 |
width_comp = ui_components.get(f'width_{prefix}') or ui_components.get(f'{prefix}_width')
|
| 43 |
height_comp = ui_components.get(f'height_{prefix}') or ui_components.get(f'{prefix}_height')
|
|
@@ -94,7 +95,6 @@ def attach_event_handlers(ui_components, demo):
|
|
| 94 |
|
| 95 |
if arch_comp and cat_comp and model_comp:
|
| 96 |
outputs = [model_comp, cat_comp]
|
| 97 |
-
if guidance_comp: outputs.append(guidance_comp)
|
| 98 |
if aspect_ratio_comp: outputs.append(aspect_ratio_comp)
|
| 99 |
outputs.extend(cn_types_list + cn_series_list + cn_filepaths_list)
|
| 100 |
outputs.extend(anima_cn_types_list + anima_cn_series_list + anima_cn_filepaths_list)
|
|
@@ -132,12 +132,15 @@ def attach_event_handlers(ui_components, demo):
|
|
| 132 |
diffsynth_cn_types_list, diffsynth_cn_series_list, diffsynth_cn_filepaths_list,
|
| 133 |
krea2_cn_types_list, krea2_cn_series_list, krea2_cn_filepaths_list,
|
| 134 |
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,
|
| 135 |
-
ref_latent_accordion, hidream_o1_ref_accordion,
|
| 136 |
-
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, boogu_edit_acc=boogu_edit_accordion, ref_img_acc=ref_img_accordion
|
|
|
|
| 137 |
)
|
| 138 |
inputs = [arch_comp, cat_comp]
|
| 139 |
if aspect_ratio_comp:
|
| 140 |
inputs.append(aspect_ratio_comp)
|
|
|
|
|
|
|
| 141 |
arch_comp.change(fn=update_fn, inputs=inputs, outputs=outputs)
|
| 142 |
cat_comp.change(fn=update_fn, inputs=inputs, outputs=outputs)
|
| 143 |
|
|
@@ -145,7 +148,6 @@ def attach_event_handlers(ui_components, demo):
|
|
| 145 |
outputs2 = []
|
| 146 |
if arch_comp: outputs2.append(arch_comp)
|
| 147 |
if cat_comp: outputs2.append(cat_comp)
|
| 148 |
-
if guidance_comp: outputs2.append(guidance_comp)
|
| 149 |
if aspect_ratio_comp: outputs2.append(aspect_ratio_comp)
|
| 150 |
outputs2.extend(cn_types_list + cn_series_list + cn_filepaths_list)
|
| 151 |
outputs2.extend(anima_cn_types_list + anima_cn_series_list + anima_cn_filepaths_list)
|
|
@@ -188,9 +190,12 @@ def attach_event_handlers(ui_components, demo):
|
|
| 188 |
diffsynth_cn_types_list, diffsynth_cn_series_list, diffsynth_cn_filepaths_list,
|
| 189 |
krea2_cn_types_list, krea2_cn_series_list, krea2_cn_filepaths_list,
|
| 190 |
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,
|
| 191 |
-
ref_latent_accordion, hidream_o1_ref_accordion,
|
| 192 |
-
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, boogu_edit_acc=boogu_edit_accordion, ref_img_acc=ref_img_accordion
|
|
|
|
| 193 |
)
|
|
|
|
|
|
|
| 194 |
model_comp.change(fn=change_fn, inputs=inputs2, outputs=outputs2)
|
| 195 |
|
| 196 |
create_lora_event_handlers(prefix, ui_components)
|
|
@@ -214,6 +219,164 @@ def attach_event_handlers(ui_components, demo):
|
|
| 214 |
create_reference_image_event_handlers(prefix, ui_components)
|
| 215 |
create_run_event(prefix, task_type, ui_components)
|
| 216 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 217 |
if 'view_mode_inpaint' in ui_components:
|
| 218 |
def toggle_inpaint_fullscreen_view(view_mode):
|
| 219 |
is_fullscreen = (view_mode == "Fullscreen View")
|
|
@@ -255,7 +418,7 @@ def attach_event_handlers(ui_components, demo):
|
|
| 255 |
)
|
| 256 |
|
| 257 |
all_load_outputs = []
|
| 258 |
-
for prefix in
|
| 259 |
if f'controlnet_types_{prefix}' in ui_components:
|
| 260 |
all_load_outputs.extend(ui_components[f'controlnet_types_{prefix}'])
|
| 261 |
all_load_outputs.extend(ui_components[f'controlnet_series_{prefix}'])
|
|
@@ -283,7 +446,7 @@ def attach_event_handlers(ui_components, demo):
|
|
| 283 |
outputs=all_load_outputs
|
| 284 |
)
|
| 285 |
|
| 286 |
-
for prefix in
|
| 287 |
aspect_ratio_dropdown = ui_components.get(f'aspect_ratio_{prefix}') or ui_components.get(f'{prefix}_aspect_ratio_dropdown')
|
| 288 |
width_component = ui_components.get(f'width_{prefix}') or ui_components.get(f'{prefix}_width')
|
| 289 |
height_component = ui_components.get(f'height_{prefix}') or ui_components.get(f'{prefix}_height')
|
|
|
|
| 29 |
from .run_handlers import create_run_event
|
| 30 |
|
| 31 |
def attach_event_handlers(ui_components, demo):
|
| 32 |
+
prefixes = ["imagegen", "txt2img", "img2img", "inpaint", "outpaint", "hires_fix"]
|
| 33 |
+
active_prefixes = [p for p in prefixes if f'base_model_{p}' in ui_components]
|
| 34 |
+
|
| 35 |
+
for prefix in active_prefixes:
|
| 36 |
+
task_type = prefix if prefix != "imagegen" else None
|
| 37 |
+
type_comp = ui_components.get(f'type_{prefix}') # for unified imagegen UI
|
| 38 |
|
| 39 |
arch_comp = ui_components.get(f'model_arch_{prefix}')
|
| 40 |
cat_comp = ui_components.get(f'model_cat_{prefix}')
|
| 41 |
model_comp = ui_components.get(f'base_model_{prefix}')
|
|
|
|
| 42 |
aspect_ratio_comp = ui_components.get(f'aspect_ratio_{prefix}') or ui_components.get(f'{prefix}_aspect_ratio_dropdown')
|
| 43 |
width_comp = ui_components.get(f'width_{prefix}') or ui_components.get(f'{prefix}_width')
|
| 44 |
height_comp = ui_components.get(f'height_{prefix}') or ui_components.get(f'{prefix}_height')
|
|
|
|
| 95 |
|
| 96 |
if arch_comp and cat_comp and model_comp:
|
| 97 |
outputs = [model_comp, cat_comp]
|
|
|
|
| 98 |
if aspect_ratio_comp: outputs.append(aspect_ratio_comp)
|
| 99 |
outputs.extend(cn_types_list + cn_series_list + cn_filepaths_list)
|
| 100 |
outputs.extend(anima_cn_types_list + anima_cn_series_list + anima_cn_filepaths_list)
|
|
|
|
| 132 |
diffsynth_cn_types_list, diffsynth_cn_series_list, diffsynth_cn_filepaths_list,
|
| 133 |
krea2_cn_types_list, krea2_cn_series_list, krea2_cn_filepaths_list,
|
| 134 |
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,
|
| 135 |
+
ref_latent_accordion, hidream_o1_ref_accordion, prompt_comp, neg_prompt_comp, steps_comp, cfg_comp, sampler_comp, scheduler_comp,
|
| 136 |
+
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, boogu_edit_acc=boogu_edit_accordion, ref_img_acc=ref_img_accordion,
|
| 137 |
+
task_type=task_type, type_comp=type_comp
|
| 138 |
)
|
| 139 |
inputs = [arch_comp, cat_comp]
|
| 140 |
if aspect_ratio_comp:
|
| 141 |
inputs.append(aspect_ratio_comp)
|
| 142 |
+
if type_comp:
|
| 143 |
+
inputs.append(type_comp)
|
| 144 |
arch_comp.change(fn=update_fn, inputs=inputs, outputs=outputs)
|
| 145 |
cat_comp.change(fn=update_fn, inputs=inputs, outputs=outputs)
|
| 146 |
|
|
|
|
| 148 |
outputs2 = []
|
| 149 |
if arch_comp: outputs2.append(arch_comp)
|
| 150 |
if cat_comp: outputs2.append(cat_comp)
|
|
|
|
| 151 |
if aspect_ratio_comp: outputs2.append(aspect_ratio_comp)
|
| 152 |
outputs2.extend(cn_types_list + cn_series_list + cn_filepaths_list)
|
| 153 |
outputs2.extend(anima_cn_types_list + anima_cn_series_list + anima_cn_filepaths_list)
|
|
|
|
| 190 |
diffsynth_cn_types_list, diffsynth_cn_series_list, diffsynth_cn_filepaths_list,
|
| 191 |
krea2_cn_types_list, krea2_cn_series_list, krea2_cn_filepaths_list,
|
| 192 |
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,
|
| 193 |
+
ref_latent_accordion, hidream_o1_ref_accordion, prompt_comp, neg_prompt_comp, steps_comp, cfg_comp, sampler_comp, scheduler_comp,
|
| 194 |
+
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, boogu_edit_acc=boogu_edit_accordion, ref_img_acc=ref_img_accordion,
|
| 195 |
+
task_type=task_type, type_comp=type_comp
|
| 196 |
)
|
| 197 |
+
if type_comp:
|
| 198 |
+
inputs2.append(type_comp)
|
| 199 |
model_comp.change(fn=change_fn, inputs=inputs2, outputs=outputs2)
|
| 200 |
|
| 201 |
create_lora_event_handlers(prefix, ui_components)
|
|
|
|
| 219 |
create_reference_image_event_handlers(prefix, ui_components)
|
| 220 |
create_run_event(prefix, task_type, ui_components)
|
| 221 |
|
| 222 |
+
# Dynamic Type toggle event for unified imagegen UI
|
| 223 |
+
if 'type_imagegen' in ui_components:
|
| 224 |
+
def on_type_change(type_val, model_name):
|
| 225 |
+
from core.settings import MODEL_TYPE_MAP, FEATURES_CONFIG, TASK_FEATURES_CONFIG, ARCHITECTURES_CONFIG
|
| 226 |
+
is_txt2img = (type_val == "Txt2Img")
|
| 227 |
+
is_img2img = (type_val == "Img2Img")
|
| 228 |
+
is_inpaint = (type_val == "Inpaint")
|
| 229 |
+
is_outpaint = (type_val == "Outpaint")
|
| 230 |
+
is_hires_fix = (type_val == "Hires. Fix")
|
| 231 |
+
|
| 232 |
+
denoise_val = 0.7 if is_img2img else (1.0 if is_inpaint else (0.55 if is_hires_fix else 0.7))
|
| 233 |
+
run_text = "Run Inpaint" if is_inpaint else ("Run Outpaint" if is_outpaint else ("Run Hires. Fix" if is_hires_fix else "Run"))
|
| 234 |
+
|
| 235 |
+
prompt_lines = 6 if is_inpaint else 3
|
| 236 |
+
gallery_cols = 2 if is_txt2img else 1
|
| 237 |
+
gallery_height = 627 if is_txt2img else (505 if is_img2img else (510 if is_inpaint else (685 if is_outpaint else 610)))
|
| 238 |
+
|
| 239 |
+
updates = {
|
| 240 |
+
ui_components['image_input_col_imagegen']: gr.update(visible=not is_txt2img),
|
| 241 |
+
ui_components['input_image_imagegen']: gr.update(visible=(is_img2img or is_outpaint or is_hires_fix)),
|
| 242 |
+
ui_components['inpaint_box_imagegen']: gr.update(visible=is_inpaint),
|
| 243 |
+
ui_components['prompt_imagegen']: gr.update(lines=prompt_lines),
|
| 244 |
+
ui_components['neg_prompt_imagegen']: gr.update(lines=prompt_lines),
|
| 245 |
+
ui_components['aspect_ratio_row_imagegen']: gr.update(visible=is_txt2img),
|
| 246 |
+
ui_components['width_height_row_imagegen']: gr.update(visible=is_txt2img),
|
| 247 |
+
ui_components['denoise_row_imagegen']: gr.update(visible=(is_img2img or is_inpaint or is_hires_fix)),
|
| 248 |
+
ui_components['denoise_imagegen']: gr.update(value=denoise_val),
|
| 249 |
+
ui_components['grow_mask_by_imagegen']: gr.update(visible=is_inpaint),
|
| 250 |
+
ui_components['outpaint_pads_col_imagegen']: gr.update(visible=is_outpaint),
|
| 251 |
+
ui_components['hires_upscaler_row_imagegen']: gr.update(visible=is_hires_fix),
|
| 252 |
+
ui_components['run_imagegen']: gr.update(value=run_text),
|
| 253 |
+
ui_components['result_imagegen']: gr.update(columns=gallery_cols, height=gallery_height),
|
| 254 |
+
}
|
| 255 |
+
|
| 256 |
+
# Re-evaluate feature accordion visibility based on task + architecture intersection
|
| 257 |
+
type_map = {'Txt2Img': 'txt2img', 'Img2Img': 'img2img', 'Inpaint': 'inpaint', 'Outpaint': 'outpaint', 'Hires. Fix': 'hires_fix'}
|
| 258 |
+
current_task = type_map.get(type_val, 'txt2img')
|
| 259 |
+
|
| 260 |
+
m_type = MODEL_TYPE_MAP.get(model_name, "SDXL") if model_name else "SDXL"
|
| 261 |
+
architectures_dict = ARCHITECTURES_CONFIG.get('architectures', {})
|
| 262 |
+
arch_model_type = architectures_dict.get(m_type, {}).get("model_type", m_type.lower().replace(" ", "").replace(".", ""))
|
| 263 |
+
|
| 264 |
+
arch_enabled_chains = FEATURES_CONFIG.get(arch_model_type, {}).get('enabled_chains', [])
|
| 265 |
+
task_enabled_chains = TASK_FEATURES_CONFIG.get(current_task, {}).get('enabled_chains', [])
|
| 266 |
+
enabled_chains = [c for c in arch_enabled_chains if c in task_enabled_chains]
|
| 267 |
+
|
| 268 |
+
prefix = 'imagegen'
|
| 269 |
+
accordion_chain_map = {
|
| 270 |
+
f'lora_accordion_{prefix}': 'lora',
|
| 271 |
+
f'controlnet_accordion_{prefix}': 'controlnet',
|
| 272 |
+
f'anima_controlnet_lllite_accordion_{prefix}': 'anima_controlnet_lllite',
|
| 273 |
+
f'diffsynth_controlnet_accordion_{prefix}': 'diffsynth_controlnet',
|
| 274 |
+
f'krea2_controlnet_accordion_{prefix}': 'krea2_controlnet',
|
| 275 |
+
f'ipadapter_accordion_{prefix}': 'ipadapter',
|
| 276 |
+
f'sd3_ipadapter_accordion_{prefix}': 'sd3_ipadapter',
|
| 277 |
+
f'flux1_ipadapter_accordion_{prefix}': 'flux1_ipadapter',
|
| 278 |
+
f'style_accordion_{prefix}': 'style',
|
| 279 |
+
f'embedding_accordion_{prefix}': 'embedding',
|
| 280 |
+
f'conditioning_accordion_{prefix}': 'conditioning',
|
| 281 |
+
f'reference_latent_accordion_{prefix}': 'reference_latent',
|
| 282 |
+
f'hidream_o1_reference_accordion_{prefix}': 'hidream_o1_reference',
|
| 283 |
+
f'joyai_reference_accordion_{prefix}': 'joyai_image',
|
| 284 |
+
f'krea2_identity_edit_accordion_{prefix}': 'krea2_identity_edit',
|
| 285 |
+
f'krea2_reference_edit_accordion_{prefix}': 'krea2_style_reference',
|
| 286 |
+
f'qwen_image_edit_accordion_{prefix}': 'qwen_image_edit',
|
| 287 |
+
f'boogu_edit_accordion_{prefix}': 'boogu_image_edit',
|
| 288 |
+
f'reference_image_accordion_{prefix}': 'reference_image',
|
| 289 |
+
f'pid_accordion_{prefix}': 'pid',
|
| 290 |
+
f'vae_accordion_{prefix}': 'vae',
|
| 291 |
+
}
|
| 292 |
+
for comp_key, chain_name in accordion_chain_map.items():
|
| 293 |
+
comp = ui_components.get(comp_key)
|
| 294 |
+
if comp:
|
| 295 |
+
updates[comp] = gr.update(visible=(chain_name in enabled_chains))
|
| 296 |
+
|
| 297 |
+
return updates
|
| 298 |
+
|
| 299 |
+
type_change_outputs = [
|
| 300 |
+
ui_components['image_input_col_imagegen'],
|
| 301 |
+
ui_components['input_image_imagegen'],
|
| 302 |
+
ui_components['inpaint_box_imagegen'],
|
| 303 |
+
ui_components['prompt_imagegen'],
|
| 304 |
+
ui_components['neg_prompt_imagegen'],
|
| 305 |
+
ui_components['aspect_ratio_row_imagegen'],
|
| 306 |
+
ui_components['width_height_row_imagegen'],
|
| 307 |
+
ui_components['denoise_row_imagegen'],
|
| 308 |
+
ui_components['denoise_imagegen'],
|
| 309 |
+
ui_components['grow_mask_by_imagegen'],
|
| 310 |
+
ui_components['outpaint_pads_col_imagegen'],
|
| 311 |
+
ui_components['hires_upscaler_row_imagegen'],
|
| 312 |
+
ui_components['run_imagegen'],
|
| 313 |
+
ui_components['result_imagegen'],
|
| 314 |
+
]
|
| 315 |
+
# Add feature accordion outputs for task-based visibility
|
| 316 |
+
accordion_keys = [
|
| 317 |
+
'lora_accordion_imagegen', 'controlnet_accordion_imagegen',
|
| 318 |
+
'anima_controlnet_lllite_accordion_imagegen', 'diffsynth_controlnet_accordion_imagegen',
|
| 319 |
+
'krea2_controlnet_accordion_imagegen', 'ipadapter_accordion_imagegen',
|
| 320 |
+
'sd3_ipadapter_accordion_imagegen', 'flux1_ipadapter_accordion_imagegen',
|
| 321 |
+
'style_accordion_imagegen', 'embedding_accordion_imagegen',
|
| 322 |
+
'conditioning_accordion_imagegen', 'reference_latent_accordion_imagegen',
|
| 323 |
+
'hidream_o1_reference_accordion_imagegen', 'joyai_reference_accordion_imagegen',
|
| 324 |
+
'krea2_identity_edit_accordion_imagegen', 'krea2_reference_edit_accordion_imagegen',
|
| 325 |
+
'qwen_image_edit_accordion_imagegen', 'boogu_edit_accordion_imagegen',
|
| 326 |
+
'reference_image_accordion_imagegen', 'pid_accordion_imagegen', 'vae_accordion_imagegen',
|
| 327 |
+
]
|
| 328 |
+
for key in accordion_keys:
|
| 329 |
+
if key in ui_components:
|
| 330 |
+
type_change_outputs.append(ui_components[key])
|
| 331 |
+
ui_components['type_imagegen'].change(
|
| 332 |
+
fn=on_type_change,
|
| 333 |
+
inputs=[ui_components['type_imagegen'], ui_components['base_model_imagegen']],
|
| 334 |
+
outputs=type_change_outputs,
|
| 335 |
+
show_progress=False
|
| 336 |
+
)
|
| 337 |
+
|
| 338 |
+
# Fullscreen view toggle for imagegen
|
| 339 |
+
if 'view_mode_imagegen' in ui_components:
|
| 340 |
+
def toggle_imagegen_fullscreen_view(view_mode):
|
| 341 |
+
is_fullscreen = (view_mode == "Fullscreen View")
|
| 342 |
+
other_elements_visible = not is_fullscreen
|
| 343 |
+
editor_height = 800 if is_fullscreen else 272
|
| 344 |
+
|
| 345 |
+
updates = {
|
| 346 |
+
ui_components['type_imagegen']: gr.update(visible=other_elements_visible),
|
| 347 |
+
ui_components['prompts_col_imagegen']: gr.update(visible=other_elements_visible),
|
| 348 |
+
ui_components['params_and_gallery_row_imagegen']: gr.update(visible=other_elements_visible),
|
| 349 |
+
ui_components['accordion_wrapper_imagegen']: gr.update(visible=other_elements_visible),
|
| 350 |
+
ui_components['input_image_dict_imagegen']: gr.update(height=editor_height),
|
| 351 |
+
}
|
| 352 |
+
|
| 353 |
+
model_and_run_rows = ui_components.get('model_and_run_row_imagegen', [])
|
| 354 |
+
for row in model_and_run_rows:
|
| 355 |
+
updates[row] = gr.update(visible=other_elements_visible)
|
| 356 |
+
|
| 357 |
+
return updates
|
| 358 |
+
|
| 359 |
+
output_components = [ui_components['type_imagegen']]
|
| 360 |
+
model_and_run_rows = ui_components.get('model_and_run_row_imagegen', [])
|
| 361 |
+
if isinstance(model_and_run_rows, list):
|
| 362 |
+
output_components.extend(model_and_run_rows)
|
| 363 |
+
else:
|
| 364 |
+
output_components.append(model_and_run_rows)
|
| 365 |
+
|
| 366 |
+
output_components.extend([
|
| 367 |
+
ui_components['prompts_col_imagegen'],
|
| 368 |
+
ui_components['params_and_gallery_row_imagegen'],
|
| 369 |
+
ui_components['accordion_wrapper_imagegen'],
|
| 370 |
+
ui_components['input_image_dict_imagegen']
|
| 371 |
+
])
|
| 372 |
+
|
| 373 |
+
ui_components['view_mode_imagegen'].change(
|
| 374 |
+
fn=toggle_imagegen_fullscreen_view,
|
| 375 |
+
inputs=[ui_components['view_mode_imagegen']],
|
| 376 |
+
outputs=output_components,
|
| 377 |
+
show_progress=False
|
| 378 |
+
)
|
| 379 |
+
|
| 380 |
if 'view_mode_inpaint' in ui_components:
|
| 381 |
def toggle_inpaint_fullscreen_view(view_mode):
|
| 382 |
is_fullscreen = (view_mode == "Fullscreen View")
|
|
|
|
| 418 |
)
|
| 419 |
|
| 420 |
all_load_outputs = []
|
| 421 |
+
for prefix in prefixes:
|
| 422 |
if f'controlnet_types_{prefix}' in ui_components:
|
| 423 |
all_load_outputs.extend(ui_components[f'controlnet_types_{prefix}'])
|
| 424 |
all_load_outputs.extend(ui_components[f'controlnet_series_{prefix}'])
|
|
|
|
| 446 |
outputs=all_load_outputs
|
| 447 |
)
|
| 448 |
|
| 449 |
+
for prefix in prefixes:
|
| 450 |
aspect_ratio_dropdown = ui_components.get(f'aspect_ratio_{prefix}') or ui_components.get(f'{prefix}_aspect_ratio_dropdown')
|
| 451 |
width_component = ui_components.get(f'width_{prefix}') or ui_components.get(f'{prefix}_width')
|
| 452 |
height_component = ui_components.get(f'height_{prefix}') or ui_components.get(f'{prefix}_height')
|
ui/events/run_handlers.py
CHANGED
|
@@ -1,7 +1,21 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
from core.generation_logic import generate_image_wrapper
|
| 3 |
|
| 4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
run_inputs_map = {
|
| 6 |
'model_display_name': ui_components[f'base_model_{prefix}'],
|
| 7 |
'positive_prompt': ui_components.get(f'prompt_{prefix}') or ui_components.get(f'{prefix}_positive_prompt'),
|
|
@@ -13,29 +27,47 @@ def create_run_event(prefix: str, task_type: str, ui_components: dict):
|
|
| 13 |
'sampler': ui_components.get(f'sampler_{prefix}') or ui_components.get(f'{prefix}_sampler_name'),
|
| 14 |
'scheduler': ui_components.get(f'scheduler_{prefix}') or ui_components.get(f'{prefix}_scheduler'),
|
| 15 |
'zero_gpu_duration': ui_components.get(f'zero_gpu_{prefix}'),
|
| 16 |
-
'guidance': ui_components.get(f'guidance_{prefix}'),
|
| 17 |
-
'task_type': gr.State(task_type)
|
| 18 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
|
| 20 |
if ui_components.get(f'pid_settings_{prefix}'):
|
| 21 |
run_inputs_map['pid_settings'] = ui_components[f'pid_settings_{prefix}']
|
| 22 |
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
})
|
| 28 |
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
'
|
| 32 |
-
'
|
| 33 |
-
'
|
| 34 |
-
|
| 35 |
-
if
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
|
| 40 |
lora_data_components = ui_components.get(f'all_lora_components_flat_{prefix}', [])
|
| 41 |
controlnet_data_components = ui_components.get(f'all_controlnet_components_flat_{prefix}', [])
|
|
@@ -103,6 +135,9 @@ def create_run_event(prefix: str, task_type: str, ui_components: dict):
|
|
| 103 |
assign_chain_data('boogu_edit_data', boogu_edit_data_components)
|
| 104 |
assign_chain_data('reference_image_data', reference_image_data_components)
|
| 105 |
|
|
|
|
|
|
|
|
|
|
| 106 |
return ui_dict
|
| 107 |
|
| 108 |
run_btn = ui_components.get(f'run_{prefix}') or ui_components.get(f'{prefix}_run_button')
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
from core.generation_logic import generate_image_wrapper
|
| 3 |
|
| 4 |
+
TYPE_TASK_MAP = {
|
| 5 |
+
'Txt2Img': 'txt2img',
|
| 6 |
+
'Img2Img': 'img2img',
|
| 7 |
+
'Inpaint': 'inpaint',
|
| 8 |
+
'Outpaint': 'outpaint',
|
| 9 |
+
'Hires. Fix': 'hires_fix'
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
def create_run_event(prefix: str, task_type: str = None, ui_components: dict = None):
|
| 13 |
+
if ui_components is None and isinstance(task_type, dict):
|
| 14 |
+
ui_components = task_type
|
| 15 |
+
task_type = None
|
| 16 |
+
|
| 17 |
+
type_comp = ui_components.get(f'type_{prefix}')
|
| 18 |
+
|
| 19 |
run_inputs_map = {
|
| 20 |
'model_display_name': ui_components[f'base_model_{prefix}'],
|
| 21 |
'positive_prompt': ui_components.get(f'prompt_{prefix}') or ui_components.get(f'{prefix}_positive_prompt'),
|
|
|
|
| 27 |
'sampler': ui_components.get(f'sampler_{prefix}') or ui_components.get(f'{prefix}_sampler_name'),
|
| 28 |
'scheduler': ui_components.get(f'scheduler_{prefix}') or ui_components.get(f'{prefix}_scheduler'),
|
| 29 |
'zero_gpu_duration': ui_components.get(f'zero_gpu_{prefix}'),
|
|
|
|
|
|
|
| 30 |
}
|
| 31 |
+
|
| 32 |
+
if type_comp:
|
| 33 |
+
run_inputs_map['ui_type'] = type_comp
|
| 34 |
+
elif task_type:
|
| 35 |
+
run_inputs_map['task_type'] = gr.State(task_type)
|
| 36 |
|
| 37 |
if ui_components.get(f'pid_settings_{prefix}'):
|
| 38 |
run_inputs_map['pid_settings'] = ui_components[f'pid_settings_{prefix}']
|
| 39 |
|
| 40 |
+
# Generic / Txt2Img inputs
|
| 41 |
+
if ui_components.get(f'width_{prefix}') or ui_components.get(f'{prefix}_width'):
|
| 42 |
+
run_inputs_map['width'] = ui_components.get(f'width_{prefix}') or ui_components.get(f'{prefix}_width')
|
| 43 |
+
if ui_components.get(f'height_{prefix}') or ui_components.get(f'{prefix}_height'):
|
| 44 |
+
run_inputs_map['height'] = ui_components.get(f'height_{prefix}') or ui_components.get(f'{prefix}_height')
|
| 45 |
|
| 46 |
+
# Task specific inputs
|
| 47 |
+
if ui_components.get(f'input_image_{prefix}'):
|
| 48 |
+
run_inputs_map['img2img_image'] = ui_components[f'input_image_{prefix}']
|
| 49 |
+
run_inputs_map['outpaint_image'] = ui_components[f'input_image_{prefix}']
|
| 50 |
+
run_inputs_map['hires_image'] = ui_components[f'input_image_{prefix}']
|
| 51 |
+
|
| 52 |
+
if ui_components.get(f'denoise_{prefix}'):
|
| 53 |
+
run_inputs_map['denoise'] = ui_components[f'denoise_{prefix}']
|
| 54 |
+
run_inputs_map['img2img_denoise'] = ui_components[f'denoise_{prefix}']
|
| 55 |
+
run_inputs_map['inpaint_denoise'] = ui_components[f'denoise_{prefix}']
|
| 56 |
+
run_inputs_map['hires_denoise'] = ui_components[f'denoise_{prefix}']
|
| 57 |
+
|
| 58 |
+
if ui_components.get(f'input_image_dict_{prefix}'):
|
| 59 |
+
run_inputs_map['inpaint_image_dict'] = ui_components[f'input_image_dict_{prefix}']
|
| 60 |
+
if ui_components.get(f'grow_mask_by_{prefix}'):
|
| 61 |
+
run_inputs_map['grow_mask_by'] = ui_components[f'grow_mask_by_{prefix}']
|
| 62 |
+
|
| 63 |
+
if ui_components.get(f'left_{prefix}'): run_inputs_map['left'] = ui_components[f'left_{prefix}']
|
| 64 |
+
if ui_components.get(f'right_{prefix}'): run_inputs_map['right'] = ui_components[f'right_{prefix}']
|
| 65 |
+
if ui_components.get(f'top_{prefix}'): run_inputs_map['top'] = ui_components[f'top_{prefix}']
|
| 66 |
+
if ui_components.get(f'bottom_{prefix}'): run_inputs_map['bottom'] = ui_components[f'bottom_{prefix}']
|
| 67 |
+
if ui_components.get(f'feathering_{prefix}'): run_inputs_map['feathering'] = ui_components[f'feathering_{prefix}']
|
| 68 |
+
|
| 69 |
+
if ui_components.get(f'hires_upscaler_{prefix}'): run_inputs_map['hires_upscaler'] = ui_components[f'hires_upscaler_{prefix}']
|
| 70 |
+
if ui_components.get(f'hires_scale_by_{prefix}'): run_inputs_map['hires_scale_by'] = ui_components[f'hires_scale_by_{prefix}']
|
| 71 |
|
| 72 |
lora_data_components = ui_components.get(f'all_lora_components_flat_{prefix}', [])
|
| 73 |
controlnet_data_components = ui_components.get(f'all_controlnet_components_flat_{prefix}', [])
|
|
|
|
| 135 |
assign_chain_data('boogu_edit_data', boogu_edit_data_components)
|
| 136 |
assign_chain_data('reference_image_data', reference_image_data_components)
|
| 137 |
|
| 138 |
+
if 'ui_type' in ui_dict:
|
| 139 |
+
ui_dict['task_type'] = TYPE_TASK_MAP.get(ui_dict['ui_type'], 'txt2img')
|
| 140 |
+
|
| 141 |
return ui_dict
|
| 142 |
|
| 143 |
run_btn = ui_components.get(f'run_{prefix}') or ui_components.get(f'{prefix}_run_button')
|
ui/{shared/inpaint_ui.py → imagegen_ui.py}
RENAMED
|
@@ -1,125 +1,197 @@
|
|
| 1 |
-
import gradio as gr
|
| 2 |
-
from core.settings import MODEL_MAP_CHECKPOINT, MODEL_DEFAULTS_CONFIG
|
| 3 |
-
from .
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
components[f'
|
| 41 |
-
|
| 42 |
-
with gr.Row() as
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
components[f'
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
from core.settings import MODEL_MAP_CHECKPOINT, MODEL_DEFAULTS_CONFIG
|
| 3 |
+
from comfy_integration.nodes import SAMPLER_CHOICES, SCHEDULER_CHOICES
|
| 4 |
+
from .shared.ui_components import (
|
| 5 |
+
RESOLUTION_MAP,
|
| 6 |
+
create_lora_settings_ui,
|
| 7 |
+
create_controlnet_ui, create_anima_controlnet_lllite_ui, create_diffsynth_controlnet_ui, create_krea2_controlnet_ui, create_ipadapter_ui, create_embedding_ui,
|
| 8 |
+
create_conditioning_ui, create_vae_override_ui,
|
| 9 |
+
create_model_architecture_filter_ui, create_category_filter_ui,
|
| 10 |
+
create_sd3_ipadapter_ui, create_flux1_ipadapter_ui, create_style_ui,
|
| 11 |
+
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, create_boogu_edit_ui,
|
| 12 |
+
create_pid_ui
|
| 13 |
+
)
|
| 14 |
+
|
| 15 |
+
default_vals = MODEL_DEFAULTS_CONFIG.get('Default', {})
|
| 16 |
+
DEFAULT_STEPS = default_vals.get('steps', 20)
|
| 17 |
+
DEFAULT_CFG = default_vals.get('cfg', 5.0)
|
| 18 |
+
DEFAULT_SAMPLER = default_vals.get('sampler_name', 'euler')
|
| 19 |
+
DEFAULT_SCHEDULER = default_vals.get('scheduler', 'simple')
|
| 20 |
+
DEFAULT_POS_PROMPT = default_vals.get('positive_prompt', '')
|
| 21 |
+
DEFAULT_NEG_PROMPT = default_vals.get('negative_prompt', '')
|
| 22 |
+
|
| 23 |
+
TYPE_CHOICES = ["Txt2Img", "Img2Img", "Inpaint", "Outpaint", "Hires. Fix"]
|
| 24 |
+
|
| 25 |
+
def create_ui():
|
| 26 |
+
"""Creates the unified UI components for ImageGen."""
|
| 27 |
+
prefix = "imagegen"
|
| 28 |
+
components = {}
|
| 29 |
+
|
| 30 |
+
with gr.Column():
|
| 31 |
+
components[f'type_{prefix}'] = gr.Radio(
|
| 32 |
+
choices=TYPE_CHOICES,
|
| 33 |
+
value="Txt2Img",
|
| 34 |
+
label="Task",
|
| 35 |
+
interactive=True
|
| 36 |
+
)
|
| 37 |
+
|
| 38 |
+
with gr.Row() as arch_row:
|
| 39 |
+
components.update(create_model_architecture_filter_ui(prefix))
|
| 40 |
+
components[f'arch_row_{prefix}'] = arch_row
|
| 41 |
+
|
| 42 |
+
with gr.Row() as model_and_run_row:
|
| 43 |
+
components.update(create_category_filter_ui(prefix))
|
| 44 |
+
components[f'base_model_{prefix}'] = gr.Dropdown(
|
| 45 |
+
label="Base Model",
|
| 46 |
+
choices=list(MODEL_MAP_CHECKPOINT.keys()),
|
| 47 |
+
value=list(MODEL_MAP_CHECKPOINT.keys())[0],
|
| 48 |
+
scale=3,
|
| 49 |
+
allow_custom_value=True
|
| 50 |
+
)
|
| 51 |
+
with gr.Column(scale=1):
|
| 52 |
+
components[f'run_{prefix}'] = gr.Button("Run", variant="primary")
|
| 53 |
+
components[f'model_and_run_row_{prefix}'] = [arch_row, model_and_run_row]
|
| 54 |
+
|
| 55 |
+
with gr.Row() as inputs_prompts_row:
|
| 56 |
+
with gr.Column(scale=1, visible=False) as image_input_col:
|
| 57 |
+
components[f'input_image_{prefix}'] = gr.Image(
|
| 58 |
+
type="pil",
|
| 59 |
+
label="Input Image (No Scaling)",
|
| 60 |
+
height=255,
|
| 61 |
+
visible=False
|
| 62 |
+
)
|
| 63 |
+
with gr.Column(visible=False) as inpaint_box:
|
| 64 |
+
components[f'view_mode_{prefix}'] = gr.Radio(
|
| 65 |
+
["Normal View", "Fullscreen View"],
|
| 66 |
+
label="Editor View",
|
| 67 |
+
value="Normal View",
|
| 68 |
+
interactive=True
|
| 69 |
+
)
|
| 70 |
+
components[f'input_image_dict_{prefix}'] = gr.ImageEditor(
|
| 71 |
+
type="pil",
|
| 72 |
+
label="Image & Mask (No Scaling)",
|
| 73 |
+
height=272
|
| 74 |
+
)
|
| 75 |
+
components[f'inpaint_box_{prefix}'] = inpaint_box
|
| 76 |
+
components[f'image_input_col_{prefix}'] = image_input_col
|
| 77 |
+
|
| 78 |
+
with gr.Column(scale=2) as prompts_col:
|
| 79 |
+
components[f'prompt_{prefix}'] = gr.Text(label="Prompt", lines=3, value=DEFAULT_POS_PROMPT)
|
| 80 |
+
components[f'neg_prompt_{prefix}'] = gr.Text(label="Negative prompt", lines=3, value=DEFAULT_NEG_PROMPT)
|
| 81 |
+
components[f'prompts_col_{prefix}'] = prompts_col
|
| 82 |
+
components[f'inputs_prompts_row_{prefix}'] = inputs_prompts_row
|
| 83 |
+
|
| 84 |
+
with gr.Row() as params_and_gallery_row:
|
| 85 |
+
with gr.Column(scale=1) as params_col:
|
| 86 |
+
# Txt2Img parameters
|
| 87 |
+
with gr.Row(visible=True) as aspect_ratio_row:
|
| 88 |
+
components[f'aspect_ratio_{prefix}'] = gr.Dropdown(
|
| 89 |
+
label="Aspect Ratio",
|
| 90 |
+
choices=list(RESOLUTION_MAP.get('sdxl', {}).keys()),
|
| 91 |
+
value="1:1 (Square)",
|
| 92 |
+
interactive=True,
|
| 93 |
+
allow_custom_value=True
|
| 94 |
+
)
|
| 95 |
+
components[f'aspect_ratio_row_{prefix}'] = aspect_ratio_row
|
| 96 |
+
|
| 97 |
+
with gr.Row(visible=True) as width_height_row:
|
| 98 |
+
components[f'width_{prefix}'] = gr.Number(label="Width", value=1024, interactive=True)
|
| 99 |
+
components[f'height_{prefix}'] = gr.Number(label="Height", value=1024, interactive=True)
|
| 100 |
+
components[f'width_height_row_{prefix}'] = width_height_row
|
| 101 |
+
|
| 102 |
+
# Img2Img / Inpaint / Hires. Fix Denoise parameter & Inpaint Grow Mask By parameter
|
| 103 |
+
with gr.Row(visible=False) as denoise_row:
|
| 104 |
+
components[f'denoise_{prefix}'] = gr.Slider(
|
| 105 |
+
label="Denoise Strength",
|
| 106 |
+
minimum=0.0,
|
| 107 |
+
maximum=1.0,
|
| 108 |
+
step=0.01,
|
| 109 |
+
value=0.7
|
| 110 |
+
)
|
| 111 |
+
components[f'grow_mask_by_{prefix}'] = gr.Slider(
|
| 112 |
+
label="Grow Mask By",
|
| 113 |
+
minimum=0,
|
| 114 |
+
maximum=64,
|
| 115 |
+
step=1,
|
| 116 |
+
value=6,
|
| 117 |
+
visible=False
|
| 118 |
+
)
|
| 119 |
+
components[f'denoise_row_{prefix}'] = denoise_row
|
| 120 |
+
|
| 121 |
+
# Outpaint Pad & Feathering parameters
|
| 122 |
+
with gr.Column(visible=False) as outpaint_pads_col:
|
| 123 |
+
with gr.Row():
|
| 124 |
+
components[f'left_{prefix}'] = gr.Slider(label="Pad Left", minimum=0, maximum=512, step=64, value=64)
|
| 125 |
+
components[f'right_{prefix}'] = gr.Slider(label="Pad Right", minimum=0, maximum=512, step=64, value=64)
|
| 126 |
+
with gr.Row():
|
| 127 |
+
components[f'top_{prefix}'] = gr.Slider(label="Pad Top", minimum=0, maximum=512, step=64, value=64)
|
| 128 |
+
components[f'bottom_{prefix}'] = gr.Slider(label="Pad Bottom", minimum=0, maximum=512, step=64, value=64)
|
| 129 |
+
components[f'feathering_{prefix}'] = gr.Slider(label="Feathering / Grow Mask", minimum=0, maximum=100, step=1, value=10)
|
| 130 |
+
components[f'outpaint_pads_col_{prefix}'] = outpaint_pads_col
|
| 131 |
+
|
| 132 |
+
# Hires. Fix Upscaler parameters
|
| 133 |
+
with gr.Row(visible=False) as hires_upscaler_row:
|
| 134 |
+
components[f'hires_upscaler_{prefix}'] = gr.Dropdown(
|
| 135 |
+
label="Upscaler",
|
| 136 |
+
choices=["nearest-exact", "bilinear", "area", "bicubic", "bislerp"],
|
| 137 |
+
value="nearest-exact"
|
| 138 |
+
)
|
| 139 |
+
components[f'hires_scale_by_{prefix}'] = gr.Slider(
|
| 140 |
+
label="Upscale by",
|
| 141 |
+
minimum=1.0,
|
| 142 |
+
maximum=4.0,
|
| 143 |
+
step=0.1,
|
| 144 |
+
value=1.5
|
| 145 |
+
)
|
| 146 |
+
components[f'hires_upscaler_row_{prefix}'] = hires_upscaler_row
|
| 147 |
+
|
| 148 |
+
# Common parameters
|
| 149 |
+
with gr.Row():
|
| 150 |
+
components[f'sampler_{prefix}'] = gr.Dropdown(
|
| 151 |
+
label="Sampler",
|
| 152 |
+
choices=SAMPLER_CHOICES,
|
| 153 |
+
value=DEFAULT_SAMPLER if DEFAULT_SAMPLER in SAMPLER_CHOICES else (SAMPLER_CHOICES[0] if SAMPLER_CHOICES else 'euler')
|
| 154 |
+
)
|
| 155 |
+
components[f'scheduler_{prefix}'] = gr.Dropdown(
|
| 156 |
+
label="Scheduler",
|
| 157 |
+
choices=SCHEDULER_CHOICES,
|
| 158 |
+
value=DEFAULT_SCHEDULER if DEFAULT_SCHEDULER in SCHEDULER_CHOICES else (SCHEDULER_CHOICES[0] if SCHEDULER_CHOICES else 'simple')
|
| 159 |
+
)
|
| 160 |
+
with gr.Row():
|
| 161 |
+
components[f'steps_{prefix}'] = gr.Slider(label="Steps", minimum=1, maximum=100, step=1, value=DEFAULT_STEPS)
|
| 162 |
+
components[f'cfg_{prefix}'] = gr.Slider(label="CFG Scale", minimum=1.0, maximum=20.0, step=0.1, value=DEFAULT_CFG)
|
| 163 |
+
with gr.Row():
|
| 164 |
+
components[f'seed_{prefix}'] = gr.Number(label="Seed (-1 for random)", value=-1, precision=0)
|
| 165 |
+
components[f'batch_size_{prefix}'] = gr.Slider(label="Batch Size", minimum=1, maximum=16, step=1, value=1)
|
| 166 |
+
with gr.Row():
|
| 167 |
+
components[f'zero_gpu_{prefix}'] = gr.Number(label="ZeroGPU Duration (s)", value=60, placeholder="Default: 60s, Max: 120s", info="Optional: Set how long to reserve the GPU. Longer jobs may need more time.")
|
| 168 |
+
|
| 169 |
+
with gr.Column(scale=1):
|
| 170 |
+
components[f'result_{prefix}'] = gr.Gallery(label="Result", show_label=False, columns=2, object_fit="contain", height=627)
|
| 171 |
+
components[f'params_and_gallery_row_{prefix}'] = params_and_gallery_row
|
| 172 |
+
|
| 173 |
+
with gr.Column() as accordion_wrapper:
|
| 174 |
+
components.update(create_lora_settings_ui(prefix))
|
| 175 |
+
components.update(create_controlnet_ui(prefix))
|
| 176 |
+
components.update(create_anima_controlnet_lllite_ui(prefix))
|
| 177 |
+
components.update(create_diffsynth_controlnet_ui(prefix))
|
| 178 |
+
components.update(create_krea2_controlnet_ui(prefix))
|
| 179 |
+
components.update(create_ipadapter_ui(prefix))
|
| 180 |
+
components.update(create_flux1_ipadapter_ui(prefix))
|
| 181 |
+
components.update(create_sd3_ipadapter_ui(prefix))
|
| 182 |
+
components.update(create_embedding_ui(prefix))
|
| 183 |
+
components.update(create_style_ui(prefix))
|
| 184 |
+
components.update(create_conditioning_ui(prefix))
|
| 185 |
+
components.update(create_reference_latent_ui(prefix))
|
| 186 |
+
components.update(create_hidream_o1_reference_ui(prefix))
|
| 187 |
+
components.update(create_joyai_reference_ui(prefix))
|
| 188 |
+
components.update(create_krea2_identity_edit_ui(prefix))
|
| 189 |
+
components.update(create_krea2_reference_edit_ui(prefix))
|
| 190 |
+
components.update(create_qwen_image_edit_ui(prefix))
|
| 191 |
+
components.update(create_boogu_edit_ui(prefix))
|
| 192 |
+
components.update(create_reference_image_ui(prefix))
|
| 193 |
+
components.update(create_vae_override_ui(prefix))
|
| 194 |
+
components.update(create_pid_ui(prefix))
|
| 195 |
+
components[f'accordion_wrapper_{prefix}'] = accordion_wrapper
|
| 196 |
+
|
| 197 |
+
return components
|
ui/layout.py
CHANGED
|
@@ -2,7 +2,7 @@ import os
|
|
| 2 |
import gradio as gr
|
| 3 |
from core.settings import *
|
| 4 |
|
| 5 |
-
from .
|
| 6 |
|
| 7 |
MAX_DYNAMIC_CONTROLS = 10
|
| 8 |
|
|
@@ -14,26 +14,9 @@ def build_ui(event_handler_function):
|
|
| 14 |
gr.Markdown(
|
| 15 |
"This demo is a streamlined version of the [Comfy web UI](https://github.com/RioShiina47/comfy-webui)'s [ImageGen](https://huggingface.co/spaces/RioShiina/ImageGen) functionality. Support [High-Level MCP](https://rioshiina-imagegen.hf.space/gradio_api/mcp/) 🤖"
|
| 16 |
)
|
| 17 |
-
|
| 18 |
-
with gr.TabItem("Txt2Img", id=0):
|
| 19 |
-
ui_components.update(txt2img_ui.create_ui())
|
| 20 |
-
|
| 21 |
-
with gr.TabItem("Img2Img", id=1):
|
| 22 |
-
ui_components.update(img2img_ui.create_ui())
|
| 23 |
-
|
| 24 |
-
with gr.TabItem("Inpaint", id=2):
|
| 25 |
-
ui_components.update(inpaint_ui.create_ui())
|
| 26 |
-
|
| 27 |
-
with gr.TabItem("Outpaint", id=3):
|
| 28 |
-
ui_components.update(outpaint_ui.create_ui())
|
| 29 |
-
|
| 30 |
-
with gr.TabItem("Hires. Fix", id=4):
|
| 31 |
-
ui_components.update(hires_fix_ui.create_ui())
|
| 32 |
-
|
| 33 |
-
ui_components["tabs"] = tabs
|
| 34 |
-
ui_components["image_gen_tabs"] = tabs
|
| 35 |
|
| 36 |
-
gr.Markdown("<div style='text-align:
|
| 37 |
|
| 38 |
event_handler_function(ui_components, demo)
|
| 39 |
|
|
@@ -54,5 +37,6 @@ def build_ui(event_handler_function):
|
|
| 54 |
for fn in demo.fns.values():
|
| 55 |
if getattr(fn, "api_name", None) not in high_level_names:
|
| 56 |
fn.show_api = False
|
|
|
|
| 57 |
|
| 58 |
return demo
|
|
|
|
| 2 |
import gradio as gr
|
| 3 |
from core.settings import *
|
| 4 |
|
| 5 |
+
from .imagegen_ui import create_ui as create_imagegen_ui
|
| 6 |
|
| 7 |
MAX_DYNAMIC_CONTROLS = 10
|
| 8 |
|
|
|
|
| 14 |
gr.Markdown(
|
| 15 |
"This demo is a streamlined version of the [Comfy web UI](https://github.com/RioShiina47/comfy-webui)'s [ImageGen](https://huggingface.co/spaces/RioShiina/ImageGen) functionality. Support [High-Level MCP](https://rioshiina-imagegen.hf.space/gradio_api/mcp/) 🤖"
|
| 16 |
)
|
| 17 |
+
ui_components.update(create_imagegen_ui())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
+
gr.Markdown("<div style='text-align: left; margin-top: 20px;'>Made by RioShiina with ❤️<br><a href='https://github.com/RioShiina47' target='_blank'>GitHub</a> | <a href='https://huggingface.co/RioShiina' target='_blank'>Hugging Face</a> | <a href='https://civitai.com/user/RioShiina' target='_blank'>Civitai</a></div>")
|
| 20 |
|
| 21 |
event_handler_function(ui_components, demo)
|
| 22 |
|
|
|
|
| 37 |
for fn in demo.fns.values():
|
| 38 |
if getattr(fn, "api_name", None) not in high_level_names:
|
| 39 |
fn.show_api = False
|
| 40 |
+
fn.api_name = False
|
| 41 |
|
| 42 |
return demo
|
ui/shared/hires_fix_ui.py
DELETED
|
@@ -1,111 +0,0 @@
|
|
| 1 |
-
import gradio as gr
|
| 2 |
-
from core.settings import MODEL_MAP_CHECKPOINT, MODEL_DEFAULTS_CONFIG
|
| 3 |
-
from comfy_integration.nodes import SAMPLER_CHOICES, SCHEDULER_CHOICES
|
| 4 |
-
from .ui_components import (
|
| 5 |
-
create_lora_settings_ui,
|
| 6 |
-
create_controlnet_ui, create_anima_controlnet_lllite_ui, create_diffsynth_controlnet_ui, create_krea2_controlnet_ui, create_ipadapter_ui, create_embedding_ui,
|
| 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, create_boogu_edit_ui
|
| 11 |
-
)
|
| 12 |
-
|
| 13 |
-
default_vals = MODEL_DEFAULTS_CONFIG.get('Default', {})
|
| 14 |
-
DEFAULT_STEPS = default_vals.get('steps', 20)
|
| 15 |
-
DEFAULT_CFG = default_vals.get('cfg', 5.0)
|
| 16 |
-
DEFAULT_SAMPLER = default_vals.get('sampler_name', 'euler')
|
| 17 |
-
DEFAULT_SCHEDULER = default_vals.get('scheduler', 'simple')
|
| 18 |
-
DEFAULT_POS_PROMPT = default_vals.get('positive_prompt', '')
|
| 19 |
-
DEFAULT_NEG_PROMPT = default_vals.get('negative_prompt', '')
|
| 20 |
-
|
| 21 |
-
def create_ui():
|
| 22 |
-
prefix = "hires_fix"
|
| 23 |
-
components = {}
|
| 24 |
-
|
| 25 |
-
with gr.Column():
|
| 26 |
-
components.update(create_model_architecture_filter_ui(prefix))
|
| 27 |
-
|
| 28 |
-
with gr.Row():
|
| 29 |
-
components.update(create_category_filter_ui(prefix))
|
| 30 |
-
components[f'base_model_{prefix}'] = gr.Dropdown(
|
| 31 |
-
label="Base Model",
|
| 32 |
-
choices=list(MODEL_MAP_CHECKPOINT.keys()),
|
| 33 |
-
value=list(MODEL_MAP_CHECKPOINT.keys())[0],
|
| 34 |
-
scale=3,
|
| 35 |
-
allow_custom_value=True
|
| 36 |
-
)
|
| 37 |
-
with gr.Column(scale=1):
|
| 38 |
-
components[f'run_{prefix}'] = gr.Button("Run Hires. Fix", variant="primary")
|
| 39 |
-
|
| 40 |
-
with gr.Row():
|
| 41 |
-
with gr.Column(scale=1):
|
| 42 |
-
components[f'input_image_{prefix}'] = gr.Image(type="pil", label="Input Image (No Scaling)", height=255)
|
| 43 |
-
with gr.Column(scale=2):
|
| 44 |
-
components[f'prompt_{prefix}'] = gr.Text(label="Prompt", lines=3, value=DEFAULT_POS_PROMPT)
|
| 45 |
-
components[f'neg_prompt_{prefix}'] = gr.Text(label="Negative prompt", lines=3, value=DEFAULT_NEG_PROMPT)
|
| 46 |
-
|
| 47 |
-
with gr.Row():
|
| 48 |
-
with gr.Column(scale=1):
|
| 49 |
-
with gr.Row():
|
| 50 |
-
components[f'hires_upscaler_{prefix}'] = gr.Dropdown(
|
| 51 |
-
label="Upscaler",
|
| 52 |
-
choices=["nearest-exact", "bilinear", "area", "bicubic", "bislerp"],
|
| 53 |
-
value="nearest-exact"
|
| 54 |
-
)
|
| 55 |
-
components[f'hires_scale_by_{prefix}'] = gr.Slider(
|
| 56 |
-
label="Upscale by", minimum=1.0, maximum=4.0, step=0.1, value=1.5
|
| 57 |
-
)
|
| 58 |
-
|
| 59 |
-
with gr.Row():
|
| 60 |
-
components[f'denoise_{prefix}'] = gr.Slider(label="Denoise Strength", minimum=0.0, maximum=1.0, step=0.01, value=0.55)
|
| 61 |
-
|
| 62 |
-
with gr.Row():
|
| 63 |
-
components[f'sampler_{prefix}'] = gr.Dropdown(
|
| 64 |
-
label="Sampler",
|
| 65 |
-
choices=SAMPLER_CHOICES,
|
| 66 |
-
value=DEFAULT_SAMPLER if DEFAULT_SAMPLER in SAMPLER_CHOICES else (SAMPLER_CHOICES[0] if SAMPLER_CHOICES else 'euler')
|
| 67 |
-
)
|
| 68 |
-
components[f'scheduler_{prefix}'] = gr.Dropdown(
|
| 69 |
-
label="Scheduler",
|
| 70 |
-
choices=SCHEDULER_CHOICES,
|
| 71 |
-
value=DEFAULT_SCHEDULER if DEFAULT_SCHEDULER in SCHEDULER_CHOICES else (SCHEDULER_CHOICES[0] if SCHEDULER_CHOICES else 'simple')
|
| 72 |
-
)
|
| 73 |
-
with gr.Row():
|
| 74 |
-
components[f'steps_{prefix}'] = gr.Slider(label="Steps", minimum=1, maximum=100, step=1, value=DEFAULT_STEPS)
|
| 75 |
-
components[f'cfg_{prefix}'] = gr.Slider(label="CFG Scale", minimum=1.0, maximum=20.0, step=0.1, value=DEFAULT_CFG)
|
| 76 |
-
with gr.Row():
|
| 77 |
-
components[f'seed_{prefix}'] = gr.Number(label="Seed (-1 for random)", value=-1, precision=0)
|
| 78 |
-
components[f'batch_size_{prefix}'] = gr.Slider(label="Batch Size", minimum=1, maximum=16, step=1, value=1)
|
| 79 |
-
with gr.Row():
|
| 80 |
-
components[f'guidance_{prefix}'] = gr.Slider(label="Guidance (FLUX)", minimum=1.0, maximum=10.0, step=0.1, value=3.5, visible=False, interactive=True)
|
| 81 |
-
components[f'zero_gpu_{prefix}'] = gr.Number(label="ZeroGPU Duration (s)", value=None, placeholder="Default: 60s, Max: 120s", info="Optional: Set how long to reserve the GPU.")
|
| 82 |
-
|
| 83 |
-
components[f'width_{prefix}'] = gr.State(value=512)
|
| 84 |
-
components[f'height_{prefix}'] = gr.State(value=512)
|
| 85 |
-
|
| 86 |
-
with gr.Column(scale=1):
|
| 87 |
-
components[f'result_{prefix}'] = gr.Gallery(label="Result", show_label=False, columns=1, object_fit="contain", height=610)
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
components.update(create_lora_settings_ui(prefix))
|
| 91 |
-
components.update(create_controlnet_ui(prefix))
|
| 92 |
-
components.update(create_anima_controlnet_lllite_ui(prefix))
|
| 93 |
-
components.update(create_diffsynth_controlnet_ui(prefix))
|
| 94 |
-
components.update(create_krea2_controlnet_ui(prefix))
|
| 95 |
-
components.update(create_ipadapter_ui(prefix))
|
| 96 |
-
components.update(create_flux1_ipadapter_ui(prefix))
|
| 97 |
-
components.update(create_sd3_ipadapter_ui(prefix))
|
| 98 |
-
components.update(create_style_ui(prefix))
|
| 99 |
-
components.update(create_embedding_ui(prefix))
|
| 100 |
-
components.update(create_conditioning_ui(prefix))
|
| 101 |
-
components.update(create_reference_latent_ui(prefix))
|
| 102 |
-
components.update(create_hidream_o1_reference_ui(prefix))
|
| 103 |
-
components.update(create_joyai_reference_ui(prefix))
|
| 104 |
-
components.update(create_krea2_identity_edit_ui(prefix))
|
| 105 |
-
components.update(create_krea2_reference_edit_ui(prefix))
|
| 106 |
-
components.update(create_qwen_image_edit_ui(prefix))
|
| 107 |
-
components.update(create_boogu_edit_ui(prefix))
|
| 108 |
-
components.update(create_reference_image_ui(prefix))
|
| 109 |
-
components.update(create_vae_override_ui(prefix))
|
| 110 |
-
|
| 111 |
-
return components
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ui/shared/img2img_ui.py
DELETED
|
@@ -1,92 +0,0 @@
|
|
| 1 |
-
import gradio as gr
|
| 2 |
-
from core.settings import MODEL_MAP_CHECKPOINT, MODEL_DEFAULTS_CONFIG
|
| 3 |
-
from comfy_integration.nodes import SAMPLER_CHOICES, SCHEDULER_CHOICES
|
| 4 |
-
from .ui_components import (
|
| 5 |
-
create_lora_settings_ui,
|
| 6 |
-
create_controlnet_ui, create_anima_controlnet_lllite_ui, create_diffsynth_controlnet_ui, create_krea2_controlnet_ui, create_ipadapter_ui, create_embedding_ui,
|
| 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, create_boogu_edit_ui
|
| 11 |
-
)
|
| 12 |
-
|
| 13 |
-
default_vals = MODEL_DEFAULTS_CONFIG.get('Default', {})
|
| 14 |
-
DEFAULT_STEPS = default_vals.get('steps', 20)
|
| 15 |
-
DEFAULT_CFG = default_vals.get('cfg', 5.0)
|
| 16 |
-
DEFAULT_SAMPLER = default_vals.get('sampler_name', 'euler')
|
| 17 |
-
DEFAULT_SCHEDULER = default_vals.get('scheduler', 'simple')
|
| 18 |
-
DEFAULT_POS_PROMPT = default_vals.get('positive_prompt', '')
|
| 19 |
-
DEFAULT_NEG_PROMPT = default_vals.get('negative_prompt', '')
|
| 20 |
-
|
| 21 |
-
def create_ui():
|
| 22 |
-
prefix = "img2img"
|
| 23 |
-
components = {}
|
| 24 |
-
|
| 25 |
-
with gr.Column():
|
| 26 |
-
components.update(create_model_architecture_filter_ui(prefix))
|
| 27 |
-
|
| 28 |
-
with gr.Row():
|
| 29 |
-
components.update(create_category_filter_ui(prefix))
|
| 30 |
-
components[f'base_model_{prefix}'] = gr.Dropdown(label="Base Model", choices=list(MODEL_MAP_CHECKPOINT.keys()), value=list(MODEL_MAP_CHECKPOINT.keys())[0], scale=3, allow_custom_value=True)
|
| 31 |
-
with gr.Column(scale=1):
|
| 32 |
-
components[f'run_{prefix}'] = gr.Button("Run", variant="primary")
|
| 33 |
-
|
| 34 |
-
with gr.Row():
|
| 35 |
-
with gr.Column(scale=1):
|
| 36 |
-
components[f'input_image_{prefix}'] = gr.Image(type="pil", label="Input Image (No Scaling)", height=255)
|
| 37 |
-
|
| 38 |
-
with gr.Column(scale=2):
|
| 39 |
-
components[f'prompt_{prefix}'] = gr.Text(label="Prompt", lines=3, value=DEFAULT_POS_PROMPT)
|
| 40 |
-
components[f'neg_prompt_{prefix}'] = gr.Text(label="Negative prompt", lines=3, value=DEFAULT_NEG_PROMPT)
|
| 41 |
-
|
| 42 |
-
with gr.Row():
|
| 43 |
-
with gr.Column(scale=1):
|
| 44 |
-
components[f'denoise_{prefix}'] = gr.Slider(label="Denoise Strength", minimum=0.0, maximum=1.0, step=0.01, value=0.7)
|
| 45 |
-
|
| 46 |
-
with gr.Row():
|
| 47 |
-
components[f'sampler_{prefix}'] = gr.Dropdown(
|
| 48 |
-
label="Sampler",
|
| 49 |
-
choices=SAMPLER_CHOICES,
|
| 50 |
-
value=DEFAULT_SAMPLER if DEFAULT_SAMPLER in SAMPLER_CHOICES else (SAMPLER_CHOICES[0] if SAMPLER_CHOICES else 'euler')
|
| 51 |
-
)
|
| 52 |
-
components[f'scheduler_{prefix}'] = gr.Dropdown(
|
| 53 |
-
label="Scheduler",
|
| 54 |
-
choices=SCHEDULER_CHOICES,
|
| 55 |
-
value=DEFAULT_SCHEDULER if DEFAULT_SCHEDULER in SCHEDULER_CHOICES else (SCHEDULER_CHOICES[0] if SCHEDULER_CHOICES else 'simple')
|
| 56 |
-
)
|
| 57 |
-
with gr.Row():
|
| 58 |
-
components[f'steps_{prefix}'] = gr.Slider(label="Steps", minimum=1, maximum=100, step=1, value=DEFAULT_STEPS)
|
| 59 |
-
components[f'cfg_{prefix}'] = gr.Slider(label="CFG Scale", minimum=1.0, maximum=20.0, step=0.1, value=DEFAULT_CFG)
|
| 60 |
-
with gr.Row():
|
| 61 |
-
components[f'seed_{prefix}'] = gr.Number(label="Seed (-1 for random)", value=-1, precision=0)
|
| 62 |
-
components[f'batch_size_{prefix}'] = gr.Slider(label="Batch Size", minimum=1, maximum=16, step=1, value=1)
|
| 63 |
-
with gr.Row():
|
| 64 |
-
components[f'guidance_{prefix}'] = gr.Slider(label="Guidance (FLUX)", minimum=1.0, maximum=10.0, step=0.1, value=3.5, visible=False, interactive=True)
|
| 65 |
-
components[f'zero_gpu_{prefix}'] = gr.Number(label="ZeroGPU Duration (s)", value=None, placeholder="Default: 60s, Max: 120s", info="Optional: Set how long to reserve the GPU. Longer jobs may need more time.")
|
| 66 |
-
|
| 67 |
-
with gr.Column(scale=1):
|
| 68 |
-
components[f'result_{prefix}'] = gr.Gallery(label="Result", show_label=False, columns=1, object_fit="contain", height=505)
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
components.update(create_lora_settings_ui(prefix))
|
| 72 |
-
components.update(create_controlnet_ui(prefix))
|
| 73 |
-
components.update(create_anima_controlnet_lllite_ui(prefix))
|
| 74 |
-
components.update(create_diffsynth_controlnet_ui(prefix))
|
| 75 |
-
components.update(create_krea2_controlnet_ui(prefix))
|
| 76 |
-
components.update(create_ipadapter_ui(prefix))
|
| 77 |
-
components.update(create_flux1_ipadapter_ui(prefix))
|
| 78 |
-
components.update(create_sd3_ipadapter_ui(prefix))
|
| 79 |
-
components.update(create_embedding_ui(prefix))
|
| 80 |
-
components.update(create_style_ui(prefix))
|
| 81 |
-
components.update(create_conditioning_ui(prefix))
|
| 82 |
-
components.update(create_reference_latent_ui(prefix))
|
| 83 |
-
components.update(create_hidream_o1_reference_ui(prefix))
|
| 84 |
-
components.update(create_joyai_reference_ui(prefix))
|
| 85 |
-
components.update(create_krea2_identity_edit_ui(prefix))
|
| 86 |
-
components.update(create_krea2_reference_edit_ui(prefix))
|
| 87 |
-
components.update(create_qwen_image_edit_ui(prefix))
|
| 88 |
-
components.update(create_boogu_edit_ui(prefix))
|
| 89 |
-
components.update(create_reference_image_ui(prefix))
|
| 90 |
-
components.update(create_vae_override_ui(prefix))
|
| 91 |
-
|
| 92 |
-
return components
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ui/shared/outpaint_ui.py
DELETED
|
@@ -1,107 +0,0 @@
|
|
| 1 |
-
import gradio as gr
|
| 2 |
-
from core.settings import MODEL_MAP_CHECKPOINT, MODEL_DEFAULTS_CONFIG
|
| 3 |
-
from comfy_integration.nodes import SAMPLER_CHOICES, SCHEDULER_CHOICES
|
| 4 |
-
from .ui_components import (
|
| 5 |
-
create_lora_settings_ui,
|
| 6 |
-
create_controlnet_ui, create_anima_controlnet_lllite_ui, create_diffsynth_controlnet_ui, create_krea2_controlnet_ui, create_ipadapter_ui, create_embedding_ui,
|
| 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, create_boogu_edit_ui
|
| 11 |
-
)
|
| 12 |
-
|
| 13 |
-
default_vals = MODEL_DEFAULTS_CONFIG.get('Default', {})
|
| 14 |
-
DEFAULT_STEPS = default_vals.get('steps', 20)
|
| 15 |
-
DEFAULT_CFG = default_vals.get('cfg', 5.0)
|
| 16 |
-
DEFAULT_SAMPLER = default_vals.get('sampler_name', 'euler')
|
| 17 |
-
DEFAULT_SCHEDULER = default_vals.get('scheduler', 'simple')
|
| 18 |
-
DEFAULT_POS_PROMPT = default_vals.get('positive_prompt', '')
|
| 19 |
-
DEFAULT_NEG_PROMPT = default_vals.get('negative_prompt', '')
|
| 20 |
-
|
| 21 |
-
def create_ui():
|
| 22 |
-
prefix = "outpaint"
|
| 23 |
-
components = {}
|
| 24 |
-
|
| 25 |
-
with gr.Column():
|
| 26 |
-
components.update(create_model_architecture_filter_ui(prefix))
|
| 27 |
-
|
| 28 |
-
with gr.Row():
|
| 29 |
-
components.update(create_category_filter_ui(prefix))
|
| 30 |
-
components[f'base_model_{prefix}'] = gr.Dropdown(
|
| 31 |
-
label="Base Model",
|
| 32 |
-
choices=list(MODEL_MAP_CHECKPOINT.keys()),
|
| 33 |
-
value=list(MODEL_MAP_CHECKPOINT.keys())[0],
|
| 34 |
-
scale=3,
|
| 35 |
-
allow_custom_value=True
|
| 36 |
-
)
|
| 37 |
-
with gr.Column(scale=1):
|
| 38 |
-
components[f'run_{prefix}'] = gr.Button("Run Outpaint", variant="primary")
|
| 39 |
-
|
| 40 |
-
with gr.Row():
|
| 41 |
-
with gr.Column(scale=1):
|
| 42 |
-
components[f'input_image_{prefix}'] = gr.Image(type="pil", label="Input Image (No Scaling)", height=255)
|
| 43 |
-
with gr.Column(scale=2):
|
| 44 |
-
components[f'prompt_{prefix}'] = gr.Text(label="Prompt", lines=3, value=DEFAULT_POS_PROMPT)
|
| 45 |
-
components[f'neg_prompt_{prefix}'] = gr.Text(label="Negative prompt", lines=3, value=DEFAULT_NEG_PROMPT)
|
| 46 |
-
|
| 47 |
-
with gr.Row():
|
| 48 |
-
with gr.Column(scale=1):
|
| 49 |
-
with gr.Row():
|
| 50 |
-
components[f'left_{prefix}'] = gr.Slider(label="Pad Left", minimum=0, maximum=512, step=64, value=64)
|
| 51 |
-
components[f'right_{prefix}'] = gr.Slider(label="Pad Right", minimum=0, maximum=512, step=64, value=64)
|
| 52 |
-
with gr.Row():
|
| 53 |
-
components[f'top_{prefix}'] = gr.Slider(label="Pad Top", minimum=0, maximum=512, step=64, value=64)
|
| 54 |
-
components[f'bottom_{prefix}'] = gr.Slider(label="Pad Bottom", minimum=0, maximum=512, step=64, value=64)
|
| 55 |
-
|
| 56 |
-
components[f'feathering_{prefix}'] = gr.Slider(label="Feathering / Grow Mask", minimum=0, maximum=100, step=1, value=10)
|
| 57 |
-
|
| 58 |
-
with gr.Row():
|
| 59 |
-
components[f'sampler_{prefix}'] = gr.Dropdown(
|
| 60 |
-
label="Sampler",
|
| 61 |
-
choices=SAMPLER_CHOICES,
|
| 62 |
-
value=DEFAULT_SAMPLER if DEFAULT_SAMPLER in SAMPLER_CHOICES else (SAMPLER_CHOICES[0] if SAMPLER_CHOICES else 'euler')
|
| 63 |
-
)
|
| 64 |
-
components[f'scheduler_{prefix}'] = gr.Dropdown(
|
| 65 |
-
label="Scheduler",
|
| 66 |
-
choices=SCHEDULER_CHOICES,
|
| 67 |
-
value=DEFAULT_SCHEDULER if DEFAULT_SCHEDULER in SCHEDULER_CHOICES else (SCHEDULER_CHOICES[0] if SCHEDULER_CHOICES else 'simple')
|
| 68 |
-
)
|
| 69 |
-
with gr.Row():
|
| 70 |
-
components[f'steps_{prefix}'] = gr.Slider(label="Steps", minimum=1, maximum=100, step=1, value=DEFAULT_STEPS)
|
| 71 |
-
components[f'cfg_{prefix}'] = gr.Slider(label="CFG Scale", minimum=1.0, maximum=20.0, step=0.1, value=DEFAULT_CFG)
|
| 72 |
-
with gr.Row():
|
| 73 |
-
components[f'seed_{prefix}'] = gr.Number(label="Seed (-1 for random)", value=-1, precision=0)
|
| 74 |
-
components[f'batch_size_{prefix}'] = gr.Slider(label="Batch Size", minimum=1, maximum=16, step=1, value=1)
|
| 75 |
-
with gr.Row():
|
| 76 |
-
components[f'guidance_{prefix}'] = gr.Slider(label="Guidance (FLUX)", minimum=1.0, maximum=10.0, step=0.1, value=3.5, visible=False, interactive=True)
|
| 77 |
-
components[f'zero_gpu_{prefix}'] = gr.Number(label="ZeroGPU Duration (s)", value=None, placeholder="Default: 60s, Max: 120s", info="Optional: Set how long to reserve the GPU.")
|
| 78 |
-
|
| 79 |
-
components[f'width_{prefix}'] = gr.State(value=512)
|
| 80 |
-
components[f'height_{prefix}'] = gr.State(value=512)
|
| 81 |
-
|
| 82 |
-
with gr.Column(scale=1):
|
| 83 |
-
components[f'result_{prefix}'] = gr.Gallery(label="Result", show_label=False, columns=1, object_fit="contain", height=685)
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
components.update(create_lora_settings_ui(prefix))
|
| 87 |
-
components.update(create_controlnet_ui(prefix))
|
| 88 |
-
components.update(create_anima_controlnet_lllite_ui(prefix))
|
| 89 |
-
components.update(create_diffsynth_controlnet_ui(prefix))
|
| 90 |
-
components.update(create_krea2_controlnet_ui(prefix))
|
| 91 |
-
components.update(create_ipadapter_ui(prefix))
|
| 92 |
-
components.update(create_flux1_ipadapter_ui(prefix))
|
| 93 |
-
components.update(create_sd3_ipadapter_ui(prefix))
|
| 94 |
-
components.update(create_style_ui(prefix))
|
| 95 |
-
components.update(create_embedding_ui(prefix))
|
| 96 |
-
components.update(create_conditioning_ui(prefix))
|
| 97 |
-
components.update(create_reference_latent_ui(prefix))
|
| 98 |
-
components.update(create_hidream_o1_reference_ui(prefix))
|
| 99 |
-
components.update(create_joyai_reference_ui(prefix))
|
| 100 |
-
components.update(create_krea2_identity_edit_ui(prefix))
|
| 101 |
-
components.update(create_krea2_reference_edit_ui(prefix))
|
| 102 |
-
components.update(create_qwen_image_edit_ui(prefix))
|
| 103 |
-
components.update(create_boogu_edit_ui(prefix))
|
| 104 |
-
components.update(create_reference_image_ui(prefix))
|
| 105 |
-
components.update(create_vae_override_ui(prefix))
|
| 106 |
-
|
| 107 |
-
return components
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ui/shared/txt2img_ui.py
DELETED
|
@@ -1,66 +0,0 @@
|
|
| 1 |
-
import gradio as gr
|
| 2 |
-
from core.settings import MODEL_MAP_CHECKPOINT
|
| 3 |
-
from .ui_components import (
|
| 4 |
-
create_base_parameter_ui, create_lora_settings_ui,
|
| 5 |
-
create_controlnet_ui, create_anima_controlnet_lllite_ui, create_diffsynth_controlnet_ui, create_krea2_controlnet_ui, create_ipadapter_ui, create_embedding_ui,
|
| 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, create_boogu_edit_ui,
|
| 10 |
-
create_pid_ui
|
| 11 |
-
)
|
| 12 |
-
|
| 13 |
-
def create_ui():
|
| 14 |
-
"""Creates the UI components for the Txt2Img tab."""
|
| 15 |
-
prefix = "txt2img"
|
| 16 |
-
components = {}
|
| 17 |
-
|
| 18 |
-
with gr.Column():
|
| 19 |
-
components.update(create_model_architecture_filter_ui(prefix))
|
| 20 |
-
|
| 21 |
-
with gr.Row():
|
| 22 |
-
components.update(create_category_filter_ui(prefix))
|
| 23 |
-
components[f'base_model_{prefix}'] = gr.Dropdown(
|
| 24 |
-
label="Base Model",
|
| 25 |
-
choices=list(MODEL_MAP_CHECKPOINT.keys()),
|
| 26 |
-
value=list(MODEL_MAP_CHECKPOINT.keys())[0],
|
| 27 |
-
scale=3,
|
| 28 |
-
allow_custom_value=True
|
| 29 |
-
)
|
| 30 |
-
with gr.Column(scale=1):
|
| 31 |
-
components[f'run_{prefix}'] = gr.Button("Run", variant="primary")
|
| 32 |
-
|
| 33 |
-
components[f'prompt_{prefix}'] = gr.Text(label="Prompt", lines=3)
|
| 34 |
-
components[f'neg_prompt_{prefix}'] = gr.Text(label="Negative prompt", lines=3)
|
| 35 |
-
|
| 36 |
-
with gr.Row():
|
| 37 |
-
with gr.Column(scale=1):
|
| 38 |
-
param_defaults = {'w': 1024, 'h': 1024, 'cs_vis': False, 'cs_val': 1}
|
| 39 |
-
components.update(create_base_parameter_ui(prefix, param_defaults))
|
| 40 |
-
with gr.Column(scale=1):
|
| 41 |
-
components[f'result_{prefix}'] = gr.Gallery(label="Result", show_label=False, columns=2, object_fit="contain", height=627)
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
components.update(create_lora_settings_ui(prefix))
|
| 45 |
-
components.update(create_controlnet_ui(prefix))
|
| 46 |
-
components.update(create_anima_controlnet_lllite_ui(prefix))
|
| 47 |
-
components.update(create_diffsynth_controlnet_ui(prefix))
|
| 48 |
-
components.update(create_krea2_controlnet_ui(prefix))
|
| 49 |
-
components.update(create_ipadapter_ui(prefix))
|
| 50 |
-
components.update(create_flux1_ipadapter_ui(prefix))
|
| 51 |
-
components.update(create_sd3_ipadapter_ui(prefix))
|
| 52 |
-
components.update(create_embedding_ui(prefix))
|
| 53 |
-
components.update(create_style_ui(prefix))
|
| 54 |
-
components.update(create_conditioning_ui(prefix))
|
| 55 |
-
components.update(create_reference_latent_ui(prefix))
|
| 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_boogu_edit_ui(prefix))
|
| 62 |
-
components.update(create_reference_image_ui(prefix))
|
| 63 |
-
components.update(create_vae_override_ui(prefix))
|
| 64 |
-
components.update(create_pid_ui(prefix))
|
| 65 |
-
|
| 66 |
-
return components
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ui/shared/ui_components.py
CHANGED
|
@@ -114,8 +114,7 @@ def create_base_parameter_ui(prefix, defaults=None):
|
|
| 114 |
components[f'seed_{prefix}'] = gr.Number(label="Seed (-1 for random)", value=-1, precision=0)
|
| 115 |
components[f'batch_size_{prefix}'] = gr.Slider(label="Batch Size", minimum=1, maximum=16, step=1, value=1)
|
| 116 |
with gr.Row():
|
| 117 |
-
components[f'
|
| 118 |
-
components[f'zero_gpu_{prefix}'] = gr.Number(label="ZeroGPU Duration (s)", value=None, placeholder="Default: 60s, Max: 120s", info="Optional: Set how long to reserve the GPU.")
|
| 119 |
|
| 120 |
return components
|
| 121 |
|
|
|
|
| 114 |
components[f'seed_{prefix}'] = gr.Number(label="Seed (-1 for random)", value=-1, precision=0)
|
| 115 |
components[f'batch_size_{prefix}'] = gr.Slider(label="Batch Size", minimum=1, maximum=16, step=1, value=1)
|
| 116 |
with gr.Row():
|
| 117 |
+
components[f'zero_gpu_{prefix}'] = gr.Number(label="ZeroGPU Duration (s)", value=60, placeholder="Default: 60s, Max: 120s", info="Optional: Set how long to reserve the GPU.")
|
|
|
|
| 118 |
|
| 119 |
return components
|
| 120 |
|
yaml/chain_features.yaml
CHANGED
|
@@ -5,12 +5,6 @@ lora:
|
|
| 5 |
chains: lora
|
| 6 |
display_name: "LoRA Fine-tuning Injector"
|
| 7 |
description: "Injects LoRA weights into UNet/DiT model and CLIP text encoder for custom style, character, or domain adaptation. Note: For Civitai, specify the Version ID (modelVersionId) instead of the main Model ID."
|
| 8 |
-
supported_tasks:
|
| 9 |
-
- txt2img
|
| 10 |
-
- img2img
|
| 11 |
-
- inpaint
|
| 12 |
-
- outpaint
|
| 13 |
-
- hires_fix
|
| 14 |
max_count: 5
|
| 15 |
usage_guideline: "Specify source ('Civitai' or 'Hugging Face'). For Civitai, provide lora_value as the Version ID (modelVersionId). For Hugging Face, provide HF repo file path. Scale (0.0~2.0) controls weight strength."
|
| 16 |
parameters_schema:
|
|
@@ -37,12 +31,6 @@ ipadapter:
|
|
| 37 |
chains: ipadapter
|
| 38 |
display_name: "IP-Adapter Image Prompt"
|
| 39 |
description: "Uses reference images to guide generation style, composition, structure, or face appearance without prompt text restrictions (SD1.5 & SDXL)."
|
| 40 |
-
supported_tasks:
|
| 41 |
-
- txt2img
|
| 42 |
-
- img2img
|
| 43 |
-
- inpaint
|
| 44 |
-
- outpaint
|
| 45 |
-
- hires_fix
|
| 46 |
max_count: 5
|
| 47 |
usage_guideline: "Supply global settings (preset, embeds_scaling, combine_method, final_weight) and up to 5 reference images with individual weights. Preset must match the target model architecture (SD1.5 or SDXL)."
|
| 48 |
parameters_schema:
|
|
@@ -99,12 +87,6 @@ controlnet:
|
|
| 99 |
chains: controlnet
|
| 100 |
display_name: "ControlNet Spatial Guidance"
|
| 101 |
description: "Applies structural and spatial conditioning (depth, pose, lineart, tile, scribble, canny) to guide output composition."
|
| 102 |
-
supported_tasks:
|
| 103 |
-
- txt2img
|
| 104 |
-
- img2img
|
| 105 |
-
- inpaint
|
| 106 |
-
- outpaint
|
| 107 |
-
- hires_fix
|
| 108 |
max_count: 5
|
| 109 |
usage_guideline: "Specify ControlNet type and series (must match requested model architecture e.g., SD1.5, SDXL, SD3.5, FLUX.1, Qwen-Image), pre-processed control image (Base64 Data URI or HTTP/HTTPS URL; system does NOT pre-process raw RGB images), and guidance strength."
|
| 110 |
parameters_schema:
|
|
@@ -134,12 +116,6 @@ conditioning:
|
|
| 134 |
chains: conditioning
|
| 135 |
display_name: "Regional Conditioning / Area Prompt"
|
| 136 |
description: "Defines rectangular areas (X, Y, Width, Height) and assigns specific text prompts and conditioning strengths to them."
|
| 137 |
-
supported_tasks:
|
| 138 |
-
- txt2img
|
| 139 |
-
- img2img
|
| 140 |
-
- inpaint
|
| 141 |
-
- outpaint
|
| 142 |
-
- hires_fix
|
| 143 |
max_count: 10
|
| 144 |
usage_guideline: "Define rectangular spatial areas (X, Y, width, height) and assign specific prompts and strengths to them. Supports up to 10 area prompts."
|
| 145 |
parameters_schema:
|
|
@@ -177,12 +153,6 @@ vae:
|
|
| 177 |
chains: vae
|
| 178 |
display_name: "Custom VAE Loader"
|
| 179 |
description: "Overrides default VAE model used for latent space encoding and final image decoding."
|
| 180 |
-
supported_tasks:
|
| 181 |
-
- txt2img
|
| 182 |
-
- img2img
|
| 183 |
-
- inpaint
|
| 184 |
-
- outpaint
|
| 185 |
-
- hires_fix
|
| 186 |
max_count: 1
|
| 187 |
usage_guideline: "Specify source ('Civitai' or 'Hugging Face'), then provide the vae_value (Civitai Version ID or HF file path)."
|
| 188 |
parameters_schema:
|
|
@@ -203,8 +173,6 @@ pid:
|
|
| 203 |
chains: pid
|
| 204 |
display_name: "PiD High-Resolution Refinement"
|
| 205 |
description: "Progressive Detail (PiD) upscale injector for fine detail enhancement and resolution upscaling."
|
| 206 |
-
supported_tasks:
|
| 207 |
-
- txt2img
|
| 208 |
max_count: 1
|
| 209 |
usage_guideline: "Enables PiD detail refinement pipeline using a boolean switch ('enabled': true/false)."
|
| 210 |
parameters_schema:
|
|
@@ -221,12 +189,6 @@ flux1_style:
|
|
| 221 |
chains: style
|
| 222 |
display_name: "FLUX.1 Style Reference"
|
| 223 |
description: "Applies artistic style conditioning from reference images onto FLUX.1 model generated outputs."
|
| 224 |
-
supported_tasks:
|
| 225 |
-
- txt2img
|
| 226 |
-
- img2img
|
| 227 |
-
- inpaint
|
| 228 |
-
- outpaint
|
| 229 |
-
- hires_fix
|
| 230 |
max_count: 5
|
| 231 |
usage_guideline: "Supply style reference image(s) (up to 5) encoded as Base64 Data URI or HTTP/HTTPS URL and optional strength."
|
| 232 |
parameters_schema:
|
|
@@ -248,12 +210,6 @@ reference_edit:
|
|
| 248 |
chains: reference_latent
|
| 249 |
display_name: "Reference Edit"
|
| 250 |
description: "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."
|
| 251 |
-
supported_tasks:
|
| 252 |
-
- txt2img
|
| 253 |
-
- img2img
|
| 254 |
-
- inpaint
|
| 255 |
-
- outpaint
|
| 256 |
-
- hires_fix
|
| 257 |
max_count: 10
|
| 258 |
usage_guideline: "Supply reference image(s) encoded as Base64 Data URI or HTTP/HTTPS URL. Passing a single reference image performs an Image Edit, while passing multiple images (up to 10) performs an Image Combine."
|
| 259 |
parameters_schema:
|
|
@@ -269,12 +225,6 @@ mage_flow_reference_edit:
|
|
| 269 |
chains: reference_image
|
| 270 |
display_name: "Mage-Flow Reference Edit"
|
| 271 |
description: " (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."
|
| 272 |
-
supported_tasks:
|
| 273 |
-
- txt2img
|
| 274 |
-
- img2img
|
| 275 |
-
- inpaint
|
| 276 |
-
- outpaint
|
| 277 |
-
- hires_fix
|
| 278 |
max_count: 10
|
| 279 |
usage_guideline: "Supply reference image as Base64 Data URI or HTTP/HTTPS URL."
|
| 280 |
parameters_schema:
|
|
@@ -290,12 +240,6 @@ krea2_identity_edit:
|
|
| 290 |
chains: krea2_identity_edit
|
| 291 |
display_name: "KREA2 Identity Edit"
|
| 292 |
description: "Processed using the 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."
|
| 293 |
-
supported_tasks:
|
| 294 |
-
- txt2img
|
| 295 |
-
- img2img
|
| 296 |
-
- inpaint
|
| 297 |
-
- outpaint
|
| 298 |
-
- hires_fix
|
| 299 |
max_count: 2
|
| 300 |
usage_guideline: "Supply reference image as Base64 Data URI or HTTP/HTTPS URL."
|
| 301 |
parameters_schema:
|
|
@@ -311,12 +255,6 @@ krea2_style_reference:
|
|
| 311 |
chains: krea2_style_reference
|
| 312 |
display_name: "KREA2 Style Reference"
|
| 313 |
description: "(Krea-2-Turbo recommended) Add style reference images to perform style reference editing."
|
| 314 |
-
supported_tasks:
|
| 315 |
-
- txt2img
|
| 316 |
-
- img2img
|
| 317 |
-
- inpaint
|
| 318 |
-
- outpaint
|
| 319 |
-
- hires_fix
|
| 320 |
max_count: 3
|
| 321 |
usage_guideline: "Supply style reference image as Base64 Data URI or HTTP/HTTPS URL."
|
| 322 |
parameters_schema:
|
|
@@ -332,12 +270,6 @@ diffsynth_controlnet:
|
|
| 332 |
chains: diffsynth_controlnet
|
| 333 |
display_name: "DiffSynth ControlNet"
|
| 334 |
description: "DiffSynth optimized ControlNet injector for Z-Image models."
|
| 335 |
-
supported_tasks:
|
| 336 |
-
- txt2img
|
| 337 |
-
- img2img
|
| 338 |
-
- inpaint
|
| 339 |
-
- outpaint
|
| 340 |
-
- hires_fix
|
| 341 |
max_count: 5
|
| 342 |
usage_guideline: "Supply ControlNet type (e.g., 'Canny'), series (e.g., 'alibaba-pai Controlnet Union 2.1 8steps'), pre-processed control image (Base64 Data URI or HTTP/HTTPS URL; system does NOT pre-process raw RGB images), and optional strength."
|
| 343 |
parameters_schema:
|
|
@@ -365,12 +297,6 @@ boogu_image_edit:
|
|
| 365 |
chains: boogu_image_edit
|
| 366 |
display_name: "Boogu-Image Edit"
|
| 367 |
description: " (Boogu-Image-Edit-Turbo/Boogu-Image-Edit recommended, Boogu-Image-Edit 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."
|
| 368 |
-
supported_tasks:
|
| 369 |
-
- txt2img
|
| 370 |
-
- img2img
|
| 371 |
-
- inpaint
|
| 372 |
-
- outpaint
|
| 373 |
-
- hires_fix
|
| 374 |
max_count: 2
|
| 375 |
usage_guideline: "Supply reference image as Base64 Data URI or HTTP/HTTPS URL."
|
| 376 |
parameters_schema:
|
|
@@ -386,12 +312,6 @@ joyai_reference_edit:
|
|
| 386 |
chains: joyai_image
|
| 387 |
display_name: "JoyAI Reference Edit"
|
| 388 |
description: " (JoyAI-Image-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 (JoyAI-Image-Edit recommended), while adding multiple images performs an Image Combine (JoyAI-Image-Edit-Plus recommended with ZeroGPU Duration (s) set to 120)."
|
| 389 |
-
supported_tasks:
|
| 390 |
-
- txt2img
|
| 391 |
-
- img2img
|
| 392 |
-
- inpaint
|
| 393 |
-
- outpaint
|
| 394 |
-
- hires_fix
|
| 395 |
max_count: 2
|
| 396 |
usage_guideline: "Supply JoyAI reference image as Base64 Data URI or HTTP/HTTPS URL."
|
| 397 |
parameters_schema:
|
|
@@ -407,12 +327,6 @@ qwen_image_edit:
|
|
| 407 |
chains: qwen_image_edit
|
| 408 |
display_name: "Qwen-Image Edit"
|
| 409 |
description: " (lightx2v/Qwen-Image-Edit-2511-Lightning recommended) In txt2img mode, adding a single reference image performs an Image Edit, while adding multiple images performs an Image Combine."
|
| 410 |
-
supported_tasks:
|
| 411 |
-
- txt2img
|
| 412 |
-
- img2img
|
| 413 |
-
- inpaint
|
| 414 |
-
- outpaint
|
| 415 |
-
- hires_fix
|
| 416 |
max_count: 3
|
| 417 |
usage_guideline: "Supply reference image(s) (up to 3) encoded as Base64 Data URI or HTTP/HTTPS URL. Passing a single reference image performs an Image Edit, while passing multiple images performs an Image Combine."
|
| 418 |
parameters_schema:
|
|
@@ -428,12 +342,6 @@ hidream_o1_smoothing:
|
|
| 428 |
chains: hidream_o1_smoothing
|
| 429 |
display_name: "HiDream O1 Smoothing Injector"
|
| 430 |
description: "HiDream O1 detail smoothing and artifact reduction injector."
|
| 431 |
-
supported_tasks:
|
| 432 |
-
- txt2img
|
| 433 |
-
- img2img
|
| 434 |
-
- inpaint
|
| 435 |
-
- outpaint
|
| 436 |
-
- hires_fix
|
| 437 |
max_count: 1
|
| 438 |
usage_guideline: "Configures smoothing factor for HiDream models."
|
| 439 |
parameters_schema:
|
|
@@ -449,12 +357,6 @@ krea2_controlnet:
|
|
| 449 |
chains: krea2_controlnet
|
| 450 |
display_name: "KREA2 ControlNet"
|
| 451 |
description: "Processed using the facok/comfyui-krea2-controlnet node."
|
| 452 |
-
supported_tasks:
|
| 453 |
-
- txt2img
|
| 454 |
-
- img2img
|
| 455 |
-
- inpaint
|
| 456 |
-
- outpaint
|
| 457 |
-
- hires_fix
|
| 458 |
max_count: 5
|
| 459 |
usage_guideline: "Supply ControlNet type (e.g., 'Depth'), series (e.g., 'Patil'), pre-processed control image (Base64 Data URI or HTTP/HTTPS URL; system does NOT pre-process raw RGB images), and optional strength."
|
| 460 |
parameters_schema:
|
|
@@ -489,12 +391,6 @@ anima_controlnet_lllite:
|
|
| 489 |
chains: anima_controlnet_lllite
|
| 490 |
display_name: "Anima ControlNet LLLite"
|
| 491 |
description: "Anima model-specific lightweight ControlNet."
|
| 492 |
-
supported_tasks:
|
| 493 |
-
- txt2img
|
| 494 |
-
- img2img
|
| 495 |
-
- inpaint
|
| 496 |
-
- outpaint
|
| 497 |
-
- hires_fix
|
| 498 |
max_count: 5
|
| 499 |
usage_guideline: "Supply Anima ControlNet LLLite type (e.g., 'Depth'), series (e.g., 'kohya-ss'), pre-processed control image (Base64 Data URI or HTTP/HTTPS URL; system does NOT pre-process raw RGB images), and optional strength."
|
| 500 |
parameters_schema:
|
|
@@ -524,12 +420,6 @@ hidream_o1_reference:
|
|
| 524 |
chains: hidream_o1_reference
|
| 525 |
display_name: "HiDream-O1 Reference Edit"
|
| 526 |
description: " (HiDream-O1-Image-Dev recommended with resolution set to 4.0MP, e.g., 2048x2048) For HiDream-O1 models, this feature enables reference image editing and combining capabilities. In txt2img mode, adding a single reference image performs an Image Edit, while adding multiple images performs an Image Combine."
|
| 527 |
-
supported_tasks:
|
| 528 |
-
- txt2img
|
| 529 |
-
- img2img
|
| 530 |
-
- inpaint
|
| 531 |
-
- outpaint
|
| 532 |
-
- hires_fix
|
| 533 |
max_count: 9
|
| 534 |
usage_guideline: "Supply reference image(s) (up to 9) encoded as Base64 Data URI or HTTP/HTTPS URL. Passing a single reference image performs an Image Edit, while passing multiple images performs an Image Combine."
|
| 535 |
parameters_schema:
|
|
@@ -545,12 +435,6 @@ flux1_ipadapter:
|
|
| 545 |
chains: flux1_ipadapter
|
| 546 |
display_name: "Flux1 IP-Adapter"
|
| 547 |
description: "FLUX.1 model-specific IP-Adapter implementation."
|
| 548 |
-
supported_tasks:
|
| 549 |
-
- txt2img
|
| 550 |
-
- img2img
|
| 551 |
-
- inpaint
|
| 552 |
-
- outpaint
|
| 553 |
-
- hires_fix
|
| 554 |
max_count: 5
|
| 555 |
usage_guideline: "Supply reference image (Base64 Data URI or HTTP/HTTPS URL), optional weight (default 1.0), start_at (default 0.0), and end_at (default 1.0). Up to 5 images supported."
|
| 556 |
parameters_schema:
|
|
@@ -586,12 +470,6 @@ sd3_ipadapter:
|
|
| 586 |
chains: sd3_ipadapter
|
| 587 |
display_name: "SD3 IP-Adapter"
|
| 588 |
description: "SD3/SD3.5 model-specific IP-Adapter implementation."
|
| 589 |
-
supported_tasks:
|
| 590 |
-
- txt2img
|
| 591 |
-
- img2img
|
| 592 |
-
- inpaint
|
| 593 |
-
- outpaint
|
| 594 |
-
- hires_fix
|
| 595 |
max_count: 5
|
| 596 |
usage_guideline: "Supply reference image (Base64 Data URI or HTTP/HTTPS URL), optional weight (default 1.0), start_at (default 0.0), and end_at (default 1.0). Up to 5 images supported."
|
| 597 |
parameters_schema:
|
|
@@ -627,12 +505,6 @@ embedding:
|
|
| 627 |
chains: embedding
|
| 628 |
display_name: "Textual Inversion Embedding Injector"
|
| 629 |
description: "Downloads Textual Inversion embedding files from Civitai or Hugging Face to the server. Note: This feature ONLY handles file downloading/preparation. To activate the embedding, manually add 'embedding:<filename>' (e.g. 'embedding:civitai_456' for Civitai ID 456, or 'embedding:filename' for Hugging Face) into your prompt or negative_prompt."
|
| 630 |
-
supported_tasks:
|
| 631 |
-
- txt2img
|
| 632 |
-
- img2img
|
| 633 |
-
- inpaint
|
| 634 |
-
- outpaint
|
| 635 |
-
- hires_fix
|
| 636 |
max_count: 5
|
| 637 |
usage_guideline: "Specify source ('Civitai' or 'Hugging Face'), and embedding_value (Civitai Version ID or HF repo file path). The file is downloaded to server; manually enter 'embedding:<filename>' in prompt or negative_prompt to activate."
|
| 638 |
parameters_schema:
|
|
|
|
| 5 |
chains: lora
|
| 6 |
display_name: "LoRA Fine-tuning Injector"
|
| 7 |
description: "Injects LoRA weights into UNet/DiT model and CLIP text encoder for custom style, character, or domain adaptation. Note: For Civitai, specify the Version ID (modelVersionId) instead of the main Model ID."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
max_count: 5
|
| 9 |
usage_guideline: "Specify source ('Civitai' or 'Hugging Face'). For Civitai, provide lora_value as the Version ID (modelVersionId). For Hugging Face, provide HF repo file path. Scale (0.0~2.0) controls weight strength."
|
| 10 |
parameters_schema:
|
|
|
|
| 31 |
chains: ipadapter
|
| 32 |
display_name: "IP-Adapter Image Prompt"
|
| 33 |
description: "Uses reference images to guide generation style, composition, structure, or face appearance without prompt text restrictions (SD1.5 & SDXL)."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
max_count: 5
|
| 35 |
usage_guideline: "Supply global settings (preset, embeds_scaling, combine_method, final_weight) and up to 5 reference images with individual weights. Preset must match the target model architecture (SD1.5 or SDXL)."
|
| 36 |
parameters_schema:
|
|
|
|
| 87 |
chains: controlnet
|
| 88 |
display_name: "ControlNet Spatial Guidance"
|
| 89 |
description: "Applies structural and spatial conditioning (depth, pose, lineart, tile, scribble, canny) to guide output composition."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
max_count: 5
|
| 91 |
usage_guideline: "Specify ControlNet type and series (must match requested model architecture e.g., SD1.5, SDXL, SD3.5, FLUX.1, Qwen-Image), pre-processed control image (Base64 Data URI or HTTP/HTTPS URL; system does NOT pre-process raw RGB images), and guidance strength."
|
| 92 |
parameters_schema:
|
|
|
|
| 116 |
chains: conditioning
|
| 117 |
display_name: "Regional Conditioning / Area Prompt"
|
| 118 |
description: "Defines rectangular areas (X, Y, Width, Height) and assigns specific text prompts and conditioning strengths to them."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
max_count: 10
|
| 120 |
usage_guideline: "Define rectangular spatial areas (X, Y, width, height) and assign specific prompts and strengths to them. Supports up to 10 area prompts."
|
| 121 |
parameters_schema:
|
|
|
|
| 153 |
chains: vae
|
| 154 |
display_name: "Custom VAE Loader"
|
| 155 |
description: "Overrides default VAE model used for latent space encoding and final image decoding."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
max_count: 1
|
| 157 |
usage_guideline: "Specify source ('Civitai' or 'Hugging Face'), then provide the vae_value (Civitai Version ID or HF file path)."
|
| 158 |
parameters_schema:
|
|
|
|
| 173 |
chains: pid
|
| 174 |
display_name: "PiD High-Resolution Refinement"
|
| 175 |
description: "Progressive Detail (PiD) upscale injector for fine detail enhancement and resolution upscaling."
|
|
|
|
|
|
|
| 176 |
max_count: 1
|
| 177 |
usage_guideline: "Enables PiD detail refinement pipeline using a boolean switch ('enabled': true/false)."
|
| 178 |
parameters_schema:
|
|
|
|
| 189 |
chains: style
|
| 190 |
display_name: "FLUX.1 Style Reference"
|
| 191 |
description: "Applies artistic style conditioning from reference images onto FLUX.1 model generated outputs."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
max_count: 5
|
| 193 |
usage_guideline: "Supply style reference image(s) (up to 5) encoded as Base64 Data URI or HTTP/HTTPS URL and optional strength."
|
| 194 |
parameters_schema:
|
|
|
|
| 210 |
chains: reference_latent
|
| 211 |
display_name: "Reference Edit"
|
| 212 |
description: "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."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 213 |
max_count: 10
|
| 214 |
usage_guideline: "Supply reference image(s) encoded as Base64 Data URI or HTTP/HTTPS URL. Passing a single reference image performs an Image Edit, while passing multiple images (up to 10) performs an Image Combine."
|
| 215 |
parameters_schema:
|
|
|
|
| 225 |
chains: reference_image
|
| 226 |
display_name: "Mage-Flow Reference Edit"
|
| 227 |
description: " (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."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 228 |
max_count: 10
|
| 229 |
usage_guideline: "Supply reference image as Base64 Data URI or HTTP/HTTPS URL."
|
| 230 |
parameters_schema:
|
|
|
|
| 240 |
chains: krea2_identity_edit
|
| 241 |
display_name: "KREA2 Identity Edit"
|
| 242 |
description: "Processed using the 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."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 243 |
max_count: 2
|
| 244 |
usage_guideline: "Supply reference image as Base64 Data URI or HTTP/HTTPS URL."
|
| 245 |
parameters_schema:
|
|
|
|
| 255 |
chains: krea2_style_reference
|
| 256 |
display_name: "KREA2 Style Reference"
|
| 257 |
description: "(Krea-2-Turbo recommended) Add style reference images to perform style reference editing."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 258 |
max_count: 3
|
| 259 |
usage_guideline: "Supply style reference image as Base64 Data URI or HTTP/HTTPS URL."
|
| 260 |
parameters_schema:
|
|
|
|
| 270 |
chains: diffsynth_controlnet
|
| 271 |
display_name: "DiffSynth ControlNet"
|
| 272 |
description: "DiffSynth optimized ControlNet injector for Z-Image models."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 273 |
max_count: 5
|
| 274 |
usage_guideline: "Supply ControlNet type (e.g., 'Canny'), series (e.g., 'alibaba-pai Controlnet Union 2.1 8steps'), pre-processed control image (Base64 Data URI or HTTP/HTTPS URL; system does NOT pre-process raw RGB images), and optional strength."
|
| 275 |
parameters_schema:
|
|
|
|
| 297 |
chains: boogu_image_edit
|
| 298 |
display_name: "Boogu-Image Edit"
|
| 299 |
description: " (Boogu-Image-Edit-Turbo/Boogu-Image-Edit recommended, Boogu-Image-Edit 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."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 300 |
max_count: 2
|
| 301 |
usage_guideline: "Supply reference image as Base64 Data URI or HTTP/HTTPS URL."
|
| 302 |
parameters_schema:
|
|
|
|
| 312 |
chains: joyai_image
|
| 313 |
display_name: "JoyAI Reference Edit"
|
| 314 |
description: " (JoyAI-Image-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 (JoyAI-Image-Edit recommended), while adding multiple images performs an Image Combine (JoyAI-Image-Edit-Plus recommended with ZeroGPU Duration (s) set to 120)."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 315 |
max_count: 2
|
| 316 |
usage_guideline: "Supply JoyAI reference image as Base64 Data URI or HTTP/HTTPS URL."
|
| 317 |
parameters_schema:
|
|
|
|
| 327 |
chains: qwen_image_edit
|
| 328 |
display_name: "Qwen-Image Edit"
|
| 329 |
description: " (lightx2v/Qwen-Image-Edit-2511-Lightning recommended) In txt2img mode, adding a single reference image performs an Image Edit, while adding multiple images performs an Image Combine."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 330 |
max_count: 3
|
| 331 |
usage_guideline: "Supply reference image(s) (up to 3) encoded as Base64 Data URI or HTTP/HTTPS URL. Passing a single reference image performs an Image Edit, while passing multiple images performs an Image Combine."
|
| 332 |
parameters_schema:
|
|
|
|
| 342 |
chains: hidream_o1_smoothing
|
| 343 |
display_name: "HiDream O1 Smoothing Injector"
|
| 344 |
description: "HiDream O1 detail smoothing and artifact reduction injector."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 345 |
max_count: 1
|
| 346 |
usage_guideline: "Configures smoothing factor for HiDream models."
|
| 347 |
parameters_schema:
|
|
|
|
| 357 |
chains: krea2_controlnet
|
| 358 |
display_name: "KREA2 ControlNet"
|
| 359 |
description: "Processed using the facok/comfyui-krea2-controlnet node."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 360 |
max_count: 5
|
| 361 |
usage_guideline: "Supply ControlNet type (e.g., 'Depth'), series (e.g., 'Patil'), pre-processed control image (Base64 Data URI or HTTP/HTTPS URL; system does NOT pre-process raw RGB images), and optional strength."
|
| 362 |
parameters_schema:
|
|
|
|
| 391 |
chains: anima_controlnet_lllite
|
| 392 |
display_name: "Anima ControlNet LLLite"
|
| 393 |
description: "Anima model-specific lightweight ControlNet."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 394 |
max_count: 5
|
| 395 |
usage_guideline: "Supply Anima ControlNet LLLite type (e.g., 'Depth'), series (e.g., 'kohya-ss'), pre-processed control image (Base64 Data URI or HTTP/HTTPS URL; system does NOT pre-process raw RGB images), and optional strength."
|
| 396 |
parameters_schema:
|
|
|
|
| 420 |
chains: hidream_o1_reference
|
| 421 |
display_name: "HiDream-O1 Reference Edit"
|
| 422 |
description: " (HiDream-O1-Image-Dev recommended with resolution set to 4.0MP, e.g., 2048x2048) For HiDream-O1 models, this feature enables reference image editing and combining capabilities. In txt2img mode, adding a single reference image performs an Image Edit, while adding multiple images performs an Image Combine."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 423 |
max_count: 9
|
| 424 |
usage_guideline: "Supply reference image(s) (up to 9) encoded as Base64 Data URI or HTTP/HTTPS URL. Passing a single reference image performs an Image Edit, while passing multiple images performs an Image Combine."
|
| 425 |
parameters_schema:
|
|
|
|
| 435 |
chains: flux1_ipadapter
|
| 436 |
display_name: "Flux1 IP-Adapter"
|
| 437 |
description: "FLUX.1 model-specific IP-Adapter implementation."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 438 |
max_count: 5
|
| 439 |
usage_guideline: "Supply reference image (Base64 Data URI or HTTP/HTTPS URL), optional weight (default 1.0), start_at (default 0.0), and end_at (default 1.0). Up to 5 images supported."
|
| 440 |
parameters_schema:
|
|
|
|
| 470 |
chains: sd3_ipadapter
|
| 471 |
display_name: "SD3 IP-Adapter"
|
| 472 |
description: "SD3/SD3.5 model-specific IP-Adapter implementation."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 473 |
max_count: 5
|
| 474 |
usage_guideline: "Supply reference image (Base64 Data URI or HTTP/HTTPS URL), optional weight (default 1.0), start_at (default 0.0), and end_at (default 1.0). Up to 5 images supported."
|
| 475 |
parameters_schema:
|
|
|
|
| 505 |
chains: embedding
|
| 506 |
display_name: "Textual Inversion Embedding Injector"
|
| 507 |
description: "Downloads Textual Inversion embedding files from Civitai or Hugging Face to the server. Note: This feature ONLY handles file downloading/preparation. To activate the embedding, manually add 'embedding:<filename>' (e.g. 'embedding:civitai_456' for Civitai ID 456, or 'embedding:filename' for Hugging Face) into your prompt or negative_prompt."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 508 |
max_count: 5
|
| 509 |
usage_guideline: "Specify source ('Civitai' or 'Hugging Face'), and embedding_value (Civitai Version ID or HF repo file path). The file is downloaded to server; manually enter 'embedding:<filename>' in prompt or negative_prompt to activate."
|
| 510 |
parameters_schema:
|
yaml/{image_gen_features.yaml → model_architecture_features.yaml}
RENAMED
|
@@ -1,200 +1,200 @@
|
|
| 1 |
-
# Feature names in enabled_chains correspond 1-to-1 with chain_injectors/<name>_injector.py
|
| 2 |
-
krea-2:
|
| 3 |
-
enabled_chains:
|
| 4 |
-
- lora
|
| 5 |
-
- krea2_controlnet
|
| 6 |
-
- krea2_identity_edit
|
| 7 |
-
- krea2_style_reference
|
| 8 |
-
- pid
|
| 9 |
-
|
| 10 |
-
mage-flow:
|
| 11 |
-
enabled_chains:
|
| 12 |
-
- reference_image
|
| 13 |
-
|
| 14 |
-
joyai-image:
|
| 15 |
-
enabled_chains:
|
| 16 |
-
- joyai_image
|
| 17 |
-
|
| 18 |
-
boogu-image:
|
| 19 |
-
enabled_chains:
|
| 20 |
-
- lora
|
| 21 |
-
- boogu_image_edit
|
| 22 |
-
- pid
|
| 23 |
-
|
| 24 |
-
pixeldit:
|
| 25 |
-
enabled_chains:
|
| 26 |
-
- conditioning
|
| 27 |
-
|
| 28 |
-
ideogram-4:
|
| 29 |
-
enabled_chains:
|
| 30 |
-
- vae
|
| 31 |
-
- pid
|
| 32 |
-
|
| 33 |
-
lens:
|
| 34 |
-
enabled_chains:
|
| 35 |
-
- conditioning
|
| 36 |
-
- pid
|
| 37 |
-
|
| 38 |
-
flux2-kv:
|
| 39 |
-
enabled_chains:
|
| 40 |
-
- lora
|
| 41 |
-
- reference_latent
|
| 42 |
-
- conditioning
|
| 43 |
-
- vae
|
| 44 |
-
- pid
|
| 45 |
-
|
| 46 |
-
flux2:
|
| 47 |
-
enabled_chains:
|
| 48 |
-
- lora
|
| 49 |
-
- reference_latent
|
| 50 |
-
- conditioning
|
| 51 |
-
- vae
|
| 52 |
-
- pid
|
| 53 |
-
|
| 54 |
-
ernie-image:
|
| 55 |
-
enabled_chains:
|
| 56 |
-
- conditioning
|
| 57 |
-
- pid
|
| 58 |
-
|
| 59 |
-
z-image:
|
| 60 |
-
enabled_chains:
|
| 61 |
-
- lora
|
| 62 |
-
- diffsynth_controlnet
|
| 63 |
-
- conditioning
|
| 64 |
-
- vae
|
| 65 |
-
- pid
|
| 66 |
-
|
| 67 |
-
qwen-image:
|
| 68 |
-
enabled_chains:
|
| 69 |
-
- lora
|
| 70 |
-
- conditioning
|
| 71 |
-
- controlnet
|
| 72 |
-
- qwen_image_edit
|
| 73 |
-
- vae
|
| 74 |
-
- pid
|
| 75 |
-
|
| 76 |
-
longcat-image:
|
| 77 |
-
enabled_chains:
|
| 78 |
-
- lora
|
| 79 |
-
- conditioning
|
| 80 |
-
- pid
|
| 81 |
-
|
| 82 |
-
cosmos-predict2:
|
| 83 |
-
enabled_chains:
|
| 84 |
-
- conditioning
|
| 85 |
-
- vae
|
| 86 |
-
|
| 87 |
-
anima:
|
| 88 |
-
enabled_chains:
|
| 89 |
-
- lora
|
| 90 |
-
- conditioning
|
| 91 |
-
- anima_controlnet_lllite
|
| 92 |
-
- vae
|
| 93 |
-
- pid
|
| 94 |
-
|
| 95 |
-
newbie-image:
|
| 96 |
-
enabled_chains:
|
| 97 |
-
- lora
|
| 98 |
-
- embedding
|
| 99 |
-
- conditioning
|
| 100 |
-
- vae
|
| 101 |
-
- pid
|
| 102 |
-
|
| 103 |
-
kandinsky-5:
|
| 104 |
-
enabled_chains:
|
| 105 |
-
- conditioning
|
| 106 |
-
- vae
|
| 107 |
-
- pid
|
| 108 |
-
|
| 109 |
-
ovis-image:
|
| 110 |
-
enabled_chains:
|
| 111 |
-
- conditioning
|
| 112 |
-
- vae
|
| 113 |
-
- pid
|
| 114 |
-
|
| 115 |
-
hunyuanimage:
|
| 116 |
-
enabled_chains:
|
| 117 |
-
- conditioning
|
| 118 |
-
- vae
|
| 119 |
-
|
| 120 |
-
chroma1-radiance:
|
| 121 |
-
enabled_chains:
|
| 122 |
-
- conditioning
|
| 123 |
-
|
| 124 |
-
chroma1:
|
| 125 |
-
enabled_chains:
|
| 126 |
-
- conditioning
|
| 127 |
-
- vae
|
| 128 |
-
- pid
|
| 129 |
-
|
| 130 |
-
omnigen2:
|
| 131 |
-
enabled_chains:
|
| 132 |
-
- reference_latent
|
| 133 |
-
- conditioning
|
| 134 |
-
- pid
|
| 135 |
-
|
| 136 |
-
lumina:
|
| 137 |
-
enabled_chains:
|
| 138 |
-
- lora
|
| 139 |
-
- embedding
|
| 140 |
-
- conditioning
|
| 141 |
-
- vae
|
| 142 |
-
- pid
|
| 143 |
-
|
| 144 |
-
hidream-o1:
|
| 145 |
-
enabled_chains:
|
| 146 |
-
- lora
|
| 147 |
-
- conditioning
|
| 148 |
-
- hidream_o1_smoothing
|
| 149 |
-
- hidream_o1_reference
|
| 150 |
-
|
| 151 |
-
hidream-i1:
|
| 152 |
-
enabled_chains:
|
| 153 |
-
- lora
|
| 154 |
-
- conditioning
|
| 155 |
-
- pid
|
| 156 |
-
|
| 157 |
-
flux1:
|
| 158 |
-
enabled_chains:
|
| 159 |
-
- lora
|
| 160 |
-
- flux1_ipadapter
|
| 161 |
-
- conditioning
|
| 162 |
-
- style
|
| 163 |
-
- controlnet
|
| 164 |
-
- vae
|
| 165 |
-
- pid
|
| 166 |
-
|
| 167 |
-
auraflow:
|
| 168 |
-
enabled_chains:
|
| 169 |
-
- lora
|
| 170 |
-
- conditioning
|
| 171 |
-
- vae
|
| 172 |
-
|
| 173 |
-
sd35:
|
| 174 |
-
enabled_chains:
|
| 175 |
-
- lora
|
| 176 |
-
- sd3_ipadapter
|
| 177 |
-
- embedding
|
| 178 |
-
- conditioning
|
| 179 |
-
- controlnet
|
| 180 |
-
- vae
|
| 181 |
-
- pid
|
| 182 |
-
|
| 183 |
-
sdxl:
|
| 184 |
-
enabled_chains:
|
| 185 |
-
- lora
|
| 186 |
-
- ipadapter
|
| 187 |
-
- embedding
|
| 188 |
-
- conditioning
|
| 189 |
-
- controlnet
|
| 190 |
-
- vae
|
| 191 |
-
- pid
|
| 192 |
-
|
| 193 |
-
sd15:
|
| 194 |
-
enabled_chains:
|
| 195 |
-
- lora
|
| 196 |
-
- ipadapter
|
| 197 |
-
- embedding
|
| 198 |
-
- conditioning
|
| 199 |
-
- controlnet
|
| 200 |
- vae
|
|
|
|
| 1 |
+
# Feature names in enabled_chains correspond 1-to-1 with chain_injectors/<name>_injector.py
|
| 2 |
+
krea-2:
|
| 3 |
+
enabled_chains:
|
| 4 |
+
- lora
|
| 5 |
+
- krea2_controlnet
|
| 6 |
+
- krea2_identity_edit
|
| 7 |
+
- krea2_style_reference
|
| 8 |
+
- pid
|
| 9 |
+
|
| 10 |
+
mage-flow:
|
| 11 |
+
enabled_chains:
|
| 12 |
+
- reference_image
|
| 13 |
+
|
| 14 |
+
joyai-image:
|
| 15 |
+
enabled_chains:
|
| 16 |
+
- joyai_image
|
| 17 |
+
|
| 18 |
+
boogu-image:
|
| 19 |
+
enabled_chains:
|
| 20 |
+
- lora
|
| 21 |
+
- boogu_image_edit
|
| 22 |
+
- pid
|
| 23 |
+
|
| 24 |
+
pixeldit:
|
| 25 |
+
enabled_chains:
|
| 26 |
+
- conditioning
|
| 27 |
+
|
| 28 |
+
ideogram-4:
|
| 29 |
+
enabled_chains:
|
| 30 |
+
- vae
|
| 31 |
+
- pid
|
| 32 |
+
|
| 33 |
+
lens:
|
| 34 |
+
enabled_chains:
|
| 35 |
+
- conditioning
|
| 36 |
+
- pid
|
| 37 |
+
|
| 38 |
+
flux2-kv:
|
| 39 |
+
enabled_chains:
|
| 40 |
+
- lora
|
| 41 |
+
- reference_latent
|
| 42 |
+
- conditioning
|
| 43 |
+
- vae
|
| 44 |
+
- pid
|
| 45 |
+
|
| 46 |
+
flux2:
|
| 47 |
+
enabled_chains:
|
| 48 |
+
- lora
|
| 49 |
+
- reference_latent
|
| 50 |
+
- conditioning
|
| 51 |
+
- vae
|
| 52 |
+
- pid
|
| 53 |
+
|
| 54 |
+
ernie-image:
|
| 55 |
+
enabled_chains:
|
| 56 |
+
- conditioning
|
| 57 |
+
- pid
|
| 58 |
+
|
| 59 |
+
z-image:
|
| 60 |
+
enabled_chains:
|
| 61 |
+
- lora
|
| 62 |
+
- diffsynth_controlnet
|
| 63 |
+
- conditioning
|
| 64 |
+
- vae
|
| 65 |
+
- pid
|
| 66 |
+
|
| 67 |
+
qwen-image:
|
| 68 |
+
enabled_chains:
|
| 69 |
+
- lora
|
| 70 |
+
- conditioning
|
| 71 |
+
- controlnet
|
| 72 |
+
- qwen_image_edit
|
| 73 |
+
- vae
|
| 74 |
+
- pid
|
| 75 |
+
|
| 76 |
+
longcat-image:
|
| 77 |
+
enabled_chains:
|
| 78 |
+
- lora
|
| 79 |
+
- conditioning
|
| 80 |
+
- pid
|
| 81 |
+
|
| 82 |
+
cosmos-predict2:
|
| 83 |
+
enabled_chains:
|
| 84 |
+
- conditioning
|
| 85 |
+
- vae
|
| 86 |
+
|
| 87 |
+
anima:
|
| 88 |
+
enabled_chains:
|
| 89 |
+
- lora
|
| 90 |
+
- conditioning
|
| 91 |
+
- anima_controlnet_lllite
|
| 92 |
+
- vae
|
| 93 |
+
- pid
|
| 94 |
+
|
| 95 |
+
newbie-image:
|
| 96 |
+
enabled_chains:
|
| 97 |
+
- lora
|
| 98 |
+
- embedding
|
| 99 |
+
- conditioning
|
| 100 |
+
- vae
|
| 101 |
+
- pid
|
| 102 |
+
|
| 103 |
+
kandinsky-5:
|
| 104 |
+
enabled_chains:
|
| 105 |
+
- conditioning
|
| 106 |
+
- vae
|
| 107 |
+
- pid
|
| 108 |
+
|
| 109 |
+
ovis-image:
|
| 110 |
+
enabled_chains:
|
| 111 |
+
- conditioning
|
| 112 |
+
- vae
|
| 113 |
+
- pid
|
| 114 |
+
|
| 115 |
+
hunyuanimage:
|
| 116 |
+
enabled_chains:
|
| 117 |
+
- conditioning
|
| 118 |
+
- vae
|
| 119 |
+
|
| 120 |
+
chroma1-radiance:
|
| 121 |
+
enabled_chains:
|
| 122 |
+
- conditioning
|
| 123 |
+
|
| 124 |
+
chroma1:
|
| 125 |
+
enabled_chains:
|
| 126 |
+
- conditioning
|
| 127 |
+
- vae
|
| 128 |
+
- pid
|
| 129 |
+
|
| 130 |
+
omnigen2:
|
| 131 |
+
enabled_chains:
|
| 132 |
+
- reference_latent
|
| 133 |
+
- conditioning
|
| 134 |
+
- pid
|
| 135 |
+
|
| 136 |
+
lumina:
|
| 137 |
+
enabled_chains:
|
| 138 |
+
- lora
|
| 139 |
+
- embedding
|
| 140 |
+
- conditioning
|
| 141 |
+
- vae
|
| 142 |
+
- pid
|
| 143 |
+
|
| 144 |
+
hidream-o1:
|
| 145 |
+
enabled_chains:
|
| 146 |
+
- lora
|
| 147 |
+
- conditioning
|
| 148 |
+
- hidream_o1_smoothing
|
| 149 |
+
- hidream_o1_reference
|
| 150 |
+
|
| 151 |
+
hidream-i1:
|
| 152 |
+
enabled_chains:
|
| 153 |
+
- lora
|
| 154 |
+
- conditioning
|
| 155 |
+
- pid
|
| 156 |
+
|
| 157 |
+
flux1:
|
| 158 |
+
enabled_chains:
|
| 159 |
+
- lora
|
| 160 |
+
- flux1_ipadapter
|
| 161 |
+
- conditioning
|
| 162 |
+
- style
|
| 163 |
+
- controlnet
|
| 164 |
+
- vae
|
| 165 |
+
- pid
|
| 166 |
+
|
| 167 |
+
auraflow:
|
| 168 |
+
enabled_chains:
|
| 169 |
+
- lora
|
| 170 |
+
- conditioning
|
| 171 |
+
- vae
|
| 172 |
+
|
| 173 |
+
sd35:
|
| 174 |
+
enabled_chains:
|
| 175 |
+
- lora
|
| 176 |
+
- sd3_ipadapter
|
| 177 |
+
- embedding
|
| 178 |
+
- conditioning
|
| 179 |
+
- controlnet
|
| 180 |
+
- vae
|
| 181 |
+
- pid
|
| 182 |
+
|
| 183 |
+
sdxl:
|
| 184 |
+
enabled_chains:
|
| 185 |
+
- lora
|
| 186 |
+
- ipadapter
|
| 187 |
+
- embedding
|
| 188 |
+
- conditioning
|
| 189 |
+
- controlnet
|
| 190 |
+
- vae
|
| 191 |
+
- pid
|
| 192 |
+
|
| 193 |
+
sd15:
|
| 194 |
+
enabled_chains:
|
| 195 |
+
- lora
|
| 196 |
+
- ipadapter
|
| 197 |
+
- embedding
|
| 198 |
+
- conditioning
|
| 199 |
+
- controlnet
|
| 200 |
- vae
|
yaml/task_features.yaml
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Task-level feature support configuration
|
| 2 |
+
# Defines which chains (features) are available for each task type.
|
| 3 |
+
# A feature is visible in the UI only when BOTH the task AND the model architecture support it.
|
| 4 |
+
# pid only supports txt2img; all other features support all 5 tasks.
|
| 5 |
+
|
| 6 |
+
txt2img:
|
| 7 |
+
enabled_chains:
|
| 8 |
+
- lora
|
| 9 |
+
- controlnet
|
| 10 |
+
- anima_controlnet_lllite
|
| 11 |
+
- diffsynth_controlnet
|
| 12 |
+
- krea2_controlnet
|
| 13 |
+
- ipadapter
|
| 14 |
+
- flux1_ipadapter
|
| 15 |
+
- sd3_ipadapter
|
| 16 |
+
- style
|
| 17 |
+
- embedding
|
| 18 |
+
- conditioning
|
| 19 |
+
- reference_latent
|
| 20 |
+
- hidream_o1_reference
|
| 21 |
+
- hidream_o1_smoothing
|
| 22 |
+
- joyai_image
|
| 23 |
+
- krea2_identity_edit
|
| 24 |
+
- krea2_style_reference
|
| 25 |
+
- qwen_image_edit
|
| 26 |
+
- boogu_image_edit
|
| 27 |
+
- reference_image
|
| 28 |
+
- pid
|
| 29 |
+
- vae
|
| 30 |
+
|
| 31 |
+
img2img:
|
| 32 |
+
enabled_chains:
|
| 33 |
+
- lora
|
| 34 |
+
- controlnet
|
| 35 |
+
- anima_controlnet_lllite
|
| 36 |
+
- diffsynth_controlnet
|
| 37 |
+
- krea2_controlnet
|
| 38 |
+
- ipadapter
|
| 39 |
+
- flux1_ipadapter
|
| 40 |
+
- sd3_ipadapter
|
| 41 |
+
- style
|
| 42 |
+
- embedding
|
| 43 |
+
- conditioning
|
| 44 |
+
- reference_latent
|
| 45 |
+
- hidream_o1_reference
|
| 46 |
+
- hidream_o1_smoothing
|
| 47 |
+
- joyai_image
|
| 48 |
+
- krea2_identity_edit
|
| 49 |
+
- krea2_style_reference
|
| 50 |
+
- qwen_image_edit
|
| 51 |
+
- boogu_image_edit
|
| 52 |
+
- reference_image
|
| 53 |
+
- vae
|
| 54 |
+
|
| 55 |
+
inpaint:
|
| 56 |
+
enabled_chains:
|
| 57 |
+
- lora
|
| 58 |
+
- controlnet
|
| 59 |
+
- anima_controlnet_lllite
|
| 60 |
+
- diffsynth_controlnet
|
| 61 |
+
- krea2_controlnet
|
| 62 |
+
- ipadapter
|
| 63 |
+
- flux1_ipadapter
|
| 64 |
+
- sd3_ipadapter
|
| 65 |
+
- style
|
| 66 |
+
- embedding
|
| 67 |
+
- conditioning
|
| 68 |
+
- reference_latent
|
| 69 |
+
- hidream_o1_reference
|
| 70 |
+
- hidream_o1_smoothing
|
| 71 |
+
- joyai_image
|
| 72 |
+
- krea2_identity_edit
|
| 73 |
+
- krea2_style_reference
|
| 74 |
+
- qwen_image_edit
|
| 75 |
+
- boogu_image_edit
|
| 76 |
+
- reference_image
|
| 77 |
+
- vae
|
| 78 |
+
|
| 79 |
+
outpaint:
|
| 80 |
+
enabled_chains:
|
| 81 |
+
- lora
|
| 82 |
+
- controlnet
|
| 83 |
+
- anima_controlnet_lllite
|
| 84 |
+
- diffsynth_controlnet
|
| 85 |
+
- krea2_controlnet
|
| 86 |
+
- ipadapter
|
| 87 |
+
- flux1_ipadapter
|
| 88 |
+
- sd3_ipadapter
|
| 89 |
+
- style
|
| 90 |
+
- embedding
|
| 91 |
+
- conditioning
|
| 92 |
+
- reference_latent
|
| 93 |
+
- hidream_o1_reference
|
| 94 |
+
- hidream_o1_smoothing
|
| 95 |
+
- joyai_image
|
| 96 |
+
- krea2_identity_edit
|
| 97 |
+
- krea2_style_reference
|
| 98 |
+
- qwen_image_edit
|
| 99 |
+
- boogu_image_edit
|
| 100 |
+
- reference_image
|
| 101 |
+
- vae
|
| 102 |
+
|
| 103 |
+
hires_fix:
|
| 104 |
+
enabled_chains:
|
| 105 |
+
- lora
|
| 106 |
+
- controlnet
|
| 107 |
+
- anima_controlnet_lllite
|
| 108 |
+
- diffsynth_controlnet
|
| 109 |
+
- krea2_controlnet
|
| 110 |
+
- ipadapter
|
| 111 |
+
- flux1_ipadapter
|
| 112 |
+
- sd3_ipadapter
|
| 113 |
+
- style
|
| 114 |
+
- embedding
|
| 115 |
+
- conditioning
|
| 116 |
+
- reference_latent
|
| 117 |
+
- hidream_o1_reference
|
| 118 |
+
- hidream_o1_smoothing
|
| 119 |
+
- joyai_image
|
| 120 |
+
- krea2_identity_edit
|
| 121 |
+
- krea2_style_reference
|
| 122 |
+
- qwen_image_edit
|
| 123 |
+
- boogu_image_edit
|
| 124 |
+
- reference_image
|
| 125 |
+
- vae
|