← Back to PRs

#16569: feat(tts): add optional piper provider core support

by akalypse open 2026-02-14 21:47 View on GitHub →
stale size: S
## Summary - Problem: Piper was not fully supported as a first-class TTS provider in core provider selection/config flow. - Why it matters: Self-hosted users could not cleanly select/use Piper through standard TTS paths and provider commands. - What changed: Added core Piper provider support across TTS provider typing, config schema, provider selection/ status, and runtime synthesis path. - What did NOT change (scope boundary): No language-aware routing in this PR (that is split to follow-up PR), no docker-compose infra changes. ## Change Type (select all) - [ ] Bug fix - [x] Feature - [ ] Refactor - [ ] Docs - [ ] Security hardening - [ ] Chore/infra ## Scope (select all touched areas) - [ ] Gateway / orchestration - [x] Skills / tool execution - [ ] Auth / tokens - [ ] Memory / storage - [x] Integrations - [x] API / contracts - [ ] UI / DX - [ ] CI/CD / infra ## Linked Issue/PR - Closes # - Related # ## User-visible / Behavior Changes - /tts provider piper is now supported. - TTS provider status output includes Piper readiness (Piper URL: ✅/❌). - Core config accepts messages.tts.piper with baseUrl, voice, timeoutMs. - Telephony path explicitly keeps Piper unsupported (unchanged behavior for telephony capabilities). - Piper endpoint is configurable: OpenClaw uses this precedence for base URL -> messages.tts.piper.baseUrl, then PIPER_HTTP_URL, then fallback default http://piper-http:5001. ## Security Impact (required) - New permissions/capabilities? (No) - Secrets/tokens handling changed? (No) - New/changed network calls? (Yes) - Command/tool execution surface changed? (No) - Data access scope changed? (No) - If any Yes, explain risk + mitigation: - Risk: New outbound HTTP call path to configured Piper endpoint. - Mitigation: Endpoint is explicitly configured (messages.tts.piper.baseUrl or env fallback), request scope is limited to TTS payload, existing timeout handling and error propagation are preserved. ## Repro + Verification ### Environment - OS: macOS - Runtime/container: local dev + Docker build validation during branch prep - Model/provider: TTS provider selection flow - Integration/channel (if any): TTS command path (/tts provider) - Relevant config (redacted): - messages.tts.provider: "piper" - messages.tts.piper.baseUrl: "http://piper-http:5001" ### Steps 1. Set TTS provider to Piper via command or config. 2. Run provider status command (/tts provider) and inspect provider list/status. 3. Execute TTS flow and verify provider resolution includes Piper. 4. Run targeted TTS tests. ### Expected - Piper accepted as a valid provider. - Piper shown in provider status. - Provider order/fallback logic includes Piper. - TTS runtime can execute Piper path when configured. ### Actual - Matches expected after this change. ## Evidence Attach at least one: - [x] Failing test/log before + passing after - [ ] Trace/log snippets - [ ] Screenshot/recording - [ ] Perf numbers (if relevant) ## Human Verification (required) - Verified scenarios: - Added/updated tests in src/tts/tts.test.ts for Piper core provider behavior. - Ran pnpm test -- src/tts/tts.test.ts (passing). - Edge cases checked: - Blank Piper base URL input normalizes to default Piper URL fallback. - Piper marked unsupported in telephony path as intended. - What you did not verify: - Full production E2E across all messaging channels. ## Compatibility / Migration - Backward compatible? (Yes) - Config/env changes? (Optional) - Migration needed? (No) - If yes, exact upgrade steps: - Optional: set messages.tts.provider: piper and messages.tts.piper.baseUrl. ## Failure Recovery (if this breaks) - How to disable/revert this change quickly: - Switch provider back to openai/elevenlabs/edge, or revert this commit. - Files/config to restore: - src/auto-reply/reply/commands-tts.ts - src/config/types.tts.ts - src/config/zod-schema.core.ts - src/tts/tts.ts - src/tts/tts.test.ts - Known bad symptoms reviewers should watch for: - /tts provider piper not accepted. - Piper incorrectly shown unavailable despite configured base URL. ## Risks and Mitigations - Risk: Provider fallback order changes can alter which provider is attempted first when Piper is selected. - Mitigation: Scoped tests verify provider ordering and configuration checks. - Risk: Piper endpoint misconfiguration can cause failed synthesis attempts. - Mitigation: Clear status output (Piper URL) and existing timeout/error handling in runtime path. - Risk: default endpoint may not exist in every deployment. - Mitigation: endpoint is explicitly overridable via config/env; default is only a fallback. <!-- greptile_comment --> <h3>Greptile Summary</h3> Adds Piper as a first-class TTS provider across the type system, config schema, provider selection/status commands, and the runtime synthesis path. The implementation follows existing provider patterns (type union, Zod schema, resolved config, provider order, `isTtsProviderConfigured`, and the `textToSpeech` loop). - **Type & schema**: `TtsProvider` union, `TtsConfig`, Zod schema, and `ResolvedTtsConfig` all correctly extended with Piper fields (`baseUrl`, `voice`, `timeoutMs`). - **Config resolution**: `resolveTtsConfig` resolves Piper base URL with a three-tier precedence (config → `PIPER_HTTP_URL` env → default `http://piper-http:5001`) and strips trailing slashes via `normalizeUrl`. - **Provider commands**: `/tts provider` status and validation updated to include Piper; telephony path correctly skips Piper. - **Temp directory leak**: The Piper synthesis path in `textToSpeech` does not clean up the temp directory when `piperTTS()` throws, unlike the Edge provider path which explicitly calls `rmSync`. This will leak temp directories on Piper failures. - **Help text gap**: The `ttsUsage()` help text was not updated to list Piper as an available provider, so users won't discover it through `/tts help`. <h3>Confidence Score: 3/5</h3> - Functional but has a temp directory leak on Piper errors and a missing help text entry that should be fixed before merge. - The core integration is well-structured and follows existing patterns. However, the temp directory leak in the Piper error path is a real resource issue (especially under repeated failures), and the missing help text is a user-facing oversight. Neither is critical/blocking, but both should be addressed. - `src/tts/tts.ts` (temp directory leak in Piper error path), `src/auto-reply/reply/commands-tts.ts` (help text missing Piper) <sub>Last reviewed commit: 486a8fa</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs