summaryrefslogtreecommitdiff
path: root/internal/story
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-06 16:15:53 +0300
committerPaul Buetow <paul@buetow.org>2026-04-06 16:15:53 +0300
commitdf87a6af7bf1beea8dcc8bbeb5f299025cb2e8f4 (patch)
treeb21627409c7778a6e70a60f3f2b312f68df44a47 /internal/story
parent85fd2a50049ae9e7efad6ef0b45d3f2a754fe340 (diff)
feat: --narrate opt-in narration, panel variety mandate, v0.23.0v0.23.0
- Add --narrate flag (default false); narration is now opt-in to save TTS quota - Add VARIETY MANDATE to story page prompts: each panel must differ in camera angle, pose, location, lighting, and foreground — prevents repeated compositions - Wire NarrateEnabled through RunnerConfig and main.go - Update README: --narrate flag, updated output file table, narrator voice examples Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/story')
-rw-r--r--internal/story/artist.go4
-rw-r--r--internal/story/runner.go9
2 files changed, 13 insertions, 0 deletions
diff --git a/internal/story/artist.go b/internal/story/artist.go
index 3e6b191..e3a0fb6 100644
--- a/internal/story/artist.go
+++ b/internal/story/artist.go
@@ -550,6 +550,10 @@ func buildStoryPagePrompt(section string, pageNum, totalPages int, style, bible
"Each panel is separated by a thin black gutter line. "+
"All 4 panels must be clearly distinct scenes — NOT one continuous image. "+
"The full image area must be covered by the 4 panels with no empty space.\n"+
+ "VARIETY MANDATE — every panel MUST differ from the others in at least 3 of these dimensions: "+
+ "camera angle (close-up, medium shot, wide shot, bird's-eye, low angle), "+
+ "character pose or action, location or background detail, lighting or time-of-day, "+
+ "and foreground objects. Repeating the same angle or composition across panels is FORBIDDEN.\n"+
renderReq+
"STRICT CONSISTENCY RULES — apply to every single panel:\n"+
" • Human characters: identical face, AGE APPEARANCE, hair colour/style, and clothing "+
diff --git a/internal/story/runner.go b/internal/story/runner.go
index 3399bb4..e5e9aa5 100644
--- a/internal/story/runner.go
+++ b/internal/story/runner.go
@@ -50,6 +50,9 @@ type RunnerConfig struct {
// uses this value directly. Combine with loadOrGenerate's skip-existing logic
// to repair a partial comic run without regenerating already-present pages.
Slug string
+ // NarrateEnabled controls whether a cinematic MP3 narration is generated
+ // after comic creation. Defaults to false — narration is opt-in via --narrate.
+ NarrateEnabled bool
}
// Runner orchestrates the full pipeline: text → image → narration.
@@ -172,6 +175,12 @@ func (r *Runner) Run(batchFile string) error {
r.drawComicPages(result.StoryText, result.Bible, slug, entries)
+ // Narration is opt-in (--narrate flag). Skip entirely when not requested
+ // so runs complete faster and don't consume TTS quota unnecessarily.
+ if r.config != nil && !r.config.NarrateEnabled {
+ fmt.Println("Narration skipped (use --narrate to enable).")
+ return nil
+ }
return r.handleNarration(result.StoryText, slug, comicsDir)
}