Second session of the day. Added text-to-speech with 31 Kokoro voices (including Santa and Fenrir), expanded from 8 vibes to 22 with seasonal/aesthetic/genre themes, embedded Twitch streams in the media feed, fixed a cascade of queue sync bugs, shipped YouTube search, follower alerts, emote rendering, and ran full code reviews that caught three production-impacting issues.
Text-to-Speech Integration
Kokoro TTS (82M params, CPU-based, no VRAM impact) now reads chat messages and generation results aloud on stream. 31 voices available — from sensible defaults (Adam, Bella) to meme gold (Santa, Fenrir the Epic, Puck the Mischievous), plus three Spanish voices. Per-user voice selection via !myvoice bella persists to disk across restarts. Mods control the stream's default voice with !voice, and can toggle chat TTS, generation TTS, or the master switch independently via !tts on/off/chat/gen. Volume is independently adjustable with !volume (video) and !ttsvolume (TTS). A pronunciation override map ensures "JefeHz" is spoken as "Jefe Hertz" and "AIMemeLord" as "A.I. Meme Lord."
22 Vibes
Expanded from 8 to 22 vibe themes. Each one changes three things: the overlay color palette (CSS custom properties), the image generation style hints (appended to prompts), and the idle video injection pool (8-10 curated YouTube videos per vibe). New additions include seasonal vibes (spring, summer, autumn, winter), aesthetic vibes (pastel-princess, chill, forest, synthwave, hand-drawn), and genre vibes (horror, steampunk, underwater, noir, psychedelic). The prompt rewriter was also overhauled — Ollama was completely rewriting prompts into unrelated content, so we bypassed it entirely. User prompts now pass through directly with quality tags and light vibe suffixes. A trained local model can replace this later.
Queue Wars
The media queue went through four bug-fix iterations during the live stream. First: an infinite skip loop where the overlay called /api/media/skip on video end, the server broadcast media_skip back, the overlay called skip again, repeat until crash. Fixed with a dedicated /api/media/advance endpoint that doesn't broadcast skip events. Second: videos repeating because the overlay's local currentMedia wasn't syncing from the server. Third: new videos not auto-starting when the queue went from empty to items. Fourth: fair round-robin insertion so one user can't monopolize the queue — each user gets one slot before anyone gets a second.
Twitch Embeds and YouTube Search
!host oceanmanor embeds another Twitch stream directly in the media viewport via the Twitch Embed SDK. Twitch's mature content warning requires a one-time click via OBS Interact, but after that the stream plays with audio routed through OBS. !yt techno viking now searches YouTube via yt-dlp and queues the top result — no URL needed. Video titles are auto-fetched on queue add (in a thread executor so it doesn't block the event loop), and a JSONL play history logs every video for later analysis.
Code Reviews and Fixes
Two parallel code reviews caught six issues. The three critical ones were fixed immediately: a one-character CDN URL typo that broke all Twitch emotes in the chat overlay (jtvnbs.net → jtvnw.net), a missing get_vibe() method that made idle injection always use the default video pool, and a synchronous yt-dlp call inside an async endpoint that blocked the event loop for 5-10 seconds per queue add. On the Jefebot side: the EventSub reconnect fix was emitting connection_failed which permanently disabled EventSub routing even though reconnects continued in the background, and the follower subscription was grabbing the wrong broadcaster ID from the subscriptions map.
Also Shipped
- GygaxBot Session IV published to jefehz.org/gygaxbot
- Follower alerts with animated overlay popup
- Twitch emotes rendered as images in Live Chat
- 325 output captions (was 45), 230 terminal demo messages
- Command advertising via pre-canned rotating messages (no API calls)
- #aimemelord translation and greeting service enabled
- Translation false positive fix (English-to-English echo)
!imagealias,!help/!commands/!voices- Queue bump up/down buttons on dashboard
- Glitch vibe animation scoped to UI only (not media viewport)
What's Next
- Per-vibe particle effects (snowfall, cherry blossoms, fireflies)
!sharechatfor cross-channel chat relay- Trained local prompt expansion model (replace the bypassed Ollama)
- Voice resolution tightening (too greedy on partial matches)
- Media history analysis — cross-reference plays with playlists