Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions agents-core/vision_agents/core/stt/stt.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from vision_agents.core.edge.types import Participant
from vision_agents.core.events.manager import EventManager
from vision_agents.core.observability import MetricsCollector
from vision_agents.core.stt import events
from vision_agents.core.stt.events import (
STTConnectedEvent,
STTDisconnectedEvent,
Expand Down Expand Up @@ -87,6 +88,7 @@ def __init__(
self.provider_name = provider_name or self.__class__.__name__

self.events = EventManager()
self.events.register_events_from_module(events, ignore_not_compatible=True)
self.metrics = MetricsCollector()

self._output: Stream[Transcript | TurnEnded | TurnStarted] = Stream()
Expand Down
37 changes: 30 additions & 7 deletions plugins/cartesia/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[Cartesia](https://cartesia.ai) is a service that provides Speech-to-Text (STT) and Text-to-Speech (TTS) capabilities. It's designed for real-time voice applications, making it ideal for voice AI agents, transcription pipelines, and conversational interfaces.

The Cartesia plugin for the Stream Python AI SDK allows you to add TTS functionality to your project.
The Cartesia plugin for the Stream Python AI SDK allows you to add STT and TTS functionality to your project.

## Installation

Expand All @@ -16,19 +16,20 @@ uv add vision-agents-plugins-cartesia

## Examples

Read on for some key details and check out our [Cartesia examples](https://github.com/GetStream/vision-agents/tree/main/examples/other_examples/plugins_examples/tts_cartesia) to see working code samples:
Read on for some key details and check out our [Cartesia examples](https://github.com/GetStream/Vision-Agents/tree/main/plugins/cartesia/example) to see working code samples:

- in [tts.py](https://github.com/GetStream/vision-agents/tree/main/examples/other_examples/plugins_examples/tts_cartesia/tts.py) we see a simple bot greeting users upon joining a call
- in [narrator-example.py](https://github.com/GetStream/vision-agents/tree/main/examples/other_examples/plugins_examples/tts_cartesia/narrator-example.py) we see a well-prompted combination of a STT -> LLM -> TTS flow that leverages the powers of Cartesia's Sonic 3 model to narrate a creative story from the user's input
- in [main.py](https://github.com/GetStream/Vision-Agents/blob/main/plugins/cartesia/example/main.py) we see a voice bot that uses Cartesia STT and TTS in a Stream call
- in [narrator-example.py](https://github.com/GetStream/Vision-Agents/blob/main/plugins/cartesia/example/narrator-example.py) we see a well-prompted combination of an STT -> LLM -> TTS flow that leverages Cartesia's Ink and Sonic models to narrate a creative story from the user's input

## Initialisation

The Cartesia plugin for Stream exists in the form of the `TTS` class:
The Cartesia plugin for Stream exposes `STT` and `TTS` classes:

```python

from vision_agents.plugins import cartesia

stt = cartesia.STT()
tts = cartesia.TTS()
```

Expand All @@ -39,17 +40,39 @@ tts = cartesia.TTS()

## Parameters

These are the parameters available in the CartesiaTTS plugin for you to customise:
These are the parameters available in the Cartesia STT plugin for you to customise:

| Name | Type | Default | Description |
|---------------------|-----------------|----------------------------------------|---------------------------------------------------------------------------------------------------------------|
| `api_key` | `str` or `None` | `None` | Your Cartesia API key. If not provided, the plugin will look for the `CARTESIA_API_KEY` environment variable. |
| `model` | `str` | `"ink-2"` | ID of the Cartesia STT model to use. |
| `sample_rate` | `int` | `16000` | Sample rate (in Hz) sent to Cartesia. |
| `encoding` | `str` | `"pcm_s16le"` | PCM encoding sent to Cartesia. |
| `cartesia_version` | `str` | `"2026-03-01"` | Cartesia API version used for the turn-detection websocket. |

These are the parameters available in the Cartesia TTS plugin for you to customise:

| Name | Type | Default | Description |
|---------------|-----------------|------------------------------------------|---------------------------------------------------------------------------------------------------------------|
| `api_key` | `str` or `None` | `None` | Your Cartesia API key. If not provided, the plugin will look for the `CARTESIA_API_KEY` environment variable. |
| `model_id` | `str` | `"sonic-3"` | ID of the Cartesia STT or TTS model to use. Defaults to the recently released Sonic-3 |
| `model_id` | `str` | `"sonic-3.5"` | ID of the Cartesia TTS model to use. |
| `voice_id` | `str` or `None` | `"f9836c6e-a0bd-460e-9d3c-f7299fa60f94"` | ID of the voice to use for TTS responses. |
| `sample_rate` | `int` | `16000` | Sample rate (in Hz) used for audio processing. |

## Functionality

### Send audio to transcribe speech

`STT` streams PCM audio to Cartesia Ink and emits transcript and turn events that Vision Agents can use for interruption and eager turn handling.

```python theme={null}
agent = Agent(
...,
stt=cartesia.STT(),
tts=cartesia.TTS(),
)
```

### Send text to convert to speech

The `send_iter()` method sends the text passed in for the service to synthesize
Expand Down
20 changes: 11 additions & 9 deletions plugins/cartesia/example/README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
# Stream + Cartesia TTS Bot Example
# Stream + Cartesia Voice Bot Example

This example demonstrates how to build a text-to-speech bot that joins a Stream video call and greets participants
using [Cartesia's](https://cartesia.ai/?utm_medium=partner&utm_source=getstream) Sonic voices.
This example demonstrates how to build a voice bot that joins a Stream video call, transcribes participants with Cartesia STT, and speaks responses with Cartesia TTS.

## What it does

- 🤖 Creates a TTS bot that joins a Stream video call
- 🌐 Opens a browser interface for users to join the call
- 🔊 Greets users when they join using Cartesia TTS
- 🎙️ Sends audio directly to the call in real-time
- Creates a voice bot that joins a Stream video call
- Uses Cartesia Ink for realtime STT and turn detection
- Uses Cartesia Sonic for TTS responses
- Uses OpenAI for the LLM response

## Prerequisites

1. **Stream Account**: Get your API credentials from [Stream Dashboard](https://getstream.io/try-for-free/?utm_source=github.com&utm_medium=referral&utm_campaign=vision_agents)
2. **Cartesia Account**: Get your API key from [Cartesia](https://cartesia.ai/?utm_medium=partner&utm_source=getstream)
3. **Python 3.10+**: Required for running the example
3. **OpenAI Account**: Set an `OPENAI_API_KEY` for the example LLM.
4. **Python 3.10+**: Required for running the example

## Installation

Expand All @@ -31,7 +31,7 @@ You can use your preferred package manager, but we recommend [`uv`](https://docs
```

3. **Set up environment variables:**
Rename `env.example` to `.env` and fill in your actual credentials.
Create a `.env` file with `STREAM_API_KEY`, `STREAM_API_SECRET`, `CARTESIA_API_KEY`, and `OPENAI_API_KEY`.

## Usage

Expand All @@ -40,3 +40,5 @@ Run the example:
```bash
uv run main.py run
```

Join the generated call, speak into your microphone, and the bot should answer out loud.
32 changes: 21 additions & 11 deletions plugins/cartesia/example/main.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
#!/usr/bin/env python3
"""
Example: Text-to-Speech with Cartesia using Agent class
Example: Speech-to-Text and Text-to-Speech with Cartesia using Agent class

This minimal example shows how to:
1. Create an Agent with TTS capabilities
1. Create an Agent with Cartesia STT and TTS
2. Join a Stream video call
3. Greet users when they join
3. Greet users and respond to spoken input

Run it, join the call in your browser, and hear the bot greet you 🗣️
Run it, join the call in your browser, and speak to the bot.

Usage::
python main.py
uv run main.py run

The script looks for the following env vars (see `env.example`):
STREAM_API_KEY / STREAM_API_SECRET
CARTESIA_API_KEY
OPENAI_API_KEY
"""

import asyncio
import logging

from dotenv import load_dotenv
Expand All @@ -31,11 +33,15 @@


async def create_agent(**kwargs) -> Agent:
# Create agent with TTS
"""Create an agent with Cartesia STT and TTS."""
agent = Agent(
edge=getstream.Edge(),
agent_user=User(name="TTS Bot", id="agent"),
instructions="I'm a TTS bot that greets users when they join.",
agent_user=User(name="Cartesia Voice Bot", id="agent"),
instructions=(
"You're a helpful voice AI assistant. "
"Keep replies short and conversational."
),
stt=cartesia.STT(),
llm=openai.LLM(model="gpt-4o-mini"),
tts=cartesia.TTS(),
)
Expand All @@ -44,12 +50,16 @@ async def create_agent(**kwargs) -> Agent:


async def join_call(agent: Agent, call_type: str, call_id: str, **kwargs) -> None:
# Create a call
call = await agent.create_call(call_type, call_id)

# Join call and wait
logger.info("Starting Cartesia STT/TTS voice bot")

async with agent.join(call):
await agent.simple_response("tell me something interesting in a short sentence")
logger.info("Joined call")
await asyncio.sleep(3)
await agent.simple_response(
"Hello! I'm listening. What would you like to talk about?"
)
await agent.finish()


Expand Down
4 changes: 2 additions & 2 deletions plugins/cartesia/example/narrator-example.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from vision_agents.core import Runner
from vision_agents.core.agents import Agent, AgentLauncher
from vision_agents.core.edge.types import User
from vision_agents.plugins import cartesia, deepgram, getstream, openai
from vision_agents.plugins import cartesia, getstream, openai

logger = logging.getLogger(__name__)

Expand All @@ -37,7 +37,7 @@ async def create_agent(**kwargs) -> Agent:
edge=getstream.Edge(),
agent_user=User(name="Narrator", id="agent"),
instructions="You're the narrator of a story. When you're given a topic start narrating a story and make heavy use of the audio markup tags to customize the speech output that are described in @sonic3-info.md.",
stt=deepgram.STT(),
stt=cartesia.STT(),
llm=openai.LLM(model="gpt-4o-mini"),
tts=cartesia.TTS(),
)
Expand Down
10 changes: 4 additions & 6 deletions plugins/cartesia/example/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@ dependencies = [
"vision-agents-plugins-cartesia",
"vision-agents-plugins-getstream",
"vision-agents-plugins-openai",
"vision-agents-plugins-deepgram",
]

[tool.uv.sources]
vision-agents = { editable = true }
vision-agents-plugins-cartesia = { editable = true }
vision-agents-plugins-getstream = { editable = true }
vision-agents-plugins-openai = { editable = true }
vision-agents-plugins-deepgram = { editable = true }
"vision-agents" = { path = "../../../agents-core", editable = true }
"vision-agents-plugins-cartesia" = { path = "..", editable = true }
"vision-agents-plugins-getstream" = { path = "../../getstream", editable = true }
"vision-agents-plugins-openai" = { path = "../../openai", editable = true }
5 changes: 3 additions & 2 deletions plugins/cartesia/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ build-backend = "hatchling.build"
[project]
name = "vision-agents-plugins-cartesia"
dynamic = ["version"]
description = "Cartesia TTS integration for Vision Agents"
description = "Cartesia STT and TTS integration for Vision Agents"
readme = "README.md"
keywords = ["cartesia", "TTS", "text-to-speech", "AI", "voice agents", "agents"]
keywords = ["cartesia", "STT", "TTS", "speech-to-text", "text-to-speech", "AI", "voice agents", "agents"]
requires-python = ">=3.10"
license = "MIT"
dependencies = [
"vision-agents",
"cartesia>=3.0.2,<3.1",
"websockets>=15.0.1,<16",
]

[project.urls]
Expand Down
Loading
Loading