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
| Module | Role |
|---|---|
tts_pipeline.py | Batch processor — directory scan, ordering, per-file pipeline |
tts_single.py | Single-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:
index.md(always first)pipeline/directory (tutorial flow)- 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 ---.