Audio version — Estimated duration: 3 min 12 sec

Pipeline flow

flowchart LR
    A[Scan .md files] --> B[Order files]
    B --> C[Build system prompt]
    C --> D[LLM rewrite]
    D --> E[Save voice-notes/]
    E --> F[TTS synthesis]
    F --> G[Embed audio tag]

Module layout

ModuleRole
tts_pipeline.pyBatch processor — directory scan, ordering, per-file pipeline
tts_single.pySingle-file wrapper — thin CLI over tts_pipeline internals

tts_single.py imports directly from tts_pipeline.py — all shared logic lives in one module.

Key internals

System prompt

build_system_prompt() constructs a prompt from the directory structure tree and (optionally) the root index.md content. The prompt instructs the LLM to:

  • Write conversational, spoken-word text
  • Avoid markdown, bullets, tables
  • Use verbal signposts
  • Output only the voice-ready text

File ordering

get_files_in_order() sorts files by:

  1. index.md (always first)
  2. pipeline/ directory (tutorial flow)
  3. Everything else (alphabetical)

Index files get a shortened prompt (~200 words) and a segue to the next file.

Rate limiting

A sliding-window limiter in _acquire() caps Cerebras API calls at 5 per 60 seconds. _rate_calls is a module-level list of timestamps pruned on each call.

Piper model management

download_piper_model() constructs the Hugging Face URL from the voice name and downloads both .onnx and .onnx.json to models/. Cached after first download.

Audio embed

inject_audio_tag() prepends an <audio> element with a mutagen-parsed duration to the source .md. Skips files that already have the **Audio version** marker. Handles YAML frontmatter by inserting after the closing ---.