This commit is contained in:
Chad Bailey
2025-04-03 17:18:26 +00:00
parent 8f33f00c3f
commit 974e989cb5
58 changed files with 85 additions and 40 deletions

View File

Before

Width:  |  Height:  |  Size: 733 KiB

After

Width:  |  Height:  |  Size: 733 KiB

View File

@@ -1,4 +1,7 @@
FROM dailyco/pipecat-base:latest
RUN apt-get update && apt-get install ffmpeg -y
COPY ./pipecat pipecat
COPY ./requirements.txt requirements.txt
@@ -6,4 +9,4 @@ COPY ./assets assets
RUN pip install --no-cache-dir --upgrade -r requirements.txt
COPY ./bot.py bot.py
COPY ./bot.py bot.py

View File

Before

Width:  |  Height:  |  Size: 759 KiB

After

Width:  |  Height:  |  Size: 759 KiB

View File

Before

Width:  |  Height:  |  Size: 884 KiB

After

Width:  |  Height:  |  Size: 884 KiB

View File

Before

Width:  |  Height:  |  Size: 876 KiB

After

Width:  |  Height:  |  Size: 876 KiB

View File

Before

Width:  |  Height:  |  Size: 881 KiB

After

Width:  |  Height:  |  Size: 881 KiB

View File

Before

Width:  |  Height:  |  Size: 866 KiB

After

Width:  |  Height:  |  Size: 866 KiB

View File

Before

Width:  |  Height:  |  Size: 874 KiB

After

Width:  |  Height:  |  Size: 874 KiB

View File

Before

Width:  |  Height:  |  Size: 882 KiB

After

Width:  |  Height:  |  Size: 882 KiB

View File

Before

Width:  |  Height:  |  Size: 885 KiB

After

Width:  |  Height:  |  Size: 885 KiB

View File

Before

Width:  |  Height:  |  Size: 888 KiB

After

Width:  |  Height:  |  Size: 888 KiB

View File

Before

Width:  |  Height:  |  Size: 890 KiB

After

Width:  |  Height:  |  Size: 890 KiB

View File

Before

Width:  |  Height:  |  Size: 898 KiB

After

Width:  |  Height:  |  Size: 898 KiB

View File

Before

Width:  |  Height:  |  Size: 836 KiB

After

Width:  |  Height:  |  Size: 836 KiB

View File

Before

Width:  |  Height:  |  Size: 903 KiB

After

Width:  |  Height:  |  Size: 903 KiB

View File

Before

Width:  |  Height:  |  Size: 908 KiB

After

Width:  |  Height:  |  Size: 908 KiB

View File

Before

Width:  |  Height:  |  Size: 908 KiB

After

Width:  |  Height:  |  Size: 908 KiB

View File

Before

Width:  |  Height:  |  Size: 905 KiB

After

Width:  |  Height:  |  Size: 905 KiB

View File

Before

Width:  |  Height:  |  Size: 903 KiB

After

Width:  |  Height:  |  Size: 903 KiB

View File

Before

Width:  |  Height:  |  Size: 866 KiB

After

Width:  |  Height:  |  Size: 866 KiB

View File

Before

Width:  |  Height:  |  Size: 849 KiB

After

Width:  |  Height:  |  Size: 849 KiB

View File

Before

Width:  |  Height:  |  Size: 866 KiB

After

Width:  |  Height:  |  Size: 866 KiB

View File

Before

Width:  |  Height:  |  Size: 866 KiB

After

Width:  |  Height:  |  Size: 866 KiB

View File

Before

Width:  |  Height:  |  Size: 864 KiB

After

Width:  |  Height:  |  Size: 864 KiB

View File

Before

Width:  |  Height:  |  Size: 858 KiB

After

Width:  |  Height:  |  Size: 858 KiB

View File

Before

Width:  |  Height:  |  Size: 875 KiB

After

Width:  |  Height:  |  Size: 875 KiB

View File

Before

Width:  |  Height:  |  Size: 881 KiB

After

Width:  |  Height:  |  Size: 881 KiB

View File

@@ -18,13 +18,15 @@ the conversation flow.
"""
import os
import sys
import aiohttp
from dotenv import load_dotenv
from loguru import logger
from PIL import Image
from pipecatcloud.agent import DailySessionArguments
from pipecatcloud.agent import SessionArguments as PCCSessionArguments
from pipecatcloud.agent import (
DailySessionArguments,
)
from pipecat.adapters.schemas.function_schema import FunctionSchema
from pipecat.adapters.schemas.tools_schema import ToolsSchema
@@ -43,17 +45,20 @@ from pipecat.pipeline.task import PipelineParams, PipelineTask
from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext
from pipecat.processors.frame_processor import FrameDirection, FrameProcessor
from pipecat.processors.frameworks.rtvi import RTVIConfig, RTVIObserver, RTVIProcessor
from pipecat.services.cartesia import CartesiaTTSService
from pipecat.services.gladia import GladiaSTTService
from pipecat.services.openai import OpenAILLMService
from pipecat.transports.services.daily import DailyParams, DailyTransport
from pipecat.services.cartesia.tts import CartesiaTTSService
from pipecat.services.gladia.stt import GladiaSTTService
from pipecat.services.openai.llm import OpenAILLMService
from pipecat.transports.services.daily import DailyTransport
from pipecat.transports.services.pipecat_cloud import (
PipecatCloudParams,
PipecatCloudSessionArguments,
PipecatCloudTransport,
SessionArguments,
)
load_dotenv(override=True)
logger.add(sys.stderr, level="DEBUG")
print(f"DailyTransport: {DailyTransport}")
# Check if we're in local development mode
LOCAL_RUN = os.getenv("LOCAL_RUN")
@@ -67,7 +72,7 @@ if LOCAL_RUN:
logger.error("Could not import local_runner module. Local development mode may not work.")
# Logger for local dev
# logger.add(sys.stderr, level="DEBUG")
logger.add(sys.stderr, level="DEBUG")
sprites = []
script_dir = os.path.dirname(__file__)
@@ -133,7 +138,7 @@ async def fetch_weather_from_api(function_name, tool_call_id, args, llm, context
await result_callback({"conditions": "nice", "temperature": "75"})
async def main(session_args: SessionArguments):
async def main(session_args: PipecatCloudSessionArguments):
"""Main bot execution function.
Sets up and runs the bot pipeline including:
@@ -276,10 +281,16 @@ async def bot(args: DailySessionArguments):
body: The configuration object from the request body
session_id: The session ID for logging
"""
logger.info(f"Bot process initialized {args.room_url} {args.token}")
pcc_args = PipecatCloudSessionArguments(
room_url=args.room.url,
token=args.token,
body=args.body,
session_id=args.session_id,
)
logger.info(f"Bot process initialized {pcc_args.room_url} {pcc_args.token}")
try:
await main(args)
await main(pcc_args)
logger.info("Bot process completed")
except Exception as e:
logger.exception(f"Error in bot process: {str(e)}")
@@ -293,19 +304,22 @@ async def local_daily():
try:
async with aiohttp.ClientSession() as session:
(room_url, token) = await configure(session)
args = PipecatCloudSessionArguments(
room_url=room_url, token=token, body={}, session_id=None
)
logger.warning("_")
logger.warning("_")
logger.warning(f"Talk to your voice agent here: {room_url}")
logger.warning("_")
logger.warning("_")
webbrowser.open(room_url)
await main(room_url, token, config={})
await main(args)
except Exception as e:
logger.exception(f"Error in local development mode: {e}")
async def local_webrtc(webrtc_connection):
await main(SessionArguments(webrtc_connection=webrtc_connection))
await main(PipecatCloudSessionArguments(webrtc_connection=webrtc_connection))
# Local development entry point

View File

@@ -1,9 +1,9 @@
#!/bin/bash
set -e
VERSION="0.1"
DOCKER_USERNAME="your-docker-hub-username"
AGENT_NAME="simple-chatbot"
VERSION="0.2"
DOCKER_USERNAME="chadbailey59"
AGENT_NAME="pcc-transport-chatbot"
# Build the Docker image with the correct context
echo "Building Docker image..."

View File

@@ -0,0 +1,7 @@
agent_name = "pcc-transport-chatbot"
image = "chadbailey59/pcc-transport-chatbot:0.2"
secret_set = "pcc-transport-chatbot-secrets"
[scaling]
min_instances = 0
max_instances = 2

View File

@@ -0,0 +1,5 @@
python-dotenv
fastapi[all]
uvicorn
-e ./pipecat[daily,cartesia,openai,silero,gladia,webrtc]
pipecatcloud

View File

@@ -1,6 +0,0 @@
agent_name = "simple-chatbot"
image = "your-docker-hub-username/simple-chatbot:0.1"
secret_set = "simple-chatbot-secrets"
[scaling]
min_instances = 0

View File

@@ -1,5 +0,0 @@
python-dotenv
fastapi[all]
uvicorn
pipecat-ai[daily,cartesia,openai,silero]
pipecatcloud

View File

@@ -1,11 +1,16 @@
#
# Copyright (c) 20242025, Daily
#
# SPDX-License-Identifier: BSD 2-Clause License
#
import logging
from dataclasses import dataclass
from functools import wraps
from typing import Any, Callable, Optional, Union
from fastapi import WebSocket
from pipecatcloud.agent import DailySessionArguments, WebSocketSessionArguments
from pipecatcloud.agent import SessionArguments as PCCSessionArguments
from pipecatcloud.agent import DailySessionArguments, SessionArguments, WebSocketSessionArguments
from pydantic import BaseModel, ConfigDict
from pipecat.transports.base_transport import BaseTransport, TransportParams
@@ -29,7 +34,7 @@ logger = logging.getLogger(__name__)
@dataclass
class WebRTCSessionArguments(PCCSessionArguments):
class WebRTCSessionArguments(SessionArguments):
"""WebRTC based agent session arguments. The arguments are received by the
bot() entry point.
"""
@@ -64,8 +69,14 @@ class PipecatCloudParams(TransportParams):
def to_websocket_params(self) -> FastAPIWebsocketParams:
"""Convert to FastAPIWebsocketParams."""
base_params = self.model_dump()
# Remove WebSocket-specific fields since we'll add them explicitly
websocket_fields = ["add_wav_header", "serializer", "session_timeout"]
for field in websocket_fields:
base_params.pop(field, None)
return FastAPIWebsocketParams(
**self.model_dump(),
**base_params,
add_wav_header=self.add_wav_header,
serializer=self.serializer,
session_timeout=self.session_timeout,
@@ -73,8 +84,20 @@ class PipecatCloudParams(TransportParams):
def to_daily_params(self) -> DailyParams:
"""Convert to DailyParams."""
base_params = self.model_dump()
# Remove Daily-specific fields since we'll add them explicitly
daily_fields = [
"api_url",
"api_key",
"dialin_settings",
"transcription_enabled",
"transcription_settings",
]
for field in daily_fields:
base_params.pop(field, None)
return DailyParams(
**self.model_dump(),
**base_params,
api_url=self.api_url,
api_key=self.api_key,
dialin_settings=self.dialin_settings,
@@ -83,7 +106,7 @@ class PipecatCloudParams(TransportParams):
)
class SessionArguments:
class PipecatCloudSessionArguments:
"""Arguments for creating a PipecatCloudTransport session.
This class can be initialized with arguments for any of the supported transport types:
@@ -98,16 +121,20 @@ class SessionArguments:
websocket: Optional[WebSocket] = None,
room_url: Optional[str] = None,
token: Optional[str] = None,
bot_name: Optional[str] = None,
webrtc_connection: Optional[SmallWebRTCConnection] = None,
session_id: Optional[str] = None,
body: Optional[dict] = None,
):
"""Initialize session arguments for any supported transport type."""
if websocket is not None:
self._args = WebSocketSessionArguments(websocket=websocket, session_id=session_id)
elif any(x is not None for x in (room_url, token, bot_name)):
elif room_url is not None:
self._args = DailySessionArguments(
room_url=room_url, token=token, bot_name=bot_name, session_id=session_id
# TODO-CB: bot_name is missing from DailySessionArguments?
room_url=room_url,
token=token,
session_id=session_id,
body=body,
)
elif webrtc_connection is not None:
self._args = WebRTCSessionArguments(
@@ -163,14 +190,13 @@ class PipecatCloudTransport(BaseTransport):
def __init__(
self,
session_args: SessionArguments,
session_args: PipecatCloudSessionArguments,
params: Optional[Union[PipecatCloudParams, TransportParams]] = None,
*,
input_name: Optional[str] = None,
output_name: Optional[str] = None,
):
super().__init__(input_name=input_name, output_name=output_name)
logger.debug(f"SessionArguments: {session_args}")
# Convert TransportParams to PipecatCloudParams if needed
if isinstance(params, TransportParams):
@@ -200,7 +226,8 @@ class PipecatCloudTransport(BaseTransport):
self._transport = DailyTransport(
args.room_url,
args.token,
args.bot_name,
# TODO-CB: Bot name is missing from DailySessionArguments
"Bot",
params=daily_params,
input_name=input_name,
output_name=output_name,