Skip to content

Add Quickdial plugin for STT and TTS#6490

Open
roshanpuru wants to merge 7 commits into
livekit:mainfrom
roshanpuru:add-quickdial-plugin
Open

Add Quickdial plugin for STT and TTS#6490
roshanpuru wants to merge 7 commits into
livekit:mainfrom
roshanpuru:add-quickdial-plugin

Conversation

@roshanpuru

Copy link
Copy Markdown

Adds a livekit-plugins-quickdial plugin providing STT and TTS via Quickdial β€” a CPU-optimized, real-time voice API (no GPU, priced per character). It follows the existing plugin structure (mirrors livekit-plugins-gnani) and registers via Plugin.register_plugin.

from livekit.plugins import quickdial, silero

session = AgentSession(
    stt=quickdial.STT(language="en"),
    tts=quickdial.TTS(voice="alba"),
    vad=silero.VAD.load(),
    llm=...,
)

Files

  • livekit-plugins/livekit-plugins-quickdial/ β€” package (__init__, stt, tts, models, log, version, py.typed, pyproject.toml, README.md)
  • livekit-agents/pyproject.toml β€” added the quickdial optional-dependency extra
  • .github/next-release/changeset-quickdial-plugin.md β€” changeset
  • examples/voice_agents/quickdial_agent.py β€” runnable example

Two coordination items πŸ™

  1. CLA β€” I will sign the CLA Assistant check on this PR.
  2. PyPI namespace β€” we currently own livekit-plugins-quickdial on PyPI (from our standalone build). Happy to transfer the PyPI project to LiveKit’s org so your release bot can publish it β€” just let me know the account/org to add as owner (or your preferred process).

Notes: I was unable to regenerate uv.lock in my environment β€” happy for a maintainer to regenerate or point me at the right command. Likewise glad to add unit tests to match your harness, and to adjust anything (copyright headers, versioning) to your conventions. The standalone source also lives at https://github.com/samay-ai/livekit-plugins-quickdial. Thanks!

@roshanpuru
roshanpuru requested a review from a team as a code owner July 20, 2026 19:06
@CLAassistant

CLAassistant commented Jul 20, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

…/Hume)

Remove SynthesizeStream (TTS) and SpeechStream (STT). Both classes declare
streaming=False, so the AgentSession already uses ChunkedStream via StreamAdapter
(TTS) and _recognize_impl via VAD (STT); the WS paths were never exercised by the
framework and could hang β€” _recv only broke on socket close, so on a persistent
connection asyncio.gather(_send, _recv) never resolved (addresses Devin review).

Base tts.TTS.stream()/stt.STT.stream() raise NotImplementedError pointing to
StreamAdapter, so removing the overrides is safe.
devin-ai-integration[bot]

This comment was marked as resolved.

_recognize_impl already sends the per-request language override in the request
config, but the fallback passed to _to_speech_event was hard-coded to the default
(self._opts.language). When the server response omits 'language', the transcript
was labelled with the default instead of the requested language. Pass the effective
cfg['language'] instead (addresses Devin review).
devin-ai-integration[bot]

This comment was marked as resolved.

After removing the WS SpeechStream, sample_rate was no longer read anywhere β€”
_recognize_impl sends a WAV whose header carries the rate and the server handles
it (same as the OpenAI Whisper STT). Remove the unused constructor param, the
_STTOptions field, and the now-unused SAMPLE_RATE/NUM_CHANNELS constants
(addresses Devin review).
@roshanpuru

Copy link
Copy Markdown
Author

πŸ‘‹ Ready for a maintainer review whenever someone has a moment.

  • βœ… CI is green β€” ruff, type-check (3.10/3.13), unit-tests, blockguard tests, and CLA signed.
  • βœ… All Devin Review findings are resolved. The plugin is now batch-only β€” TTS ChunkedStream (POST /v1/tts) and STT _recognize_impl (POST /v1/stt) with capabilities.streaming=False, so the AgentSession wraps them in StreamAdapter (TTS) and VAD-segments for STT, matching the OpenAI and Hume plugins. Along the way I removed the unused WebSocket paths, fixed the STT result to carry the effective per-request language, and dropped a dead sample_rate param.

Happy to make any changes you'd like. One coordination item for merge: the livekit-plugins-quickdial name on PyPI β€” glad to grant/transfer it to the LiveKit org however you prefer. Thanks for taking a look! πŸ™

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.

2 participants