Spaces:
Running
Running
File size: 7,394 Bytes
85f900d | 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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | """
VoiceVault β Gradio Application Entry Point
============================================
HuggingFace Spaces entry point and local development server.
Run locally: python app.py
Deploy: Push to HuggingFace Spaces (app.py detected automatically)
Architecture:
4-tab Gradio Blocks layout:
Tab 1 β Ask VoiceVault (voice query + streaming answer + TTS)
Tab 2 β Knowledge Bases (upload + index + manage)
Tab 3 β Analytics (query stats + KB inventory)
Tab 4 β Settings (runtime parameters)
Startup:
1. Ensure data directories exist (cfg.ensure_directories)
2. Initialize KBManager (central SQLite DB)
3. Lazy-init WhisperTranscriber and AnswerChain (no model downloads at startup)
4. Build 4-tab Gradio Blocks UI
5. Launch with Soft theme
"""
from __future__ import annotations
import logging
import sys
import gradio as gr
from config import cfg
from voicevault import __version__
from ui.tabs.ask_tab import build_ask_tab
from ui.tabs.kb_tab import build_kb_tab
from ui.tabs.analytics_tab import build_analytics_tab
from ui.tabs.settings_tab import build_settings_tab
from ui.components.audio_controls import get_tts_html
# ------------------------------------------------------------------ #
# Logging #
# ------------------------------------------------------------------ #
logging.basicConfig(
level=logging.DEBUG if cfg.debug else logging.INFO,
format="%(asctime)s | %(levelname)-8s | %(name)s | %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
handlers=[logging.StreamHandler(sys.stdout)],
)
logger = logging.getLogger(__name__)
# ------------------------------------------------------------------ #
# Startup #
# ------------------------------------------------------------------ #
_CENTRAL_DB_PATH = cfg.data_dir / "voicevault.db"
def _startup() -> tuple:
"""
Initialize all pipeline components at startup.
Returns:
(kb_manager, transcriber, answer_chain) tuple β passed to UI builders.
"""
cfg.ensure_directories()
logger.info("=" * 60)
logger.info("VoiceVault v%s β Starting up", __version__)
logger.info("Data directory : %s", cfg.data_dir.resolve())
logger.info("Central DB : %s", _CENTRAL_DB_PATH)
logger.info("Groq key : %s", "β configured" if cfg.has_groq_key() else "β not set")
logger.info("Gemini key : %s", "β configured" if cfg.has_gemini_key() else "β not set")
logger.info("Debug mode : %s", cfg.debug)
logger.info("=" * 60)
if not cfg.has_any_llm_key():
logger.warning(
"No LLM API key found. Set GROQ_API_KEY or GEMINI_API_KEY in .env "
"to enable answer generation."
)
# ββ KBManager (initializes SQLite schema) ββββββββββββββββββββββββββ
from voicevault.kb.kb_manager import KBManager
kb_manager = KBManager(db_path=_CENTRAL_DB_PATH)
logger.info("KBManager initialized β %d KB(s) found", len(kb_manager.list_kbs()))
# ββ WhisperTranscriber (lazy β no model loaded until first query) ββ
from voicevault.asr.whisper_transcriber import WhisperTranscriber
transcriber = WhisperTranscriber()
logger.info("WhisperTranscriber ready (lazy β model loads on first use)")
# ββ AnswerChain (lazy β LLM clients created per call) βββββββββββββ
from voicevault.generation.answer_chain import AnswerChain
answer_chain = AnswerChain()
logger.info("AnswerChain ready (Groq primary / Gemini fallback)")
return kb_manager, transcriber, answer_chain
# ------------------------------------------------------------------ #
# Gradio App Builder #
# ------------------------------------------------------------------ #
def build_app(kb_manager, transcriber, answer_chain) -> gr.Blocks:
"""
Construct and return the full Gradio Blocks application.
Args:
kb_manager: KBManager singleton for KB operations.
transcriber: WhisperTranscriber singleton (lazy-loaded model).
answer_chain: AnswerChain singleton (Groq β Gemini).
Returns:
Configured gr.Blocks instance (not yet launched).
"""
with gr.Blocks(
title="VoiceVault β Voice-First RAG Knowledge Agent",
analytics_enabled=False,
) as demo:
# ββ Header βββββββββββββββββββββββββββββββββββββββββββββββββ
gr.Markdown(
f"""
# ποΈ VoiceVault
**Voice-First RAG Knowledge Agent** Β·
Speak to your documents. Get cited answers out.
`v{__version__}`
"""
)
# ββ Web Speech API JS bridge ββββββββββββββββββββββββββββββββ
gr.HTML(get_tts_html(), visible=False)
# ββ Tabs βββββββββββββββββββββββββββββββββββββββββββββββββββ
with gr.Tabs():
with gr.Tab("ποΈ Ask VoiceVault"):
build_ask_tab(
transcriber=transcriber,
answer_chain=answer_chain,
kb_manager=kb_manager,
db_path=_CENTRAL_DB_PATH,
)
with gr.Tab("π Knowledge Bases"):
build_kb_tab(
kb_manager=kb_manager,
db_path=_CENTRAL_DB_PATH,
)
with gr.Tab("π Analytics"):
build_analytics_tab(
kb_manager=kb_manager,
db_path=_CENTRAL_DB_PATH,
)
with gr.Tab("βοΈ Settings"):
build_settings_tab()
# ββ Footer βββββββββββββββββββββββββββββββββββββββββββββββββ
gr.Markdown(
"""
---
<div style="text-align:center; color:#888; font-size:0.8em;">
VoiceVault Β· Navnit Amrutharaj Β·
<a href="https://github.com/ninjacode911" target="_blank">github.com/ninjacode911</a> Β·
Stack: Whisper Β· ChromaDB Β· LangChain Β· Groq Β· Gradio Β· $0/month
</div>
"""
)
return demo
# ------------------------------------------------------------------ #
# Entry Point #
# ------------------------------------------------------------------ #
if __name__ == "__main__":
kb_manager, transcriber, answer_chain = _startup()
app = build_app(kb_manager, transcriber, answer_chain)
theme = gr.themes.Soft(
primary_hue="violet",
secondary_hue="purple",
neutral_hue="slate",
font=[gr.themes.GoogleFont("Inter"), "ui-sans-serif", "system-ui"],
)
app.launch(
server_name=cfg.host,
server_port=cfg.port,
share=False,
show_error=True,
theme=theme,
)
|