Spaces:
Sleeping
Sleeping
Commit ·
24352e2
1
Parent(s): 8362005
updated docker
Browse files- Dockerfile +2 -0
- bot/bot_websocket_server.py +55 -9
- server.py +45 -18
- setup.sh +7 -0
Dockerfile
CHANGED
|
@@ -11,8 +11,10 @@ RUN pip install --no-cache-dir -r requirements.txt
|
|
| 11 |
# Copy the backend code
|
| 12 |
COPY . .
|
| 13 |
|
|
|
|
| 14 |
# Expose the port the app runs on
|
| 15 |
EXPOSE 7860
|
| 16 |
|
|
|
|
| 17 |
# Run the application
|
| 18 |
CMD ["uvicorn", "server:app", "--host", "0.0.0.0", "--port", "7860"]
|
|
|
|
| 11 |
# Copy the backend code
|
| 12 |
COPY . .
|
| 13 |
|
| 14 |
+
RUN chmod +x ./setup.sh && ./setup.sh
|
| 15 |
# Expose the port the app runs on
|
| 16 |
EXPOSE 7860
|
| 17 |
|
| 18 |
+
|
| 19 |
# Run the application
|
| 20 |
CMD ["uvicorn", "server:app", "--host", "0.0.0.0", "--port", "7860"]
|
bot/bot_websocket_server.py
CHANGED
|
@@ -7,16 +7,21 @@ from pipecat.pipeline.pipeline import Pipeline
|
|
| 7 |
from pipecat.pipeline.runner import PipelineRunner
|
| 8 |
from pipecat.pipeline.task import PipelineParams, PipelineTask
|
| 9 |
from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext
|
|
|
|
| 10 |
|
| 11 |
from pipecat.services.ollama.llm import OLLamaLLMService
|
| 12 |
|
| 13 |
# from pipecat.services.fish.tts import FishAudioTTSService
|
| 14 |
-
from pipecat.services.xtts.tts import XTTSService
|
| 15 |
from pipecat.transcriptions.language import Language
|
| 16 |
-
|
| 17 |
|
| 18 |
from pipecat.processors.frameworks.rtvi import RTVIConfig, RTVIObserver, RTVIProcessor
|
| 19 |
from pipecat.serializers.protobuf import ProtobufFrameSerializer
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
from pipecat.services.whisper.stt import WhisperSTTService
|
| 21 |
from pipecat.transports.network.websocket_server import (
|
| 22 |
WebsocketServerParams,
|
|
@@ -24,10 +29,14 @@ from pipecat.transports.network.websocket_server import (
|
|
| 24 |
)
|
| 25 |
import aiohttp
|
| 26 |
|
|
|
|
| 27 |
from service.Kokoro.tts import KokoroTTSService
|
| 28 |
-
from service.orpheus.tts import OrpheusTTSService
|
|
|
|
| 29 |
# from service.chatterbot.tts import ChatterboxTTSService
|
| 30 |
|
|
|
|
|
|
|
| 31 |
SYSTEM_INSTRUCTION = f"""
|
| 32 |
"You are Gemini Chatbot, a friendly, helpful robot.
|
| 33 |
|
|
@@ -38,17 +47,45 @@ Your output will be converted to audio so don't include special characters in yo
|
|
| 38 |
Respond to what the user said in a creative and helpful way. Keep your responses brief. One or two sentences at most.
|
| 39 |
"""
|
| 40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
params=
|
| 45 |
-
serializer=ProtobufFrameSerializer(),
|
| 46 |
audio_in_enabled=True,
|
| 47 |
audio_out_enabled=True,
|
| 48 |
add_wav_header=False,
|
| 49 |
vad_analyzer=SileroVADAnalyzer(),
|
| 50 |
-
|
| 51 |
-
)
|
| 52 |
)
|
| 53 |
|
| 54 |
stt = WhisperSTTService(
|
|
@@ -110,6 +147,11 @@ async def run_bot_websocket_server():
|
|
| 110 |
# model_name="",
|
| 111 |
# sample_rate=16000,
|
| 112 |
# )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 113 |
pipeline = Pipeline(
|
| 114 |
[
|
| 115 |
ws_transport.input(),
|
|
@@ -127,8 +169,12 @@ async def run_bot_websocket_server():
|
|
| 127 |
pipeline,
|
| 128 |
params=PipelineParams(
|
| 129 |
enable_metrics=True,
|
|
|
|
| 130 |
enable_usage_metrics=True,
|
| 131 |
),
|
|
|
|
|
|
|
|
|
|
| 132 |
observers=[RTVIObserver(rtvi)],
|
| 133 |
)
|
| 134 |
|
|
|
|
| 7 |
from pipecat.pipeline.runner import PipelineRunner
|
| 8 |
from pipecat.pipeline.task import PipelineParams, PipelineTask
|
| 9 |
from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext
|
| 10 |
+
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
|
| 11 |
|
| 12 |
from pipecat.services.ollama.llm import OLLamaLLMService
|
| 13 |
|
| 14 |
# from pipecat.services.fish.tts import FishAudioTTSService
|
| 15 |
+
# from pipecat.services.xtts.tts import XTTSService
|
| 16 |
from pipecat.transcriptions.language import Language
|
| 17 |
+
# from service.Dia.tts import DiaTTSService
|
| 18 |
|
| 19 |
from pipecat.processors.frameworks.rtvi import RTVIConfig, RTVIObserver, RTVIProcessor
|
| 20 |
from pipecat.serializers.protobuf import ProtobufFrameSerializer
|
| 21 |
+
from pipecat.transports.network.fastapi_websocket import (
|
| 22 |
+
FastAPIWebsocketParams,
|
| 23 |
+
FastAPIWebsocketTransport,
|
| 24 |
+
)
|
| 25 |
from pipecat.services.whisper.stt import WhisperSTTService
|
| 26 |
from pipecat.transports.network.websocket_server import (
|
| 27 |
WebsocketServerParams,
|
|
|
|
| 29 |
)
|
| 30 |
import aiohttp
|
| 31 |
|
| 32 |
+
from dotenv import load_dotenv
|
| 33 |
from service.Kokoro.tts import KokoroTTSService
|
| 34 |
+
# from service.orpheus.tts import OrpheusTTSService
|
| 35 |
+
|
| 36 |
# from service.chatterbot.tts import ChatterboxTTSService
|
| 37 |
|
| 38 |
+
# from pipecat.utils.tracing.setup import setup_tracing
|
| 39 |
+
|
| 40 |
SYSTEM_INSTRUCTION = f"""
|
| 41 |
"You are Gemini Chatbot, a friendly, helpful robot.
|
| 42 |
|
|
|
|
| 47 |
Respond to what the user said in a creative and helpful way. Keep your responses brief. One or two sentences at most.
|
| 48 |
"""
|
| 49 |
|
| 50 |
+
load_dotenv(override=True)
|
| 51 |
+
|
| 52 |
+
# IS_TRACING_ENABLED = bool(os.getenv("ENABLE_TRACING"))
|
| 53 |
+
|
| 54 |
+
# # Initialize tracing if enabled
|
| 55 |
+
# if IS_TRACING_ENABLED:
|
| 56 |
+
# # Create the exporter
|
| 57 |
+
# otlp_exporter = OTLPSpanExporter()
|
| 58 |
+
|
| 59 |
+
# # Set up tracing with the exporter
|
| 60 |
+
# setup_tracing(
|
| 61 |
+
# service_name="pipecat-demo",
|
| 62 |
+
# exporter=otlp_exporter,
|
| 63 |
+
# console_export=bool(os.getenv("OTEL_CONSOLE_EXPORT")),
|
| 64 |
+
# )
|
| 65 |
+
# logger.info("OpenTelemetry tracing initialized")
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
async def run_bot_websocket_server(websocket_client):
|
| 69 |
+
# ws_transport = WebsocketServerTransport(
|
| 70 |
+
# params=WebsocketServerParams(
|
| 71 |
+
# serializer=ProtobufFrameSerializer(),
|
| 72 |
+
# audio_in_enabled=True,
|
| 73 |
+
# audio_out_enabled=True,
|
| 74 |
+
# add_wav_header=False,
|
| 75 |
+
# vad_analyzer=SileroVADAnalyzer(),
|
| 76 |
+
# session_timeout=60 * 3, # 3 minutes
|
| 77 |
+
# )
|
| 78 |
+
# )
|
| 79 |
|
| 80 |
+
ws_transport = FastAPIWebsocketTransport(
|
| 81 |
+
websocket=websocket_client,
|
| 82 |
+
params=FastAPIWebsocketParams(
|
|
|
|
| 83 |
audio_in_enabled=True,
|
| 84 |
audio_out_enabled=True,
|
| 85 |
add_wav_header=False,
|
| 86 |
vad_analyzer=SileroVADAnalyzer(),
|
| 87 |
+
serializer=ProtobufFrameSerializer(),
|
| 88 |
+
),
|
| 89 |
)
|
| 90 |
|
| 91 |
stt = WhisperSTTService(
|
|
|
|
| 147 |
# model_name="",
|
| 148 |
# sample_rate=16000,
|
| 149 |
# )
|
| 150 |
+
|
| 151 |
+
# TTS = DiaTTSService(
|
| 152 |
+
# model_name="nari-labs/Dia-1.6B",
|
| 153 |
+
# sample_rate=16000,
|
| 154 |
+
# )
|
| 155 |
pipeline = Pipeline(
|
| 156 |
[
|
| 157 |
ws_transport.input(),
|
|
|
|
| 169 |
pipeline,
|
| 170 |
params=PipelineParams(
|
| 171 |
enable_metrics=True,
|
| 172 |
+
allow_interruptions=True,
|
| 173 |
enable_usage_metrics=True,
|
| 174 |
),
|
| 175 |
+
# enable_turn_tracking=True,
|
| 176 |
+
# enable_tracing=IS_TRACING_ENABLED,
|
| 177 |
+
conversation_id="test",
|
| 178 |
observers=[RTVIObserver(rtvi)],
|
| 179 |
)
|
| 180 |
|
server.py
CHANGED
|
@@ -1,25 +1,37 @@
|
|
| 1 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
import asyncio
|
| 3 |
import os
|
|
|
|
| 4 |
from contextlib import asynccontextmanager
|
| 5 |
from typing import Any, Dict
|
| 6 |
|
| 7 |
import uvicorn
|
| 8 |
from dotenv import load_dotenv
|
| 9 |
-
from fastapi import FastAPI, Request, WebSocket
|
| 10 |
from fastapi.middleware.cors import CORSMiddleware
|
| 11 |
-
from fastapi.staticfiles import StaticFiles
|
| 12 |
|
| 13 |
-
from bot.
|
|
|
|
| 14 |
|
|
|
|
|
|
|
| 15 |
load_dotenv(override=True)
|
| 16 |
|
|
|
|
| 17 |
@asynccontextmanager
|
| 18 |
async def lifespan(app: FastAPI):
|
| 19 |
-
|
|
|
|
|
|
|
| 20 |
|
|
|
|
| 21 |
app = FastAPI(lifespan=lifespan)
|
| 22 |
|
|
|
|
| 23 |
app.add_middleware(
|
| 24 |
CORSMiddleware,
|
| 25 |
allow_origins=["*"],
|
|
@@ -28,28 +40,43 @@ app.add_middleware(
|
|
| 28 |
allow_headers=["*"],
|
| 29 |
)
|
| 30 |
|
|
|
|
| 31 |
@app.websocket("/ws")
|
| 32 |
async def websocket_endpoint(websocket: WebSocket):
|
| 33 |
await websocket.accept()
|
| 34 |
print("WebSocket connection accepted")
|
| 35 |
try:
|
| 36 |
-
await run_bot_websocket_server(websocket)
|
| 37 |
-
except WebSocketDisconnect:
|
| 38 |
-
print("WebSocket disconnected")
|
| 39 |
except Exception as e:
|
| 40 |
-
print(f"
|
|
|
|
| 41 |
|
| 42 |
@app.post("/connect")
|
| 43 |
async def bot_connect(request: Request) -> Dict[Any, Any]:
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
|
| 52 |
-
app.mount("/", StaticFiles(directory="static", html=True), name="static")
|
| 53 |
|
| 54 |
if __name__ == "__main__":
|
| 55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2025, Daily
|
| 3 |
+
#
|
| 4 |
+
# SPDX-License-Identifier: BSD 2-Clause License
|
| 5 |
+
#
|
| 6 |
import asyncio
|
| 7 |
import os
|
| 8 |
+
import sys
|
| 9 |
from contextlib import asynccontextmanager
|
| 10 |
from typing import Any, Dict
|
| 11 |
|
| 12 |
import uvicorn
|
| 13 |
from dotenv import load_dotenv
|
| 14 |
+
from fastapi import FastAPI, Request, WebSocket
|
| 15 |
from fastapi.middleware.cors import CORSMiddleware
|
|
|
|
| 16 |
|
| 17 |
+
# from bot.bot_fast_api import run_bot
|
| 18 |
+
from bot.bot_websocket_server import run_bot_websocket_server
|
| 19 |
|
| 20 |
+
|
| 21 |
+
# Load environment variables
|
| 22 |
load_dotenv(override=True)
|
| 23 |
|
| 24 |
+
|
| 25 |
@asynccontextmanager
|
| 26 |
async def lifespan(app: FastAPI):
|
| 27 |
+
"""Handles FastAPI startup and shutdown."""
|
| 28 |
+
yield # Run app
|
| 29 |
+
|
| 30 |
|
| 31 |
+
# Initialize FastAPI app with lifespan manager
|
| 32 |
app = FastAPI(lifespan=lifespan)
|
| 33 |
|
| 34 |
+
# Configure CORS to allow requests from any origin
|
| 35 |
app.add_middleware(
|
| 36 |
CORSMiddleware,
|
| 37 |
allow_origins=["*"],
|
|
|
|
| 40 |
allow_headers=["*"],
|
| 41 |
)
|
| 42 |
|
| 43 |
+
|
| 44 |
@app.websocket("/ws")
|
| 45 |
async def websocket_endpoint(websocket: WebSocket):
|
| 46 |
await websocket.accept()
|
| 47 |
print("WebSocket connection accepted")
|
| 48 |
try:
|
| 49 |
+
await run_bot_websocket_server(websocket)
|
|
|
|
|
|
|
| 50 |
except Exception as e:
|
| 51 |
+
print(f"Exception in run_bot: {e}")
|
| 52 |
+
|
| 53 |
|
| 54 |
@app.post("/connect")
|
| 55 |
async def bot_connect(request: Request) -> Dict[Any, Any]:
|
| 56 |
+
return {"ws_url": "ws://localhost:7860/ws"}
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
async def main():
|
| 60 |
+
config = uvicorn.Config(app, host="0.0.0.0", port=7860)
|
| 61 |
+
server = uvicorn.Server(config)
|
| 62 |
+
await server.serve()
|
| 63 |
|
|
|
|
| 64 |
|
| 65 |
if __name__ == "__main__":
|
| 66 |
+
import signal
|
| 67 |
+
|
| 68 |
+
async def serve():
|
| 69 |
+
config = uvicorn.Config(app, host="0.0.0.0", port=7860)
|
| 70 |
+
server = uvicorn.Server(config)
|
| 71 |
+
await server.serve()
|
| 72 |
+
|
| 73 |
+
loop = asyncio.new_event_loop()
|
| 74 |
+
asyncio.set_event_loop(loop)
|
| 75 |
+
|
| 76 |
+
try:
|
| 77 |
+
loop.run_until_complete(serve())
|
| 78 |
+
except KeyboardInterrupt:
|
| 79 |
+
print("Received exit signal (Ctrl+C), shutting down...")
|
| 80 |
+
finally:
|
| 81 |
+
loop.run_until_complete(loop.shutdown_asyncgens())
|
| 82 |
+
loop.close()
|
setup.sh
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
mkdir -p bot/assets
|
| 2 |
+
wget https://github.com/thewh1teagle/kokoro-onnx/releases/download/model-files-v1.0/kokoro-v1.0.onnx -O bot/assets/kokoro-v1.0.int8.onnx
|
| 3 |
+
wget https://github.com/thewh1teagle/kokoro-onnx/releases/download/model-files-v1.0/kokoro-v1.0.fp16-gpu.onnx -O bot/assets/kokoro-v1.0.fp16-gpu.onnx
|
| 4 |
+
wget https://huggingface.co/NeuML/kokoro-base-onnx/resolve/main/voices.json -O bot/assets/voices.json
|
| 5 |
+
curl -fsSL https://ollama.com/install.sh | sh
|
| 6 |
+
sleep 100
|
| 7 |
+
ollama pull llama3.1
|