Spaces:
Running
Running
File size: 4,657 Bytes
5ec72cd 38bbab9 5ec72cd 259349d 38bbab9 5ec72cd 0bfc688 259349d 5ec72cd 0bfc688 5ec72cd 259349d 0bfc688 5ec72cd 1ec6fec 5ec72cd 1ec6fec 5ec72cd f70205c 5ec72cd f70205c 5ec72cd 38bbab9 5ec72cd 259349d 5ec72cd | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | from __future__ import annotations
import json
import os
from pathlib import Path
import streamlit as st
from src.api.session_bootstrap import ensure_session_bootstrap_server
from src.api.streamlit_routes import build_session_bootstrap_path
from src.core.settings import settings
UI_DIR = Path(__file__).parent / "ui"
INDEX_TEMPLATE = UI_DIR / "index.html"
MAIN_JS = UI_DIR / "main.js"
def extract_display_name(model_id: str, provider: str) -> str:
"""Extract human-readable display name from model ID."""
# Get the model name (part after '/' if present)
if "/" in model_id:
name = model_id.split("/")[-1]
else:
name = model_id
# Special cases for well-known models
if "moonshine" in name.lower():
return "Moonshine STT"
elif "qwen" in name.lower():
return name # Keep format like "Qwen2.5-3B-Instruct"
elif "parakeet" in name.lower():
return "NVIDIA Parakeet"
elif "llama" in name.lower():
parts = name.split("-")
return f"Llama {parts[1]}" if len(parts) > 1 else name
# Default: basic cleanup
return name.replace("-", " ").title()
def generate_footer_html() -> str:
"""Generate dynamic 'Powered by' footer HTML based on current settings."""
# STT Component
stt_provider = settings.stt.STT_PROVIDER.lower()
if stt_provider == "moonshine":
stt_model_id = settings.stt.MOONSHINE_MODEL_ID
stt_url = f"https://huggingface.co/{stt_model_id}"
stt_display = extract_display_name(stt_model_id, "moonshine")
elif stt_provider == "nvidia":
stt_url = "https://build.nvidia.com/"
stt_display = extract_display_name(settings.stt.NVIDIA_STT_MODEL, "nvidia")
else:
stt_url = "#"
stt_display = f"Unknown STT ({stt_provider})"
# LLM Component
llm_provider = settings.llm.LLM_PROVIDER.lower()
if llm_provider == "huggingface":
llm_model_id = settings.llm.HUGGINGFACE_MODEL_ID
llm_url = f"https://huggingface.co/{llm_model_id}"
llm_display = extract_display_name(llm_model_id, "huggingface")
elif llm_provider == "nvidia":
llm_url = "https://build.nvidia.com/"
llm_display = extract_display_name(settings.llm.NVIDIA_MODEL, "nvidia")
else:
llm_url = "#"
llm_display = f"Unknown LLM ({llm_provider})"
# Build footer HTML
return f"""Powered by open-source core components:
<a href="{stt_url}" target="_blank" rel="noopener noreferrer">{stt_display}</a> 路
<a href="{llm_url}" target="_blank" rel="noopener noreferrer">{llm_display}</a> 路
<a href="https://huggingface.co/kyutai/pocket-tts" target="_blank" rel="noopener noreferrer">PocketTTS</a> 路
<a href="https://livekit.io/" target="_blank" rel="noopener noreferrer">LiveKit</a>"""
def render_client(*, livekit_url: str, session_bootstrap_url: str) -> None:
template = INDEX_TEMPLATE.read_text(encoding="utf-8")
js = MAIN_JS.read_text(encoding="utf-8")
footer_html = generate_footer_html()
html = (
template.replace("{{MAIN_JS}}", js)
.replace("{{LIVEKIT_URL_JSON}}", json.dumps(livekit_url))
.replace("{{SESSION_BOOTSTRAP_URL_JSON}}", json.dumps(session_bootstrap_url))
.replace("{{FOOTER_POWERED_BY}}", footer_html)
)
st.components.v1.html(html, height=900, scrolling=False)
def main() -> None:
st.set_page_config(page_title="Open Voice Agent", layout="wide")
st.markdown(
"<style>"
"header {visibility: hidden;} "
".stMainBlockContainer {padding-top: 1rem; padding-bottom: 0;} "
"iframe {border: 1px solid #252d3f; border-radius: 12px;}"
"</style>",
unsafe_allow_html=True,
)
if not settings.livekit.LIVEKIT_URL:
st.error("LIVEKIT_URL is not set in the environment.")
st.stop()
if not settings.livekit.LIVEKIT_API_KEY or not settings.livekit.LIVEKIT_API_SECRET:
st.error("LIVEKIT_API_KEY or LIVEKIT_API_SECRET is not set.")
st.stop()
use_streamlit_route = os.getenv(
"OPEN_VOICE_USE_STREAMLIT_BOOTSTRAP_ROUTE", "0"
).lower() in {"1", "true", "yes"}
if use_streamlit_route:
session_bootstrap_url = build_session_bootstrap_path()
else:
try:
session_bootstrap_url = ensure_session_bootstrap_server()
except Exception as exc:
st.error(f"Failed to start session bootstrap service: {exc}")
st.stop()
render_client(
livekit_url=settings.livekit.LIVEKIT_URL,
session_bootstrap_url=session_bootstrap_url,
)
if __name__ == "__main__":
main()
|