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