Metadata-Version: 2.5
Name: pipecat-tts-cache-router
Version: 0.1.0
Summary: Pipecat TTS service for tts-cache-router, a caching TTS router for Sarvam, Raya, ElevenLabs, OpenAI, Deepgram, xAI, Soniox, Smallest AI and Cartesia
Project-URL: Homepage, https://ttscacherouter.dev
Project-URL: Documentation, https://docs.ttscacherouter.dev/pipecat
Project-URL: Source, https://github.com/talqing/tts-cache-router
Project-URL: Changelog, https://github.com/talqing/tts-cache-router/blob/main/plugin/pipecat-tts-cache-router/CHANGELOG.md
Author: Oggnai Technologies Private Limited
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: ai,audio,cache,cartesia,deepgram,elevenlabs,openai,pipecat,raya,realtime,router,sarvam,smallestai,soniox,tts,voice,xai
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Multimedia :: Sound/Audio
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.11
Requires-Dist: pipecat-ai>=1.12.0
Description-Content-Type: text/markdown

# pipecat-tts-cache-router

[Pipecat](https://github.com/pipecat-ai/pipecat) TTS service for
[tts-cache-router](https://ttscacherouter.dev): Sarvam, Raya, ElevenLabs, OpenAI, Deepgram, xAI,
Soniox, Smallest AI and Cartesia text-to-speech, with every sentence your bot has said before served
from a per-account cache.

Same output whether you call the provider directly or through the router: each sentence reaches
the provider verbatim with your exact settings, and a cache hit replays a real provider take for
that exact request.

Full documentation: [docs.ttscacherouter.dev/pipecat](https://docs.ttscacherouter.dev/pipecat). For
LLMs and coding agents: [llms.txt](https://docs.ttscacherouter.dev/llms.txt), and this page as
Markdown at [pipecat.md](https://docs.ttscacherouter.dev/pipecat.md).

Tested with Pipecat v1.12.0. Maintained by Oggnai Technologies, the company that runs
tts-cache-router.

## Install

```bash
pip install pipecat-tts-cache-router
```

## Usage

```python
import os

from pipecat_tts_cache_router import TTSCacheRouterTTSService

tts = TTSCacheRouterTTSService(
    api_key=os.environ["TTS_CACHE_ROUTER_API_KEY"],
    settings=TTSCacheRouterTTSService.Settings(
        model="sarvam/bulbul:v3", voice="shubh", language="hi-IN"
    ),
)

pipeline = Pipeline(
    [transport.input(), stt, user_aggregator, llm, tts, transport.output(), assistant_aggregator]
)
```

Before the first request, store your Sarvam, Raya, ElevenLabs, OpenAI, Deepgram, xAI, Soniox,
Smallest AI or Cartesia API key in the dashboard at
[ttscacherouter.dev](https://ttscacherouter.dev/dashboard/provider-keys). The router keeps it
encrypted and uses it only to call that provider for your requests. Your bot authenticates with
your router API key alone, from the same dashboard.

### `TTSCacheRouterTTSService(...)`

| Argument | Default | |
|---|---|---|
| `api_key` | required | your router API key |
| `settings` | required | `TTSCacheRouterTTSService.Settings(...)`, below |
| `base_url` | `wss://api.ttscacherouter.dev` | set to your own router when self-hosting |
| `sample_rate` | the pipeline's output rate | one the provider streams: 8000, 16000, 22050 or 24000 for most; see [Models and options](https://docs.ttscacherouter.dev/reference/models) |

Other keyword arguments go to Pipecat's `WebsocketTTSService`, except `text_aggregation_mode`: the
router splits the text into sentences itself, so the service streams the LLM's text to it as it
arrives.

### `TTSCacheRouterTTSService.Settings(...)`

The settings are in the router's own names, the same for every provider:

| Setting | | |
|---|---|---|
| `model` | required | `"<provider>/<model>"`: `"sarvam/bulbul:v3"`, `"raya/standard"`, `"elevenlabs/eleven_flash_v2_5"`, `"openai/gpt-4o-mini-tts"`, `"deepgram/aura-2"`, `"xai/xai-tts"`, `"soniox/tts-rt-v2"`, `"smallestai/lightning_v3.1_pro"`, `"cartesia/sonic-3"`, … |
| `voice` | required | the provider's voice id (`GET /v1/voices` lists them) |
| `language` | `None` | the provider's own language code, where it takes one (`"hi-IN"` for Sarvam, `"hi"` for Raya, `"en"` for the rest) |
| `speed` | `None` | the speaking rate, where the provider takes one |
| `options` | `{}` | the provider's other settings, e.g. `{"temperature": 0.6}` for Sarvam, `{"voice_settings": {"stability": 0.5}}` for ElevenLabs, `{"instructions": "Speak warmly."}` for OpenAI |

Every provider's models, voices, languages and options are in
[Models and options](https://docs.ttscacherouter.dev/reference/models). The router checks the
settings when the pipeline starts, so a wrong one is reported then as an `ErrorFrame`.

### Changing settings mid-session

```python
from pipecat.frames.frames import TTSUpdateSettingsFrame

await worker.queue_frame(
    TTSUpdateSettingsFrame(delta=TTSCacheRouterTTSService.Settings(voice="priya"))
)
```

Replies that start afterwards use the new settings. A `model` of another provider starts from no
`language`, `speed` or `options` unless the update gives them.

### Interruptions

When the user interrupts, the service tells the router to stop the reply, and the provider stops
the sentence it was synthesizing. The next reply starts on the same connection.

### Transcripts

The service's `TTSTextFrame`s follow the audio: each sentence's words as its audio starts, or word
by word with ElevenLabs and Cartesia.

### Metrics

With usage metrics on, each reply's `TTSUsageMetricsData` counts only the characters the provider
synthesized (and billed); sentences served from the cache count zero. Its `model` is
`"<provider>/<model>"`.

Once a reply is all sent, the service also calls its `on_cache_stats` handlers with a `CacheStats`:
the reply's `context_id`, `sentences`, `cached_sentences`, `characters` and `billed_characters`
(and `cached_characters`, the difference):

```python
@tts.event_handler("on_cache_stats")
async def on_cache_stats(tts, stats):
    print(stats.cached_sentences, "of", stats.sentences, "sentences from the cache")
```

## Example

[`examples/pipecat_agent.py`](https://github.com/talqing/tts-cache-router/blob/main/examples/pipecat_agent.py)
is a complete bot: Deepgram speech-to-text, an OpenAI LLM and this service, on Pipecat's local
WebRTC runner. With `TTS_CACHE_ROUTER_API_KEY`, `DEEPGRAM_API_KEY` and `OPENAI_API_KEY` set:

```bash
cd examples
uv run pipecat_agent.py
```

Then open http://localhost:7860/client and talk to it.

## License

Apache-2.0.
