From d5d0b3194e10726e9ade9cb38faeba0a5f718123 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Mon, 5 Oct 2026 10:04:06 +0200 Subject: Build plan.json from templates instead of a Gemma compile The compile call only concatenated plan.md fields into fixed templates, cost about 40 s, and needed a json_schema, a consistency check and a retry. The script now builds every prompt itself. Gemma only drafts and revises plan.md, whose format gains a Pronoun line per character and a per-character Pose, and Framing must name the orientation. The draft prompt also keeps animals out of the character list and starts each description with who the person is. Co-Authored-By: Claude Opus 5.5 --- .../specs/2026-10-04-fanfictioner-design.md | 69 ++++--- fanfictioner | 230 +++++++++------------ 2 files changed, 141 insertions(+), 158 deletions(-) diff --git a/docs/superpowers/specs/2026-10-04-fanfictioner-design.md b/docs/superpowers/specs/2026-10-04-fanfictioner-design.md index cd620e8..6d054e6 100644 --- a/docs/superpowers/specs/2026-10-04-fanfictioner-design.md +++ b/docs/superpowers/specs/2026-10-04-fanfictioner-design.md @@ -5,8 +5,9 @@ Date: 2026-10-04 ## Goal Turn a free-prose story idea (`story.md`) into an illustrated, text-free book of -page images, read with `../book-reader`. A local Gemma model plans the pages and -writes the image prompts; `sd-cli` (stable-diffusion.cpp) draws them. The user +page images, read with `../book-reader`. A local Gemma model plans the pages; the +script turns the plan into image prompts from fixed templates; `sd-cli` +(stable-diffusion.cpp) draws them. The user reviews and picks among candidates at every image stage. ## Constraints @@ -25,7 +26,7 @@ reviews and picks among candidates at every image stage. ``` story.md ──Gemma draft──▶ plan.md ◀─┐ [c]onfirm / [e]dit in $EDITOR / [g]emma revise / [q]uit │ - confirm ──Gemma compile (json_schema)──▶ plan.json + confirm ──script compile (templates, no LLM)──▶ plan.json │ unload Gemma │ @@ -67,21 +68,24 @@ Style: ## Characters ### - +Pronoun: she|he|they + ## Pages ### 1. Characters: , (or "none") -Pose: -Framing: +Pose: : ; : <...> +Framing: , portrait|landscape Model: krea2 (optional, overrides the base model for this page) ``` Validation before confirm: title, Series, Book, at least one character and -one page; every name in `Characters:` exists under `## Characters`; every page -has `Pose:` when it lists characters. Failures are listed; the user edits or +one page; every character has `Pronoun:` she, he or they; every page has a +`Characters:` line and every name in it exists under `## Characters`; `Pose:` +names a pose for each listed character; `Framing:` says portrait or landscape; +page numbers run 1..N; names are safe as folder and file names. Failures are listed; the user edits or asks Gemma to revise. ## Gemma calls @@ -89,39 +93,48 @@ asks Gemma to revise. All via `POST localhost:8181/v1/chat/completions`, `model: Gemma4-12B-qat-mtp`. 1. **Draft**: system prompt holds the plan.md format and rules (no text in - images, fixed character descriptions, one page = one image, a scene may span - several pages). User message: `story.md`. Output: plan.md. -2. **Revise**: current plan.md + user's instruction → complete new plan.md. -3. **Compile**: plan.md → plan.json with `response_format` `json_schema`: + images, fixed character descriptions starting with who they are, characters + are people only while animals and objects belong to the scene, one page = one + image, a scene may span several pages). User message: `story.md`. Output: plan.md. +2. **Revise**: current plan.md + user's instruction -> complete new plan.md. A + revision that fails validation is saved as `plan.rejected.md` and plan.md is + kept; an accepted one keeps the previous version as `plan.md.bak`. + +## Compile (script, no LLM) + +On confirm the script builds plan.json from the parsed plan.md: ```json { "title": "", "series": "", "book": "", "characters": [{"name": "", "turnaround_prompt": ""}], "pages": [{ - "n": 1, "model": "zimage", "orientation": "portrait", - "characters": ["Mara", "Jon"], + "n": 1, "model": "", "orientation": "portrait", "base_prompt": "", "edits": [{"characters": ["Mara", "Jon"], "prompt": ""}] }] } ``` -Prompt-writing rules given to Gemma for compile: +Templates: -- `turnaround_prompt`: "Character turnaround reference sheet … the same - shown three times side by side, full body: front view, side view, back view … - plain light-grey background … No text, no labels." -- `base_prompt`: Style line + scene + full description of every character - present + Pose + Framing + "No text, no speech bubbles." +- `turnaround_prompt`: "Character turnaround reference sheet of one person: + The same person shown three times side by side, full body: front + view, side view, back view. Neutral standing pose, arms relaxed. Plain + light-grey background, even studio lighting.