livekit-evals 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.
- livekit_evals-0.1.1/LICENSE +21 -0
- livekit_evals-0.1.1/MANIFEST.in +7 -0
- livekit_evals-0.1.1/PKG-INFO +474 -0
- livekit_evals-0.1.1/README.md +445 -0
- livekit_evals-0.1.1/livekit_evals/__init__.py +12 -0
- livekit_evals-0.1.1/livekit_evals/webhook_handler.py +870 -0
- livekit_evals-0.1.1/livekit_evals.egg-info/PKG-INFO +474 -0
- livekit_evals-0.1.1/livekit_evals.egg-info/SOURCES.txt +11 -0
- livekit_evals-0.1.1/livekit_evals.egg-info/dependency_links.txt +1 -0
- livekit_evals-0.1.1/livekit_evals.egg-info/requires.txt +2 -0
- livekit_evals-0.1.1/livekit_evals.egg-info/top_level.txt +1 -0
- livekit_evals-0.1.1/pyproject.toml +45 -0
- livekit_evals-0.1.1/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 SuperBryn
|
|
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,474 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: livekit-evals
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Track and evaluate LiveKit agent sessions with automatic metrics, transcripts, and usage analytics
|
|
5
|
+
Author-email: Speechify <support@speechify.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/speechify/livekit-evals
|
|
8
|
+
Project-URL: Documentation, https://github.com/speechify/livekit-evals#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/speechify/livekit-evals
|
|
10
|
+
Project-URL: Issues, https://github.com/speechify/livekit-evals/issues
|
|
11
|
+
Keywords: livekit,agents,analytics,metrics,evaluation,voice-ai
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Classifier: Topic :: Communications :: Telephony
|
|
22
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: livekit-agents>=0.8.0
|
|
27
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# LiveKit Evals
|
|
31
|
+
|
|
32
|
+
[](https://badge.fury.io/py/livekit-evals)
|
|
33
|
+
[](https://www.python.org/downloads/)
|
|
34
|
+
[](https://opensource.org/licenses/MIT)
|
|
35
|
+
|
|
36
|
+
**Track and evaluate your LiveKit voice AI agents with just 3 lines of code.**
|
|
37
|
+
|
|
38
|
+
Automatically capture transcripts, usage metrics, latency data, and session analytics from your LiveKit agents. Perfect for monitoring, debugging, and optimizing your voice AI applications.
|
|
39
|
+
|
|
40
|
+
## ✨ Features
|
|
41
|
+
|
|
42
|
+
- 🎯 **3-Line Integration** - Add to any LiveKit agent in seconds
|
|
43
|
+
- 📝 **Precise Transcripts** - Accurate timing using VAD state change events
|
|
44
|
+
- 📊 **Usage Metrics** - Track LLM tokens, STT duration, TTS characters
|
|
45
|
+
- ⚡ **Latency Tracking** - Monitor LLM, STT, and TTS performance
|
|
46
|
+
- 🔍 **Auto-Detection** - Automatically extracts models, providers, and configuration
|
|
47
|
+
- 📞 **SIP Support** - Detects SIP trunking and phone numbers
|
|
48
|
+
- 🎥 **Recording URLs** - Captures egress recording links
|
|
49
|
+
- 🔐 **Secure** - API key authentication with webhook delivery
|
|
50
|
+
|
|
51
|
+
## 🚀 Quick Start
|
|
52
|
+
|
|
53
|
+
### Prerequisites
|
|
54
|
+
|
|
55
|
+
1. **Get your API key** from [https://your-platform.com/api-keys](https://your-platform.com/api-keys) *(placeholder)*
|
|
56
|
+
2. **Set environment variable:**
|
|
57
|
+
```bash
|
|
58
|
+
export SUPERBRYN_API_KEY=your_api_key_here
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Installation
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install livekit-evals
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Integration (3 Lines)
|
|
68
|
+
|
|
69
|
+
Add these lines to your LiveKit agent:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from livekit_evals import create_webhook_handler
|
|
73
|
+
|
|
74
|
+
async def entrypoint(ctx: JobContext):
|
|
75
|
+
# ... your existing setup code ...
|
|
76
|
+
|
|
77
|
+
# 1. Create webhook handler
|
|
78
|
+
webhook_handler = create_webhook_handler(
|
|
79
|
+
room=ctx.room,
|
|
80
|
+
is_deployed_on_lk_cloud=True # Set to False if self-hosting
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
# ... create your session ...
|
|
84
|
+
session = AgentSession(
|
|
85
|
+
llm=openai.LLM(model="gpt-4o-mini"),
|
|
86
|
+
stt=deepgram.STT(model="nova-3"),
|
|
87
|
+
tts=cartesia.TTS(voice="..."),
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# ... your session setup ...
|
|
91
|
+
await session.start(agent=YourAgent(), room=ctx.room)
|
|
92
|
+
|
|
93
|
+
# 2. Attach to session (MUST be after session.start, before ctx.connect)
|
|
94
|
+
if webhook_handler:
|
|
95
|
+
webhook_handler.attach_to_session(session)
|
|
96
|
+
# 3. Send webhook on shutdown
|
|
97
|
+
ctx.add_shutdown_callback(webhook_handler.send_webhook)
|
|
98
|
+
|
|
99
|
+
await ctx.connect()
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**That's it!** 🎉 Your agent will now automatically track all session data and send it to your webhook endpoint.
|
|
103
|
+
|
|
104
|
+
## 📖 Full Example
|
|
105
|
+
|
|
106
|
+
Here's a complete working example:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
import logging
|
|
110
|
+
from dotenv import load_dotenv
|
|
111
|
+
from livekit.agents import (
|
|
112
|
+
Agent,
|
|
113
|
+
AgentSession,
|
|
114
|
+
JobContext,
|
|
115
|
+
WorkerOptions,
|
|
116
|
+
cli,
|
|
117
|
+
)
|
|
118
|
+
from livekit.plugins import cartesia, deepgram, openai, silero
|
|
119
|
+
|
|
120
|
+
# Import livekit-evals
|
|
121
|
+
from livekit_evals import create_webhook_handler
|
|
122
|
+
|
|
123
|
+
logger = logging.getLogger("agent")
|
|
124
|
+
load_dotenv()
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class Assistant(Agent):
|
|
128
|
+
def __init__(self) -> None:
|
|
129
|
+
super().__init__(
|
|
130
|
+
instructions="""You are a helpful voice AI assistant.
|
|
131
|
+
You eagerly assist users with their questions.""",
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
async def entrypoint(ctx: JobContext):
|
|
136
|
+
# Logging setup
|
|
137
|
+
ctx.log_context_fields = {"room": ctx.room.name}
|
|
138
|
+
|
|
139
|
+
# Initialize webhook handler (auto-detects all metadata)
|
|
140
|
+
webhook_handler = create_webhook_handler(
|
|
141
|
+
room=ctx.room,
|
|
142
|
+
is_deployed_on_lk_cloud=True # Set to False if self-hosting
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# Set up voice AI pipeline
|
|
146
|
+
session = AgentSession(
|
|
147
|
+
llm=openai.LLM(model="gpt-4o-mini"),
|
|
148
|
+
stt=deepgram.STT(model="nova-3", language="en"),
|
|
149
|
+
tts=cartesia.TTS(voice="your-voice-id"),
|
|
150
|
+
vad=silero.VAD.load(),
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
# Start the session
|
|
154
|
+
await session.start(agent=Assistant(), room=ctx.room)
|
|
155
|
+
|
|
156
|
+
# Attach webhook handler to capture events
|
|
157
|
+
# IMPORTANT: Must be after session.start() and before ctx.connect()
|
|
158
|
+
if webhook_handler:
|
|
159
|
+
webhook_handler.attach_to_session(session)
|
|
160
|
+
ctx.add_shutdown_callback(webhook_handler.send_webhook)
|
|
161
|
+
|
|
162
|
+
# Connect to room
|
|
163
|
+
await ctx.connect()
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
if __name__ == "__main__":
|
|
167
|
+
cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint))
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## 🔧 Configuration
|
|
171
|
+
|
|
172
|
+
### Environment Variables
|
|
173
|
+
|
|
174
|
+
| Variable | Required | Description | Default |
|
|
175
|
+
|----------|----------|-------------|---------|
|
|
176
|
+
| `SUPERBRYN_API_KEY` | ✅ Yes | API key for webhook authentication | - |
|
|
177
|
+
| `LIVEKIT_PROJECT_ID` | ⚪ Optional | LiveKit project ID | Auto-detected from `LIVEKIT_URL` |
|
|
178
|
+
| `AGENT_ID` | ⚪ Optional | Unique agent identifier | Auto-detected from job metadata or `"livekit-agent"` |
|
|
179
|
+
| `VERSION_ID` | ⚪ Optional | Agent version identifier | Auto-detected from job metadata or `"v1"` |
|
|
180
|
+
|
|
181
|
+
### Setting Environment Variables
|
|
182
|
+
|
|
183
|
+
**Linux/Mac:**
|
|
184
|
+
```bash
|
|
185
|
+
export SUPERBRYN_API_KEY=your_api_key_here
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Windows (CMD):**
|
|
189
|
+
```cmd
|
|
190
|
+
set SUPERBRYN_API_KEY=your_api_key_here
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Windows (PowerShell):**
|
|
194
|
+
```powershell
|
|
195
|
+
$env:SUPERBRYN_API_KEY="your_api_key_here"
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Docker:**
|
|
199
|
+
```bash
|
|
200
|
+
docker run -e SUPERBRYN_API_KEY=your_api_key_here ...
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**.env file:**
|
|
204
|
+
```env
|
|
205
|
+
SUPERBRYN_API_KEY=your_api_key_here
|
|
206
|
+
LIVEKIT_PROJECT_ID=my-project-id
|
|
207
|
+
AGENT_ID=my-agent
|
|
208
|
+
VERSION_ID=v1.0.0
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## 📊 What Gets Tracked
|
|
212
|
+
|
|
213
|
+
### Transcript Data
|
|
214
|
+
- **Precise timing** using VAD state change events
|
|
215
|
+
- Speaker turns (user/assistant)
|
|
216
|
+
- Start/end timestamps (ISO 8601)
|
|
217
|
+
- Start/end times in milliseconds (relative to call start)
|
|
218
|
+
- Response delays between turns
|
|
219
|
+
- Interruption detection
|
|
220
|
+
- Confidence scores (when available)
|
|
221
|
+
- Language detection
|
|
222
|
+
- Speaker IDs
|
|
223
|
+
|
|
224
|
+
### Usage Metrics
|
|
225
|
+
- **LLM:** Input tokens, output tokens, total tokens, model, provider
|
|
226
|
+
- **STT:** Audio duration, model, provider
|
|
227
|
+
- **TTS:** Character count, audio duration, model, provider, voice ID
|
|
228
|
+
|
|
229
|
+
### Latency Metrics
|
|
230
|
+
- **LLM:** Time to first token (TTFT), total duration
|
|
231
|
+
- **STT:** Processing duration
|
|
232
|
+
- **TTS:** Time to first byte (TTFB), total duration
|
|
233
|
+
- **Aggregated:** Average latencies per component
|
|
234
|
+
|
|
235
|
+
### Session Metadata
|
|
236
|
+
- Agent ID and version
|
|
237
|
+
- LiveKit project ID
|
|
238
|
+
- System prompt
|
|
239
|
+
- Call duration
|
|
240
|
+
- Phone number (if SIP call)
|
|
241
|
+
- SIP trunking detection
|
|
242
|
+
- Egress recording URLs
|
|
243
|
+
- LiveKit Cloud deployment status
|
|
244
|
+
|
|
245
|
+
## 🔍 How It Works
|
|
246
|
+
|
|
247
|
+
1. **Event Listening:** Attaches to LiveKit session events (`user_state_changed`, `agent_state_changed`, `metrics_collected`, `conversation_item_added`)
|
|
248
|
+
2. **Data Aggregation:** Collects and processes events during the session
|
|
249
|
+
3. **Auto-Detection:** Extracts configuration from session objects and job metadata
|
|
250
|
+
4. **Webhook Delivery:** Sends comprehensive payload to webhook endpoint when session ends
|
|
251
|
+
|
|
252
|
+
### Webhook Payload Format
|
|
253
|
+
|
|
254
|
+
```json
|
|
255
|
+
{
|
|
256
|
+
"event": "call.ended",
|
|
257
|
+
"call": {
|
|
258
|
+
"id": "room-name",
|
|
259
|
+
"room_name": "room-name",
|
|
260
|
+
"participant_identity": "user-123",
|
|
261
|
+
"started_at": "2025-10-19T12:00:00.000Z",
|
|
262
|
+
"ended_at": "2025-10-19T12:05:30.000Z",
|
|
263
|
+
"duration_seconds": 330,
|
|
264
|
+
"transcript": {
|
|
265
|
+
"turns": [
|
|
266
|
+
{
|
|
267
|
+
"speaker": "user",
|
|
268
|
+
"text": "Hello, how are you?",
|
|
269
|
+
"timestamp": "2025-10-19T12:00:05.000Z",
|
|
270
|
+
"start_timestamp": "2025-10-19T12:00:05.000Z",
|
|
271
|
+
"end_timestamp": "2025-10-19T12:00:07.000Z",
|
|
272
|
+
"start_time_ms": 5000,
|
|
273
|
+
"end_time_ms": 7000,
|
|
274
|
+
"interrupted": false,
|
|
275
|
+
"confidence_score": 0.98,
|
|
276
|
+
"language": "en"
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
"speaker": "assistant",
|
|
280
|
+
"text": "I'm doing great, thanks for asking!",
|
|
281
|
+
"timestamp": "2025-10-19T12:00:08.000Z",
|
|
282
|
+
"start_timestamp": "2025-10-19T12:00:08.000Z",
|
|
283
|
+
"end_timestamp": "2025-10-19T12:00:11.000Z",
|
|
284
|
+
"start_time_ms": 8000,
|
|
285
|
+
"end_time_ms": 11000,
|
|
286
|
+
"response_delay_ms": 1000,
|
|
287
|
+
"interrupted": false
|
|
288
|
+
}
|
|
289
|
+
]
|
|
290
|
+
},
|
|
291
|
+
"recording_url": "https://...",
|
|
292
|
+
"metadata": {
|
|
293
|
+
"agent_id": "my-agent",
|
|
294
|
+
"livekit_project_id": "my-project",
|
|
295
|
+
"llm_model": "gpt-4o-mini",
|
|
296
|
+
"llm_provider": "openai",
|
|
297
|
+
"stt_model": "nova-3",
|
|
298
|
+
"stt_provider": "deepgram",
|
|
299
|
+
"tts_model": "sonic-english",
|
|
300
|
+
"tts_provider": "cartesia",
|
|
301
|
+
"tts_voice_id": "...",
|
|
302
|
+
"system_prompt": "You are a helpful assistant...",
|
|
303
|
+
"sip_trunking_enabled": false,
|
|
304
|
+
"egress_enabled": true,
|
|
305
|
+
"lk_agent_enabled": true,
|
|
306
|
+
"phone_number": null
|
|
307
|
+
},
|
|
308
|
+
"usage": {
|
|
309
|
+
"llm_model": "gpt-4o-mini",
|
|
310
|
+
"llm_provider": "openai",
|
|
311
|
+
"llm_input_tokens": 1250,
|
|
312
|
+
"llm_output_tokens": 850,
|
|
313
|
+
"llm_total_tokens": 2100,
|
|
314
|
+
"stt_provider": "deepgram",
|
|
315
|
+
"stt_model": "nova-3",
|
|
316
|
+
"stt_duration_seconds": 45.2,
|
|
317
|
+
"audio_duration_seconds": 45.2,
|
|
318
|
+
"tts_provider": "cartesia",
|
|
319
|
+
"tts_model": "sonic-english",
|
|
320
|
+
"tts_characters": 1200,
|
|
321
|
+
"tts_audio_duration_seconds": 42.5
|
|
322
|
+
},
|
|
323
|
+
"latency": {
|
|
324
|
+
"llm_ms": 450.5,
|
|
325
|
+
"stt_ms": 120.3,
|
|
326
|
+
"tts_ms": 180.7,
|
|
327
|
+
"total_ms": 751.5
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## 🛠️ Advanced Usage
|
|
334
|
+
|
|
335
|
+
### Custom API Key
|
|
336
|
+
|
|
337
|
+
Pass API key directly instead of using environment variable:
|
|
338
|
+
|
|
339
|
+
```python
|
|
340
|
+
webhook_handler = create_webhook_handler(
|
|
341
|
+
room=ctx.room,
|
|
342
|
+
is_deployed_on_lk_cloud=True,
|
|
343
|
+
api_key="your_api_key_here"
|
|
344
|
+
)
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Custom LiveKit Project ID
|
|
348
|
+
|
|
349
|
+
```python
|
|
350
|
+
webhook_handler = create_webhook_handler(
|
|
351
|
+
room=ctx.room,
|
|
352
|
+
is_deployed_on_lk_cloud=True,
|
|
353
|
+
livekit_project_id="my-custom-project-id"
|
|
354
|
+
)
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### Self-Hosted Agents
|
|
358
|
+
|
|
359
|
+
If you're self-hosting your LiveKit agents (not using LiveKit Cloud):
|
|
360
|
+
|
|
361
|
+
```python
|
|
362
|
+
webhook_handler = create_webhook_handler(
|
|
363
|
+
room=ctx.room,
|
|
364
|
+
is_deployed_on_lk_cloud=False # Important for cost calculation
|
|
365
|
+
)
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Passing Metadata via Job Context
|
|
369
|
+
|
|
370
|
+
You can pass custom metadata when creating LiveKit jobs:
|
|
371
|
+
|
|
372
|
+
```python
|
|
373
|
+
# When creating a job
|
|
374
|
+
job_metadata = {
|
|
375
|
+
"agent_id": "customer-support-bot",
|
|
376
|
+
"version_id": "v2.1.0",
|
|
377
|
+
"phone_number": "+1234567890"
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
The webhook handler will automatically extract these values.
|
|
382
|
+
|
|
383
|
+
## 🐛 Troubleshooting
|
|
384
|
+
|
|
385
|
+
### Webhook Not Sending
|
|
386
|
+
|
|
387
|
+
**Check API Key:**
|
|
388
|
+
```bash
|
|
389
|
+
echo $SUPERBRYN_API_KEY
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
**Enable Debug Logging:**
|
|
393
|
+
```python
|
|
394
|
+
import logging
|
|
395
|
+
logging.basicConfig(level=logging.DEBUG)
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
**Look for these log messages:**
|
|
399
|
+
- `SPEECHIFY_WEBHOOK_HANDLER_CREATED` - Handler initialized
|
|
400
|
+
- `SPEECHIFY_WEBHOOK_SENT` - Webhook delivered successfully
|
|
401
|
+
- `SPEECHIFY_WEBHOOK_UNAUTHORIZED` - Invalid API key
|
|
402
|
+
- `SPEECHIFY_WEBHOOK_FAILED` - Delivery failed
|
|
403
|
+
- `SPEECHIFY_WEBHOOK_ERROR` - Exception occurred
|
|
404
|
+
|
|
405
|
+
### Common Errors
|
|
406
|
+
|
|
407
|
+
| Error | Cause | Solution |
|
|
408
|
+
|-------|-------|----------|
|
|
409
|
+
| `SUPERBRYN_API_KEY not configured` | Missing API key | Set `SUPERBRYN_API_KEY` environment variable |
|
|
410
|
+
| `SPEECHIFY_WEBHOOK_UNAUTHORIZED` | Invalid API key | Verify your API key is correct |
|
|
411
|
+
| `SPEECHIFY_WEBHOOK_FORBIDDEN` | Expired/disabled key | Generate a new API key |
|
|
412
|
+
| `No empty turn found to fill` | State change timing issue | Usually harmless, check logs for patterns |
|
|
413
|
+
|
|
414
|
+
### Missing Transcript Data
|
|
415
|
+
|
|
416
|
+
Ensure `webhook_handler.attach_to_session(session)` is called:
|
|
417
|
+
- ✅ **After** `await session.start()`
|
|
418
|
+
- ✅ **Before** `await ctx.connect()`
|
|
419
|
+
- ✅ At the **end** of your entrypoint (no early returns)
|
|
420
|
+
|
|
421
|
+
### Provider Detection Issues
|
|
422
|
+
|
|
423
|
+
The package auto-detects providers from model names. Supported providers:
|
|
424
|
+
- OpenAI (gpt, whisper, tts-1)
|
|
425
|
+
- Anthropic (claude)
|
|
426
|
+
- Google (gemini, palm)
|
|
427
|
+
- Sarvam (saarika)
|
|
428
|
+
- ElevenLabs (eleven)
|
|
429
|
+
- Cartesia (cartesia, sonic)
|
|
430
|
+
- Deepgram (deepgram, nova)
|
|
431
|
+
|
|
432
|
+
If your provider isn't detected, it will show as `"unknown"` but won't affect functionality.
|
|
433
|
+
|
|
434
|
+
## 📝 Migration Guide
|
|
435
|
+
|
|
436
|
+
If you're currently using the standalone `webhook_handler.py`:
|
|
437
|
+
|
|
438
|
+
**Before:**
|
|
439
|
+
```python
|
|
440
|
+
from webhook_handler import create_webhook_handler
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**After:**
|
|
444
|
+
```python
|
|
445
|
+
from livekit_evals import create_webhook_handler
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
Everything else stays the same! The API is identical.
|
|
449
|
+
|
|
450
|
+
## 🤝 Contributing
|
|
451
|
+
|
|
452
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
453
|
+
|
|
454
|
+
## 📄 License
|
|
455
|
+
|
|
456
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
457
|
+
|
|
458
|
+
## 🔗 Links
|
|
459
|
+
|
|
460
|
+
- [LiveKit Agents Documentation](https://docs.livekit.io/agents/)
|
|
461
|
+
- [GitHub Repository](https://github.com/speechify/livekit-evals)
|
|
462
|
+
- [Issue Tracker](https://github.com/speechify/livekit-evals/issues)
|
|
463
|
+
- [Get API Key](https://your-platform.com/api-keys) *(placeholder)*
|
|
464
|
+
|
|
465
|
+
## 💡 Support
|
|
466
|
+
|
|
467
|
+
- 📧 Email: support@speechify.com
|
|
468
|
+
- 💬 GitHub Issues: [Report a bug](https://github.com/speechify/livekit-evals/issues)
|
|
469
|
+
- 📚 Documentation: [README](https://github.com/speechify/livekit-evals#readme)
|
|
470
|
+
|
|
471
|
+
---
|
|
472
|
+
|
|
473
|
+
Made with ❤️ by [Speechify](https://speechify.com)
|
|
474
|
+
|