Commit History
-
readme update
c9985d0 -
Use real public-domain music loops for the sound beds
jayaspjacob +1: Claude Opus 4.8 (1M context)Add four FreePD (Kevin MacLeod, CC0/public-domain) loops as the background beds — Ambient Drift (Ambient C Motion), Lo-fi Pulse (Chill Beat), Cinematic Rise (Wonder Flow), Newsroom Bed (Action Investigation) — fetched via scripts/build_music_loops.py and stored as compact mono FLAC (LFS). tts/music.py now loads/loops the real track (crossfaded to episode length) when present and falls back to the procedural numpy bed otherwise. Credits added to the README. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>d07d1a1 -
Mix procedural background music under the podcast
jayaspjacob +1: Claude Opus 4.8 (1M context)The sound bed was only a label. Add tts/music.py, which synthesizes four mood beds with numpy (Ambient Drift, Lo-fi Pulse, Cinematic Rise, Newsroom Bed) — soft sine-pad chords, tremolo, and kick pulses — with no licensing or asset files. run_tts now mixes the selected bed under the generated speech at a low level (peak-guarded), and "No music" stays a clean no-op. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>60cefb1 -
Keep emotion cues out of audio; show them as direction tags
jayaspjacob +1: Claude Opus 4.8 (1M context)S1-mini (0.5B) vocalizes "(excited)"/"(chuckling)" markers instead of acting on them (parentheses is the correct/only format per the model card; brackets wouldn't help — the model just reads the literal text). So strip the parenthetical cues from the text sent to TTS, and render them as small styled tags in the review bubbles and transcript so the emotional direction still shows. Also harden the dropdown anchor (.wrap position:relative + card stacking on focus-within). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>cd64c45 -
Fix dropdown popup mispositioning from animated ancestors
jayaspjacob +1: Claude Opus 4.8 (1M context)A CSS transform on an ancestor reparents Gradio's absolutely-positioned dropdown popup, sending the options list to the top-left. Remove transforms from elements that contain dropdowns: config/cast cards now use an opacity-only entrance and a glow-only hover (no translateY), and the container no longer sets position:relative. Transform lifts are kept only on cards without dropdowns (voice tiles, episode cards, bubbles). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>75902ca -
Add rich animations and motion polish
jayaspjacob +1: Claude Opus 4.8 (1M context)Pure-CSS flourish for the hackathon: animated aurora background, staggered entrance animations that replay on step/page transitions, glowing pulsing CTAs, hover lifts on cards/chips/avatars, a floating shimmering logo, pulsing live-status dot, focus glow on the topic box, and live equalizer waveforms on Library cards. Honors prefers-reduced-motion. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>42b0516 -
Sync the header cast chip with the picked voices
jayaspjacob +1: Claude Opus 4.8 (1M context)The top-right "Nova × Atlas" chip was static. Make it reflect the actual voice picks: the header is rebuilt from the selected voices (with matching avatar colors) whenever a voice dropdown or the speaker-count slider changes, across all three page headers. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>32a688b -
Real, saveable episodes in the Library
jayaspjacob +1: Claude Opus 4.8 (1M context)Replace the placeholder Library grid with the user's actual generated episodes. run_tts now persists each episode's wav under _episodes/ and returns an episode record; a "Save to library" button on the result screen stores it (in-session) and opens the Library, which renders a fixed pool of slots with a real audio player per saved episode. Empty-state shown when none. allowed_paths covers the episodes + samples dirs so the players can serve the files. _episodes/ is gitignored (runtime-generated). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>165b02d -
Add OpenAudio emotion/tone cues to generated scripts
jayaspjacob +1: Claude Opus 4.8 (1M context)Instruct the scriptwriter to add inline parenthetical cues from OpenAudio S1's supported set — (excited) (chuckling) (laughing) (sighing) (whispering) etc. — sparingly where they fit. These pass through parse_script and the TTS request unchanged, so the model renders them as emotion/tone. Note: S1 uses parentheses, not square brackets, and has no pause/emphasis marker (punctuation handles those), so the prompt steers away from [chuckle] -style tags that would otherwise be read aloud. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>9756234 -
Select podcast voices on the Create page
jayaspjacob +1: Claude Opus 4.8 (1M context)Add a "Cast" picker on the Create step with one voice dropdown per speaker (Nova/Atlas/Echo/Sage/Vivi/Onyx/Rune), shown per the speaker-count slider. The picked voices drive the actual TTS: each script speaker maps to that voice's reference clip (tts/voices/samples/<id>.wav), so episodes use the chosen voices and hosts sound distinct. Selected names are also passed as the script's speaker labels when distinct, so dialogue reads "Nova: …". Removes the old step-2 per-speaker preset/clone assignment (voices are now chosen up front); setup_voices just parses lines + speakers. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>4c38fd0 -
Add playable voice samples + cap episode length at 2 min
jayaspjacob +1: Claude Opus 4.8 (1M context)Voices: source permissively-licensed clips from CMU ARCTIC (fish-speech ships none), assembled by scripts/build_voice_samples.py into ~20s clips. The Voices page now renders a gr.Audio player per voice so samples are audible while browsing. Three clips also back the narrator_warm / host_energetic / guest_calm presets, so podcast hosts finally sound distinct instead of all rendering as the default speaker. UI: cap the Create LENGTH selector at 2 min (default 2) so generation stays well under the ZeroGPU 300s cap. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>310ca13
-
Pin torch/torchaudio to 2.8.0 for fish-speech audio I/O
jayaspjacob +1: Claude Opus 4.8 (1M context)torchaudio 2.9 removed torchaudio.list_audio_backends() (called in fish-speech ReferenceLoader.__init__) and migrated audio I/O to TorchCodec, which this S1-era fish-speech doesn't use -> AttributeError at engine init. 2.8.0 is the proven pair that loads the models and reaches generation on the ZeroGPU Space, and satisfies fish-speech's torch<2.9.0. Versions must match. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>09c9a6a -
Switch script LLM to an available provider model
jayaspjacob +1: Claude Opus 4.8 (1M context)HF Inference Providers no longer serve Qwen/Qwen2.5-14B-Instruct for this account ("not supported by any provider you have enabled"), causing a 400 on every script generation. Default to Qwen/Qwen2.5-7B-Instruct — same family/prompt behavior, still served, under the 32B cap. Override with LLM_MODEL (e.g. google/gemma-3-27b-it) for higher quality. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>ac82455 -
Pin fish-speech to S1 commit so the tiktoken tokenizer loads
jayaspjacob +1: Claude Opus 4.8 (1M context)The previous pin (02995ed, S2-beta line) refactored FishTokenizer to use transformers AutoTokenizer, which can't read openaudio-s1-mini: that model ships tokenizer.tiktoken + special_tokens.json (no tokenizer.json) with model_type=dual_ar, so AutoTokenizer fails, model.tokenizer is None, and every line dies in content_sequence.encode -> empty audio. Pin to 781bf1c (Finetune support of OpenAudio-S1, 2025-10-20), whose FishTokenizer loads the tiktoken vocab directly. It still exposes the dac decoder + TTSInferenceEngine + ServeTTSRequest API engine.py uses and keeps pydantic==2.9.2, so gradio==5.27.0 is unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>979b98f -
Resolve fish-speech root via __path__ (namespace package)
jayaspjacob +1: Claude Opus 4.8 (1M context)fish_speech is a PEP 420 namespace package on the Space, so __file__ is None and the previous fallback raised TypeError. Locate the package dir via __path__[0] (or by walking up setup_root's caller path) and use its parent as the project root. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>f3cc6d3 -
Fix fish-speech project-root crash by wrapping setup_root
jayaspjacob +1: Claude Opus 4.8 (1M context)The earlier find_root patch missed: setup_root lives in the pyrootutils.pyrootutils submodule and resolves find_root from that submodule's globals, not the package-level re-export. Wrap the exact attribute fish_speech calls (pyrootutils.setup_root) so the FileNotFoundError fallback to the installed package's parent dir is guaranteed to apply. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>57f0925 -
Add producing/loading screen and fix fish-speech project-root crash
jayaspjacob +1: Claude Opus 4.8 (1M context)UI: show a full-panel animated loader (orbital spinner + step checklist) while the script is written and the podcast is produced, swapped in before the work runs and out when it completes — matches the studio mockup. TTS: patch pyrootutils.find_root before importing fish_speech inference modules. A pip-installed fish-speech has no .project-root marker, so its setup_root() call raised FileNotFoundError; the fallback uses the installed package's parent dir, which we can't create as a file in root-owned site-packages at runtime. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>310b223 -
Redesign UI as Podify AI Podcast Studio
jayaspjacob +1: Claude Opus 4.8 (1M context)Theme the Gradio app to match the Podify studio mockups: dark gradient shell with a Create/Voices/Library sidebar and a three-step Create flow (topic -> review script bubbles -> finished episode). Keeps the existing research + Fish Audio backend and the pinned gradio 5.27.0; no account or upgrade UI per demo scope. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>3b8e550 -
Ignore Claude Code artifacts so they never push to the Space
jayaspjacob +1: Claude Opus 4.8 (1M context)Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>6a29d8e -
Use Qwen2.5-14B for script generation (<32B param cap)
jayaspjacob +1: Claude Opus 4.8 (1M context)Switch the default content LLM from Llama-3.3-70B to Qwen/Qwen2.5-14B-Instruct to satisfy the sub-32B model constraint. Still overridable via LLM_MODEL. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>9f34209 -
Add portaudio19-dev so pyaudio (a fish-speech dep) compiles
jayaspjacob +1: Claude Opus 4.8 (1M context)pyaudio ships only an sdist for this env, so it builds from source and needs the portaudio headers. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>237b681 -
Fix build: pin gradio to 5.27.0 to avoid pydantic conflict
jayaspjacob +1: Claude Opus 4.8 (1M context)HF's builder auto-appends the gradio `mcp` extra from 5.28.0 on, which requires pydantic>=2.11 and clashes with fish-speech 2.0's hard pin pydantic==2.9.2. gradio 5.27.0 (>5.0.0, no mcp extra) resolves cleanly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>e9e8e24 -
Fix build: bump gradio to 5.32.1 and pin fish-speech
jayaspjacob +1: Claude Opus 4.8 (1M context)fish-speech 2.0 (the OpenAudio S1 era with the dac/TTSInferenceEngine API) requires gradio>5.0.0, which conflicted with the pinned gradio 4.44.0. Align with the reference openaudio-s1-mini Space (gradio 5.32.1) and pin fish-speech to a reproducible commit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>b2c20dc -
Add Podify AI podcast generator app
jayaspjacob +1: Claude Opus 4.8 (1M context)Two-phase Gradio app: - Phase 1: LangGraph research agents (HF Inference LLM + DuckDuckGo) write a script - Phase 2: Fish Audio OpenAudio S1-mini TTS on ZeroGPU with presets + voice cloning Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>623fe6a -
initial commit
Verified signature842e5ab