@@ -93,6 +93,87 @@ class MemoirImagePromptService:
|
||||
"prompt_context": prompt_context,
|
||||
}
|
||||
|
||||
def build_cover_prompt(
|
||||
self,
|
||||
chapter_title: str,
|
||||
chapter_category: str,
|
||||
context_excerpt: str,
|
||||
) -> dict[str, str]:
|
||||
"""生成章节封面图的 image-generation prompt。"""
|
||||
style = self.CATEGORY_STYLE_MAP.get(chapter_category, self.settings.default_style)
|
||||
prompt_context = f"{chapter_category}: {chapter_title}"
|
||||
|
||||
llm_input = {
|
||||
"chapter_title": chapter_title,
|
||||
"chapter_category": chapter_category,
|
||||
"context_excerpt": context_excerpt,
|
||||
"default_style": style,
|
||||
"default_size": self.settings.default_size,
|
||||
}
|
||||
|
||||
if self.llm:
|
||||
try:
|
||||
response = self.llm.invoke(
|
||||
"Return JSON only with keys prompt, style, size. "
|
||||
"Create an image-generation prompt for a memoir chapter COVER. "
|
||||
"Emphasize: hero composition, evocative scene, chapter cover aesthetic.\n"
|
||||
+ json.dumps(llm_input, ensure_ascii=False)
|
||||
)
|
||||
parsed = json.loads(extract_json_payload(response.content))
|
||||
return {
|
||||
"prompt": _ensure_style_in_prompt(
|
||||
parsed["prompt"], parsed.get("style", style)
|
||||
),
|
||||
"style": parsed.get("style", style),
|
||||
"size": parsed.get("size", self.settings.default_size),
|
||||
"prompt_context": prompt_context,
|
||||
}
|
||||
except Exception as exc:
|
||||
logger.warning(
|
||||
"封面 prompt 生成回退到默认模板: chapter_category=%s, title=%s, error=%s",
|
||||
chapter_category,
|
||||
chapter_title,
|
||||
exc,
|
||||
)
|
||||
|
||||
return {
|
||||
"prompt": _ensure_style_in_prompt(
|
||||
self._build_cover_fallback_prompt(
|
||||
chapter_category=chapter_category,
|
||||
context_excerpt=context_excerpt,
|
||||
style=style,
|
||||
),
|
||||
style,
|
||||
),
|
||||
"style": style,
|
||||
"size": self.settings.default_size,
|
||||
"prompt_context": prompt_context,
|
||||
}
|
||||
|
||||
def _build_cover_fallback_prompt(
|
||||
self,
|
||||
chapter_category: str,
|
||||
context_excerpt: str,
|
||||
style: str,
|
||||
) -> str:
|
||||
subject = self.CATEGORY_FALLBACK_SUBJECT_MAP.get(
|
||||
chapter_category, "memoir scene"
|
||||
)
|
||||
if _contains_cjk(context_excerpt):
|
||||
return (
|
||||
f"A {style} chapter cover illustration of a {subject}, "
|
||||
"hero composition, evocative scene, emotionally resonant, "
|
||||
"cinematic framing, natural lighting, no text overlay."
|
||||
)
|
||||
details = (context_excerpt or "").strip()[:200]
|
||||
if not details:
|
||||
details = "A personal life story scene with authentic emotional detail"
|
||||
return (
|
||||
f"A {style} chapter cover illustration of a {subject}. "
|
||||
f"Scene hint: {details}. "
|
||||
"Hero composition, evocative scene, cinematic framing, no text overlay."
|
||||
)
|
||||
|
||||
def _build_fallback_prompt(
|
||||
self,
|
||||
chapter_category: str,
|
||||
|
||||
Reference in New Issue
Block a user