| | """ |
| | 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() |