# Copilot Instructions ## Running the App ```bash pip install -r requirements.txt python app.py # → http://localhost:7860 ``` Requires a GPU (T4 or A10G) for inference. No Docker, no database, no external APIs. ## Architecture Single-process Gradio app (`app.py`, ~1200 lines) that orchestrates four ML models: - **Qwen3-TTS-1.7B** (`voice_clone.py`) — zero-shot voice cloning from reference audio + cloned voice synthesis - **Supertonic TTS** — fast stock-voice fallback when no clone is available - **Qwen2.5-3B-Instruct** (`inference.py`) — story Q&A, 4-bit quantized on T4 - **Whisper-small** (`inference.py`) — child speech-to-text (loaded on demand) `tts.py` is the unified TTS interface. It delegates to Qwen3-TTS when a `voice_profile_id` is provided, otherwise falls back to Supertonic. Both backends use background-threaded streaming with a queue (maxsize=2 buffer). `voice_clone.py` manages the Qwen3-TTS model and a server-side in-memory cache of voice profiles keyed by UUID. Profiles are created via `create_voice_profile(ref_audio_path)` and reused for all subsequent synthesis calls. Stories are plain `.txt` files in `stories/` — title on line 1, blank line, then prose. No metadata DB. **State machine** governs playback: `playing → paused → playing`, `playing → asking → answering → resuming → playing`. All other transitions are illegal. The UI disables buttons for illegal transitions. ## Key Conventions - **All inference is local** — no external APIs, no data leaves the server. This is a hard privacy requirement. - **In-memory session cache only** — no database, no persistent storage of user data. - **Interruptible chunked streaming** — paragraphs are synthesized and played one at a time. Cached chunks enable instant replay/resume. - **Pre-generated Q&A** — anticipated questions generated in background during narration for sub-1s cache hits. - **VRAM budget awareness** — total ~8-9 GB on T4 (16 GB). All models lazy-loaded on demand. Use 4-bit quantization for the LLM. Qwen3-TTS (~1.7B) loads only when cloning starts. ## Story Pipeline `story_downloader/` contains utilities for acquiring new stories from Project Gutenberg: 1. `gutenberg_downloader.py` — reusable downloader/parser 2. `download_stories.py` — fetches stories by Gutenberg ID 3. `clean_stories.py` — strips headers/footers/illustration tags for TTS-clean output ## UI Gradio 5.x with custom CSS (`static/style.css`) for a Google Stitch-inspired design. Uses warm palette (#FFB347 accent, #FFF8E7 background), Nunito/Fredoka fonts, rounded cards, and micro-animations. ## Deployment Push to Hugging Face Spaces. The `README.md` frontmatter configures the Space (sdk: gradio, app_file: app.py).