Update with latest starter
This commit is contained in:
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
A template voice agent for [Pipecat Cloud](https://www.daily.co/products/pipecat-cloud/) that demonstrates building and deploying a conversational AI agent.
|
A template voice agent for [Pipecat Cloud](https://www.daily.co/products/pipecat-cloud/) that demonstrates building and deploying a conversational AI agent.
|
||||||
|
|
||||||
|
> **For a detailed step-by-step guide, see our [Quickstart Documentation](https://docs.pipecat.daily.co/quickstart).**
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- Python 3.10+
|
- Python 3.10+
|
||||||
@@ -14,25 +16,9 @@ A template voice agent for [Pipecat Cloud](https://www.daily.co/products/pipecat
|
|||||||
|
|
||||||
> **Note**: If you haven't installed Docker yet, follow the official installation guides for your platform ([Linux](https://docs.docker.com/engine/install/), [Mac](https://docs.docker.com/desktop/setup/install/mac-install/), [Windows](https://docs.docker.com/desktop/setup/install/windows-install/)). For Docker Hub, [create a free account](https://hub.docker.com/signup) and log in via terminal with `docker login`.
|
> **Note**: If you haven't installed Docker yet, follow the official installation guides for your platform ([Linux](https://docs.docker.com/engine/install/), [Mac](https://docs.docker.com/desktop/setup/install/mac-install/), [Windows](https://docs.docker.com/desktop/setup/install/windows-install/)). For Docker Hub, [create a free account](https://hub.docker.com/signup) and log in via terminal with `docker login`.
|
||||||
|
|
||||||
## Getting Started
|
## Get Started
|
||||||
|
|
||||||
### 1. Set up Python environment
|
### 1. Get the starter project
|
||||||
|
|
||||||
We recommend using a virtual environment to manage your Python dependencies.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Create a virtual environment
|
|
||||||
python -m venv venv
|
|
||||||
|
|
||||||
# Activate it
|
|
||||||
source venv/bin/activate # On Windows: venv\Scripts\activate
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
pip install -r requirements.txt
|
|
||||||
pip install pipecatcloud
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Get the starter project
|
|
||||||
|
|
||||||
Clone the starter project from GitHub:
|
Clone the starter project from GitHub:
|
||||||
|
|
||||||
@@ -41,11 +27,19 @@ git clone https://github.com/daily-co/pipecat-cloud-starter
|
|||||||
cd pipecat-cloud-starter
|
cd pipecat-cloud-starter
|
||||||
```
|
```
|
||||||
|
|
||||||
or use the Pipecat Cloud CLI to initialize a new project:
|
### 2. Set up your Python environment
|
||||||
|
|
||||||
|
We recommend using a virtual environment to manage your Python dependencies.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir pipecat-cloud-starter && cd pipecat-cloud-starter
|
# Create a virtual environment
|
||||||
pcc init
|
python -m venv .venv
|
||||||
|
|
||||||
|
# Activate it
|
||||||
|
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
||||||
|
|
||||||
|
# Install the Pipecat Cloud CLI
|
||||||
|
pip install pipecatcloud
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Authenticate with Pipecat Cloud
|
### 3. Authenticate with Pipecat Cloud
|
||||||
@@ -66,13 +60,24 @@ This starter requires the following API keys:
|
|||||||
|
|
||||||
You can test your agent locally before deploying to Pipecat Cloud:
|
You can test your agent locally before deploying to Pipecat Cloud:
|
||||||
|
|
||||||
- `DAILY_API_KEY` value can be found at [https://pipecat.daily.co](https://pipecat.daily.co) Under the `Settings` menu of your agent, in the `Daily` tab.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Set environment variables with your API keys
|
# Set environment variables with your API keys
|
||||||
export CARTESIA_API_KEY="your_cartesia_key"
|
export CARTESIA_API_KEY="your_cartesia_key"
|
||||||
export DAILY_API_KEY="your_daily_key"
|
export DAILY_API_KEY="your_daily_key"
|
||||||
export OPENAI_API_KEY="your_openai_key"
|
export OPENAI_API_KEY="your_openai_key"
|
||||||
|
```
|
||||||
|
|
||||||
|
> Your `DAILY_API_KEY` can be found at [https://pipecat.daily.co](https://pipecat.daily.co) under the `Settings` in the `Daily (WebRTC)` tab.
|
||||||
|
|
||||||
|
First install requirements:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, launch the bot.py script locally:
|
||||||
|
|
||||||
|
```bash
|
||||||
LOCAL_RUN=1 python bot.py
|
LOCAL_RUN=1 python bot.py
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -118,7 +123,7 @@ pcc secrets set my-first-agent-secrets \
|
|||||||
### 3. Deploy to Pipecat Cloud
|
### 3. Deploy to Pipecat Cloud
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pcc deploy my-first-agent your-username/my-first-agent:0.1
|
pcc deploy my-first-agent your-username/my-first-agent:0.1 --secrets my-first-agent-secrets
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note (Optional)**: For a more maintainable approach, you can use the included `pcc-deploy.toml` file:
|
> **Note (Optional)**: For a more maintainable approach, you can use the included `pcc-deploy.toml` file:
|
||||||
@@ -137,7 +142,7 @@ pcc deploy my-first-agent your-username/my-first-agent:0.1
|
|||||||
> **Note**: If your repository is private, you'll need to add credentials:
|
> **Note**: If your repository is private, you'll need to add credentials:
|
||||||
>
|
>
|
||||||
> ```bash
|
> ```bash
|
||||||
> # Create pull secret (you'll be prompted for credentials)
|
> # Create pull secret (you’ll be prompted for credentials)
|
||||||
> pcc secrets image-pull-secret pull-secret https://index.docker.io/v1/
|
> pcc secrets image-pull-secret pull-secret https://index.docker.io/v1/
|
||||||
>
|
>
|
||||||
> # Deploy with credentials
|
> # Deploy with credentials
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import os
|
|||||||
import aiohttp
|
import aiohttp
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
from pipecatcloud.agent import DailySessionArguments
|
||||||
|
|
||||||
from pipecat.audio.vad.silero import SileroVADAnalyzer
|
from pipecat.audio.vad.silero import SileroVADAnalyzer
|
||||||
from pipecat.frames.frames import LLMMessagesFrame
|
from pipecat.frames.frames import LLMMessagesFrame
|
||||||
@@ -35,110 +36,103 @@ if LOCAL_RUN:
|
|||||||
load_dotenv(override=True)
|
load_dotenv(override=True)
|
||||||
|
|
||||||
|
|
||||||
async def main(room_url: str, token: str, session_logger=None):
|
async def main(room_url: str, token: str):
|
||||||
"""Main pipeline setup and execution function.
|
"""Main pipeline setup and execution function.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
room_url: The Daily room URL
|
room_url: The Daily room URL
|
||||||
token: The Daily room token
|
token: The Daily room token
|
||||||
session_logger: Optional logger instance
|
|
||||||
"""
|
"""
|
||||||
log = session_logger or logger
|
logger.debug("Starting bot in room: {}", room_url)
|
||||||
|
|
||||||
log.debug("Starting bot in room: {}", room_url)
|
transport = DailyTransport(
|
||||||
|
room_url,
|
||||||
|
token,
|
||||||
|
"bot",
|
||||||
|
DailyParams(
|
||||||
|
audio_out_enabled=True,
|
||||||
|
transcription_enabled=True,
|
||||||
|
vad_enabled=True,
|
||||||
|
vad_analyzer=SileroVADAnalyzer(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
tts = CartesiaTTSService(
|
||||||
transport = DailyTransport(
|
api_key=os.getenv("CARTESIA_API_KEY"), voice_id="79a125e8-cd45-4c13-8a67-188112f4dd22"
|
||||||
room_url,
|
)
|
||||||
token,
|
|
||||||
"bot",
|
|
||||||
DailyParams(
|
|
||||||
audio_out_enabled=True,
|
|
||||||
transcription_enabled=True,
|
|
||||||
vad_enabled=True,
|
|
||||||
vad_analyzer=SileroVADAnalyzer(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
tts = CartesiaTTSService(
|
llm = OpenAILLMService(api_key=os.getenv("OPENAI_API_KEY"), model="gpt-4o")
|
||||||
api_key=os.getenv("CARTESIA_API_KEY"), voice_id="79a125e8-cd45-4c13-8a67-188112f4dd22"
|
|
||||||
)
|
|
||||||
|
|
||||||
llm = OpenAILLMService(api_key=os.getenv("OPENAI_API_KEY"), model="gpt-4o")
|
messages = [
|
||||||
|
{
|
||||||
|
"role": "system",
|
||||||
|
"content": "You are a helpful LLM in a WebRTC call. Your goal is to demonstrate your capabilities in a succinct way. Your output will be converted to audio so don't include special characters in your answers. Respond to what the user said in a creative and helpful way.",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
messages = [
|
context = OpenAILLMContext(messages)
|
||||||
|
context_aggregator = llm.create_context_aggregator(context)
|
||||||
|
|
||||||
|
pipeline = Pipeline(
|
||||||
|
[
|
||||||
|
transport.input(),
|
||||||
|
context_aggregator.user(),
|
||||||
|
llm,
|
||||||
|
tts,
|
||||||
|
transport.output(),
|
||||||
|
context_aggregator.assistant(),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
task = PipelineTask(
|
||||||
|
pipeline,
|
||||||
|
params=PipelineParams(
|
||||||
|
allow_interruptions=True,
|
||||||
|
enable_metrics=True,
|
||||||
|
enable_usage_metrics=True,
|
||||||
|
report_only_initial_ttfb=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
@transport.event_handler("on_first_participant_joined")
|
||||||
|
async def on_first_participant_joined(transport, participant):
|
||||||
|
logger.info("First participant joined: {}", participant["id"])
|
||||||
|
await transport.capture_participant_transcription(participant["id"])
|
||||||
|
# Kick off the conversation.
|
||||||
|
messages.append(
|
||||||
{
|
{
|
||||||
"role": "system",
|
"role": "system",
|
||||||
"content": "You are a helpful LLM in a WebRTC call. Your goal is to demonstrate your capabilities in a succinct way. Your output will be converted to audio so don't include special characters in your answers. Respond to what the user said in a creative and helpful way.",
|
"content": "Please start with 'Hello World' and introduce yourself to the user.",
|
||||||
},
|
}
|
||||||
]
|
|
||||||
|
|
||||||
context = OpenAILLMContext(messages)
|
|
||||||
context_aggregator = llm.create_context_aggregator(context)
|
|
||||||
|
|
||||||
pipeline = Pipeline(
|
|
||||||
[
|
|
||||||
transport.input(),
|
|
||||||
context_aggregator.user(),
|
|
||||||
llm,
|
|
||||||
tts,
|
|
||||||
transport.output(),
|
|
||||||
context_aggregator.assistant(),
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
|
await task.queue_frames([LLMMessagesFrame(messages)])
|
||||||
|
|
||||||
task = PipelineTask(
|
@transport.event_handler("on_participant_left")
|
||||||
pipeline,
|
async def on_participant_left(transport, participant, reason):
|
||||||
params=PipelineParams(
|
logger.info("Participant left: {}", participant)
|
||||||
allow_interruptions=True,
|
await task.cancel()
|
||||||
enable_metrics=True,
|
|
||||||
enable_usage_metrics=True,
|
|
||||||
report_only_initial_ttfb=True,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
@transport.event_handler("on_first_participant_joined")
|
runner = PipelineRunner()
|
||||||
async def on_first_participant_joined(transport, participant):
|
|
||||||
log.info("First participant joined: {}", participant["id"])
|
|
||||||
await transport.capture_participant_transcription(participant["id"])
|
|
||||||
# Kick off the conversation.
|
|
||||||
messages.append(
|
|
||||||
{
|
|
||||||
"role": "system",
|
|
||||||
"content": "Please start with 'Hello World' and introduce yourself to the user.",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
await task.queue_frames([LLMMessagesFrame(messages)])
|
|
||||||
|
|
||||||
@transport.event_handler("on_participant_left")
|
await runner.run(task)
|
||||||
async def on_participant_left(transport, participant, reason):
|
|
||||||
log.info("Participant left: {}", participant)
|
|
||||||
await task.cancel()
|
|
||||||
|
|
||||||
runner = PipelineRunner()
|
|
||||||
|
|
||||||
await runner.run(task)
|
|
||||||
|
|
||||||
|
|
||||||
async def bot(config, room_url: str, token: str, session_id=None, session_logger=None):
|
async def bot(args: DailySessionArguments):
|
||||||
"""Main bot entry point compatible with the FastAPI route handler.
|
"""Main bot entry point compatible with the FastAPI route handler.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
config: The configuration object from the request body
|
|
||||||
room_url: The Daily room URL
|
room_url: The Daily room URL
|
||||||
token: The Daily room token
|
token: The Daily room token
|
||||||
|
body: The configuration object from the request body
|
||||||
session_id: The session ID for logging
|
session_id: The session ID for logging
|
||||||
session_logger: The session-specific logger
|
|
||||||
"""
|
"""
|
||||||
log = session_logger or logger
|
logger.info(f"Bot process initialized {args.room_url} {args.token}")
|
||||||
log.info(f"Bot process initialized {room_url} {token}")
|
|
||||||
log.info(f"Bot config {config}")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await main(room_url, token, session_logger)
|
await main(args.room_url, args.token)
|
||||||
log.info("Bot process completed")
|
logger.info("Bot process completed")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.exception(f"Error in bot process: {str(e)}")
|
logger.exception(f"Error in bot process: {str(e)}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
|
pipecatcloud
|
||||||
pipecat-ai[cartesia,daily,openai,silero]>=0.0.58
|
pipecat-ai[cartesia,daily,openai,silero]>=0.0.58
|
||||||
python-dotenv~=1.0.1
|
python-dotenv~=1.0.1
|
||||||
Reference in New Issue
Block a user