FableFlow Core API ๐#
Programmatic and CLI access to the book-first generation pipeline. The pipeline runs in two phases โ Phase 1 builds the book (book_content.json โ PDF/EPUB), Phase 2 adapts it to a movie (MP4).
๐ Getting Started#
Installation#
Prerequisites: Python 3.13, Git, and (for media generation) a CUDA GPU.
git clone https://github.com/suneeta-mall/fable-flow.git
cd fable-flow
make install # uv sync โ creates .venv from uv.lock
Environment Configuration#
The LLM client uses the OpenAI wire format and points at any compatible server. Set these in .env:
MODEL_SERVER_URL=http://localhost:8000/v1 # vLLM, Ollama, or a hosted proxy
MODEL_API_KEY=your-api-key
DEFAULT_MODEL=google/gemma-4-31B-it
See Configuration for the full set of options.
CLI Usage#
The CLI exposes two commands:
# Validate an input spec without generating anything
fable-flow validate examples/cassie_beach_adventure_input.json
# Run the full pipeline: story โ book (PDF/EPUB) โ movie
fable-flow generate examples/cassie_beach_adventure_input.json
generate options:
| Flag | Effect |
|---|---|
--output, -o DIR |
Output directory (default output/<input_name>) |
--model, -m NAME |
Override the LLM from config |
--book-only |
Skip Phase 2 (movie) |
--skip-book-publish |
Skip PDF/EPUB rendering (book_content.json is still written) |
--resume |
Reuse artifacts already on disk; only generate what's missing |
Or via the Makefile:
make run INPUT=examples/cassie_beach_adventure_input.json
make validate INPUT=examples/cassie_beach_adventure_input.json
๐ Architecture#
FableFlow is a sequence of focused agents, each calling an LLM or media model. The book is the authoritative artifact; the movie adapts from it.
Phase 1 โ Book (fable_flow.agents)
DraftStoryAgent,StoryEditorAgent,FinalProofAgentโ draft, edit, proof the story (story_development.py)ChapterStructureAgent,IllustrationPlacementAgentโ chapters and illustration plan (book_assembly.py)CharacterReferenceAgentโ canonical character reference images (character_ref.py)IllustrationGeneratorAgentโ render illustrations (book_assembly.py)CoverDesignerAgentโ front/back covers (cover_designer.py)BiographyAgent,ExperimentDesignerAgent,ReflectionGeneratorAgentโ enrichment (enrichment.py)create_book_content()orchestrates these into aBookContent
Phase 2 โ Movie (fable_flow.agents)
SceneExtractorAgentโ break the book into scenes (movie_adaptation.py)SceneProductionCoordinatorโ narration-first multimedia per scene (scene_production.py)MovieAssemblerAgentโ assemble the final MP4 (movie_adaptation.py)
See the complete workflow for how these connect.
๐ง Configuration#
fable_flow.config exposes a single validated config object loaded from config/default.yaml + .env.
from fable_flow.config import config
config.model.server.url # e.g. http://localhost:8000/v1
config.model.default # e.g. google/gemma-4-31B-it
config.model.image_generation.model # e.g. black-forest-labs/FLUX.2-dev
config.paths.output # Path("output")
Key config groups (see producer/fable_flow/config.py): ModelServerConfig, ModelConfig, ImageGenerationConfig, TextToSpeechConfig, MusicGenerationConfig, VideoGenerationConfig, PathsConfig, StyleConfig, PDFConfig, BookConfig.
๐ค Model Classes#
Each media type is wrapped in an Enhanced*Model class in fable_flow.models. All generation methods are async.
from fable_flow.models.text import EnhancedTextModel
model = EnhancedTextModel() # uses config.model.default
text = await model.generate(
prompt="Enhance this story: ...",
system_message="You are a children's book editor.",
temperature=0.7,
)
| Class | Method | Returns |
|---|---|---|
EnhancedTextModel |
generate(prompt, system_message, temperature=None, max_tokens=None) |
str |
EnhancedImageModel |
generate_image(prompt, width, height, seed, negative_prompt) |
bytes (PNG) |
EnhancedImageModel |
generate_with_reference(prompt, reference_image_path, ...) |
bytes (PNG) |
EnhancedTTSModel |
generate_speech(text, voice_id=None) |
bytes |
EnhancedMusicModel |
generate_music(prompt, max_new_tokens=256) |
bytes |
EnhancedVideoModel |
generate_video(...) |
video frames |
The image/video/music/TTS classes load their pipelines on construction and expose release() to free GPU memory.
๐ Book Generation#
Books render from a BookContent object via fable_flow.publishers:
from pathlib import Path
from fable_flow.schemas.book_content import BookContent
from fable_flow.publishers import generate_pdf, generate_epub
book = BookContent.from_json_file("output/my_book/book_content.json")
generate_pdf(book, Path("output/my_book/book.pdf"))
generate_epub(book, Path("output/my_book/book.epub"))
Both are CPU-only (ReportLab for PDF, a zipped EPUB 3 package) and read styling from config.pdf / config.book.
๐ Programmatic Usage#
Run the full pipeline from Python by reusing the CLI entry point:
import asyncio
from pathlib import Path
from fable_flow.app import _run_pipeline
asyncio.run(_run_pipeline(
input_file=Path("examples/cassie_beach_adventure_input.json"),
output_dir=Path("output/cassie"),
model=None,
book_only=True,
skip_book_publish=False,
resume=True,
))
Or drive individual agents directly โ load a FableFlowInput, then call the agent you need:
from fable_flow.schemas.input_spec import FableFlowInput
from fable_flow.agents.story_development import DraftStoryAgent
spec = FableFlowInput.from_json_file("examples/cassie_beach_adventure_input.json")
draft = await DraftStoryAgent().generate_story(spec)
๐ฅ๏ธ FableFlow Studio#
Studio is a separate web app for editing book_content.json and re-running media generation. It reuses the schemas, models, and publishers above.
make studio-start # API on :8077, UI on http://localhost:3000
Key endpoints (studio/api.py): GET /api/projects, GET|POST /api/book, POST /api/ai/improve, POST /api/ai/chat, POST /api/image/regenerate, POST /api/publish.
๐ Data Models#
All artifacts are Pydantic models with from_json_file() / to_json_file():
FableFlowInput(schemas/input_spec.py) โ project, characters, story seed, production configBookContent(schemas/book_content.py) โBookMetadata,Chapter[],IllustrationSpec,Experiment,Biography,CoverImagesSceneManifest(schemas/scene_manifest.py) โSceneSpec[]plus narration/image/video/music/subtitle assets
๐งช Testing#
make test # full suite
uv run pytest tests/unit/agents -q # a subset
uv run pytest --cov=fable_flow # with coverage
๐ Further Documentation#
- Complete Workflow โ agents and pipeline details
- Story Processing โ draft โ edit โ proof
- Book Production โ PDF/EPUB generation
- Illustration Generation โ image generation
- Configuration โ all config options