feat: Phase 3 — streaming TTS WebSocket & self-hosted distribution credentials - #166
Open
dg-coreylweathers wants to merge 1 commit into
Open
Conversation
…credentials - TTS WebSocket (#148/#147/#95): Speak::speak_stream() -> SpeakStreamBuilder (model/encoding/sample_rate); handle() opens the connection and returns a SpeakStreamHandle for sending text (speak/flush/clear/close) and receiving audio + events. SpeakStreamHandle implements futures::Stream; SpeakResponse (Audio/Metadata/Flushed/Cleared/Warning/Unknown) is #[non_exhaustive] and unknown message types are preserved rather than breaking the stream. The speak feature now enables the WebSocket deps. New example text_to_speech_websocket. - Self-hosted distribution credentials: Deepgram::self_hosted() -> SelfHosted with list/get/create/delete_distribution_credentials, plus typed response models. New example self_hosted_credentials. All additive (cargo semver-checks: no new breaking changes beyond the Phase 1 #130 streaming change). Live-verified the TTS WebSocket against production; the self-hosted list path returns a correct 403 on accounts without the self-hosted scope. Closes #148, #147, #95 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
Author
|
Addressed the review's BLOCKING finding: the TTS-WS worker busy-spun (and hung on current-thread runtimes) after input close because it kept selecting on the drained input channel. |
dg-coreylweathers
force-pushed
the
feat/phase-3-tts-ws-selfhosted
branch
from
July 31, 2026 11:34
5a60203 to
570125f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 3 — Streaming TTS WebSocket + self-hosted credentials
Stacked on #165 (Phase 2). Base is
feat/phase-2-read-stream-models; GitHub will retarget tomainas the stack merges.What's included
Speak::speak_stream()→SpeakStreamBuilder(model / encoding / sample rate);handle()opens the connection →SpeakStreamHandlewithspeak/flush/clear/close, and receives audio + events.SpeakStreamHandle: futures::Stream<Item = Result<SpeakResponse>>.SpeakResponse(Audio/Metadata/Flushed/Cleared/Warning/Unknown) is#[non_exhaustive]; unknown message types are preserved rather than breaking the stream. Thespeakfeature now pulls the WebSocket deps. Modeled onsrc/listen/websocket.rs. Exampletext_to_speech_websocket.Deepgram::self_hosted()→SelfHostedwithlist/get/create/delete_distribution_credentials+ typed response models. Exampleself_hosted_credentials.Verification (Rust 1.97 container)
-D warnings/ fmt /cargo test --all --all-features(142 tests, incl. TTS-WS protocol + self-hosted deserialization tests) ✅cargo checkincl. speak-only (now pulls WS deps) ✅cargo semver-checks: no new breaking changes (only the inherited Phase 1 Extra metadata support #130 streaming breaks).Metadata+Flushed, and streamed 219 KB of audio. Self-hosted list returns a correct403 INSUFFICIENT_PERMISSIONSon accounts without the self-hosted scope (confirms the request path).Closes #148, #147, #95