feat: add NeuTTS optional skill + local TTS provider backend

* feat(skills): add bundled neutts optional skill

Add NeuTTS optional skill with CLI scaffold, bootstrap helper, and
sample voice profile. Also fixes skills_hub.py to handle binary
assets (WAV files) during skill installation.

Changes:
- optional-skills/mlops/models/neutts/ — skill + CLI scaffold
- tools/skills_hub.py — binary asset support (read_bytes, write_bytes)
- tests/tools/test_skills_hub.py — regression tests for binary assets

* feat(tts): add NeuTTS as local TTS provider backend

Add NeuTTS as a fourth TTS provider option alongside Edge, ElevenLabs,
and OpenAI. NeuTTS runs fully on-device via neutts_cli — no API key
needed.

Provider behavior:
- Explicit: set tts.provider to 'neutts' in config.yaml
- Fallback: when Edge TTS is unavailable and neutts_cli is installed,
  automatically falls back to NeuTTS instead of failing
- check_tts_requirements() now includes NeuTTS in availability checks

NeuTTS outputs WAV natively. For Telegram voice bubbles, ffmpeg
converts to Opus (same pattern as Edge TTS).

Changes:
- tools/tts_tool.py — _generate_neutts(), _check_neutts_available(),
  provider dispatch, fallback logic, Opus conversion
- hermes_cli/config.py — tts.neutts config defaults

---------

Co-authored-by: unmodeled-tyler <unmodeled.tyler@proton.me>
This commit is contained in:
Teknium 2026-03-17 02:13:34 -07:00 committed by GitHub
parent 766f4aae2b
commit cb0deb5f9d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 1359 additions and 24 deletions

View file

@ -0,0 +1,55 @@
# NeuTTS CLI
Small standalone CLI for installing, checking, and running [NeuTTS](https://github.com/neuphonic/neutts) locally.
This scaffold is designed to be a good fit for a future Hermes optional skill:
- predictable commands
- machine-friendly output for inspection
- local voice profile management
- direct local synthesis
## Commands
```bash
neutts install --all
neutts doctor
neutts list-models
neutts add-voice demo --ref-audio ./samples/jo.wav --ref-text-file ./samples/jo.txt
neutts list-voices
neutts synth --voice demo --text Hello from NeuTTS --out ./out.wav
neutts synth --voice demo --text Quick smoke test
```
## Install the bundled scaffold
```bash
cd optional-skills/mlops/models/neutts/assets/neutts-cli
python -m pip install -e .
```
## Add the bundled sample profile
This skill bundles an upstream NeuTTS sample reference in `samples/`.
```bash
cd optional-skills/mlops/models/neutts/assets/neutts-cli
PYTHONPATH=src python -m neutts_cli.cli add-voice jo-demo \
--ref-audio ./samples/jo.wav \
--ref-text-file ./samples/jo.txt \
--language en
```
Then inspect it with:
```bash
PYTHONPATH=src python -m neutts_cli.cli list-voices
```
## Notes
- `install` installs the upstream `neutts` package into the current Python environment.
- `list-voices` shows local voice profiles created with `add-voice`.
- `synth` uses NeuTTS reference cloning. A voice profile is just a saved reference audio/text pair.
- `synth` accepts quoted or unquoted text and defaults to `./out.wav` when `--out` is omitted.
- GGUF / `llama-cpp-python` acceleration can vary by platform, so the CLI prints follow-up guidance instead of forcing one build recipe.