Add Insta OF paired prompt mode
This commit is contained in:
@@ -8,6 +8,8 @@ The node is registered as:
|
|||||||
- `prompt_builder / SxCP Prompt Builder`
|
- `prompt_builder / SxCP Prompt Builder`
|
||||||
- `prompt_builder / SxCP Seed Control`
|
- `prompt_builder / SxCP Seed Control`
|
||||||
- `prompt_builder / SxCP Caption Naturalizer`
|
- `prompt_builder / SxCP Caption Naturalizer`
|
||||||
|
- `prompt_builder / SxCP Insta/OF Options`
|
||||||
|
- `prompt_builder / SxCP Insta/OF Prompt Pair`
|
||||||
|
|
||||||
It outputs:
|
It outputs:
|
||||||
|
|
||||||
@@ -41,6 +43,41 @@ It outputs:
|
|||||||
- `natural_caption`
|
- `natural_caption`
|
||||||
- `method`
|
- `method`
|
||||||
|
|
||||||
|
`SxCP Insta/OF Prompt Pair` is a special paired-output mode. It creates one
|
||||||
|
shared primary creator descriptor, then returns both a softcore prompt and a
|
||||||
|
hardcore prompt from that same descriptor. This is useful when you want the same
|
||||||
|
person/look/scene continuity but need two different prompt strengths.
|
||||||
|
|
||||||
|
It outputs:
|
||||||
|
|
||||||
|
- `softcore_prompt`
|
||||||
|
- `hardcore_prompt`
|
||||||
|
- `softcore_negative_prompt`
|
||||||
|
- `hardcore_negative_prompt`
|
||||||
|
- `softcore_caption`
|
||||||
|
- `hardcore_caption`
|
||||||
|
- `shared_descriptor`
|
||||||
|
- `metadata_json`
|
||||||
|
|
||||||
|
`SxCP Insta/OF Options` outputs `options_json`, which can be connected to the
|
||||||
|
pair node. Defaults are set so the softcore prompt is solo while the hardcore
|
||||||
|
prompt can include partners.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
|
||||||
|
- `softcore_cast`: `solo` or `same_as_hardcore`.
|
||||||
|
- `hardcore_cast`: `use_counts`, `couple`, `threesome`, or `group`.
|
||||||
|
- `hardcore_women_count` and `hardcore_men_count`: used when `hardcore_cast` is
|
||||||
|
`use_counts`. The pair mode always keeps at least one adult woman as the
|
||||||
|
primary creator so the shared descriptor remains valid.
|
||||||
|
- `softcore_level`: `social_tease`, `lingerie_tease`, `implied_nude`, or
|
||||||
|
`explicit_tease`.
|
||||||
|
- `hardcore_level`: `explicit` or `hardcore`.
|
||||||
|
- `platform_style`: `hybrid`, `instagram`, or `onlyfans`.
|
||||||
|
- `continuity`: `same_creator_same_room` keeps the scene/composition aligned;
|
||||||
|
`same_creator_new_scene` keeps the same creator descriptor but lets the
|
||||||
|
hardcore scene use its own setting.
|
||||||
|
|
||||||
## Built-In Categories
|
## Built-In Categories
|
||||||
|
|
||||||
The node keeps the original generator controls:
|
The node keeps the original generator controls:
|
||||||
|
|||||||
+146
-2
@@ -3,10 +3,24 @@ from __future__ import annotations
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from .prompt_builder import build_prompt, build_seed_config_json, category_choices, subcategory_choices
|
from .prompt_builder import (
|
||||||
|
build_insta_of_options_json,
|
||||||
|
build_insta_of_pair,
|
||||||
|
build_prompt,
|
||||||
|
build_seed_config_json,
|
||||||
|
category_choices,
|
||||||
|
subcategory_choices,
|
||||||
|
)
|
||||||
from .caption_naturalizer import naturalize_caption
|
from .caption_naturalizer import naturalize_caption
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from prompt_builder import build_prompt, build_seed_config_json, category_choices, subcategory_choices
|
from prompt_builder import (
|
||||||
|
build_insta_of_options_json,
|
||||||
|
build_insta_of_pair,
|
||||||
|
build_prompt,
|
||||||
|
build_seed_config_json,
|
||||||
|
category_choices,
|
||||||
|
subcategory_choices,
|
||||||
|
)
|
||||||
from caption_naturalizer import naturalize_caption
|
from caption_naturalizer import naturalize_caption
|
||||||
|
|
||||||
|
|
||||||
@@ -196,14 +210,144 @@ class SxCPCaptionNaturalizer:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
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"], {"default": "lingerie_tease"}),
|
||||||
|
"hardcore_level": (["explicit", "hardcore"], {"default": "hardcore"}),
|
||||||
|
"platform_style": (["hybrid", "instagram", "onlyfans"], {"default": "hybrid"}),
|
||||||
|
"continuity": (["same_creator_same_room", "same_creator_new_scene"], {"default": "same_creator_same_room"}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_TYPES = ("STRING",)
|
||||||
|
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,
|
||||||
|
platform_style,
|
||||||
|
continuity,
|
||||||
|
):
|
||||||
|
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,
|
||||||
|
platform_style=platform_style,
|
||||||
|
continuity=continuity,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
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": (["any", "asian", "white_asian"], {"default": "any"}),
|
||||||
|
"figure": (["curvy", "balanced", "bombshell"], {"default": "curvy"}),
|
||||||
|
"no_plus_women": ("BOOLEAN", {"default": False}),
|
||||||
|
"no_black": ("BOOLEAN", {"default": False}),
|
||||||
|
"trigger": ("STRING", {"default": "sxcpinup_coloredpencil"}),
|
||||||
|
"prepend_trigger_to_prompt": ("BOOLEAN", {"default": True}),
|
||||||
|
},
|
||||||
|
"optional": {
|
||||||
|
"seed_config": ("STRING", {"default": "", "multiline": True}),
|
||||||
|
"options_json": ("STRING", {"default": "", "multiline": True}),
|
||||||
|
"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,
|
||||||
|
no_plus_women,
|
||||||
|
no_black,
|
||||||
|
trigger,
|
||||||
|
prepend_trigger_to_prompt,
|
||||||
|
seed_config="",
|
||||||
|
options_json="",
|
||||||
|
extra_positive="",
|
||||||
|
extra_negative="",
|
||||||
|
):
|
||||||
|
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 "",
|
||||||
|
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 = {
|
NODE_CLASS_MAPPINGS = {
|
||||||
"SxCPPromptBuilder": SxCPPromptBuilder,
|
"SxCPPromptBuilder": SxCPPromptBuilder,
|
||||||
"SxCPSeedControl": SxCPSeedControl,
|
"SxCPSeedControl": SxCPSeedControl,
|
||||||
"SxCPCaptionNaturalizer": SxCPCaptionNaturalizer,
|
"SxCPCaptionNaturalizer": SxCPCaptionNaturalizer,
|
||||||
|
"SxCPInstaOFOptions": SxCPInstaOFOptions,
|
||||||
|
"SxCPInstaOFPromptPair": SxCPInstaOFPromptPair,
|
||||||
}
|
}
|
||||||
|
|
||||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||||
"SxCPPromptBuilder": "SxCP Prompt Builder",
|
"SxCPPromptBuilder": "SxCP Prompt Builder",
|
||||||
"SxCPSeedControl": "SxCP Seed Control",
|
"SxCPSeedControl": "SxCP Seed Control",
|
||||||
"SxCPCaptionNaturalizer": "SxCP Caption Naturalizer",
|
"SxCPCaptionNaturalizer": "SxCP Caption Naturalizer",
|
||||||
|
"SxCPInstaOFOptions": "SxCP Insta/OF Options",
|
||||||
|
"SxCPInstaOFPromptPair": "SxCP Insta/OF Prompt Pair",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1267,6 +1267,7 @@ def _build_custom_row(
|
|||||||
"style": style,
|
"style": style,
|
||||||
"item": item_text,
|
"item": item_text,
|
||||||
"item_label": item_label,
|
"item_label": item_label,
|
||||||
|
"positive_suffix": positive_suffix,
|
||||||
"custom_item": item_name,
|
"custom_item": item_name,
|
||||||
"item_axis_values": item_axis_values,
|
"item_axis_values": item_axis_values,
|
||||||
"scene_text": scene,
|
"scene_text": scene,
|
||||||
@@ -1379,3 +1380,266 @@ def build_prompt(
|
|||||||
row["negative_prompt"] = _combined_negative(row.get("negative_prompt", g.NEGATIVE_PROMPT), extra_negative)
|
row["negative_prompt"] = _combined_negative(row.get("negative_prompt", g.NEGATIVE_PROMPT), extra_negative)
|
||||||
row["trigger"] = active_trigger
|
row["trigger"] = active_trigger
|
||||||
return row
|
return row
|
||||||
|
|
||||||
|
|
||||||
|
INSTA_OF_SOFT_LEVELS = {
|
||||||
|
"social_tease": "Instagram-style thirst-trap post, suggestive but non-explicit, polished social feed energy",
|
||||||
|
"lingerie_tease": "premium OF teaser set, lingerie-focused, sensual and intimate but without explicit sex",
|
||||||
|
"implied_nude": "implied nude creator set, strategically covered body, sensual but no visible sex act",
|
||||||
|
"explicit_tease": "explicit adult tease, nudity can be visible, but no penetration or partnered sex act",
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTA_OF_HARDCORE_LEVELS = {
|
||||||
|
"explicit": "explicit adult creator content with clear sexual contact and adult-only framing",
|
||||||
|
"hardcore": "hardcore adult creator content with anatomically clear sexual contact and intense body language",
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTA_OF_PLATFORM_STYLES = {
|
||||||
|
"hybrid": "hybrid Instagram-to-OF creator shoot, polished social-media framing with intimate subscriber-content energy",
|
||||||
|
"instagram": "Instagram-inspired creator shoot, polished mirror-selfie and feed-post aesthetics",
|
||||||
|
"onlyfans": "OnlyFans-inspired creator shoot, intimate subscriber-view camera and candid premium-content framing",
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTA_OF_NEGATIVE = (
|
||||||
|
"minors, childlike appearance, teen, underage, schoolgirl, non-consensual, coercion, rape, "
|
||||||
|
"violence, injury, blood, gore, incest, bestiality, watermark, logo, readable username, social media UI"
|
||||||
|
)
|
||||||
|
|
||||||
|
INSTA_OF_SOFT_NEGATIVE = (
|
||||||
|
INSTA_OF_NEGATIVE + ", explicit intercourse, penetration, oral sex, cumshot, genital contact, group sex"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def build_insta_of_options_json(
|
||||||
|
softcore_cast: str = "solo",
|
||||||
|
hardcore_cast: str = "use_counts",
|
||||||
|
hardcore_women_count: int = 1,
|
||||||
|
hardcore_men_count: int = 1,
|
||||||
|
softcore_level: str = "lingerie_tease",
|
||||||
|
hardcore_level: str = "hardcore",
|
||||||
|
platform_style: str = "hybrid",
|
||||||
|
continuity: str = "same_creator_same_room",
|
||||||
|
) -> str:
|
||||||
|
return json.dumps(
|
||||||
|
{
|
||||||
|
"softcore_cast": softcore_cast,
|
||||||
|
"hardcore_cast": hardcore_cast,
|
||||||
|
"hardcore_women_count": int(hardcore_women_count),
|
||||||
|
"hardcore_men_count": int(hardcore_men_count),
|
||||||
|
"softcore_level": softcore_level,
|
||||||
|
"hardcore_level": hardcore_level,
|
||||||
|
"platform_style": platform_style,
|
||||||
|
"continuity": continuity,
|
||||||
|
},
|
||||||
|
ensure_ascii=True,
|
||||||
|
sort_keys=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_insta_of_options(options_json: str | dict[str, Any] | None) -> dict[str, Any]:
|
||||||
|
defaults = {
|
||||||
|
"softcore_cast": "solo",
|
||||||
|
"hardcore_cast": "use_counts",
|
||||||
|
"hardcore_women_count": 1,
|
||||||
|
"hardcore_men_count": 1,
|
||||||
|
"softcore_level": "lingerie_tease",
|
||||||
|
"hardcore_level": "hardcore",
|
||||||
|
"platform_style": "hybrid",
|
||||||
|
"continuity": "same_creator_same_room",
|
||||||
|
}
|
||||||
|
if not options_json:
|
||||||
|
return defaults
|
||||||
|
if isinstance(options_json, dict):
|
||||||
|
raw = options_json
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
raw = json.loads(str(options_json))
|
||||||
|
except json.JSONDecodeError as exc:
|
||||||
|
raise ValueError(f"Invalid Insta/OF options JSON: {exc}") from exc
|
||||||
|
if not isinstance(raw, dict):
|
||||||
|
raise ValueError("Insta/OF options must be a JSON object")
|
||||||
|
parsed = {**defaults, **raw}
|
||||||
|
parsed["softcore_cast"] = parsed["softcore_cast"] if parsed["softcore_cast"] in ("solo", "same_as_hardcore") else defaults["softcore_cast"]
|
||||||
|
parsed["hardcore_cast"] = parsed["hardcore_cast"] if parsed["hardcore_cast"] in ("use_counts", "couple", "threesome", "group") else defaults["hardcore_cast"]
|
||||||
|
parsed["softcore_level"] = parsed["softcore_level"] if parsed["softcore_level"] in INSTA_OF_SOFT_LEVELS else defaults["softcore_level"]
|
||||||
|
parsed["hardcore_level"] = parsed["hardcore_level"] if parsed["hardcore_level"] in INSTA_OF_HARDCORE_LEVELS else defaults["hardcore_level"]
|
||||||
|
parsed["platform_style"] = parsed["platform_style"] if parsed["platform_style"] in INSTA_OF_PLATFORM_STYLES else defaults["platform_style"]
|
||||||
|
parsed["continuity"] = parsed["continuity"] if parsed["continuity"] in ("same_creator_same_room", "same_creator_new_scene") else defaults["continuity"]
|
||||||
|
for key in ("hardcore_women_count", "hardcore_men_count"):
|
||||||
|
try:
|
||||||
|
parsed[key] = max(0, min(12, int(parsed[key])))
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
parsed[key] = defaults[key]
|
||||||
|
return parsed
|
||||||
|
|
||||||
|
|
||||||
|
def _insta_of_hardcore_counts(options: dict[str, Any]) -> tuple[int, int]:
|
||||||
|
policy = str(options.get("hardcore_cast", "use_counts"))
|
||||||
|
if policy == "couple":
|
||||||
|
women_count, men_count = 1, 1
|
||||||
|
elif policy == "threesome":
|
||||||
|
women_count, men_count = 2, 1
|
||||||
|
elif policy == "group":
|
||||||
|
women_count, men_count = 3, 2
|
||||||
|
else:
|
||||||
|
women_count = int(options.get("hardcore_women_count") or 0)
|
||||||
|
men_count = int(options.get("hardcore_men_count") or 0)
|
||||||
|
women_count = max(1, min(12, women_count))
|
||||||
|
men_count = max(0, min(12, men_count))
|
||||||
|
if women_count + men_count < 2:
|
||||||
|
men_count = 1
|
||||||
|
return women_count, men_count
|
||||||
|
|
||||||
|
|
||||||
|
def _insta_of_descriptor(row: dict[str, Any]) -> str:
|
||||||
|
age = str(row.get("age_band") or row.get("age") or "").strip()
|
||||||
|
age = " ".join(age.split())
|
||||||
|
age = age.removesuffix(" adults").removesuffix(" adult").strip()
|
||||||
|
pieces = [
|
||||||
|
f"{age} adult woman" if age else "adult woman",
|
||||||
|
row.get("body_phrase"),
|
||||||
|
row.get("skin"),
|
||||||
|
row.get("hair"),
|
||||||
|
row.get("eyes"),
|
||||||
|
]
|
||||||
|
return ", ".join(str(piece).strip() for piece in pieces if piece and str(piece).strip())
|
||||||
|
|
||||||
|
|
||||||
|
def _insta_of_cast_phrase(women_count: int, men_count: int) -> str:
|
||||||
|
context = _configured_cast_context(women_count, men_count)
|
||||||
|
return context["cast_summary"]
|
||||||
|
|
||||||
|
|
||||||
|
def _insta_of_active_trigger(prompt: str, trigger: str, enabled: bool) -> str:
|
||||||
|
return _prepend_trigger(prompt, trigger, enabled)
|
||||||
|
|
||||||
|
|
||||||
|
def build_insta_of_pair(
|
||||||
|
row_number: int,
|
||||||
|
start_index: int,
|
||||||
|
seed: int,
|
||||||
|
ethnicity: str,
|
||||||
|
figure: str,
|
||||||
|
no_plus_women: bool,
|
||||||
|
no_black: bool,
|
||||||
|
trigger: str,
|
||||||
|
prepend_trigger_to_prompt: bool,
|
||||||
|
seed_config: str | dict[str, Any] | None = None,
|
||||||
|
options_json: str | dict[str, Any] | None = None,
|
||||||
|
extra_positive: str = "",
|
||||||
|
extra_negative: str = "",
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
options = _parse_insta_of_options(options_json)
|
||||||
|
hard_women_count, hard_men_count = _insta_of_hardcore_counts(options)
|
||||||
|
active_trigger = trigger.strip() or g.TRIGGER
|
||||||
|
parsed_seed_config = _parse_seed_config(seed_config)
|
||||||
|
|
||||||
|
soft_row = build_prompt(
|
||||||
|
category="Provocative erotic clothes",
|
||||||
|
subcategory=RANDOM_SUBCATEGORY,
|
||||||
|
row_number=row_number,
|
||||||
|
start_index=start_index,
|
||||||
|
seed=seed,
|
||||||
|
clothing="minimal",
|
||||||
|
ethnicity=ethnicity,
|
||||||
|
poses="evocative",
|
||||||
|
backside_bias=0.0,
|
||||||
|
figure=figure,
|
||||||
|
no_plus_women=no_plus_women,
|
||||||
|
no_black=no_black,
|
||||||
|
minimal_clothing_ratio=-1,
|
||||||
|
standard_pose_ratio=-1,
|
||||||
|
trigger=active_trigger,
|
||||||
|
prepend_trigger_to_prompt=False,
|
||||||
|
extra_positive="",
|
||||||
|
extra_negative="",
|
||||||
|
seed_config=parsed_seed_config,
|
||||||
|
women_count=1,
|
||||||
|
men_count=0,
|
||||||
|
)
|
||||||
|
hard_row = build_prompt(
|
||||||
|
category="Hardcore sexual poses",
|
||||||
|
subcategory=RANDOM_SUBCATEGORY,
|
||||||
|
row_number=row_number,
|
||||||
|
start_index=start_index,
|
||||||
|
seed=seed,
|
||||||
|
clothing="minimal",
|
||||||
|
ethnicity=ethnicity,
|
||||||
|
poses="evocative",
|
||||||
|
backside_bias=0.0,
|
||||||
|
figure=figure,
|
||||||
|
no_plus_women=no_plus_women,
|
||||||
|
no_black=no_black,
|
||||||
|
minimal_clothing_ratio=-1,
|
||||||
|
standard_pose_ratio=-1,
|
||||||
|
trigger=active_trigger,
|
||||||
|
prepend_trigger_to_prompt=False,
|
||||||
|
extra_positive="",
|
||||||
|
extra_negative="",
|
||||||
|
seed_config=parsed_seed_config,
|
||||||
|
women_count=hard_women_count,
|
||||||
|
men_count=hard_men_count,
|
||||||
|
)
|
||||||
|
|
||||||
|
descriptor = _insta_of_descriptor(soft_row)
|
||||||
|
platform_style = INSTA_OF_PLATFORM_STYLES[options["platform_style"]]
|
||||||
|
soft_level = INSTA_OF_SOFT_LEVELS[options["softcore_level"]]
|
||||||
|
hard_level = INSTA_OF_HARDCORE_LEVELS[options["hardcore_level"]]
|
||||||
|
hard_scene = soft_row["scene_text"] if options["continuity"] == "same_creator_same_room" else hard_row["scene_text"]
|
||||||
|
hard_composition = soft_row["composition"] if options["continuity"] == "same_creator_same_room" else hard_row["composition"]
|
||||||
|
soft_cast = (
|
||||||
|
"solo creator setup; the primary creator is alone in the softcore version"
|
||||||
|
if options["softcore_cast"] == "solo"
|
||||||
|
else f"non-explicit teaser setup with the same adult cast as the hardcore version: {_insta_of_cast_phrase(hard_women_count, hard_men_count)}"
|
||||||
|
)
|
||||||
|
hard_cast = _insta_of_cast_phrase(hard_women_count, hard_men_count)
|
||||||
|
|
||||||
|
soft_prompt = (
|
||||||
|
f"Insta/OF softcore mode: {platform_style}. Shared primary creator descriptor: {descriptor}. "
|
||||||
|
f"Softcore setup: {soft_level}. Cast continuity: {soft_cast}. "
|
||||||
|
f"Outfit: {soft_row['item']}. Pose: {soft_row['pose']}. Setting: {soft_row['scene_text']}. "
|
||||||
|
f"Facial expression: {soft_row['expression']}. Composition: {soft_row['composition']}. "
|
||||||
|
"Keep the softcore version adult-only, consensual, seductive, creator-shot, and non-explicit. "
|
||||||
|
f"{soft_row['positive_suffix']} Avoid: {INSTA_OF_SOFT_NEGATIVE}."
|
||||||
|
)
|
||||||
|
hard_prompt = (
|
||||||
|
f"Insta/OF hardcore mode: {platform_style}. Shared primary creator descriptor: {descriptor}. "
|
||||||
|
f"Hardcore setup: {hard_level}. Cast: {hard_cast}. "
|
||||||
|
"Apply the shared descriptor to the most visually central woman, keeping her continuous with the softcore version. "
|
||||||
|
f"Role graph: {hard_row['role_graph']} Sexual scene: {hard_row['item']}. "
|
||||||
|
f"Setting: {hard_scene}. Facial expressions: {hard_row['expression']}. Composition: {hard_composition}. "
|
||||||
|
"All participants are consenting adults 21+. "
|
||||||
|
f"{hard_row['positive_suffix']} Avoid: {INSTA_OF_NEGATIVE}."
|
||||||
|
)
|
||||||
|
if extra_positive.strip():
|
||||||
|
soft_prompt = f"{soft_prompt.rstrip()} {extra_positive.strip()}"
|
||||||
|
hard_prompt = f"{hard_prompt.rstrip()} {extra_positive.strip()}"
|
||||||
|
|
||||||
|
soft_prompt = _insta_of_active_trigger(soft_prompt, active_trigger, bool(prepend_trigger_to_prompt))
|
||||||
|
hard_prompt = _insta_of_active_trigger(hard_prompt, active_trigger, bool(prepend_trigger_to_prompt))
|
||||||
|
soft_negative = _combined_negative(INSTA_OF_SOFT_NEGATIVE, extra_negative)
|
||||||
|
hard_negative = _combined_negative(INSTA_OF_NEGATIVE, extra_negative)
|
||||||
|
soft_caption = (
|
||||||
|
f"{active_trigger}, Insta/OF softcore mode, {descriptor}, {soft_level}, "
|
||||||
|
f"{soft_row['item']}, {soft_row['pose']}, {soft_row['scene_text']}, {soft_row['composition']}"
|
||||||
|
)
|
||||||
|
hard_caption = (
|
||||||
|
f"{active_trigger}, Insta/OF hardcore mode, same primary creator descriptor, {descriptor}, "
|
||||||
|
f"{hard_cast}, {hard_row['role_graph']}, {hard_row['item']}, {hard_scene}, {hard_composition}"
|
||||||
|
)
|
||||||
|
metadata = {
|
||||||
|
"mode": "Insta/OF",
|
||||||
|
"options": options,
|
||||||
|
"shared_descriptor": descriptor,
|
||||||
|
"softcore_prompt": soft_prompt,
|
||||||
|
"hardcore_prompt": hard_prompt,
|
||||||
|
"softcore_negative_prompt": soft_negative,
|
||||||
|
"hardcore_negative_prompt": hard_negative,
|
||||||
|
"softcore_caption": soft_caption,
|
||||||
|
"hardcore_caption": hard_caption,
|
||||||
|
"softcore_row": soft_row,
|
||||||
|
"hardcore_row": hard_row,
|
||||||
|
"hardcore_women_count": hard_women_count,
|
||||||
|
"hardcore_men_count": hard_men_count,
|
||||||
|
}
|
||||||
|
return metadata
|
||||||
|
|||||||
Reference in New Issue
Block a user