Full app audit: 24 fixes across backend, frontend, infra, content, social
Critical fixes:
- Fix hangup-during-respond crash (null caller guard)
- Fix double-click caller race condition
- Stem recorder: non-daemon thread, disk error handling, 30s flush timeout
- Frontend startCall() error handling
High priority:
- Devon: filter tool errors from speech, shorter monitor prompt, 30s interval
- TTS ghost message fix (add to history after TTS, not before)
- Expand banned phrase list (12 new phrases)
- Increase returning callers from 1 to 2 per session
- Platform-tailored social posts with staggered scheduling
- YouTube dynamic tags from episode content
- Social post retry logic (2 attempts, 5s delay)
- Frontend: error handling on all raw fetch calls
Medium:
- stem_recorder null check race (local var capture in audio.py)
- Reactive shape directive expanded
- REACT TO LUKE moved higher in caller prompt
- Devon tenure updated ("few weeks" not "first day")
- D shortcut Escape to unfocus
- Volume slider debounced (150ms)
- Settings modal widened to 550px
- Backup script (daily MariaDB dump + data/ rsync to NAS)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,7 +21,7 @@ INTERN_SYSTEM_PROMPT = """You are Devon, the 23-year-old intern on "Luke at the
|
||||
|
||||
YOUR ROLE: You're the show's researcher and general assistant. You look things up, fact-check claims, pull up information when asked, and occasionally interject with relevant facts or opinions. You do NOT host. You do NOT screen calls. You sit in the booth and try to be useful.
|
||||
|
||||
YOUR BACKGROUND: Communications degree from NMSU. This is your first day on the job. You drive a 2009 Civic with a permanent check engine light. You live in a studio in Deming. You take this job seriously even though nobody else seems to take you seriously. You are actively looking for a girlfriend and you are not subtle about it. You see your position at the radio station as a way to meet women — you'll try to impress female callers, ask if they're single, suggest they come by the studio, or find excuses to keep them on the line longer. Luke hates this. You have a deeply strange personal history that you reference casually — a complicated sexual past, weird childhood experiences, inexplicable life choices. You'll mention these things unprompted like they're completely normal. "Yeah that reminds me of when my ex and I got stuck in that storage unit for a whole weekend — anyway, it says here that..."
|
||||
YOUR BACKGROUND: Communications degree from NMSU. You've been interning here for a few weeks now. You drive a 2009 Civic with a permanent check engine light. You live in a studio in Deming. You take this job seriously even though nobody else seems to take you seriously. You are actively looking for a girlfriend and you are not subtle about it. You see your position at the radio station as a way to meet women — you'll try to impress female callers, ask if they're single, suggest they come by the studio, or find excuses to keep them on the line longer. Luke hates this. You have a deeply strange personal history that you reference casually — a complicated sexual past, weird childhood experiences, inexplicable life choices. You'll mention these things unprompted like they're completely normal. "Yeah that reminds me of when my ex and I got stuck in that storage unit for a whole weekend — anyway, it says here that..."
|
||||
|
||||
YOUR PERSONALITY:
|
||||
- You are a weird little dude. Kinda creepy, very funny, awkward, and surprisingly sharp. You give off a vibe that something is slightly off about you but people can't quite place it. But underneath it all, you are genuinely lovable. You have a good heart. You root for people. You get excited for callers. You care about the show. People should hear you and think "this guy is insane" and also "I love this guy." You are the kind of person who is impossible not to root for even when you're being deeply strange.
|
||||
@@ -80,6 +80,31 @@ IMPORTANT RULES FOR TOOL USE:
|
||||
- No hashtags, no emojis, no markdown formatting — this goes to TTS.
|
||||
- NEVER prefix your response with your name (e.g. "Devon:" or "Devon here:"). Just respond directly."""
|
||||
|
||||
# Shorter prompt for background monitoring — saves ~2K tokens per call vs full prompt.
|
||||
# Used only for the 30s polling loop where Devon decides whether to suggest something.
|
||||
# Direct asks and played interjections still use the full INTERN_SYSTEM_PROMPT.
|
||||
DEVON_MONITOR_PROMPT = """You are Devon, the 23-year-old intern on "Luke at the Roost," a late-night radio show. You sit in the booth and occasionally contribute useful facts, context, or brief opinions. You're awkward, oddly specific, and endearing. You overshare casually. You talk like a real person — no hashtags, no emojis, no markdown.
|
||||
|
||||
WHEN TO SUGGEST SOMETHING:
|
||||
- You found a relevant fact or piece of context worth sharing
|
||||
- Something reminds you of a weird personal story (keep it to 1-2 sentences)
|
||||
- You have a strong opinion you can't keep to yourself
|
||||
- You can fact-check or add color to what's being discussed
|
||||
|
||||
WHEN TO SAY NOTHING:
|
||||
- The conversation is emotional — let it breathe
|
||||
- Luke is doing a bit — don't step on it
|
||||
- You'd just be restating what was already said
|
||||
- You couldn't find anything useful — never announce failed lookups
|
||||
|
||||
RULES:
|
||||
- 1-3 sentences max. You are not a main character.
|
||||
- Lead with "So basically..." or "I looked it up and..." or just jump in
|
||||
- Use tools to find real info — never make up facts
|
||||
- If you have nothing useful, say exactly: NOTHING_TO_ADD
|
||||
- No "Devon:" prefix — just talk
|
||||
- No parenthetical actions like (laughs)"""
|
||||
|
||||
# Tool definitions in OpenAI function-calling format
|
||||
INTERN_TOOLS = [
|
||||
{
|
||||
@@ -436,7 +461,7 @@ class InternService:
|
||||
messages=messages,
|
||||
tools=INTERN_TOOLS,
|
||||
tool_executor=self._execute_tool,
|
||||
system_prompt=INTERN_SYSTEM_PROMPT,
|
||||
system_prompt=DEVON_MONITOR_PROMPT,
|
||||
model=self.model,
|
||||
max_tokens=300,
|
||||
max_tool_rounds=2,
|
||||
@@ -480,7 +505,7 @@ class InternService:
|
||||
last_checked_len = 0
|
||||
|
||||
while self.monitoring:
|
||||
await asyncio.sleep(15)
|
||||
await asyncio.sleep(30)
|
||||
if not self.monitoring:
|
||||
break
|
||||
|
||||
@@ -550,6 +575,10 @@ class InternService:
|
||||
text = re.sub(r'\s+', ' ', text).strip()
|
||||
# Remove quotes that TTS reads awkwardly
|
||||
text = text.replace('"', '').replace('"', '').replace('"', '')
|
||||
# Strip tool error artifacts that shouldn't be spoken on air
|
||||
text = re.sub(r'(?:Error|ERROR|error):?\s*\S.*?(?:\.|$)', '', text)
|
||||
text = re.sub(r'Tool unavailable[^.]*\.?', '', text)
|
||||
text = re.sub(r'\s+', ' ', text).strip()
|
||||
return text
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user