Spaces:
Running
on
Zero
Running
on
Zero
| def inject(assembler, chain_definition, chain_items): | |
| if not chain_items: | |
| return | |
| final_settings = {} | |
| if chain_items and isinstance(chain_items[-1], dict) and chain_items[-1].get('is_final_settings'): | |
| final_settings = chain_items.pop() | |
| if not chain_items: | |
| return | |
| end_node_name = chain_definition.get('end') | |
| if not end_node_name or end_node_name not in assembler.node_map: | |
| print(f"Warning: Target node '{end_node_name}' for IPAdapter chain not found. Skipping chain injection.") | |
| return | |
| end_node_id = assembler.node_map[end_node_name] | |
| if 'model' not in assembler.workflow[end_node_id]['inputs']: | |
| print(f"Warning: Target node '{end_node_name}' is missing 'model' input. Skipping IPAdapter chain.") | |
| return | |
| current_model_connection = assembler.workflow[end_node_id]['inputs']['model'] | |
| model_type = final_settings.get('model_type', 'sdxl') | |
| megapixels = 1.05 if model_type == 'sdxl' else 0.39 | |
| pos_embed_outputs = [] | |
| neg_embed_outputs = [] | |
| for i, item_data in enumerate(chain_items): | |
| loader_type = 'FaceID' if 'FACEID' in item_data.get('preset', '') else 'Unified' | |
| loader_template_name = "IPAdapterUnifiedLoader" | |
| if loader_type == 'FaceID': | |
| loader_template_name = "IPAdapterUnifiedLoaderFaceID" | |
| image_loader_id = assembler._get_unique_id() | |
| image_loader_node = assembler._get_node_template("LoadImage") | |
| image_loader_node['inputs']['image'] = item_data['image'] | |
| assembler.workflow[image_loader_id] = image_loader_node | |
| image_scaler_id = assembler._get_unique_id() | |
| image_scaler_node = assembler._get_node_template("ImageScaleToTotalPixels") | |
| image_scaler_node['inputs']['image'] = [image_loader_id, 0] | |
| image_scaler_node['inputs']['megapixels'] = megapixels | |
| image_scaler_node['inputs']['upscale_method'] = "lanczos" | |
| assembler.workflow[image_scaler_id] = image_scaler_node | |
| ipadapter_loader_id = assembler._get_unique_id() | |
| ipadapter_loader_node = assembler._get_node_template(loader_template_name) | |
| ipadapter_loader_node['inputs']['model'] = current_model_connection | |
| ipadapter_loader_node['inputs']['preset'] = item_data['preset'] | |
| if loader_type == 'FaceID': | |
| ipadapter_loader_node['inputs']['lora_strength'] = item_data.get('lora_strength', 0.6) | |
| assembler.workflow[ipadapter_loader_id] = ipadapter_loader_node | |
| encoder_id = assembler._get_unique_id() | |
| encoder_node = assembler._get_node_template("IPAdapterEncoder") | |
| encoder_node['inputs']['weight'] = item_data['weight'] | |
| encoder_node['inputs']['ipadapter'] = [ipadapter_loader_id, 1] | |
| encoder_node['inputs']['image'] = [image_scaler_id, 0] | |
| assembler.workflow[encoder_id] = encoder_node | |
| pos_embed_outputs.append([encoder_id, 0]) | |
| neg_embed_outputs.append([encoder_id, 1]) | |
| pos_combiner_id = assembler._get_unique_id() | |
| pos_combiner_node = assembler._get_node_template("IPAdapterCombineEmbeds") | |
| pos_combiner_node['inputs']['method'] = final_settings.get('final_combine_method', 'concat') | |
| for i, conn in enumerate(pos_embed_outputs): | |
| pos_combiner_node['inputs'][f'embed{i+1}'] = conn | |
| assembler.workflow[pos_combiner_id] = pos_combiner_node | |
| neg_combiner_id = assembler._get_unique_id() | |
| neg_combiner_node = assembler._get_node_template("IPAdapterCombineEmbeds") | |
| neg_combiner_node['inputs']['method'] = final_settings.get('final_combine_method', 'concat') | |
| for i, conn in enumerate(neg_embed_outputs): | |
| neg_combiner_node['inputs'][f'embed{i+1}'] = conn | |
| assembler.workflow[neg_combiner_id] = neg_combiner_node | |
| final_loader_type = 'FaceID' if 'FACEID' in final_settings.get('final_preset', '') else 'Unified' | |
| final_loader_template_name = "IPAdapterUnifiedLoader" | |
| if final_loader_type == 'FaceID': | |
| final_loader_template_name = "IPAdapterUnifiedLoaderFaceID" | |
| final_loader_id = assembler._get_unique_id() | |
| final_loader_node = assembler._get_node_template(final_loader_template_name) | |
| final_loader_node['inputs']['model'] = current_model_connection | |
| final_loader_node['inputs']['preset'] = final_settings.get('final_preset', 'STANDARD (medium strength)') | |
| if final_loader_type == 'FaceID': | |
| final_loader_node['inputs']['lora_strength'] = final_settings.get('final_lora_strength', 0.6) | |
| assembler.workflow[final_loader_id] = final_loader_node | |
| apply_embeds_id = assembler._get_unique_id() | |
| apply_embeds_node = assembler._get_node_template("IPAdapterEmbeds") | |
| apply_embeds_node['inputs']['weight'] = final_settings.get('final_weight', 1.0) | |
| apply_embeds_node['inputs']['embeds_scaling'] = final_settings.get('final_embeds_scaling', 'V only') | |
| apply_embeds_node['inputs']['model'] = [final_loader_id, 0] | |
| apply_embeds_node['inputs']['ipadapter'] = [final_loader_id, 1] | |
| apply_embeds_node['inputs']['pos_embed'] = [pos_combiner_id, 0] | |
| apply_embeds_node['inputs']['neg_embed'] = [neg_combiner_id, 0] | |
| assembler.workflow[apply_embeds_id] = apply_embeds_node | |
| assembler.workflow[end_node_id]['inputs']['model'] = [apply_embeds_id, 0] | |
| print(f"IPAdapter injector applied. Redirected '{end_node_name}' model input through {len(chain_items)} reference images.") |