feat: add subject profile controls

This commit is contained in:
2026-05-18 18:38:10 +08:00
parent 87ffa6bac7
commit 33c3aef669
4 changed files with 377 additions and 6 deletions

View File

@@ -3948,6 +3948,20 @@ class GenerateSceneAssetReq(BaseModel):
product_images: list[dict] = Field(default_factory=list)
class SubjectProfilePreference(BaseModel):
mode: Literal["random", "manual"] = "random"
gender: str = ""
age: str = ""
wardrobe: str = ""
region_ethnicity: str = ""
skin_tone: str = ""
body: str = ""
hair: str = ""
mood: str = ""
resolved_summary: str = ""
prompt_summary: str = ""
class GenerateSubjectAssetsReq(BaseModel):
subject_kind: SubjectKind = "object"
background: AssetBackground = "white"
@@ -3959,10 +3973,43 @@ class GenerateSubjectAssetsReq(BaseModel):
subject_template_id: str = ""
subject_style: Literal["transparent_human", "source_actor"] = "transparent_human"
reconstruction_mode: Literal["same", "similar"] = "same"
subject_profile: SubjectProfilePreference | None = None
prompt: str = ""
replace_views: bool = False
def _subject_profile_prompt_clause(profile: SubjectProfilePreference | None) -> str:
if not profile:
return ""
prompt_summary = (profile.prompt_summary or "").strip()
resolved_summary = (profile.resolved_summary or "").strip()
if prompt_summary:
body = prompt_summary[:1400]
else:
parts = [
("gender presentation", profile.gender),
("age range", profile.age),
("wardrobe style", profile.wardrobe),
("regional/ethnic appearance cues", profile.region_ethnicity),
("skin tone", profile.skin_tone),
("body proportion", profile.body),
("hair style", profile.hair),
("commercial mood", profile.mood),
]
body = "; ".join(f"{name}: {value.strip()}" for name, value in parts if value and value.strip())[:1400]
if not body and not resolved_summary:
return ""
mode = "random-composed" if profile.mode == "random" else "manually selected"
resolved = f" UI summary: {resolved_summary[:700]}." if resolved_summary else ""
return (
f"Structured subject casting profile ({mode}, locked for this request): {body}. "
"This profile overrides ambiguous source/template traits for gender presentation, age range, wardrobe, regional/ethnic appearance cues, skin tone, body proportion, hair, and commercial mood. "
"Apply the same profile uniformly to every requested view; do not mix different genders, ages, skin tones, wardrobes, or character identities inside the pack."
+ resolved
+ " "
)
class UpdateProductRefsReq(BaseModel):
items: list[dict] = Field(default_factory=list)
@@ -4490,6 +4537,7 @@ def generate_subject_assets(job_id: str, idx: int, element_id: str, req: Generat
)
prompt_extra = req.prompt.strip()
prompt_extra_clause = f"User direction: {prompt_extra[:1200]} " if prompt_extra else ""
subject_profile_clause = _subject_profile_prompt_clause(req.subject_profile)
identity_lock_clause = (
"Identity lock: these API calls generate one high-definition multi-view pack for ONE single subject, but each individual output file must show only its one requested view. "
"Before rendering, infer one consistent character bible from the supplied text brief and generation instructions: gender presentation, age range, body proportions, head shape, face direction cues, material, silhouette, wardrobe/material style, and commercial mood. "
@@ -4554,6 +4602,7 @@ def generate_subject_assets(job_id: str, idx: int, element_id: str, req: Generat
+ neck_product_clause
+ canvas_clause
+ prompt_extra_clause
+ subject_profile_clause
+ actor_style_clause
+ framing_clause
+ f"Create a high-definition standalone asset on a solid {bg_phrase} background. "