fixup
|
Before Width: | Height: | Size: 733 KiB After Width: | Height: | Size: 733 KiB |
@@ -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
|
||||
|
Before Width: | Height: | Size: 759 KiB After Width: | Height: | Size: 759 KiB |
|
Before Width: | Height: | Size: 884 KiB After Width: | Height: | Size: 884 KiB |
|
Before Width: | Height: | Size: 876 KiB After Width: | Height: | Size: 876 KiB |
|
Before Width: | Height: | Size: 881 KiB After Width: | Height: | Size: 881 KiB |
|
Before Width: | Height: | Size: 866 KiB After Width: | Height: | Size: 866 KiB |
|
Before Width: | Height: | Size: 874 KiB After Width: | Height: | Size: 874 KiB |
|
Before Width: | Height: | Size: 882 KiB After Width: | Height: | Size: 882 KiB |
|
Before Width: | Height: | Size: 885 KiB After Width: | Height: | Size: 885 KiB |
|
Before Width: | Height: | Size: 888 KiB After Width: | Height: | Size: 888 KiB |
|
Before Width: | Height: | Size: 890 KiB After Width: | Height: | Size: 890 KiB |
|
Before Width: | Height: | Size: 898 KiB After Width: | Height: | Size: 898 KiB |
|
Before Width: | Height: | Size: 836 KiB After Width: | Height: | Size: 836 KiB |
|
Before Width: | Height: | Size: 903 KiB After Width: | Height: | Size: 903 KiB |
|
Before Width: | Height: | Size: 908 KiB After Width: | Height: | Size: 908 KiB |
|
Before Width: | Height: | Size: 908 KiB After Width: | Height: | Size: 908 KiB |
|
Before Width: | Height: | Size: 905 KiB After Width: | Height: | Size: 905 KiB |
|
Before Width: | Height: | Size: 903 KiB After Width: | Height: | Size: 903 KiB |
|
Before Width: | Height: | Size: 866 KiB After Width: | Height: | Size: 866 KiB |
|
Before Width: | Height: | Size: 849 KiB After Width: | Height: | Size: 849 KiB |
|
Before Width: | Height: | Size: 866 KiB After Width: | Height: | Size: 866 KiB |
|
Before Width: | Height: | Size: 866 KiB After Width: | Height: | Size: 866 KiB |
|
Before Width: | Height: | Size: 864 KiB After Width: | Height: | Size: 864 KiB |
|
Before Width: | Height: | Size: 858 KiB After Width: | Height: | Size: 858 KiB |
|
Before Width: | Height: | Size: 875 KiB After Width: | Height: | Size: 875 KiB |
|
Before Width: | Height: | Size: 881 KiB After Width: | Height: | Size: 881 KiB |
@@ -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
|
||||
@@ -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..."
|
||||
7
examples/pcc-transport-chatbot/server/pcc-deploy.toml
Normal 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
|
||||
5
examples/pcc-transport-chatbot/server/requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
python-dotenv
|
||||
fastapi[all]
|
||||
uvicorn
|
||||
-e ./pipecat[daily,cartesia,openai,silero,gladia,webrtc]
|
||||
pipecatcloud
|
||||
@@ -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
|
||||
@@ -1,5 +0,0 @@
|
||||
python-dotenv
|
||||
fastapi[all]
|
||||
uvicorn
|
||||
pipecat-ai[daily,cartesia,openai,silero]
|
||||
pipecatcloud
|
||||
@@ -1,11 +1,16 @@
|
||||
#
|
||||
# Copyright (c) 2024–2025, 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,
|
||||
|
||||