Commit Graph

73 Commits

Author SHA1 Message Date
7d88c76f90 Add post-production pipeline: stem recorder, postprod script, recording UI
New stem recording system captures 5 time-aligned WAV files (host, caller,
music, sfx, ads) during live shows. Standalone postprod.py processes stems
into broadcast-ready MP3 with gap removal, voice compression, music ducking,
and EBU R128 loudness normalization.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 17:53:32 -07:00
356bf145b8 Add show improvement features: crossfade, emotions, returning callers, transcripts, screening
- Music crossfade: smooth 3-second blend between tracks instead of hard stop/start
- Emotional detection: analyze host mood from recent messages so callers adapt tone
- AI caller summaries: generate call summaries with timestamps for show history
- Returning callers: persist regular callers across sessions with call history
- Session export: generate transcripts with speaker labels and chapter markers
- Caller screening: AI pre-screens phone callers to get name and topic while queued

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 02:43:01 -07:00
de5577e582 Add local food opinions, nostalgia, and show history reactions
Callers now have strong food opinions (Sparky's green chile, Blake's
Lotaburger, etc.), nostalgic memories of how their town used to be,
and 60% chance of having a strong reaction to a previous caller that
they bring up early in the call by name.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 01:51:39 -07:00
c789069f6f Add weather, time, season, and situational context for callers
Weather lookup via Open-Meteo API with 30-min cache, time/day
awareness (Mountain time), moon phase calculation, seasonal context
with local events, and probabilistic situational details: road
context, phone situation, background music, recent errands, TV tonight.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 01:46:27 -07:00
bd6c8ccbab Landing page: testimonials slider, how-it-works page, 25 TTS voices
- Add testimonial slider with 8 fake caller reviews
- Add how-it-works page with visual architecture diagram
- Expand voice pools: Inworld 25 voices (14M/11F), ElevenLabs 22 (14M/8F)
- Voice pools auto-switch when TTS provider changes
- Add cover art locally, update cache-busted image refs
- Add "More from Luke" footer links (MMG, prints, YouTube)
- Ad channel configurable in settings UI

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 01:34:30 -07:00
f654a5cbb1 Deep caller personality: named people, memories, vehicles, opinions, arcs
- Named relationships (20M/20F): "my buddy Ray", "my wife Linda" — not generic
- Relationship status with detail: "married 15 years, second marriage"
- Vehicle they drive: rural southwest flavor (F-150s, Tacomas, old Broncos)
- What they were doing before calling: grounds call in a physical moment
- Specific memory/story to reference: flash floods, poker wins, desert nights
- Food/drink right now: Tecate on the porch, third cup of coffee
- Strong random opinions: speed limits, green chile, desert philosophy
- Contradictions/secrets: tough guy who cries at TV, reads physics at work
- Verbal fingerprints: 2 specific phrases per caller
- Emotional arcs: mood shifts during the call
- Show relationship: first-timer, regular, skeptic, reactive
- Late-night reasons: why they're awake
- Topic drift tendencies for some callers
- Regional speech patterns in prompt (over in, down the road, out here)
- Opening line variety based on personality
- Local town news enrichment via SearXNG
- Ad channel now configurable in settings UI

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 01:01:32 -07:00
6447edd0ae Add architecture diagram and system documentation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 00:36:17 -07:00
79e6bc79be Add topic callers, town knowledge, dynamic response lengths
- 30% of callers now call about topics (prestige TV, science, poker,
  astrophotography, physics, tech, US news) instead of personal problems
- 86 curated interests weighted toward shows like Severance, Breaking Bad,
  The Wire, LOST, Westworld, etc. Removed reality TV/celebrity gossip
- 32-town knowledge base with real facts so callers don't invent landmarks
- Smart topic detection for news enrichment (keyword->search query mapping)
- Enrichment now summarizes articles naturally via LLM instead of quoting headlines
- Prompt rewrite for varied response lengths and no rehashing
- Extra weight for Animas and Lordsburg callers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 00:14:38 -07:00
9452b07c5c Ads play once on channel 11, separate from music
- Add dedicated ad playback system (no loop, own channel)
- Ad channel defaults to 11, saved/loaded with audio settings
- Separate play_ad/stop_ad methods and API endpoints
- Frontend stop button now calls /api/ads/stop instead of stopMusic

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 22:35:07 -07:00
aa3899b1fc Harden LLM: model fallback chain, reuse client, remove fighting timeouts
- Primary model gets 15s, then auto-falls back through gemini-flash,
  gpt-4o-mini, llama-3.1-8b (10s each)
- Always returns a response — canned in-character line as last resort
- Reuse httpx client instead of creating new one per request
- Remove asyncio.timeout wrappers that were killing requests before
  the LLM service could try fallbacks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 22:07:39 -07:00
73129374f4 Bake news context into caller backgrounds at pickup time
Instead of injecting research into every LLM call (which bloated prompts
and caused timeouts), do one quick SearXNG search when a caller is picked
up and add a relevant headline to their background. 3s timeout — if search
is slow, caller just doesn't reference news. Zero impact on live conversation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 21:47:46 -07:00
164f8fbc6e Remove news/research from caller prompts — was causing timeouts
Research results were bloating the system prompt, making LLM calls
slower and hitting the 20s timeout. Callers don't need news awareness
to have good conversations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 21:44:22 -07:00
e45ba2617a Switch news service from Google News to local SearXNG
- Use local SearXNG at localhost:8888 instead of Google News RSS
- No more 302 redirects or blocked requests — local is fast and reliable
- 5s timeout on all SearXNG requests
- Removed async locks (no contention needed for local service)
- Re-enabled research and headlines

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 21:34:45 -07:00
c03f46ea96 Disable news research — was breaking calls
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 21:32:50 -07:00
69b7078142 Fix research hanging: add timeouts, fix keyword extraction, cache failures
- Google News RSS returns 302: add follow_redirects and User-Agent header
- Cache failed headline fetches for 5min so they don't retry every call
- Add 8s timeout on background research tasks
- Fix keyword extraction: skip short texts, require 2+ proper nouns (not names),
  increase min word length to 6, add radio show filler to stop words
- Stops garbage searches like "Megan welcome" and "sounds thats youre"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 21:25:31 -07:00
b3fb3b1127 Fix AI caller hanging on 'thinking...' indefinitely
- Add 30s timeout to all frontend fetch calls (safeFetch)
- Add 20s asyncio.timeout around lock+LLM in chat, ai-respond, auto-respond
- Reduce OpenRouter timeout from 60s to 25s
- Reduce Inworld TTS timeout from 60s to 25s
- Return graceful fallback responses on timeout instead of hanging

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 21:16:15 -07:00
cac80a4b52 Localize callers to NM bootheel area
80% from Lordsburg/Animas/Portal/Playas/Deming/Silver City area,
20% out-of-staters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 20:46:51 -07:00
e30d4c8856 Add ads system, diversify callers, update website descriptions
- Add ads playback system with backend endpoints and frontend UI
- Diversify AI callers: randomize voices per session, expand jobs/problems/interests/quirks/locations
- Update website tagline and descriptions to "biologically questionable organisms"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 20:38:25 -07:00
eafcf27beb Add SEO, structured data, sitemap, and llms.txt
- Expanded meta description with keywords
- Canonical URL
- JSON-LD PodcastSeries structured data
- RSS alternate link for feed discovery
- robots.txt allowing all crawlers
- sitemap.xml
- llms.txt for LLM indexing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 14:07:45 -07:00
d5fd89fc9a Add on-air toggle for phone call routing
When off air, callers hear a message and get disconnected. When on
air, calls route normally. Toggle button added to frontend header
with pulsing red ON AIR indicator.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 14:03:38 -07:00
0a614eba6d Add banner, Apple Podcasts link, feed proxy, and fetch retry
- Add roostbanner.png hero banner image
- Add Apple Podcasts subscribe button
- Add Cloudflare Pages Function to proxy RSS feed (avoids CORS)
- Add fetch timeout and retry for episode loading
- Add contact email to footer
- Replace favicon with inline SVG rooster

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 14:03:29 -07:00
e979c4151d Update color scheme to match new cover art and bust image cache
Warm rustic bar palette (dark wood browns, orange neon accent, cream
text) replacing the previous navy/pink theme. Added ?v=2 to all
cover art URLs to force new image.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 13:04:38 -07:00
e6b9401848 Add episode list with RSS parsing and sticky audio player
Fetches episodes from Castopod RSS feed, renders episode cards with
play buttons, and provides a sticky bottom audio player with progress
bar and seeking. Falls back to CORS proxy if direct fetch fails.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 12:49:16 -07:00
d14000887c Add landing page with hero section, subscribe links, and dark theme
Static site for lukeattheroost.com with cover art, phone number,
subscribe buttons (Spotify, YouTube, Apple, RSS), and OG meta tags.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 12:49:12 -07:00
7adf1bbcad Fix LLM model list, Castopod API, and server runner
- Remove gpt-4o-realtime (WebSocket-only) from OpenRouter models
- Increase OpenRouter timeout to 60s and max_tokens to 150
- Handle empty LLM responses
- Fix publish_episode.py for current Castopod API fields
- Add port conflict check and graceful shutdown to run.sh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 01:56:09 -07:00
a94fc92647 Improve SignalWire streaming, randomize caller names, update frontend
- Add streamSid tracking and per-caller send locks for SignalWire
- Improve TTS streaming with real-time pacing and detailed logging
- Block host audio to caller during TTS playback
- Randomize caller names between sessions from name pools
- Update page title and show phone number in UI

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 01:56:05 -07:00
b0643d6082 Add recording diagnostics and refresh music list on play
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 01:00:41 -07:00
0412f4487f Enhance caller personality for depth and authenticity
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 00:39:49 -07:00
50e3d3af7d Include news and research context in caller prompts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 00:35:55 -07:00
a06d0a22e1 Wire up headline fetch and background research triggers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 00:22:49 -07:00
e46337a05a Add session news/research fields and helper functions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 00:21:25 -07:00
e28579f909 Add NewsService for current events awareness
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 00:18:40 -07:00
437980dfd4 Update tests for SignalWire phone caller format
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 17:47:50 -07:00
ecc30c44e1 Update frontend for phone caller display
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 17:46:48 -07:00
9361a3c2e2 Remove browser call-in page 2026-02-05 17:46:37 -07:00
9016f9734f Add SignalWire endpoints, update queue/hangup for phone callers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 17:45:08 -07:00
051790136e Update CallerService for SignalWire protocol
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 17:41:27 -07:00
c22818bfec Add SignalWire configuration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 17:38:41 -07:00
a1c94a3682 Fix unnatural response cutoffs
- Replace aggressive sentence-count limiting with ensure_complete_thought()
  which only trims if the LLM was actually cut off mid-sentence
- Softer prompt guidance for natural brevity instead of rigid sentence count
- max_tokens at 100 as natural length cap

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 17:18:22 -07:00
9d4b8a0d22 Replace token-based truncation with sentence-count limiting
- max_tokens back to 150 so LLM can finish thoughts
- New limit_sentences() keeps only first 2 complete sentences
- Never cuts mid-sentence — always ends at punctuation
- Applied to both chat and auto-respond paths

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 17:15:04 -07:00
9c5f7c5cfe Add debug logging and safety for piggybacked recording
- Log chunk count and peak audio level on recording stop
- Add null check on _recorded_audio in callback
- Small delay after stopping piggybacked recording for callback to finish

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 17:11:51 -07:00
6a56967540 Enforce shorter AI responses and prevent cut-off sentences
- Reduce max_tokens from 100 to 75 for shorter output
- Add truncate_to_complete_sentence() to trim at last punctuation
- Applied to both chat and auto-respond paths

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 17:07:41 -07:00
0e65fa5084 Force shorter AI responses — max 1-2 sentences
- Much stronger prompt language: "no more than 2 sentences EVER"
- Added "DO NOT ramble" instruction
- Reduced max_tokens back to 100 as hard limit

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 17:05:51 -07:00
3192735615 Fix AI responses being cut off
- Increase max_tokens from 100 to 150 to avoid mid-sentence truncation
- Tighten prompt to 1-2 short sentences with emphasis on completing them

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 17:04:12 -07:00
d583b48af0 Fix choppy/distorted audio to live caller
- Mute host mic forwarding while TTS is streaming to prevent interleaving
  both audio sources into the same playback buffer
- Replace nearest-neighbor downsampling with box-filter averaging on both
  server (host mic) and browser (caller mic) for anti-aliased resampling

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 17:01:33 -07:00
d4e25ceb88 Stream TTS audio to caller in real-time chunks
TTS audio was sent as a single huge WebSocket frame that overflowed the
browser's 3s ring buffer. Now streams in 60ms chunks at real-time rate.
Also increased browser ring buffer from 3s to 10s as safety net.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 16:56:22 -07:00
97d37f3381 Send AI TTS audio to live caller during auto-respond
The auto-respond function played AI TTS to the local Loopback channel
but didn't send it over WebSocket to the live caller in the browser.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 16:53:41 -07:00
eaedc4214b Reduce live caller latency and improve reliability
- Replace per-callback async task spawning with persistent queue-based sender
- Buffer host mic to 60ms chunks (was 21ms) to reduce WebSocket frame rate
- Reduce server ring buffer prebuffer from 150ms to 80ms
- Reduce browser playback jitter buffer from 150ms to 100ms

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 16:47:17 -07:00
af8606b5b7 Fix recording conflict when host stream is active
When a live caller is on air, the host stream already has an InputStream
open. Opening a second one for push-to-talk recording causes a conflict.
Now recording piggybacks on the host stream callback instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 16:42:07 -07:00
4d97ea9099 Replace queue with ring buffer jitter absorption for live caller audio
- Server: 150ms pre-buffer ring buffer eliminates gaps from timing mismatches
- Browser playback: 150ms jitter buffer (up from 80ms) for network jitter
- Capture chunks: 960 samples/60ms (better network efficiency)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 16:37:50 -07:00