Conversation
added 13 commits
June 1, 2026 06:10
- Reconstruct video_generator.py with full API (cancel, continue, resume, retry, preview, list_jobs) and thread-safe RLock guards - Add render_pipeline.py with parallel scene compilation, checkpointing, frame critic loop, and REPL code fixing - Add llm_providers.py with multi-provider support (OpenAI, Claude, Kimi, MiniMax, Ollama) - Add tts_generator.py with OpenAI and ElevenLabs TTS support - Add script_import.py for parsing scripts in multiple formats - Add frame_critic.py for visual quality critique - Add style_registry.py, visual_events.py, video_settings.py - Add provider_health.py, prompt_template.py, env_loader.py - Harden concat_video.py with subprocess validation and tempfile usage - Update main.py Flask API with new endpoints and 16MB upload limit - Update animations.py to return (data, error) tuples - Add 67 tests across json_utils, llm_providers, script_import, video_generator_integration, loose_format, messy_import - Add GitHub Actions CI workflow (ruff, black, mypy, pytest) - Add Docker HEALTHCHECK and restart.ps1 helper
…ad race - Add 47 tests for render_pipeline (cancellation, checkpointing, REPL) - Add 16 tests for concat_video (sanitize, compile, concat, merge) - Add 13 tests for frame_critic (env parsing, critique, prompt building) - Fix flaky test_generate_video_workflow_success caused by daemon threads from test_start_video_generation_creates_job leaking into next test - Store worker threads in _job_threads dict instead of job record to avoid Flask JSON serialization errors - Update clean_jobs fixture to cancel and join lingering threads
- Add 62 tests for video_settings, llm_errors, env_loader, provider_health, llm_chat - Add 24 Flask endpoint integration tests (test_api_endpoints.py) - Fix llm_errors.py: check 'suspended' before generic 'insufficient balance' - Fix llm_chat.py: Ollama vision passes base64 strings directly (was decoding to bytes causing JSON serialization crash) - Fix clean_jobs fixture to cancel and join lingering daemon threads, eliminating flaky test_generate_video_workflow_success - Store worker threads in _job_threads dict to avoid Flask JSON errors - Update README.md with multi-provider setup, Docker instructions, API docs, troubleshooting table - Add AGENTS.md with project conventions and common pitfalls Total: 200 tests passing
- Add _safe_project_path() validator to concat_video.py, tts_generator.py, frame_critic.py — rejects paths outside project root, null bytes, empty - Validate inputs in compile_video, concatenate_videos, merge_video_and_audio - Validate audio paths in get_audio_duration and concatenate_audio_fragments - Validate video_path in extract_video_frames - Add 13 path-security tests (traversal, absolute outside, null bytes, empty) - Update concat_video tests to use project-relative temp files so they continue passing under the new validation rules 213 tests passing
- Add video_assembler.py using MoviePy 2.x for programmable editing - Title cards and end screens with dark navy Topic2Manim styling - Crossfade and fade-to-black transitions between scenes - Audio fade in/out processing - Fallback to ffmpeg concat if MoviePy fails - Wire all settings through video_settings (UI-configurable) - Update frontend: transition type, title/end toggles, durations, audio fade - Update tests for new settings and race-condition fix
…eview Interactive HTML wrapper (feature 2): - video_html_wrapper.py generates self-contained HTML player with chapter navigation, scene seeking, prev/next buttons, and download link - Uses ffprobe to compute actual scene durations for accurate timestamps - Integrated into video_generator.py — html_url returned in job status - Frontend shows 'Open Interactive Player' button alongside video result Better script editor (feature 3): - New /api/preview-code endpoint compiles raw Manim code synchronously - Each scene card in script review gets collapsible 'Manim Code' section - Users can paste/write Manim Python code, specify class name, and preview - Preview renders at preview quality via compile_video and shows in modal - collectScriptFromEditor captures code and code_class for future pipeline use Tests: 4 new API endpoint tests for preview-code (217 total passing)
- New src/db.py module with httpx-based Supabase REST client - Falls back to local JSON files if SUPABASE_URL/SUPABASE_KEY not set - Job data serialized to rows with JSONB columns for script, checkpoint, config - video_generator.py uses db.persist_job / db.load_job / db.list_recent_jobs - On startup, recent jobs sync from Supabase into the in-memory dict - No new heavy dependencies — uses httpx (already installed via openai)
- OpenAI-compatible clients now get 60s timeout + 2 retries (was indefinite) - Ollama default changed from https://ollama.com to http://localhost:11434 (the actual Ollama API endpoint). Default model changed to llama3.2. - SSL verification disabled for local Ollama instances (localhost, 127.0.0.1, :11434, host.docker.internal) to avoid self-signed cert errors - Ollama model listing timeout reduced from 30s to 15s - Provider health checks catch APITimeoutError specifically and report clear 'Connection timed out' messages instead of raw stack traces - Updated tests: local Ollama is considered configured by default
Backend: - POST /api/batch accepts a list of topics and starts a video job for each - GET /api/batch/:batch_id returns aggregate status with per-job progress - Batches are tracked in-memory with polling-friendly status counts Frontend: - New 'Batch' tab alongside 'From Topic' and 'Import Script' - Textarea accepts one topic per line (up to 50) - Batch progress panel shows completion bar and per-job status cards - Auto-polls batch status every 3 seconds until complete
- generate_scene_code() in render_pipeline.py now checks for 'code' and 'code_class' fields on scene data (from the script editor) - When custom code is present, it skips LLM generation and uses the user's code directly — preserving class_name for compilation - Falls back to AI generation when no custom code is provided - Added 4 tests: custom code path, LLM fallback, batch create, batch empty
Narrative Arc Planner: - New src/narrative_planner.py generates structured pedagogical plans before any scene script is written - Plans include: title, hook, misconception, aha_moment, emotional_arc, scene_beats with purpose/pacing, visual_metaphors, color_theme - Integrated into video_generator.py — plan is generated first, then fed into script generation as narrative context - Job status persists the narrative_plan for frontend display Enhanced Script Generation (animations.py): - Script prompt now requires narrative arc structure: Scene 1 = HOOK (question/paradox, never 'Today we will learn...') Scenes 2-3 = SETUP (show the intuitive but WRONG approach) Middle = BUILD (visual intuition before formulas) Aha scene = REVEAL (extra breathing room, dramatic visual) Final = PAYOFF + CLOSE (real-world connection, single takeaway) Enhanced Manim Code Generation (manim_generator.py): - Color palette system: max 5 colors, specific hex values, no raw RED/BLUE - Opacity & visual salience: primary 1.0, secondary 0.5-0.7, structural 0.15-0.25 - Typography hierarchy: 48/36/30/24/20px scale with monospace fonts - Breathing room enforcement: mandatory self.wait(1.0) after reveals, self.wait(2.0) after aha moments - Better easing guidance: smooth default, linear only for mechanical, specific run_time ranges per animation type - Beat-based timing with explicit wait annotations Tests: 229 passing (added 5 narrative_planner tests)
… style overrides Content Quality Roadmap (all items): - Auto-captions: SRT generation + ffmpeg subtitle burn with ASS styling - Background music: mood inference from topic/visual events, configurable volume - Sound effects: mapped from visual events at scene timestamps - Quality metrics: Flesch Reading Ease, WPM pacing, retention prediction scoring - Scene thumbnails: ffmpeg frame extraction + PIL overlays + composite timeline - Per-scene style overrides: color palette, animation speed, font size Frontend integration: - New toggles: captions, music, SFX, thumbnails - Music volume slider with dB readout - Results panel: quality metrics scorecard + suggestions - Results panel: scene thumbnail timeline + grid - Real-time script linter: debounced metrics API calls during editing - Style override controls per scene card API additions: - GET /api/jobs/<id>/metrics - GET /api/jobs/<id>/thumbnails - POST /api/metrics/analyze Tests: 32 new tests across 3 files (261 total passing)
Vector Database (src/vector_snippets.py): - SQLite-backed storage for Manim code snippets with embeddings - OpenAI text-embedding-3-small + Ollama nomic-embed-text support - Cosine similarity search with configurable threshold - Automatic snippet extraction from completed jobs - Semantic search injected into LLM prompts as relevant examples Chapter Auto-Segmentation (src/chapter_segmentation.py): - LLM-based semantic grouping of scenes into chapters - Heuristic fallback: explicit chapter fields, title shifts, content keywords - Groups 2-4 scenes per chapter naturally - Integrated into interactive HTML player API additions: - POST /api/snippets/search — semantic search for code snippets - GET /api/snippets/count — total snippet count - POST /api/chapters/segment — auto-segment scenes into chapters Tests: 16 new tests (277 total passing)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This branch bundles 5 major feature groups aimed at making Topic2Manim a production-ready automation tool for multi-channel YouTube workflows.
🎬 1. MoviePy Video Assembly
Replaces raw ffmpeg concat with video_assembler.py
Title cards, crossfade/fade-to-black transitions, end screens
Audio fade in/out
Cross-platform font discovery via PIL
Falls back to ffmpeg if MoviePy fails
📋 2. Interactive HTML Player
video_html_wrapper.py generates a self-contained HTML player alongside every MP4
Chapter navigation with accurate timestamps (via ffprobe)
Scene seeking, prev/next buttons, download link
Returned as html_url in job status; frontend shows "Open Interactive Player" button
📝 3. Inline Manim Code Editor + Live Preview
New POST /api/preview-code endpoint compiles raw Manim code synchronously
Each scene card in the script review editor gets a collapsible "Manim Code" section
Users can write Python code, specify a class name, and preview at -pql quality
Custom code is captured by collectScriptFromEditor() and flows through the render pipeline — when code + code_class are present, LLM generation is skipped entirely
☁️ 4. Supabase Database Persistence
New src/db.py uses httpx (already installed) to sync jobs to Supabase REST API
Falls back to local JSON files if SUPABASE_URL/SUPABASE_KEY are not set
Jobs sync from cloud/local into memory on server startup
Replaces ad-hoc file persistence in video_generator.py
🔌 5. Provider Reliability + Batch Queue
OpenAI-compatible clients: 60s timeout + 2 retries (was indefinite)
Ollama default fixed to http://localhost:11434 with llama3.2
SSL verification disabled for local Ollama instances
Health checks catch APITimeoutError with clear messages
New Batch tab: paste one topic per line, queue up to 50 videos
POST /api/batch + GET /api/batch/:id with live progress polling
Test Results
222 passed in ~12s
After merging
git checkout main && git pull
uv sync (or pip install -e .)
Optional: add SUPABASE_URL and SUPABASE_KEY to .env for cloud persistence
Optional: set OLLAMA_BASE_URL=http://localhost:11434 if running Ollama locally