File size: 4,758 Bytes
3fc4dbc 6bf2879 3fc4dbc 6bf2879 3fc4dbc 6bf2879 3fc4dbc 6bf2879 7e5fab5 6bf2879 7e5fab5 6bf2879 7e5fab5 6bf2879 7e5fab5 6bf2879 7e5fab5 6bf2879 7e5fab5 6bf2879 7e5fab5 6bf2879 7e5fab5 6bf2879 7e5fab5 6bf2879 7e5fab5 6bf2879 7e5fab5 6bf2879 7e5fab5 | 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 | """
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
# ββ Path fix: ensure the project root is on sys.path regardless of where
# `streamlit run` is invoked from. Without this, `import ui` and
# `import modules` fail when the CWD is not the project root.
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import streamlit as st
from dotenv import load_dotenv
load_dotenv() # loads .env β os.environ before any module reads env vars
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 βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s | %(levelname)s | %(name)s | %(message)s",
)
# ββ Page config (must be first Streamlit call) ββββββββββββββββββββββββββββββββ
st.set_page_config(
page_title="VoiceVerse Pro",
page_icon="ποΈ",
layout="wide",
initial_sidebar_state="expanded",
)
# ββ Global styles βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
inject_css()
# ββ Session state βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
state = get_pipeline_state()
# ββ Sidebar β typed SidebarConfig ββββββββββββββββββββββββββββββββββββββββββββ
config = sidebar.render(current_stage=state.stage)
# ββ Header + stage tracker ββββββββββββββββββββββββββββββββββββββββββββββββββββ
render_header()
render_stage_tracker(state.stage)
# ββ Mode selector (prominent main-area toggle) ββββββββββββββββββββββββββββββββ
selected_mode = render_mode_selector()
# Sync the session-state selection back into config so all stages see it
from ui.state import OutputMode
config.output_mode = OutputMode(selected_mode)
# ββ Two-column layout βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
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)
# ββ Debug panel βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
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() |