summaryrefslogtreecommitdiff
path: root/internal/story
AgeCommit message (Collapse)Author
2026-04-08Release v0.28.0: story gallery aggregation and stronger ultra-realistic promptsv0.28.0Paul Buetow
- Copy *_gallery_*.png into comics/gallery after each --story run - Expand ultra-realistic rendering instructions in image prompts - Add gallery copy test; document comics/ in gitignore; sample vocab batch asset Made-with: Cursor
2026-04-08refactor(dip): inject archive, models, story, and gui at composition rootsPaul Buetow
Define Archiver, ModelLister, and StoryRunner interfaces in their packages. gui.New returns App; Application carries an injectable Archiver from Config. cmd/totalrecall wires default implementations via runDeps for tests and DI. Made-with: Cursor
2026-04-08feat(httpctx): add timeouts for OpenAI, Gemini, and HTTP downloadsPaul Buetow
Introduce internal/httpctx with non-zero http.Client timeouts for go-openai and google.golang.org/genai, shared image download client, and WithTimeoutUnlessSet for operation-level deadlines when callers use Background. Wire NewOpenAIClient/NewGenAIClient everywhere clients are constructed. Apply Search timeouts for DALL-E and Nano Banana, provider audio timeouts, model-list timeouts, Veo operation timeouts, story page download context, and single-word CLI processing cap. Made-with: Cursor
2026-04-06feat: mandatory speech bubbles in story panels, v0.26.0v0.26.0Paul Buetow
Two-part fix for missing dialogue bubbles: 1. Panel script prompt: each panel description must include quoted Bulgarian dialogue for the character to speak/think. At least 3 of 4 panels per page must have speech or thought text in the description. 2. Image prompt: added MANDATORY SPEECH BUBBLES block requiring at least 3 of 4 panels to contain a bubble, describing exact white-background/black-outline style for speech and cloud-shape for thought bubbles, all text Bulgarian Cyrillic. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06feat: Gemini panel script drives comic panels in narrative order, v0.25.0v0.25.0Paul Buetow
Previously story text was split mechanically into 5 sections and each panel was guessed from raw prose — causing repeated compositions and incoherent plots. Now GenerateFull requests a 20-entry panel visual script (P1-A…P5-D) from Gemini in the same API call as the story and bible. Each panel gets an explicit 1-2 sentence description of WHO/WHAT/WHERE/expression, written in chronological story order. buildStoryPagePrompt now uses these descriptions to drive the image model directly ("Draw each panel EXACTLY as described") instead of "scene N from the excerpt". Falls back to excerpt-driven prompts when the script is absent or incomplete. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06feat: --narrate opt-in narration, panel variety mandate, v0.23.0v0.23.0Paul Buetow
- 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>
2026-04-06refactor: decompose Processor god object into focused files (SRP)Paul Buetow
Extract audio coordination (voice selection, config assembly, attribution writing) into audio_coordinator.go, card directory management into card_store.go, and image downloading/searcher construction into image_downloader.go. processor.go shrinks from ~1119 to ~575 lines, each file now has a single clear responsibility. Also apply go fmt to all touched files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04feat: progressive retry backoff for rate-limited image generationPaul Buetow
Replace fixed 10s retry pause with pageRetryBase × attempt (15s→30s→45s→60s) and increase max retries from 3 to 5. Extracted shared retryPage() helper used by both generateStoryPage and generatePageWithRetry to keep retry logic DRY. Gallery pages that fail due to Gemini rate limits now recover automatically instead of being silently skipped after just 30 seconds of retries. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04feat: skip existing pages on re-run, add --story-slug for targeted repairv0.18.0Paul Buetow
- loadOrGenerate() in artist.go skips API calls for pages already on disk, loading bytes for the reference chain. Re-runs now only generate missing pages instead of regenerating the whole comic. - --story-slug flag forces the output directory slug so a repair run writes to the same directory as the original (e.g. --story-slug ai-jungle-quest). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04fix: remove per-page location lock to allow scene transitions in panelsPaul Buetow
The strict LOCATION rule (all 4 panels must show the exact same location) prevented natural scene progression within a page's story excerpt. Removed so characters can move through the environment across panels on a single page. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04feat: use photography-only style pool for ultra-realistic mode, update READMEv0.17.0Paul Buetow
Ultra-realistic mode now picks from a dedicated realisticStyles pool (DSLR photography, cinematic stills, hyper-realistic) instead of the comicStyles pool. This prevents "comic strip" language from dominating the model's output when photorealistic rendering is requested. README updated: 12-page comic count (5 gallery pages), rendering mode description clarified to show both pools and the 50/50 random default. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04fix: enforce per-page location from story excerpt, bump to 0.16.0v0.16.0Paul Buetow
- Add explicit LOCATION rule to story page prompt: all panels must show only the location described in that page's excerpt, not any other story location - Strengthen excerpt label so model illustrates only the current excerpt - Bump version to 0.16.0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04fix: gender-neutral gallery/cover prompts, support multiple main charactersv0.15.0Paul Buetow
- Replace all "heroine/her" references in gallery poses with gender-neutral "main character/them" - Explicitly instruct model to preserve character gender, not invent new characters - Support multiple main characters in gallery page instruction - Fix cover and back cover orientation: remove "portrait orientation" (canvas is 16:9 landscape) - Bump version to 0.15.0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04feat: 5 gallery pages with distinct poses, fix single-image layoutv0.14.0Paul Buetow
- Increase galleryPageCount from 3 to 5 (12 total pages per comic) - Add 2 new gallery poses: profile close-up and power stance full-body - Fix gallery prompt: explicitly state single 16:9 landscape image, no grid/panels Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04feat: random ultra-realistic/comic style, --no-ultra-realistic flag, updated ↵v0.13.0Paul Buetow
README - Random 50/50 rendering mode per run (ultra-realistic or standard comic style) - --no-ultra-realistic flag forces standard comic style when set - renderingRequirement const centralised and applied to all image prompts via DRY renderReq() method - Log rendering mode chosen at generation time - Update README: correct page count (10), output filenames, all --story flags documented - Bump version to 0.13.0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04feat: photorealistic rendering requirement in all image prompts, ↵v0.12.0Paul Buetow
vocabulary/theme files - Add renderingRequirement const applied to all prompts (cover, story pages, back cover, gallery) - Write <slug>_comic_vocabulary.txt with vocabulary words and story text for learning - Write <slug>_theme.txt recording the --story-theme used for easy reproduction - Enforce adult (18+) characters in generator to avoid content policy blocks on revealing clothing - Add cover/back cover retry logic (same pageMaxRetries as story pages) - Bump version to 0.12.0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04feat: 5 story pages, 3 gallery pages, cover retry, adult characters, shorter ↵v0.11.0Paul Buetow
TTS chunks - Increase story pages from 3 to 5 (10 total with cover/gallery/back) - Add 3 text-free gallery pages with close-up heroine poses before back cover - Add retry logic to cover and back cover generation (same as story pages) - Enforce adult (18+) characters in generator prompt to avoid content policy blocks - Reduce TTS chunk size from 200 to 100 words to stay under 1-minute quality threshold - Increase TTS timeout from 2 to 3 minutes to avoid spurious deadline exceeded errors Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03fixPaul Buetow
2026-04-03feat: comic pipeline v0.10.0 — iterative chaining, title slugs, comics ↵Paul Buetow
subfolder, 16:9 - Iterative image chaining: each page receives cover + prev page as pixel-level reference (multimodal) so the model copies appearance directly, not from text alone - --story-theme flag overrides random genre pick per run - Gemini now generates a short comic title (---COMIC TITLE--- separator) used as the output slug; all files named <slug>_cover.png, <slug>_page_1.png, etc. - All comic output stored under comics/<slug>/ subdirectory - Aspect ratio changed to 16:9 (ThinkPad X1 Gen 9 screen fit; 16:10 not supported) - Bulgarian language rule moved to top of every prompt for stronger compliance - Dynamic story-specific cover masthead + publisher logo badge matching story genre - --story-theme "a thrilling space..." forces genre without touching random pool Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03feat: append Gemini-generated cinematic epilogue at end of narrationPaul Buetow
- buildConclusion() calls gemini-2.5-flash (same SystemInstruction pattern) to write a 3-4 sentence Bulgarian cinematic epilogue (~40-60 words, ~15-30s) that reflects the story's emotion rather than recapping the plot - narrateConclusion() narrates it as a separate TTS chunk and appends it to the chunk list before final concatenation; failure is non-fatal - Narrator struct now stores apiKey for the text-generation call - Single-chunk path simplified: Rename instead of unnecessary concatenation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03fix: split long story narration into chunks to preserve voice qualityPaul Buetow
Gemini TTS voice quality degrades noticeably over long single-call texts. Split the story into ~200-word paragraph-aligned chunks, narrate each separately, then concatenate with ffmpeg's concat demuxer (copy codec, no re-encoding). Short stories (single chunk) still use one call. Temp files are written to a OS temp dir and cleaned up automatically. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03feat: lock age appearance across all comic pages, covers, and back coverPaul Buetow
- Bible prompt now requires EXACT age for each character (e.g. "8-year-old girl") and explicitly states age must not change across any page, cover, or back cover - Story page consistency rules now call out AGE APPEARANCE alongside face and clothing - Cover prompt: "Do NOT invent new characters or use generic stand-ins" — only story characters with matching age/face/clothing may appear - Back cover prompt: same restriction, plus "same age, same face, same clothing, same animals as in the interior pages" - Both covers updated with: "a child must never look older or younger than defined" Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03feat: traditional comic covers, animal consistency, back-cover blurb, PDF outputPaul Buetow
Cover/back improvements: - Front cover: MANDATORY TITLE instruction makes 'BULGARIAN VOCABULARY ADVENTURE' dominate the top 20% of the cover in bold masthead lettering - Back cover: Gemini generates a 2-3 sentence English marketing blurb that is embedded verbatim in the blurb-box instruction (italic display type) - Both covers now specify Silver-Age / Bronze-Age comic production layout (price box, barcode strip, cover lines) Animal consistency: - Character bible prompt now treats animals as named characters — specifies exact breed, fur colour/pattern, markings, and eye colour; instructs model never to substitute a generic animal or change markings between pages - Story page prompts add explicit animal consistency rule alongside human rules Bible/blurb reliability: - Switch helper calls to same SystemInstruction + user-content pattern that the story generator uses successfully with gemini-2.5-flash - Increase MaxOutputTokens to 8192 and timeout to 90s to match story generator - Retry pause extended to 15s for free-tier RPM recovery between rapid calls - Removed deprecated gemini-2.0-flash model references PDF generation (new internal/story/pdf.go): - AssembleComicPDF() combines all 5 images into comic.pdf via ImageMagick convert - Pages are in reading order: cover → story pages → back cover - Non-fatal: warns if ImageMagick is not installed, never blocks the pipeline Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03feat: 5-page comic with cover/back cover, 9-panel grid, and character biblePaul Buetow
- Add comic_cover.png and comic_back.png flanking the 3 story pages - Switch story pages to 3:4 portrait aspect ratio for standard comic proportions - Request 9-panel (3×3) grid layout in every story page prompt - Generate a Gemini character bible before image generation to lock characters, clothing, and setting across all 5 pages — clothing only changes if the story explicitly directs it - Fix nil-writer panic in cover warning path - Fix undefined comicPageCount reference in runner.go Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03feat: character bible for consistent comic panel charactersPaul Buetow
- Generate a Gemini character bible before panel image generation - Bible describes each character (name, age, hair, eyes, clothing) and setting; it is prepended to every panel prompt to lock visual consistency - Revert to 3 separate comic_page_N.png files (4:3 aspect ratio) - bibleMaxTokens=2048 to avoid Gemini 2.5 Flash thinking-token starvation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03feat: single tall comic strip with consistent characters and more dramatic ↵Paul Buetow
narration - Replace 3 separate comic pages with one 9:16 tall comic_strip.png - Prompt explicitly requests 3 vertically stacked panels with consistent characters - Add AspectRatio field to SearchOptions; NanoBanana uses it when set - Make cinematic narration instruction more dramatic (movie trailer narrator style) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03feat: add --story cinematic narration and comic strip generationPaul Buetow
- Generates a ~500-word Bulgarian vocabulary story from a batch file - Produces 3 comic pages via NanoBanana (90% ultra-realistic style) - Art style chosen randomly per run; override with --story-style - Cinematic Gemini TTS narration saved as story_narration.mp3 - Random voice from curated pool (Charon, Fenrir, Enceladus, Algieba, Aoede, Schedar) - Override narrator voice with --narrator-voice - Falls back to story_tts_todo.txt if narration fails - No new API key required — reuses existing GOOGLE_API_KEY - Bump version to 0.9.4 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>