from __future__ import annotations import json try: from .generation_profile_config import ( build_generation_profile_json, generation_profile_choices, ) from .prompt_builder import ( build_ethnicity_list_json, build_filter_config_json, ) except ImportError: # Allows local smoke tests from the repository root. from generation_profile_config import ( build_generation_profile_json, generation_profile_choices, ) from prompt_builder import ( build_ethnicity_list_json, build_filter_config_json, ) SXCP_GENERATION_PROFILE = "SXCP_GENERATION_PROFILE" SXCP_FILTER_CONFIG = "SXCP_FILTER_CONFIG" SXCP_ETHNICITY_LIST = "SXCP_ETHNICITY_LIST" class SxCPGenerationProfile: @classmethod def INPUT_TYPES(cls): return { "required": { "profile": (generation_profile_choices(), {"default": "balanced"}), "clothing_override": (["profile_default", "random", "full", "minimal"], {"default": "profile_default"}), "poses_override": (["profile_default", "random", "standard", "evocative"], {"default": "profile_default"}), "expression_enabled": ("BOOLEAN", {"default": True}), "expression_intensity_mode": (["profile_default", "random", "fixed"], {"default": "profile_default"}), "expression_intensity": ("FLOAT", {"default": -1.0, "min": -1.0, "max": 1.0, "step": 0.01}), "backside_bias": ("FLOAT", {"default": -1.0, "min": -1.0, "max": 1.0, "step": 0.01}), "minimal_clothing_ratio": ("FLOAT", {"default": -1.0, "min": -1.0, "max": 1.0, "step": 0.01}), "standard_pose_ratio": ("FLOAT", {"default": -1.0, "min": -1.0, "max": 1.0, "step": 0.01}), "trigger_policy": (["profile_default", "prepend_trigger", "do_not_prepend"], {"default": "profile_default"}), } } RETURN_TYPES = (SXCP_GENERATION_PROFILE, "STRING") RETURN_NAMES = ("generation_profile", "summary") FUNCTION = "build" CATEGORY = "prompt_builder" def build( self, profile, clothing_override, poses_override, expression_enabled, expression_intensity_mode, expression_intensity, backside_bias, minimal_clothing_ratio, standard_pose_ratio, trigger_policy, ): config = build_generation_profile_json( profile=profile, clothing_override=clothing_override, poses_override=poses_override, expression_enabled=expression_enabled, expression_intensity_mode=expression_intensity_mode, expression_intensity=expression_intensity, backside_bias=backside_bias, minimal_clothing_ratio=minimal_clothing_ratio, standard_pose_ratio=standard_pose_ratio, trigger_policy=trigger_policy, ) parsed = json.loads(config) if not parsed.get("expression_enabled", True): expression_summary = "expression disabled" elif float(parsed.get("expression_intensity", 0.5)) < 0: expression_summary = "expression random" else: expression_summary = f"expression {parsed['expression_intensity']}" summary = f"{parsed['profile']}: {parsed['clothing']}, {parsed['poses']}, {expression_summary}" return config, summary class SxCPAdvancedFilters: @classmethod def INPUT_TYPES(cls): return { "required": { "include_european": ("BOOLEAN", {"default": True}), "include_mediterranean_mena": ("BOOLEAN", {"default": True}), "include_latina": ("BOOLEAN", {"default": True}), "include_east_asian": ("BOOLEAN", {"default": True}), "include_southeast_asian": ("BOOLEAN", {"default": True}), "include_south_asian": ("BOOLEAN", {"default": True}), "include_black_african": ("BOOLEAN", {"default": True}), "include_indigenous": ("BOOLEAN", {"default": True}), "include_mixed": ("BOOLEAN", {"default": True}), "include_plus_size": ("BOOLEAN", {"default": True}), "figure": (["random", "curvy", "balanced", "bombshell"], {"default": "random"}), } } RETURN_TYPES = (SXCP_FILTER_CONFIG,) RETURN_NAMES = ("filter_config",) FUNCTION = "build" CATEGORY = "prompt_builder" def build( self, include_european, include_mediterranean_mena, include_latina, include_east_asian, include_southeast_asian, include_south_asian, include_black_african, include_indigenous, include_mixed, include_plus_size, figure, ): return ( build_filter_config_json( figure=figure, include_european=include_european, include_mediterranean_mena=include_mediterranean_mena, include_latina=include_latina, include_east_asian=include_east_asian, include_southeast_asian=include_southeast_asian, include_south_asian=include_south_asian, include_black_african=include_black_african, include_indigenous=include_indigenous, include_mixed=include_mixed, include_plus_size=include_plus_size, ), ) class SxCPEthnicityList: @classmethod def INPUT_TYPES(cls): return { "required": { "include_european": ("BOOLEAN", {"default": False}), "include_mediterranean_mena": ("BOOLEAN", {"default": False}), "include_latina": ("BOOLEAN", {"default": False}), "include_east_asian": ("BOOLEAN", {"default": False}), "include_southeast_asian": ("BOOLEAN", {"default": False}), "include_south_asian": ("BOOLEAN", {"default": False}), "include_black_african": ("BOOLEAN", {"default": False}), "include_indigenous": ("BOOLEAN", {"default": False}), "include_mixed": ("BOOLEAN", {"default": False}), "include_asian": ("BOOLEAN", {"default": False}), "include_white_asian": ("BOOLEAN", {"default": False}), "include_western_european": ("BOOLEAN", {"default": False}), "include_french_european": ("BOOLEAN", {"default": False}), "include_germanic_european": ("BOOLEAN", {"default": False}), "include_nordic_european": ("BOOLEAN", {"default": False}), "include_celtic_european": ("BOOLEAN", {"default": False}), "include_slavic_european": ("BOOLEAN", {"default": False}), "include_baltic_european": ("BOOLEAN", {"default": False}), "include_alpine_european": ("BOOLEAN", {"default": False}), "include_balkan_european": ("BOOLEAN", {"default": False}), "include_greek_mediterranean": ("BOOLEAN", {"default": False}), "include_italian_mediterranean": ("BOOLEAN", {"default": False}), "include_iberian_mediterranean": ("BOOLEAN", {"default": False}), "strict_excludes": ("BOOLEAN", {"default": True}), } } RETURN_TYPES = (SXCP_ETHNICITY_LIST, SXCP_FILTER_CONFIG, "STRING") RETURN_NAMES = ("ethnicity_list", "filter_config", "summary") FUNCTION = "build" CATEGORY = "prompt_builder" def build( self, include_european, include_mediterranean_mena, include_latina, include_east_asian, include_southeast_asian, include_south_asian, include_black_african, include_indigenous, include_mixed, include_asian, include_white_asian, include_western_european, include_french_european, include_germanic_european, include_nordic_european, include_celtic_european, include_slavic_european, include_baltic_european, include_alpine_european, include_balkan_european, include_greek_mediterranean, include_italian_mediterranean, include_iberian_mediterranean, strict_excludes, ): result = build_ethnicity_list_json( include_european=include_european, include_mediterranean_mena=include_mediterranean_mena, include_latina=include_latina, include_east_asian=include_east_asian, include_southeast_asian=include_southeast_asian, include_south_asian=include_south_asian, include_black_african=include_black_african, include_indigenous=include_indigenous, include_mixed=include_mixed, include_asian=include_asian, include_white_asian=include_white_asian, include_western_european=include_western_european, include_french_european=include_french_european, include_germanic_european=include_germanic_european, include_nordic_european=include_nordic_european, include_celtic_european=include_celtic_european, include_slavic_european=include_slavic_european, include_baltic_european=include_baltic_european, include_alpine_european=include_alpine_european, include_balkan_european=include_balkan_european, include_greek_mediterranean=include_greek_mediterranean, include_italian_mediterranean=include_italian_mediterranean, include_iberian_mediterranean=include_iberian_mediterranean, strict_excludes=strict_excludes, ) return result["ethnicity"], result["filter_config"], result["summary"] NODE_CLASS_MAPPINGS = { "SxCPGenerationProfile": SxCPGenerationProfile, "SxCPAdvancedFilters": SxCPAdvancedFilters, "SxCPEthnicityList": SxCPEthnicityList, } NODE_DISPLAY_NAME_MAPPINGS = { "SxCPGenerationProfile": "SxCP Generation Profile", "SxCPAdvancedFilters": "SxCP Advanced Filters", "SxCPEthnicityList": "SxCP Ethnicity List", }