Add character engine prompt builder
This commit is contained in:
@@ -0,0 +1,79 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from ..schema.character import Character, Outfit
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class PromptConfig:
|
||||||
|
quality_prefix: str = "masterpiece, best quality, highly detailed"
|
||||||
|
negative: str = "lowres, bad anatomy, bad hands, text, error, missing fingers, cropped, worst quality, low quality, blurry, deformed"
|
||||||
|
|
||||||
|
|
||||||
|
class PromptBuilder:
|
||||||
|
|
||||||
|
def __init__(self, config: Optional[PromptConfig] = None):
|
||||||
|
self.config = config or PromptConfig()
|
||||||
|
|
||||||
|
def build(
|
||||||
|
self,
|
||||||
|
character: Character,
|
||||||
|
outfit_name: str = "default",
|
||||||
|
scene: str = "",
|
||||||
|
extra_tags: Optional[list[str]] = None,
|
||||||
|
) -> dict[str, str]:
|
||||||
|
segments = []
|
||||||
|
|
||||||
|
segments.append(self.config.quality_prefix)
|
||||||
|
|
||||||
|
segments.append(self._appearance_segment(character))
|
||||||
|
|
||||||
|
outfit = self._find_outfit(character, outfit_name)
|
||||||
|
if outfit:
|
||||||
|
segments.append(outfit.description)
|
||||||
|
|
||||||
|
if character.style_tags:
|
||||||
|
segments.append(", ".join(character.style_tags))
|
||||||
|
|
||||||
|
if scene:
|
||||||
|
segments.append(scene)
|
||||||
|
|
||||||
|
if extra_tags:
|
||||||
|
segments.append(", ".join(extra_tags))
|
||||||
|
|
||||||
|
positive = ", ".join(seg for seg in segments if seg)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"positive": positive,
|
||||||
|
"negative": self.config.negative,
|
||||||
|
}
|
||||||
|
|
||||||
|
def _appearance_segment(self, character: Character) -> str:
|
||||||
|
parts = []
|
||||||
|
app = character.appearance
|
||||||
|
|
||||||
|
gender_map = {"female": "1girl", "male": "1boy", "other": "1person"}
|
||||||
|
parts.append(gender_map.get(character.gender.value, "1person"))
|
||||||
|
|
||||||
|
if app.hair:
|
||||||
|
parts.append(app.hair)
|
||||||
|
if app.eyes:
|
||||||
|
parts.append(app.eyes)
|
||||||
|
if app.skin:
|
||||||
|
parts.append(f"{app.skin} skin")
|
||||||
|
if app.build:
|
||||||
|
parts.append(f"{app.build} build")
|
||||||
|
for feat in app.features:
|
||||||
|
parts.append(feat)
|
||||||
|
|
||||||
|
return ", ".join(parts)
|
||||||
|
|
||||||
|
def _find_outfit(self, character: Character, name: str) -> Optional[Outfit]:
|
||||||
|
for outfit in character.outfits:
|
||||||
|
if outfit.name == name:
|
||||||
|
return outfit
|
||||||
|
if character.outfits:
|
||||||
|
return character.outfits[0]
|
||||||
|
return None
|
||||||
Reference in New Issue
Block a user