| """ |
| app.py |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ |
| VoiceVerse Pro β Streamlit Orchestrator (2026 Stable Build) |
| |
| This file is intentionally thin. Its only jobs are: |
| 1. Configure the Streamlit page |
| 2. Inject global CSS |
| 3. Render the header and stage tracker |
| 4. Delegate every pipeline stage to its own UI module |
| 5. Provide a debug panel for development |
| |
| All business logic lives in modules/ |
| All UI rendering logic lives in ui/ |
| |
| Pipeline flow: |
| ui.sidebar β SidebarConfig |
| ui.stage_upload β PipelineState.stage 0 β 1 |
| ui.stage_retrieve β PipelineState.stage 1 β 2 |
| ui.stage_generate β PipelineState.stage 2 β 3 |
| ui.stage_audio β PipelineState.stage 3 β 4 |
| """ |
|
|
| import logging |
| import os |
| import sys |
|
|
| |
| |
| |
| sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) |
|
|
| import streamlit as st |
| from dotenv import load_dotenv |
|
|
| load_dotenv() |
|
|
| from ui import ( |
| get_pipeline_state, |
| inject_css, |
| render_header, |
| render_stage_tracker, |
| render_mode_selector, |
| sidebar, |
| stage_upload, |
| stage_retrieve, |
| stage_generate, |
| stage_audio, |
| ) |
|
|
| |
| logging.basicConfig( |
| level=logging.INFO, |
| format="%(asctime)s | %(levelname)s | %(name)s | %(message)s", |
| ) |
|
|
| |
| st.set_page_config( |
| page_title="VoiceVerse Pro", |
| page_icon="ποΈ", |
| layout="wide", |
| initial_sidebar_state="expanded", |
| ) |
|
|
| |
| inject_css() |
|
|
| |
| state = get_pipeline_state() |
|
|
| |
| config = sidebar.render(current_stage=state.stage) |
|
|
| |
| render_header() |
| render_stage_tracker(state.stage) |
|
|
| |
| selected_mode = render_mode_selector() |
|
|
| |
| from ui.state import OutputMode |
| config.output_mode = OutputMode(selected_mode) |
|
|
| |
| col_left, col_right = st.columns([1, 1.3], gap="large") |
|
|
| with col_left: |
| stage_upload.render(state, config) |
| stage_retrieve.render(state, config) |
|
|
| with col_right: |
| stage_generate.render(state, config) |
| stage_audio.render(state, config) |
|
|
| |
| st.divider() |
| with st.expander("π οΈ Debug & System Info", expanded=False): |
| import sys, platform |
| st.markdown( |
| f"**Python:** `{sys.version}` \n" |
| f"**Platform:** `{platform.platform()}` \n" |
| f"**Pipeline Stage:** `{state.stage}` \n" |
| f"**Chunks Indexed:** `{state.total_chunks}` \n" |
| f"**Context Retrieved:** `{state.has_context}` \n" |
| f"**Script Generated:** `{state.has_script}` \n" |
| f"**Audio Ready:** `{state.has_audio}`" |
| ) |
| if st.button("π Reset All State"): |
| for k in list(st.session_state.keys()): |
| del st.session_state[k] |
| st.rerun() |