Skip to content

feat(voice): fall back to macOS say when ElevenLabs unavailable#897

Closed
blu3dot wants to merge 1 commit intodanielmiessler:mainfrom
blu3dot:feat/voice-macos-say-fallback
Closed

feat(voice): fall back to macOS say when ElevenLabs unavailable#897
blu3dot wants to merge 1 commit intodanielmiessler:mainfrom
blu3dot:feat/voice-macos-say-fallback

Conversation

@blu3dot
Copy link
Copy Markdown

@blu3dot blu3dot commented Mar 3, 2026

Summary

When ELEVENLABS_API_KEY is missing or the ElevenLabs API call fails, VoiceServer now falls back to the macOS native say command instead of silently skipping voice output. This gives new users immediate voice feedback without requiring ElevenLabs setup.

Problem

VoiceServer silently skips all TTS when ELEVENLABS_API_KEY is missing. New users who haven't configured ElevenLabs get zero voice feedback with no indication why — the server returns HTTP 200, making the failure invisible.

Solution

After the ElevenLabs TTS path is skipped (no API key) or fails (API error), fall back to /usr/bin/say:

  • Reuses existing applyPronunciations() so custom pronunciation rules apply to native voice too
  • Reuses existing spawnSafe() helper (array-form spawn, no shell injection)
  • Only triggers when ElevenLabs path didn't play (no double-speak)
  • Fails gracefully — logs error, doesn't crash server
  • Uses error: unknown with instanceof type guard (also upgrades the adjacent ElevenLabs catch block)

macOS-onlysay is present on all macOS versions. Linux equivalent is out of scope for this PR (see #855, #872 for cross-platform audio work).

Test plan

  • Start server with no ELEVENLABS_API_KEY → send notification → hear macOS say voice
  • Set invalid ELEVENLABS_API_KEY → send notification → ElevenLabs fails → fallback to say
  • Both paths fail (e.g., Linux) → notification still displays, no voice, error logged
  • Custom pronunciations from pronunciations.json apply to say output

Post-Deploy Monitoring & Validation

No additional operational monitoring required: additive fallback path, existing behavior unchanged when ElevenLabs key is configured.


Compound Engineered 🤖 Generated with Claude Code

When ELEVENLABS_API_KEY is missing or the ElevenLabs API call fails,
the VoiceServer now falls back to macOS native `say` command instead
of silently skipping voice output. Pronunciation rules from
pronunciations.json are applied to the fallback too.

- Only triggers when ElevenLabs path didn't play (no double-speak)
- Reuses existing spawnSafe() and applyPronunciations() helpers
- Fails gracefully — logs error, doesn't crash server
- Uses error: unknown with instanceof type guard
- TODO: Linux equivalent (see danielmiessler#855, danielmiessler#872)

Co-Authored-By: Claude <noreply@anthropic.com>
@blu3dot
Copy link
Copy Markdown
Author

blu3dot commented Mar 3, 2026

Closing to test locally before resubmitting.

@blu3dot blu3dot closed this Mar 3, 2026
@blu3dot blu3dot deleted the feat/voice-macos-say-fallback branch March 3, 2026 23:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant