feat(tts): add built-in VOICEVOX-compatible TTS provider - #67808
Conversation
627cc63 to
36addaf
Compare
teknium1
left a comment
There was a problem hiding this comment.
Thanks for the focused local-TTS implementation. The VOICEVOX request remains unimplemented on current main, but this PR has integration gaps to resolve.
Problems
hermes_cli/tools_config.py:377adds only thehermes toolsrow. The separatehermes setup ttsflow does not listvoicevoxinhermes_cli/setup.py:941-977, so the setup integration requested in #67803 is incomplete.- #67803 asks for
GET /speakersexposed throughlist_voices(). The proposed generator only calls/audio_queryand/synthesis(tools/tts_tool.py:2266-2295at PR head), so users still need the manual speaker lookup documented by the PR. - Current TTS docs identify voice-listing APIs as a Python-plugin case (
website/docs/user-guide/features/tts.md:331-346), whileAGENTS.md:513-516directs custom/local-only backends to plugins. Please resolve this placement with maintainers before adding another hardcoded native provider.
Suggested changes
- Add the setup/status wiring and tests.
- Implement the speaker-catalog path, or narrow the feature/docs accordingly.
- Re-scope to the TTS provider plugin surface unless maintainers explicitly choose a built-in.
Automated hermes-sweeper review.
| @@ -373,6 +373,12 @@ def _checklist_toolset_keys(platform: str) -> Set[str]: | |||
| "tts_provider": "piper", | |||
| "post_setup": "piper", | |||
| }, | |||
| { | |||
| "name": "VOICEVOX (local, Japanese)", | |||
There was a problem hiding this comment.
This makes VOICEVOX selectable in hermes tools, but the separate hermes setup tts flow still omits it from provider_labels and providers (hermes_cli/setup.py:941-977). Please wire the provider into that flow as well; #67803 explicitly requests setup integration.
| # Provider: VOICEVOX (local, Japanese TTS, zero dependencies) | ||
| # =========================================================================== | ||
|
|
||
| def _generate_voicevox_tts(text: str, output_path: str, tts_config: Dict[str, Any]) -> str: |
There was a problem hiding this comment.
The feature spec in #67803 calls for GET /speakers exposed through voice listing, but this implementation only performs /audio_query and /synthesis. Please add the catalog path and connect it to the supported TTS provider selection/listing surface, or narrow the feature claim.
Add voicevox as a first-class local TTS provider that talks to any VOICEVOX-compatible HTTP engine (VOICEVOX, AivisSpeech, Sharevox, VOICEPEAK) via the standard two-step API (audio_query → synthesis). - Zero external dependencies: uses only stdlib urllib.request - Configurable base_url and speaker ID via tts.voicevox.* - Availability probe via GET /version - Clear error messages for engine-offline and invalid-speaker cases - WAV output with ffmpeg conversion for MP3/Opus (Telegram voice bubbles) - Registered in BUILTIN_TTS_PROVIDERS, tts_registry, config defaults, hermes tools picker, and documentation - 14 new tests covering registration, dispatch, synthesis, error paths Fixes NousResearch#67803
36addaf to
cf2d5c2
Compare
|
Thanks for the detailed review. I have pushed the completed integration in The updated branch now:
Local verification after rebasing:
Regarding placement: I am the author of #67803. I initially proposed a built-in provider because VOICEVOX is a widely used local TTS engine in Japan, requires no API key or additional Python SDK, and extends the existing TTS provider surface without adding a new model tool. That said, I am not attached to the built-in placement. I would be happy to re-scope this as a standalone TTS provider plugin if that is the preferred maintenance direction. Could a maintainer confirm whether VOICEVOX should remain built in or move to the plugin surface? I have kept the completed built-in implementation in the branch so the integration can be reviewed concretely. |
SummaryFour PRs are associated with this complex. #7815, #17092, and #17885 concern Piper support for #8508, while #67808 addresses #67803 with a VOICEVOX-compatible provider, speaker discovery, setup integration, configuration, documentation, and tests. Related pull requests
Duplicates#7815 and #17885 substantially overlap as native Piper implementations for #8508, with #7815 closed as superseded after #17885 landed; #17092 is related Piper work but uses a distinct external HTTP transport. None duplicates #67808’s VOICEVOX implementation. Suggested consolidationKeep #67808 open with a salvage path: preserve its complete VOICEVOX protocol, speaker-catalog, setup, error-handling, and test work while obtaining maintainer re-review on the contributor-raised native-provider-versus-plugin placement decision, re-scoping or splitting only if that decision requires it. Leave #7815 and #17092 closed, treat #7815 as superseded by merged #17885 for the Piper path, and retain #17885 as the merged Piper reference implementation. Complex graphflowchart LR
classDef open fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
classDef merged fill:#dcfce7,stroke:#15803d,color:#14532d
classDef closed fill:#e5e7eb,stroke:#6b7280,color:#1f2937
classDef unverified fill:#f3f4f6,stroke:#9ca3af,color:#374151
classDef best stroke-width:3px,stroke:#b45309
classDef target stroke-width:3px,stroke:#4338ca
I67803(["issue #67803 (open)"])
P67808["PR #67808 (open)"]
P67808 -->|best fix| I67803
class I67803 open
class P67808 open
class P67808 best
class P67808 target
click I67803 "https://github.com/NousResearch/hermes-agent/issues/67803"
click P67808 "https://github.com/NousResearch/hermes-agent/pull/67808"
Graph: solid arrow = fixes / best fix, dashed arrow = partial or unverified (see edge label); boxed group = PRs duplicating each other; amber border = best fix; indigo border = target; gray node = closed (state tag in the node label). Cross-PR triage: Reviewed 4 pull requests and 2 issues in this complex. Diffs were read for 3 of 4 PRs (rest unavailable); Assessment working set: 107 kB of PR diffs, 20 kB of issue/PR text, 8 kB of discussion (11 comments), 6 verify verdicts. verdicts reflect diff content, not PR titles. Part of an automated triage batch. |
Summary
Add
voicevoxas a built-in local TTS provider that talks to any VOICEVOX-compatible HTTP engine — VOICEVOX, AivisSpeech, Sharevox, VOICEPEAK, etc.Closes #67803
What's included
tools/tts_tool.py_generate_voicevox_tts(),_check_voicevox_available(), dispatch case, Opus conversion,check_tts_requirements()agent/tts_registry.py"voicevox"in_BUILTIN_NAMEShermes_cli/config.pybase_url,speaker)hermes_cli/tools_config.pyhermes toolspicker entrywebsite/docs/user-guide/features/tts.mdtests/tools/test_tts_voicevox.pyDesign decisions
urllib.request(stdlib) — no pip install, unlike Piper (piper-tts) or NeuTTS (neutts[all]).POST /audio_query→POST /synthesis, matching the VOICEVOX engine spec.GET /versionwith 3s timeout; clear error message when the engine is offline.Config
Testing
tests/tools/test_tts_voicevox.py— 14 new tests (all mocked HTTP, no engine required)tests/agent/test_tts_registry.py— registry sync check passestests/tools/test_tts_piper.py— no regressions