Add character engine prompt builder

This commit is contained in:
JayXiao
2026-03-17 14:22:08 +08:00
parent feedb5334c
commit 1d2938d255
2 changed files with 79 additions and 0 deletions

View File

@@ -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