πŸ€– Manhwa Recap Robot

Turn a one-line premise into a complete AI manhwa recap video: original story narration β†’ AI Horde images β†’ TTS voice β†’ Ken Burns motion MP4.

Live: https://manhwa-recap-robot.val.run/

Files

FilePurpose
main.tsHTTP server. Serves index.html/app.js (via staticHTTPServer) and the POST /api/generate AI Horde image backend.
index.htmlThe app UI.
app.jsAll client logic β€” story writing, strict scripting engine, image/voice/video compilation.

The Strict Scripting Engine

Instead of recapping real manhwa pages, the tool writes an original story from a premise and enforces a hard line-level style:

  • Present tense, active voice
  • 8–12 words per line
  • One action per sentence
  • No filler or meta-commentary

How it's enforced in app.js:

  • validateLine(line) β€” heuristic validator that returns { ok, words, issues[] }. It flags violations (past-tense verbs, passive …by…, chained actions, filler phrases) rather than silently rewriting text, since programmatic grammar conversion is unreliable.
  • renderValidation(lines) β€” paints each line in the storyboard green/red with its word count and the exact issue, plus a summary note.
  • writeStory β€” after an LLM call, if more than ~30% of lines fail validation, it retries the LLM up to 2Γ—, feeding back the precise list of failing lines ("Line 2 (14w): 14 words…") so the model corrects itself. One or fewer bad lines is tolerated.
  • defaultStory() β€” the no-key offline fallback. Fixed bug: the original returned a hard-coded 5 lines regardless of the panel count, so narration repeated verbatim. It now builds exactly count distinct lines via combinatorial slot-filling (NARR_OPEN Γ— NARR_WHERE Γ— NARR_THREAT), validated in place, so 12 panels never repeat.

Keys

All keyed services are optional (click πŸ”‘ Keys in the app and save β†’ stored in your browser's localStorage):

  • LLM Key β€” any OpenAI-compatible endpoint (sk-… from OpenAI/OpenRouter/Groq) for AI story writing.
  • AI Horde Key β€” server-side secret for images. Optional (anonymous works, with lower queue priority). Set the val's AI_HORDE_KEY env var.
  • Murf AI Key β€” paid TTS; leave blank to use the free TTS proxy (tts-proxy).

Image backend

main.ts generates one image per panel on AI Horde as same-origin data URLs (so the canvas is never tainted), polling until done with a 2‑min/panel cap. Every panel shows a canvas placeholder instantly, then real art swaps in as each URL resolves.

Notes on the AI Horde integration (these were the bugs that blocked image generation):

  • Dimensions must be multiples of 64 β€” the backend snaps them.
  • An apikey header is required on every request β€” it defaults to the shared anonymous key 0000000000.
  • Anonymous is capped at 850Γ—850 β€” the backend scales the requested size down to fit while preserving aspect ratio. Setting a registered AI_HORDE_KEY lifts the cap to 2048 (full 720p/1080p quality).