Spaces:
Runtime error
Runtime error
| """ | |
| Discovery Lens β Entry point | |
| """ | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| import streamlit as st | |
| from components.theme import apply_theme, LOGO_SVG | |
| st.set_page_config( | |
| page_title="Discovery Lens", | |
| page_icon="π", | |
| layout="wide", | |
| initial_sidebar_state="expanded", | |
| ) | |
| apply_theme() | |
| defaults = { | |
| "goal": "", | |
| "product_name": "", | |
| "goal_validated": False, | |
| "context_block": "", | |
| "chunks": [], | |
| "embeddings": None, | |
| "clusters": [], | |
| "scored_clusters": [], | |
| "ost": {}, | |
| "source_map": {}, | |
| } | |
| for key, value in defaults.items(): | |
| if key not in st.session_state: | |
| st.session_state[key] = value | |
| # ββ Header ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| st.markdown( | |
| f'<div style="display:flex;align-items:center;gap:18px;margin-bottom:8px;">' | |
| f'{LOGO_SVG}' | |
| f'<div>' | |
| f'<h1 style="margin:0;font-size:2.8rem;color:#26215C;line-height:1.1;">Discovery Lens</h1>' | |
| f'<p style="margin:4px 0 0;color:#534AB7;font-size:1.05rem;">' | |
| f'Discovery data is everywhere. <em>Insight isn\'t.</em></p>' | |
| f'</div></div>', | |
| unsafe_allow_html=True, | |
| ) | |
| st.markdown("<div style='margin-top:2rem;'></div>", unsafe_allow_html=True) | |
| # ββ Pipeline steps βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| steps = ["Extract", "Chunk", "Embed", "Cluster", "Score", "OST"] | |
| cols = st.columns(len(steps) * 2 - 1) | |
| for i, step in enumerate(steps): | |
| with cols[i * 2]: | |
| st.markdown( | |
| f'<div style="background:#FFFFFF;border:1.5px solid #D0CCF0;border-radius:8px;' | |
| f'padding:10px 6px;text-align:center;font-weight:700;color:#26215C;font-size:13px;">' | |
| f'{step}</div>', | |
| unsafe_allow_html=True, | |
| ) | |
| if i < len(steps) - 1: | |
| with cols[i * 2 + 1]: | |
| st.markdown( | |
| '<div style="text-align:center;color:#534AB7;font-size:22px;' | |
| 'padding-top:6px;">βΊ</div>', | |
| unsafe_allow_html=True, | |
| ) | |
| st.markdown("<div style='margin-top:2.5rem;'></div>", unsafe_allow_html=True) | |
| # ββ How it works βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| st.markdown( | |
| '<div style="background:#FFFFFF;border:1.5px solid #E0DFDB;border-radius:12px;' | |
| 'padding:24px 28px;">' | |
| '<h3 style="color:#26215C;margin-top:0;">How it works</h3>' | |
| '<div style="display:flex;align-items:flex-start;gap:12px;margin-bottom:14px;">' | |
| '<span style="font-size:1.2rem;font-weight:800;color:#534AB7;min-width:28px;">β </span>' | |
| '<div><strong style="color:#26215C;">Set your goal</strong>' | |
| '<span style="color:#555;"> β Enter your product name and goal statement. ' | |
| 'An AI coach validates quality and suggests a rewrite if it\'s vague.</span></div></div>' | |
| '<div style="display:flex;align-items:flex-start;gap:12px;margin-bottom:14px;">' | |
| '<span style="font-size:1.2rem;font-weight:800;color:#534AB7;min-width:28px;">β‘</span>' | |
| '<div><strong style="color:#26215C;">Upload your files</strong>' | |
| '<span style="color:#555;"> β Interviews, reviews, support tickets, usability notes ' | |
| '(PDF, DOCX, CSV, TXT). Tag each file with its source type.</span></div></div>' | |
| '<div style="display:flex;align-items:flex-start;gap:12px;">' | |
| '<span style="font-size:1.2rem;font-weight:800;color:#534AB7;min-width:28px;">β’</span>' | |
| '<div><strong style="color:#26215C;">Get your OST</strong>' | |
| '<span style="color:#555;"> β The tool clusters insights, frames opportunities in JTBD ' | |
| 'language, scores them with deterministic ODI signals, and shows exactly which quotes ' | |
| 'justify every decision.</span></div></div>' | |
| '</div>', | |
| unsafe_allow_html=True, | |
| ) | |
| st.markdown( | |
| '<p style="margin-top:1.5rem;color:#534AB7;font-weight:600;font-size:15px;">' | |
| 'π Use the sidebar to get started.</p>', | |
| unsafe_allow_html=True, | |
| ) | |
| if st.checkbox("Show session state (debug)", value=False): | |
| st.json({k: str(v)[:200] if v else v for k, v in st.session_state.items()}) | |