Skip to content

feat(voice): Kokoro local-TTS backend as a private alternative to ElevenLabs (+ mute toggle & statusline indicator)#1465

Draft
HotSauceHacker wants to merge 1 commit into
danielmiessler:mainfrom
HotSauceHacker:feat/kokoro-local-tts-backend
Draft

feat(voice): Kokoro local-TTS backend as a private alternative to ElevenLabs (+ mute toggle & statusline indicator)#1465
HotSauceHacker wants to merge 1 commit into
danielmiessler:mainfrom
HotSauceHacker:feat/kokoro-local-tts-backend

Conversation

@HotSauceHacker

@HotSauceHacker HotSauceHacker commented Jul 11, 2026

Copy link
Copy Markdown

What and why

LifeOS voice (PULSE/VoiceServer/voice.ts) currently speaks via ElevenLabs, which sends the text of every notification to a cloud API and requires an API key. This PR adds a fully-local alternative powered by Kokoro: no API key, and no text or audio ever leaves the machine. That fits the privacy posture many people want from a personal AI.

It is opt-in and backward-compatible. With PAI_VOICE_BACKEND unset, the ElevenLabs path is byte-for-byte unchanged.

What's included

  • voice.ts: playKokoroVoice() POSTs {text, voice} to a warm local daemon, selected ahead of ElevenLabs when PAI_VOICE_BACKEND=kokoro. Also adds a live mute gate read from voice-mute.json on every notification. Muting silences TTS only; desktop notifications still fire, and it fails open.
  • kokoro_server.py: a small warm Kokoro daemon (GET /health, POST /speak) that keeps the model resident so utterances skip cold-start. The audio player is env-configurable (PAI_KOKORO_PLAYER) for non-macOS.
  • TOOLS/VoiceMute.ts: an on|off|toggle|status CLI writing the shared state file, bindable to a keyboard shortcut for a live mute hotkey.
  • LIFEOS_StatusLine.sh: a mute glyph (audible / muted) in the header, read live from the same state file.
  • DOCUMENTATION/Notifications/KokoroVoiceBackend.md: setup (deps, model, daemon, env vars) plus an optional skhd keyboard-shortcut guide.

Trying it

See the setup doc. In short: install kokoro-onnx plus model files, run the daemon, and set PAI_VOICE_BACKEND=kokoro in the Pulse process environment.

Notes

  • Developed and tested on macOS (plays via afplay; Linux via PAI_KOKORO_PLAYER=aplay).
  • Scoped to the voice subsystem and additive. No existing behavior changes unless the env var is set.
  • Opened as a draft for feedback on fit and placement before finalizing.

…ne indicator

Adds a fully-local voice backend (Kokoro) as a private alternative to the
cloud ElevenLabs path: no API key, and no text or audio leaves the machine.
Opt-in via PAI_VOICE_BACKEND=kokoro; ElevenLabs behavior is unchanged when unset.

- voice.ts: playKokoroVoice() POSTs to a warm local daemon, selected ahead of
  ElevenLabs. Adds a live mute gate (voice-mute.json) read per notification that
  silences TTS only; desktop notifications still fire; fail-open.
- kokoro_server.py: warm Kokoro daemon (GET /health, POST /speak); audio player
  is env-configurable (PAI_KOKORO_PLAYER) for non-macOS.
- TOOLS/VoiceMute.ts: on/off/toggle/status CLI, bindable to a keyboard shortcut.
- LIFEOS_StatusLine.sh: mute glyph read live from the same state file.
- DOCUMENTATION/Notifications/KokoroVoiceBackend.md: setup and hotkey guide.
@HotSauceHacker HotSauceHacker force-pushed the feat/kokoro-local-tts-backend branch from d1863b9 to 4239a18 Compare July 11, 2026 21:02
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