from __future__ import annotations import json try: from .prompt_builder import ( build_insta_of_options_json, build_insta_of_pair, camera_detail_choices, camera_mode_choices, ethnicity_choices, hardcore_detail_density_choices, ) except ImportError: # Allows local smoke tests from the repository root. from prompt_builder import ( build_insta_of_options_json, build_insta_of_pair, camera_detail_choices, camera_mode_choices, ethnicity_choices, hardcore_detail_density_choices, ) SXCP_SEED_CONFIG = "SXCP_SEED_CONFIG" SXCP_CAMERA_CONFIG = "SXCP_CAMERA_CONFIG" SXCP_LOCATION_CONFIG = "SXCP_LOCATION_CONFIG" SXCP_COMPOSITION_CONFIG = "SXCP_COMPOSITION_CONFIG" SXCP_INSTA_OF_OPTIONS = "SXCP_INSTA_OF_OPTIONS" SXCP_HARDCORE_POSITION_CONFIG = "SXCP_HARDCORE_POSITION_CONFIG" SXCP_CHARACTER_CAST = "SXCP_CHARACTER_CAST" SXCP_CHARACTER_PROFILE = "SXCP_CHARACTER_PROFILE" SXCP_ETHNICITY_LIST = "SXCP_ETHNICITY_LIST" SXCP_FILTER_CONFIG = "SXCP_FILTER_CONFIG" SXCP_STYLE_CONFIG = "SXCP_STYLE_CONFIG" class SxCPInstaOFOptions: @classmethod def INPUT_TYPES(cls): return { "required": { "softcore_cast": (["solo", "same_as_hardcore"], {"default": "solo"}), "hardcore_cast": (["use_counts", "couple", "threesome", "group"], {"default": "use_counts"}), "hardcore_women_count": ("INT", {"default": 1, "min": 0, "max": 12, "step": 1}), "hardcore_men_count": ("INT", {"default": 1, "min": 0, "max": 12, "step": 1}), "softcore_level": (["social_tease", "lingerie_tease", "implied_nude", "explicit_tease", "explicit_nude"], {"default": "lingerie_tease"}), "hardcore_level": (["explicit", "hardcore"], {"default": "hardcore"}), "softcore_expression_enabled": ("BOOLEAN", {"default": True}), "hardcore_expression_enabled": ("BOOLEAN", {"default": True}), "softcore_expression_intensity": ("FLOAT", {"default": 0.45, "min": 0.0, "max": 1.0, "step": 0.01}), "hardcore_expression_intensity": ("FLOAT", {"default": 0.85, "min": 0.0, "max": 1.0, "step": 0.01}), "platform_style": (["hybrid", "instagram", "onlyfans"], {"default": "hybrid"}), "continuity": (["same_creator_same_room", "same_creator_new_scene"], {"default": "same_creator_same_room"}), "hardcore_clothing_continuity": (["none", "same_outfit", "partially_removed", "implied_nude", "explicit_nude"], {"default": "partially_removed"}), "softcore_camera_mode": (["from_camera_config"] + camera_mode_choices(), {"default": "handheld_selfie"}), "hardcore_camera_mode": (["from_camera_config", "same_as_softcore"] + camera_mode_choices(), {"default": "from_camera_config"}), "camera_detail": (["from_camera_config"] + camera_detail_choices(), {"default": "from_camera_config"}), "hardcore_detail_density": (hardcore_detail_density_choices(), {"default": "balanced"}), } } RETURN_TYPES = (SXCP_INSTA_OF_OPTIONS,) RETURN_NAMES = ("options_json",) FUNCTION = "build" CATEGORY = "prompt_builder" def build( self, softcore_cast, hardcore_cast, hardcore_women_count, hardcore_men_count, softcore_level, hardcore_level, softcore_expression_enabled, hardcore_expression_enabled, softcore_expression_intensity, hardcore_expression_intensity, platform_style, continuity, hardcore_clothing_continuity, softcore_camera_mode, hardcore_camera_mode, camera_detail, hardcore_detail_density, ): return ( build_insta_of_options_json( softcore_cast=softcore_cast, hardcore_cast=hardcore_cast, hardcore_women_count=hardcore_women_count, hardcore_men_count=hardcore_men_count, softcore_level=softcore_level, hardcore_level=hardcore_level, softcore_expression_enabled=softcore_expression_enabled, hardcore_expression_enabled=hardcore_expression_enabled, softcore_expression_intensity=softcore_expression_intensity, hardcore_expression_intensity=hardcore_expression_intensity, platform_style=platform_style, continuity=continuity, hardcore_clothing_continuity=hardcore_clothing_continuity, softcore_camera_mode=softcore_camera_mode, hardcore_camera_mode=hardcore_camera_mode, camera_detail=camera_detail, hardcore_detail_density=hardcore_detail_density, ), ) class SxCPInstaOFPromptPair: @classmethod def INPUT_TYPES(cls): return { "required": { "row_number": ("INT", {"default": 1, "min": 1, "max": 1000000, "step": 1}), "start_index": ("INT", {"default": 41, "min": 1, "max": 1000000, "step": 1}), "seed": ("INT", {"default": 20260614, "min": 0, "max": 0xFFFFFFFF, "step": 1}), "ethnicity": (ethnicity_choices(), {"default": "any"}), "figure": (["random", "curvy", "balanced", "bombshell"], {"default": "random"}), "trigger": ("STRING", {"default": "sxcpinup_coloredpencil"}), "prepend_trigger_to_prompt": ("BOOLEAN", {"default": True}), }, "optional": { "seed_config": (SXCP_SEED_CONFIG,), "options_json": (SXCP_INSTA_OF_OPTIONS,), "filter_config": (SXCP_FILTER_CONFIG,), "ethnicity_list": (SXCP_ETHNICITY_LIST,), "camera_config": (SXCP_CAMERA_CONFIG,), "softcore_camera_config": (SXCP_CAMERA_CONFIG,), "hardcore_camera_config": (SXCP_CAMERA_CONFIG,), "location_config": (SXCP_LOCATION_CONFIG,), "composition_config": (SXCP_COMPOSITION_CONFIG,), "style_config": (SXCP_STYLE_CONFIG,), "character_profile": (SXCP_CHARACTER_PROFILE,), "character_cast": (SXCP_CHARACTER_CAST,), "hardcore_position_config": (SXCP_HARDCORE_POSITION_CONFIG,), "extra_positive": ("STRING", {"default": "", "multiline": True}), "extra_negative": ("STRING", {"default": "", "multiline": True}), }, } RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING", "STRING", "STRING", "STRING", "STRING") RETURN_NAMES = ( "softcore_prompt", "hardcore_prompt", "softcore_negative_prompt", "hardcore_negative_prompt", "softcore_caption", "hardcore_caption", "shared_descriptor", "metadata_json", ) FUNCTION = "build" CATEGORY = "prompt_builder" def build( self, row_number, start_index, seed, ethnicity, figure, trigger, prepend_trigger_to_prompt, seed_config="", options_json="", filter_config="", ethnicity_list="", camera_config="", softcore_camera_config="", hardcore_camera_config="", location_config="", composition_config="", style_config="", character_profile="", character_cast="", hardcore_position_config="", extra_positive="", extra_negative="", no_plus_women=False, no_black=False, ): row = build_insta_of_pair( row_number=row_number, start_index=start_index, seed=seed, ethnicity=ethnicity, figure=figure, no_plus_women=no_plus_women, no_black=no_black, trigger=trigger, prepend_trigger_to_prompt=prepend_trigger_to_prompt, seed_config=seed_config or "", options_json=options_json or "", filter_config=ethnicity_list or filter_config or "", camera_config=camera_config or "", softcore_camera_config=softcore_camera_config or "", hardcore_camera_config=hardcore_camera_config or "", location_config=location_config or "", composition_config=composition_config or "", style_config=style_config or "", character_profile=character_profile or "", character_cast=character_cast or "", hardcore_position_config=hardcore_position_config or "", extra_positive=extra_positive or "", extra_negative=extra_negative or "", ) return ( row["softcore_prompt"], row["hardcore_prompt"], row["softcore_negative_prompt"], row["hardcore_negative_prompt"], row["softcore_caption"], row["hardcore_caption"], row["shared_descriptor"], json.dumps(row, ensure_ascii=True, sort_keys=True), ) NODE_CLASS_MAPPINGS = { "SxCPInstaOFOptions": SxCPInstaOFOptions, "SxCPInstaOFPromptPair": SxCPInstaOFPromptPair, } NODE_DISPLAY_NAME_MAPPINGS = { "SxCPInstaOFOptions": "SxCP Insta/OF Options", "SxCPInstaOFPromptPair": "SxCP Insta/OF Prompt Pair", }