pipecat-rumik 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pipecat_rumik-0.1.1/.env.example +12 -0
- pipecat_rumik-0.1.1/.gitignore +12 -0
- pipecat_rumik-0.1.1/LICENSE +21 -0
- pipecat_rumik-0.1.1/PKG-INFO +284 -0
- pipecat_rumik-0.1.1/README.md +233 -0
- pipecat_rumik-0.1.1/RELEASE.md +136 -0
- pipecat_rumik-0.1.1/TESTING.md +213 -0
- pipecat_rumik-0.1.1/examples/smoke_rumik_http.py +125 -0
- pipecat_rumik-0.1.1/examples/smoke_rumik_ws.py +187 -0
- pipecat_rumik-0.1.1/examples/smoke_rumik_ws_suite.py +294 -0
- pipecat_rumik-0.1.1/pyproject.toml +81 -0
- pipecat_rumik-0.1.1/scripts/inspect_wav.py +78 -0
- pipecat_rumik-0.1.1/src/pipecat_rumik/__init__.py +6 -0
- pipecat_rumik-0.1.1/src/pipecat_rumik/py.typed +1 -0
- pipecat_rumik-0.1.1/src/pipecat_rumik/services/__init__.py +1 -0
- pipecat_rumik-0.1.1/src/pipecat_rumik/services/rumik/__init__.py +5 -0
- pipecat_rumik-0.1.1/src/pipecat_rumik/services/rumik/tts.py +560 -0
- pipecat_rumik-0.1.1/src/pipecat_rumik/settings.py +18 -0
- pipecat_rumik-0.1.1/tests/test_settings.py +51 -0
- pipecat_rumik-0.1.1/tests/test_tts_http.py +255 -0
- pipecat_rumik-0.1.1/tests/test_tts_websocket.py +432 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rumik AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pipecat-rumik
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Rumik text-to-speech services for Pipecat
|
|
5
|
+
Project-URL: Homepage, https://rumik.ai
|
|
6
|
+
Project-URL: Repository, https://github.com/ira-rumik/pipecat-rumik
|
|
7
|
+
Project-URL: Issues, https://github.com/ira-rumik/pipecat-rumik/issues
|
|
8
|
+
Project-URL: Support, https://github.com/ira-rumik/pipecat-rumik/issues
|
|
9
|
+
Author: Rumik AI
|
|
10
|
+
Maintainer: Rumik AI
|
|
11
|
+
License: MIT License
|
|
12
|
+
|
|
13
|
+
Copyright (c) 2026 Rumik AI
|
|
14
|
+
|
|
15
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
16
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
17
|
+
in the Software without restriction, including without limitation the rights
|
|
18
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
19
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
20
|
+
furnished to do so, subject to the following conditions:
|
|
21
|
+
|
|
22
|
+
The above copyright notice and this permission notice shall be included in all
|
|
23
|
+
copies or substantial portions of the Software.
|
|
24
|
+
|
|
25
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
26
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
27
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
28
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
29
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
30
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
31
|
+
SOFTWARE.
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
Keywords: pipecat,rumik,speech,text-to-speech,tts,voice-ai
|
|
34
|
+
Classifier: Development Status :: 3 - Alpha
|
|
35
|
+
Classifier: Intended Audience :: Developers
|
|
36
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
37
|
+
Classifier: Programming Language :: Python :: 3
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
40
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
|
|
41
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
42
|
+
Requires-Python: >=3.11
|
|
43
|
+
Requires-Dist: aiohttp>=3.9
|
|
44
|
+
Requires-Dist: certifi>=2024.2.2
|
|
45
|
+
Requires-Dist: pipecat-ai<2,>=1.0.0
|
|
46
|
+
Requires-Dist: websockets>=13
|
|
47
|
+
Provides-Extra: dev
|
|
48
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
49
|
+
Requires-Dist: ruff>=0.8; extra == 'dev'
|
|
50
|
+
Description-Content-Type: text/markdown
|
|
51
|
+
|
|
52
|
+
# pipecat-rumik
|
|
53
|
+
|
|
54
|
+
Text-to-speech service implementations for
|
|
55
|
+
[Pipecat](https://github.com/pipecat-ai/pipecat) using Rumik's TTS APIs.
|
|
56
|
+
|
|
57
|
+
## Overview
|
|
58
|
+
|
|
59
|
+
`pipecat-rumik` provides two Pipecat TTS services:
|
|
60
|
+
|
|
61
|
+
- `RumikTTSService` for WebSocket-based synthesis in interactive voice
|
|
62
|
+
pipelines.
|
|
63
|
+
- `RumikHttpTTSService` for HTTP request/response synthesis.
|
|
64
|
+
|
|
65
|
+
The package follows Pipecat's service conventions: constructor-level provider
|
|
66
|
+
configuration, runtime-configurable `Settings`, raw PCM audio frames, metrics,
|
|
67
|
+
and standard service connection events.
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from pipecat_rumik import RumikHttpTTSService, RumikTTSService, RumikTTSSettings
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Installation
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pip install pipecat-rumik
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
For local development:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
uv sync --extra dev
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Prerequisites
|
|
86
|
+
|
|
87
|
+
Before using either service, configure access to the Rumik gateway:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
export RUMIK_API_KEY=...
|
|
91
|
+
export RUMIK_GATEWAY_URL=...
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Optional environment variables used by the smoke-test examples:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
export RUMIK_MODEL=muga
|
|
98
|
+
export RUMIK_SPEAKER_ID=0
|
|
99
|
+
export RUMIK_DESCRIPTION=neutral
|
|
100
|
+
export RUMIK_TEMPERATURE=0.6
|
|
101
|
+
export RUMIK_TOPK=40
|
|
102
|
+
export RUMIK_MAX_NEW_TOKENS=2048
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Service Selection
|
|
106
|
+
|
|
107
|
+
| Service | Transport | Recommended Use |
|
|
108
|
+
| --- | --- | --- |
|
|
109
|
+
| `RumikTTSService` | WebSocket | Interactive Pipecat voice agents that need interruption-aware TTS. |
|
|
110
|
+
| `RumikHttpTTSService` | HTTP | Simpler synthesis flows where a request/response API is preferred. |
|
|
111
|
+
|
|
112
|
+
Use the WebSocket service for conversational applications. Use the HTTP service
|
|
113
|
+
for batch-style synthesis or integration tests that do not need a persistent TTS
|
|
114
|
+
connection.
|
|
115
|
+
|
|
116
|
+
## Configuration
|
|
117
|
+
|
|
118
|
+
### RumikTTSService
|
|
119
|
+
|
|
120
|
+
| Parameter | Type | Required | Description |
|
|
121
|
+
| --- | --- | --- | --- |
|
|
122
|
+
| `api_key` | `str` | yes | Rumik API key. |
|
|
123
|
+
| `gateway_url` | `str` | yes | Rumik gateway base URL. |
|
|
124
|
+
| `settings` | `RumikTTSService.Settings \| None` | no | Runtime-configurable TTS settings. |
|
|
125
|
+
| `sample_rate` | `int \| None` | no | Output sample rate. Rumik currently emits 24 kHz PCM. |
|
|
126
|
+
| `full_response_aggregation` | `bool` | no | Buffer a complete LLM response before sending it to Rumik. Defaults to `True`. |
|
|
127
|
+
|
|
128
|
+
### RumikHttpTTSService
|
|
129
|
+
|
|
130
|
+
| Parameter | Type | Required | Description |
|
|
131
|
+
| --- | --- | --- | --- |
|
|
132
|
+
| `api_key` | `str` | yes | Rumik API key. |
|
|
133
|
+
| `gateway_url` | `str` | yes | Rumik gateway base URL. |
|
|
134
|
+
| `aiohttp_session` | `aiohttp.ClientSession` | yes | Caller-owned HTTP session. |
|
|
135
|
+
| `settings` | `RumikHttpTTSService.Settings \| None` | no | Runtime-configurable TTS settings. |
|
|
136
|
+
| `sample_rate` | `int \| None` | no | Output sample rate. Rumik currently emits 24 kHz PCM. |
|
|
137
|
+
|
|
138
|
+
## Settings
|
|
139
|
+
|
|
140
|
+
Both services use Pipecat's service settings pattern:
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
settings=RumikTTSService.Settings(...)
|
|
144
|
+
settings=RumikHttpTTSService.Settings(...)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`RumikTTSService.Settings` and `RumikHttpTTSService.Settings` are aliases of
|
|
148
|
+
`RumikTTSSettings`.
|
|
149
|
+
|
|
150
|
+
| Setting | Type | Default | Used By | Description |
|
|
151
|
+
| --- | --- | --- | --- | --- |
|
|
152
|
+
| `model` | `str \| None` | `"muga"` | HTTP, WS | Rumik model identifier. |
|
|
153
|
+
| `voice` | `str \| None` | `None` | inherited | Reserved for Pipecat provider compatibility. |
|
|
154
|
+
| `language` | `Language \| str \| None` | `None` | inherited | Reserved for Pipecat provider compatibility. |
|
|
155
|
+
| `speaker_id` | `int` | `0` | WS | Rumik WebSocket speaker ID. |
|
|
156
|
+
| `description` | `str \| None` | `"neutral"` | HTTP | Voice/style description. |
|
|
157
|
+
| `temperature` | `float \| None` | `0.6` | HTTP | Sampling temperature. |
|
|
158
|
+
| `topk` | `int \| None` | `40` | HTTP | Top-k sampling. |
|
|
159
|
+
| `max_new_tokens` | `int \| None` | `2048` | HTTP | Maximum generated audio tokens. |
|
|
160
|
+
|
|
161
|
+
Runtime updates use Pipecat's `TTSUpdateSettingsFrame` with
|
|
162
|
+
`RumikTTSSettings`.
|
|
163
|
+
|
|
164
|
+
## Usage
|
|
165
|
+
|
|
166
|
+
### WebSocket Service
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
import os
|
|
170
|
+
|
|
171
|
+
from pipecat_rumik import RumikTTSService
|
|
172
|
+
|
|
173
|
+
tts = RumikTTSService(
|
|
174
|
+
api_key=os.environ["RUMIK_API_KEY"],
|
|
175
|
+
gateway_url=os.environ["RUMIK_GATEWAY_URL"],
|
|
176
|
+
settings=RumikTTSService.Settings(
|
|
177
|
+
model="muga",
|
|
178
|
+
speaker_id=0,
|
|
179
|
+
),
|
|
180
|
+
)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
By default, `RumikTTSService` uses full-response aggregation. This sends one
|
|
184
|
+
complete assistant response to Rumik instead of creating a separate TTS request
|
|
185
|
+
for every sentence.
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
tts = RumikTTSService(
|
|
189
|
+
api_key=os.environ["RUMIK_API_KEY"],
|
|
190
|
+
gateway_url=os.environ["RUMIK_GATEWAY_URL"],
|
|
191
|
+
full_response_aggregation=False,
|
|
192
|
+
)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### HTTP Service
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
import os
|
|
199
|
+
|
|
200
|
+
import aiohttp
|
|
201
|
+
|
|
202
|
+
from pipecat_rumik import RumikHttpTTSService
|
|
203
|
+
|
|
204
|
+
async with aiohttp.ClientSession() as session:
|
|
205
|
+
tts = RumikHttpTTSService(
|
|
206
|
+
api_key=os.environ["RUMIK_API_KEY"],
|
|
207
|
+
gateway_url=os.environ["RUMIK_GATEWAY_URL"],
|
|
208
|
+
aiohttp_session=session,
|
|
209
|
+
settings=RumikHttpTTSService.Settings(
|
|
210
|
+
model="muga",
|
|
211
|
+
description="neutral",
|
|
212
|
+
temperature=0.6,
|
|
213
|
+
topk=40,
|
|
214
|
+
max_new_tokens=2048,
|
|
215
|
+
),
|
|
216
|
+
)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
The HTTP service uses the caller-owned `aiohttp.ClientSession`. Create and close
|
|
220
|
+
the session in your application code.
|
|
221
|
+
|
|
222
|
+
## Notes
|
|
223
|
+
|
|
224
|
+
- **WebSocket vs HTTP**: The WebSocket service is intended for interactive
|
|
225
|
+
Pipecat conversations. The HTTP service is useful for simpler batch-style
|
|
226
|
+
synthesis.
|
|
227
|
+
- **Request lifecycle**: The WebSocket service keeps one active synthesis
|
|
228
|
+
request per connection so audio chunks are routed deterministically to the
|
|
229
|
+
active Pipecat audio context.
|
|
230
|
+
- **Interruption handling**: On interruption, the WebSocket service closes the
|
|
231
|
+
active socket and opens a fresh session before accepting the next synthesis
|
|
232
|
+
request.
|
|
233
|
+
- **Audio format**: Rumik currently emits 24 kHz, mono, signed 16-bit PCM. The
|
|
234
|
+
services validate provider responses against this audio contract before
|
|
235
|
+
emitting Pipecat audio frames.
|
|
236
|
+
- **HTTP response handling**: The HTTP service validates the WAV response,
|
|
237
|
+
removes the WAV container, and emits raw PCM frames.
|
|
238
|
+
|
|
239
|
+
## Event Handlers
|
|
240
|
+
|
|
241
|
+
`RumikTTSService` supports Pipecat's standard service connection events:
|
|
242
|
+
|
|
243
|
+
| Event | Description |
|
|
244
|
+
| --- | --- |
|
|
245
|
+
| `on_connected` | Connected to the Rumik WebSocket service. |
|
|
246
|
+
| `on_disconnected` | Disconnected from the Rumik WebSocket service. |
|
|
247
|
+
| `on_connection_error` | WebSocket connection error occurred. |
|
|
248
|
+
|
|
249
|
+
```python
|
|
250
|
+
@tts.event_handler("on_connected")
|
|
251
|
+
async def on_connected(service):
|
|
252
|
+
print("Connected to Rumik")
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Examples
|
|
256
|
+
|
|
257
|
+
The repository includes manual smoke tests:
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
env PYTHONPATH=src uv run python examples/smoke_rumik_http.py
|
|
261
|
+
env PYTHONPATH=src uv run python examples/smoke_rumik_ws.py
|
|
262
|
+
env PYTHONPATH=src uv run python examples/smoke_rumik_ws_suite.py
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
The smoke tests require real Rumik credentials. Unit tests do not.
|
|
266
|
+
|
|
267
|
+
## Testing
|
|
268
|
+
|
|
269
|
+
Offline checks:
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
uv run --locked pytest -q
|
|
273
|
+
uv run --locked ruff check src tests examples scripts
|
|
274
|
+
uv run --locked python -m compileall -q src tests examples scripts
|
|
275
|
+
uv build
|
|
276
|
+
uv run --with twine twine check dist/*
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
See [TESTING.md](TESTING.md) for the full test checklist and
|
|
280
|
+
[RELEASE.md](RELEASE.md) for TestPyPI/PyPI release steps.
|
|
281
|
+
|
|
282
|
+
## License
|
|
283
|
+
|
|
284
|
+
This package is released under the MIT License. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# pipecat-rumik
|
|
2
|
+
|
|
3
|
+
Text-to-speech service implementations for
|
|
4
|
+
[Pipecat](https://github.com/pipecat-ai/pipecat) using Rumik's TTS APIs.
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
`pipecat-rumik` provides two Pipecat TTS services:
|
|
9
|
+
|
|
10
|
+
- `RumikTTSService` for WebSocket-based synthesis in interactive voice
|
|
11
|
+
pipelines.
|
|
12
|
+
- `RumikHttpTTSService` for HTTP request/response synthesis.
|
|
13
|
+
|
|
14
|
+
The package follows Pipecat's service conventions: constructor-level provider
|
|
15
|
+
configuration, runtime-configurable `Settings`, raw PCM audio frames, metrics,
|
|
16
|
+
and standard service connection events.
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
from pipecat_rumik import RumikHttpTTSService, RumikTTSService, RumikTTSSettings
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install pipecat-rumik
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
For local development:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
uv sync --extra dev
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Prerequisites
|
|
35
|
+
|
|
36
|
+
Before using either service, configure access to the Rumik gateway:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
export RUMIK_API_KEY=...
|
|
40
|
+
export RUMIK_GATEWAY_URL=...
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Optional environment variables used by the smoke-test examples:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
export RUMIK_MODEL=muga
|
|
47
|
+
export RUMIK_SPEAKER_ID=0
|
|
48
|
+
export RUMIK_DESCRIPTION=neutral
|
|
49
|
+
export RUMIK_TEMPERATURE=0.6
|
|
50
|
+
export RUMIK_TOPK=40
|
|
51
|
+
export RUMIK_MAX_NEW_TOKENS=2048
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Service Selection
|
|
55
|
+
|
|
56
|
+
| Service | Transport | Recommended Use |
|
|
57
|
+
| --- | --- | --- |
|
|
58
|
+
| `RumikTTSService` | WebSocket | Interactive Pipecat voice agents that need interruption-aware TTS. |
|
|
59
|
+
| `RumikHttpTTSService` | HTTP | Simpler synthesis flows where a request/response API is preferred. |
|
|
60
|
+
|
|
61
|
+
Use the WebSocket service for conversational applications. Use the HTTP service
|
|
62
|
+
for batch-style synthesis or integration tests that do not need a persistent TTS
|
|
63
|
+
connection.
|
|
64
|
+
|
|
65
|
+
## Configuration
|
|
66
|
+
|
|
67
|
+
### RumikTTSService
|
|
68
|
+
|
|
69
|
+
| Parameter | Type | Required | Description |
|
|
70
|
+
| --- | --- | --- | --- |
|
|
71
|
+
| `api_key` | `str` | yes | Rumik API key. |
|
|
72
|
+
| `gateway_url` | `str` | yes | Rumik gateway base URL. |
|
|
73
|
+
| `settings` | `RumikTTSService.Settings \| None` | no | Runtime-configurable TTS settings. |
|
|
74
|
+
| `sample_rate` | `int \| None` | no | Output sample rate. Rumik currently emits 24 kHz PCM. |
|
|
75
|
+
| `full_response_aggregation` | `bool` | no | Buffer a complete LLM response before sending it to Rumik. Defaults to `True`. |
|
|
76
|
+
|
|
77
|
+
### RumikHttpTTSService
|
|
78
|
+
|
|
79
|
+
| Parameter | Type | Required | Description |
|
|
80
|
+
| --- | --- | --- | --- |
|
|
81
|
+
| `api_key` | `str` | yes | Rumik API key. |
|
|
82
|
+
| `gateway_url` | `str` | yes | Rumik gateway base URL. |
|
|
83
|
+
| `aiohttp_session` | `aiohttp.ClientSession` | yes | Caller-owned HTTP session. |
|
|
84
|
+
| `settings` | `RumikHttpTTSService.Settings \| None` | no | Runtime-configurable TTS settings. |
|
|
85
|
+
| `sample_rate` | `int \| None` | no | Output sample rate. Rumik currently emits 24 kHz PCM. |
|
|
86
|
+
|
|
87
|
+
## Settings
|
|
88
|
+
|
|
89
|
+
Both services use Pipecat's service settings pattern:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
settings=RumikTTSService.Settings(...)
|
|
93
|
+
settings=RumikHttpTTSService.Settings(...)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
`RumikTTSService.Settings` and `RumikHttpTTSService.Settings` are aliases of
|
|
97
|
+
`RumikTTSSettings`.
|
|
98
|
+
|
|
99
|
+
| Setting | Type | Default | Used By | Description |
|
|
100
|
+
| --- | --- | --- | --- | --- |
|
|
101
|
+
| `model` | `str \| None` | `"muga"` | HTTP, WS | Rumik model identifier. |
|
|
102
|
+
| `voice` | `str \| None` | `None` | inherited | Reserved for Pipecat provider compatibility. |
|
|
103
|
+
| `language` | `Language \| str \| None` | `None` | inherited | Reserved for Pipecat provider compatibility. |
|
|
104
|
+
| `speaker_id` | `int` | `0` | WS | Rumik WebSocket speaker ID. |
|
|
105
|
+
| `description` | `str \| None` | `"neutral"` | HTTP | Voice/style description. |
|
|
106
|
+
| `temperature` | `float \| None` | `0.6` | HTTP | Sampling temperature. |
|
|
107
|
+
| `topk` | `int \| None` | `40` | HTTP | Top-k sampling. |
|
|
108
|
+
| `max_new_tokens` | `int \| None` | `2048` | HTTP | Maximum generated audio tokens. |
|
|
109
|
+
|
|
110
|
+
Runtime updates use Pipecat's `TTSUpdateSettingsFrame` with
|
|
111
|
+
`RumikTTSSettings`.
|
|
112
|
+
|
|
113
|
+
## Usage
|
|
114
|
+
|
|
115
|
+
### WebSocket Service
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
import os
|
|
119
|
+
|
|
120
|
+
from pipecat_rumik import RumikTTSService
|
|
121
|
+
|
|
122
|
+
tts = RumikTTSService(
|
|
123
|
+
api_key=os.environ["RUMIK_API_KEY"],
|
|
124
|
+
gateway_url=os.environ["RUMIK_GATEWAY_URL"],
|
|
125
|
+
settings=RumikTTSService.Settings(
|
|
126
|
+
model="muga",
|
|
127
|
+
speaker_id=0,
|
|
128
|
+
),
|
|
129
|
+
)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
By default, `RumikTTSService` uses full-response aggregation. This sends one
|
|
133
|
+
complete assistant response to Rumik instead of creating a separate TTS request
|
|
134
|
+
for every sentence.
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
tts = RumikTTSService(
|
|
138
|
+
api_key=os.environ["RUMIK_API_KEY"],
|
|
139
|
+
gateway_url=os.environ["RUMIK_GATEWAY_URL"],
|
|
140
|
+
full_response_aggregation=False,
|
|
141
|
+
)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### HTTP Service
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
import os
|
|
148
|
+
|
|
149
|
+
import aiohttp
|
|
150
|
+
|
|
151
|
+
from pipecat_rumik import RumikHttpTTSService
|
|
152
|
+
|
|
153
|
+
async with aiohttp.ClientSession() as session:
|
|
154
|
+
tts = RumikHttpTTSService(
|
|
155
|
+
api_key=os.environ["RUMIK_API_KEY"],
|
|
156
|
+
gateway_url=os.environ["RUMIK_GATEWAY_URL"],
|
|
157
|
+
aiohttp_session=session,
|
|
158
|
+
settings=RumikHttpTTSService.Settings(
|
|
159
|
+
model="muga",
|
|
160
|
+
description="neutral",
|
|
161
|
+
temperature=0.6,
|
|
162
|
+
topk=40,
|
|
163
|
+
max_new_tokens=2048,
|
|
164
|
+
),
|
|
165
|
+
)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
The HTTP service uses the caller-owned `aiohttp.ClientSession`. Create and close
|
|
169
|
+
the session in your application code.
|
|
170
|
+
|
|
171
|
+
## Notes
|
|
172
|
+
|
|
173
|
+
- **WebSocket vs HTTP**: The WebSocket service is intended for interactive
|
|
174
|
+
Pipecat conversations. The HTTP service is useful for simpler batch-style
|
|
175
|
+
synthesis.
|
|
176
|
+
- **Request lifecycle**: The WebSocket service keeps one active synthesis
|
|
177
|
+
request per connection so audio chunks are routed deterministically to the
|
|
178
|
+
active Pipecat audio context.
|
|
179
|
+
- **Interruption handling**: On interruption, the WebSocket service closes the
|
|
180
|
+
active socket and opens a fresh session before accepting the next synthesis
|
|
181
|
+
request.
|
|
182
|
+
- **Audio format**: Rumik currently emits 24 kHz, mono, signed 16-bit PCM. The
|
|
183
|
+
services validate provider responses against this audio contract before
|
|
184
|
+
emitting Pipecat audio frames.
|
|
185
|
+
- **HTTP response handling**: The HTTP service validates the WAV response,
|
|
186
|
+
removes the WAV container, and emits raw PCM frames.
|
|
187
|
+
|
|
188
|
+
## Event Handlers
|
|
189
|
+
|
|
190
|
+
`RumikTTSService` supports Pipecat's standard service connection events:
|
|
191
|
+
|
|
192
|
+
| Event | Description |
|
|
193
|
+
| --- | --- |
|
|
194
|
+
| `on_connected` | Connected to the Rumik WebSocket service. |
|
|
195
|
+
| `on_disconnected` | Disconnected from the Rumik WebSocket service. |
|
|
196
|
+
| `on_connection_error` | WebSocket connection error occurred. |
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
@tts.event_handler("on_connected")
|
|
200
|
+
async def on_connected(service):
|
|
201
|
+
print("Connected to Rumik")
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Examples
|
|
205
|
+
|
|
206
|
+
The repository includes manual smoke tests:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
env PYTHONPATH=src uv run python examples/smoke_rumik_http.py
|
|
210
|
+
env PYTHONPATH=src uv run python examples/smoke_rumik_ws.py
|
|
211
|
+
env PYTHONPATH=src uv run python examples/smoke_rumik_ws_suite.py
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
The smoke tests require real Rumik credentials. Unit tests do not.
|
|
215
|
+
|
|
216
|
+
## Testing
|
|
217
|
+
|
|
218
|
+
Offline checks:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
uv run --locked pytest -q
|
|
222
|
+
uv run --locked ruff check src tests examples scripts
|
|
223
|
+
uv run --locked python -m compileall -q src tests examples scripts
|
|
224
|
+
uv build
|
|
225
|
+
uv run --with twine twine check dist/*
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
See [TESTING.md](TESTING.md) for the full test checklist and
|
|
229
|
+
[RELEASE.md](RELEASE.md) for TestPyPI/PyPI release steps.
|
|
230
|
+
|
|
231
|
+
## License
|
|
232
|
+
|
|
233
|
+
This package is released under the MIT License. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Releasing pipecat-rumik
|
|
2
|
+
|
|
3
|
+
Use this checklist for TestPyPI and PyPI releases. Do not commit API tokens,
|
|
4
|
+
`.pypirc`, generated `dist/` artifacts, or smoke-test audio files.
|
|
5
|
+
|
|
6
|
+
## Prerequisites
|
|
7
|
+
|
|
8
|
+
- `main` is clean and pushed.
|
|
9
|
+
- GitHub Actions is green on the commit being released.
|
|
10
|
+
- The repository is public-ready: no secrets, local paths, private app names, or
|
|
11
|
+
internal migration notes in the tracked tree.
|
|
12
|
+
- Before making a previously private repository public, delete old workflow
|
|
13
|
+
runs/logs or publish from a fresh public repository created from the clean
|
|
14
|
+
tree.
|
|
15
|
+
- Live HTTP, WebSocket, and interactive interruption tests have been run.
|
|
16
|
+
- A TestPyPI account exists.
|
|
17
|
+
- A PyPI account exists before the real release.
|
|
18
|
+
|
|
19
|
+
For a new package, the first TestPyPI upload usually needs an account-level API
|
|
20
|
+
token because the project does not exist yet. After the first upload, prefer a
|
|
21
|
+
project-scoped token.
|
|
22
|
+
|
|
23
|
+
## Build and Check
|
|
24
|
+
|
|
25
|
+
Build from a clean checkout:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git status --short --branch
|
|
29
|
+
rm -rf dist
|
|
30
|
+
uv build
|
|
31
|
+
uv run --with twine twine check dist/*
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Inspect package contents:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
tar -tzf dist/*.tar.gz | sort
|
|
38
|
+
python -m zipfile -l dist/*.whl
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Expected result:
|
|
42
|
+
|
|
43
|
+
- `LICENSE`, `README.md`, `pyproject.toml`, `src/pipecat_rumik`, examples, and
|
|
44
|
+
tests are present in the source distribution.
|
|
45
|
+
- The wheel contains only the importable package and `.dist-info` metadata.
|
|
46
|
+
- `.env`, `.venv`, caches, generated WAV files, and `dist/` contents are absent
|
|
47
|
+
from the source distribution.
|
|
48
|
+
|
|
49
|
+
## Upload to TestPyPI
|
|
50
|
+
|
|
51
|
+
Set the TestPyPI API token in the shell session only:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
export TWINE_USERNAME=__token__
|
|
55
|
+
export TWINE_PASSWORD=...
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Upload:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
uv run --with twine twine upload \
|
|
62
|
+
--repository-url https://test.pypi.org/legacy/ \
|
|
63
|
+
dist/*
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
If TestPyPI rejects the upload because the version already exists, bump
|
|
67
|
+
`version` in `pyproject.toml`, rebuild, and upload the new version. Package
|
|
68
|
+
versions are immutable once uploaded.
|
|
69
|
+
|
|
70
|
+
## Install From TestPyPI
|
|
71
|
+
|
|
72
|
+
Use a clean environment. The extra PyPI index is required because dependencies
|
|
73
|
+
such as `pipecat-ai` may not exist on TestPyPI.
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
python3 -m venv /tmp/pipecat-rumik-testpypi
|
|
77
|
+
/tmp/pipecat-rumik-testpypi/bin/python -m pip install --upgrade pip
|
|
78
|
+
/tmp/pipecat-rumik-testpypi/bin/python -m pip install \
|
|
79
|
+
--index-url https://test.pypi.org/simple/ \
|
|
80
|
+
--extra-index-url https://pypi.org/simple/ \
|
|
81
|
+
pipecat-rumik==0.1.1
|
|
82
|
+
/tmp/pipecat-rumik-testpypi/bin/python -c "from pipecat_rumik import RumikTTSService, RumikHttpTTSService, RumikTTSSettings; print(RumikTTSService.__name__, RumikHttpTTSService.__name__, RumikTTSSettings.__name__)"
|
|
83
|
+
/tmp/pipecat-rumik-testpypi/bin/python -m pip check
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Then run the unit tests against the installed package:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
/tmp/pipecat-rumik-testpypi/bin/python -m pip install pytest
|
|
90
|
+
/tmp/pipecat-rumik-testpypi/bin/python -m unittest discover -s tests
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Upload to PyPI
|
|
94
|
+
|
|
95
|
+
Only do this after TestPyPI install verification and live provider testing pass.
|
|
96
|
+
|
|
97
|
+
Set the real PyPI API token in the shell session only:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
export TWINE_USERNAME=__token__
|
|
101
|
+
export TWINE_PASSWORD=...
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Upload:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
uv run --with twine twine upload dist/*
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Verify from a fresh environment:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
python3 -m venv /tmp/pipecat-rumik-pypi
|
|
114
|
+
/tmp/pipecat-rumik-pypi/bin/python -m pip install --upgrade pip
|
|
115
|
+
/tmp/pipecat-rumik-pypi/bin/python -m pip install pipecat-rumik==0.1.1
|
|
116
|
+
/tmp/pipecat-rumik-pypi/bin/python -c "from pipecat_rumik import RumikTTSService; print(RumikTTSService.__name__)"
|
|
117
|
+
/tmp/pipecat-rumik-pypi/bin/python -m pip check
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Tag the Release
|
|
121
|
+
|
|
122
|
+
After the PyPI package is verified:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
git tag v0.1.1
|
|
126
|
+
git push origin v0.1.1
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
If the release fails after uploading to PyPI, do not reuse the same version.
|
|
130
|
+
Bump to a new patch version and release again.
|
|
131
|
+
|
|
132
|
+
## References
|
|
133
|
+
|
|
134
|
+
- Python Packaging User Guide: https://packaging.python.org/en/latest/tutorials/packaging-projects/
|
|
135
|
+
- PyPI upload API: https://docs.pypi.org/api/upload/
|
|
136
|
+
- PyPI API token help: https://pypi.org/help/#apitoken
|