|
import gradio as gr |
|
import os |
|
import logging |
|
from fastapi import FastAPI, Request |
|
from main import PhoneChatbotApp |
|
import asyncio |
|
import uvicorn |
|
from threading import Thread |
|
from elevenlabs import ElevenLabs |
|
|
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s") |
|
logger = logging.getLogger(__name__) |
|
|
|
app = FastAPI() |
|
phone_app = PhoneChatbotApp() |
|
log_output = "" |
|
|
|
def append_log(message): |
|
global log_output |
|
log_output += f"{message}\n" |
|
logger.info(message) |
|
|
|
@app.post("/webhook") |
|
async def webhook(request: Request): |
|
data = await request.json() |
|
append_log(f"Webhook received: {data}") |
|
return {"status": "ok"} |
|
|
|
def get_elevenlabs_voices(elevenlabs_api_key): |
|
try: |
|
client = ElevenLabs(api_key=elevenlabs_api_key) |
|
voices = client.voices.get_all() |
|
return {voice.name: voice.voice_id for voice in voices.voices} |
|
except Exception as e: |
|
append_log(f"Error fetching ElevenLabs voices: {e}") |
|
return {"Default (Rachel)": "cgSgspJ2msm6clMCkdW9"} |
|
|
|
def save_config(daily_api_key, daily_domain, deepgram_api_key, elevenlabs_api_key, elevenlabs_voice_id, azure_openai_api_key, silence_timeout, max_prompts): |
|
instructions = """ |
|
Set the following Hugging Face Secrets in your Space (Settings > Secrets): |
|
- deepgram: {} |
|
- elevenlabs: {} |
|
- dailyco: {} |
|
- azure_openai: {} |
|
- DAILY_DOMAIN: {} |
|
- ELEVENLABS_VOICE_ID: {} |
|
- SILENCE_TIMEOUT_SECONDS: {} |
|
- MAX_SILENCE_PROMPTS: {} |
|
|
|
1. Go to your Hugging Face Space > Settings > Secrets. |
|
2. Add each secret with the exact name and value shown above. |
|
3. Redeploy the Space to apply the changes. |
|
""".format( |
|
deepgram_api_key, elevenlabs_api_key, daily_api_key, azure_openai_api_key, |
|
daily_domain, elevenlabs_voice_id, silence_timeout, max_prompts |
|
) |
|
append_log("Generated Hugging Face Secrets instructions") |
|
return instructions |
|
|
|
def get_call_summary(): |
|
if phone_app.current_call_stats["start_time"]: |
|
return [[ |
|
phone_app.current_call_stats["start_time"], |
|
phone_app.current_call_stats["end_time"], |
|
phone_app.current_call_stats["duration_seconds"], |
|
phone_app.current_call_stats["silence_events"], |
|
phone_app.current_call_stats["ended_by_silence"] |
|
]] |
|
return [] |
|
|
|
def run_phone_app(): |
|
asyncio.run(phone_app.run()) |
|
|
|
with gr.Blocks(theme=gr.themes.Soft(), css="static/style.css") as demo: |
|
gr.Markdown("# Phone Chatbot Web App") |
|
|
|
with gr.Tabs(): |
|
with gr.TabItem("Configuration"): |
|
daily_api_key = gr.Textbox(label="Daily API Key", type="password") |
|
daily_domain = gr.Textbox(label="Daily Domain", value="your-username.daily.co") |
|
deepgram_api_key = gr.Textbox(label="Deepgram API Key", type="password") |
|
elevenlabs_api_key = gr.Textbox(label="ElevenLabs API Key", type="password") |
|
elevenlabs_voice = gr.Dropdown( |
|
label="ElevenLabs Voice", |
|
choices=["Default (Rachel)"], |
|
value="Default (Rachel)" |
|
) |
|
azure_openai_api_key = gr.Textbox(label="Azure OpenAI API Key", type="password") |
|
silence_timeout = gr.Slider(5, 30, value=10, step=1, label="Silence Timeout (seconds)") |
|
max_prompts = gr.Slider(1, 5, value=3, step=1, label="Max Silence Prompts") |
|
save_btn = gr.Button("Generate Hugging Face Secrets Instructions") |
|
config_output = gr.Textbox(label="Instructions", lines=10) |
|
|
|
def update_voices(elevenlabs_api_key): |
|
voices = get_elevenlabs_voices(elevenlabs_api_key) |
|
return gr.Dropdown.update(choices=list(voices.keys()), value=list(voices.keys())[0]) |
|
|
|
elevenlabs_api_key.change( |
|
fn=update_voices, |
|
inputs=elevenlabs_api_key, |
|
outputs=elevenlabs_voice |
|
) |
|
|
|
def prepare_config(daily_api_key, daily_domain, deepgram_api_key, elevenlabs_api_key, elevenlabs_voice, azure_openai_api_key, silence_timeout, max_prompts): |
|
voices = get_elevenlabs_voices(elevenlabs_api_key) |
|
voice_id = voices.get(elevenlabs_voice, "cgSgspJ2msm6clMCkdW9") |
|
return save_config(daily_api_key, daily_domain, deepgram_api_key, elevenlabs_api_key, voice_id, azure_openai_api_key, silence_timeout, max_prompts) |
|
|
|
save_btn.click( |
|
fn=prepare_config, |
|
inputs=[daily_api_key, daily_domain, deepgram_api_key, elevenlabs_api_key, |
|
elevenlabs_voice, azure_openai_api_key, silence_timeout, max_prompts], |
|
outputs=config_output |
|
) |
|
|
|
with gr.TabItem("Call Status"): |
|
log_box = gr.Textbox(label="Real-time Logs", lines=20, value=lambda: log_output) |
|
|
|
with gr.TabItem("Call Summary"): |
|
summary_table = gr.Dataframe( |
|
headers=["Start Time", "End Time", "Duration (s)", "Silence Events", "Ended by Silence"], |
|
value=get_call_summary, |
|
label="Call Summaries" |
|
) |
|
refresh_btn = gr.Button("Refresh Summary") |
|
refresh_btn.click(fn=get_call_summary, outputs=summary_table) |
|
|
|
|
|
Thread(target=run_phone_app, daemon=True).start() |
|
|
|
|
|
def start_server(): |
|
uvicorn.run(app, host="0.0.0.0", port=7860) |
|
|
|
Thread(target=start_server, daemon=True).start() |
|
|
|
demo.launch(server_name="0.0.0.0", server_port=7861) |