Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import requests | |
| # Hardcoded active backend URL for your Hugging Face production environment | |
| BACKEND_URL = "https://goodgoals-natarajanreformed-backend.hf.space" | |
| # 1. Establish Ultra-Premium Page Configuration | |
| st.set_page_config( | |
| page_title="Natarajan AI β Workspace", | |
| page_icon="π", | |
| layout="wide", | |
| initial_sidebar_state="expanded" | |
| ) | |
| # 2. Inject Custom CSS Framework (Fixes Contrast, Typography, & Layouts) | |
| st.markdown(""" | |
| <style> | |
| /* Base Application Overrides */ | |
| .stApp { | |
| background: linear-gradient(180deg, #0A0B10 0%, #050608 100%) !important; | |
| color: #F1F5F9 !important; | |
| font-family: 'Inter', system-ui, -apple-system, sans-serif; | |
| } | |
| /* Sidebar Glassmorphic Design & Text Contrast Fixes */ | |
| section[data-testid="stSidebar"] { | |
| background-color: #0E1017 !important; | |
| border-right: 1px solid rgba(255, 255, 255, 0.03) !important; | |
| } | |
| /* FIX: High-contrast sidebar info box */ | |
| .sidebar-info-box { | |
| background: rgba(30, 41, 59, 0.5) !important; | |
| border: 1px solid rgba(255, 255, 255, 0.08) !important; | |
| border-radius: 12px; | |
| padding: 16px; | |
| margin-top: 15px; | |
| color: #E2E8F0 !important; | |
| } | |
| .sidebar-info-box strong { | |
| color: #3B82F6 !important; | |
| } | |
| /* Modern Header Cards */ | |
| .premium-card { | |
| background: rgba(19, 21, 31, 0.4); | |
| border: 1px solid rgba(255, 255, 255, 0.03); | |
| border-radius: 16px; | |
| padding: 20px; | |
| margin-bottom: 16px; | |
| backdrop-filter: blur(12px); | |
| transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1); | |
| } | |
| .premium-card:hover { | |
| border-color: rgba(37, 99, 235, 0.2); | |
| background: rgba(19, 21, 31, 0.6); | |
| transform: translateY(-1px); | |
| } | |
| /* Seamless Input Capsule */ | |
| .stTextInput>div>div>input { | |
| background-color: #13151F !important; | |
| color: #F1F5F9 !important; | |
| border: 1px solid rgba(255, 255, 255, 0.05) !important; | |
| border-radius: 14px !important; | |
| padding: 14px 18px !important; | |
| font-size: 14px !important; | |
| } | |
| /* Custom Chat Containers */ | |
| .chat-row-user { | |
| background: rgba(37, 99, 235, 0.1) !important; | |
| border-left: 3px solid #2563EB !important; | |
| padding: 16px 20px; | |
| border-radius: 8px; | |
| margin-bottom: 12px; | |
| } | |
| .chat-row-error { | |
| background: rgba(244, 63, 94, 0.08) !important; | |
| border: 1px solid rgba(244, 63, 94, 0.2) !important; | |
| border-left: 3px solid #F43F5E !important; | |
| padding: 16px 20px; | |
| border-radius: 8px; | |
| margin-bottom: 12px; | |
| color: #FDA4AF !important; | |
| } | |
| .chat-row-assistant { | |
| background: rgba(255, 255, 255, 0.02) !important; | |
| border-left: 3px solid #64748B !important; | |
| padding: 16px 20px; | |
| border-radius: 8px; | |
| margin-bottom: 12px; | |
| } | |
| /* Status Pills */ | |
| .status-pill { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 6px; | |
| background: rgba(16, 185, 129, 0.06); | |
| color: #10B981; | |
| padding: 4px 12px; | |
| border-radius: 99px; | |
| font-size: 11px; | |
| font-weight: 600; | |
| border: 1px solid rgba(16, 185, 129, 0.15); | |
| } | |
| .status-pill-error { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 6px; | |
| background: rgba(244, 63, 94, 0.06); | |
| color: #F43F5E; | |
| padding: 4px 12px; | |
| border-radius: 99px; | |
| font-size: 11px; | |
| font-weight: 600; | |
| border: 1px solid rgba(244, 63, 94, 0.15); | |
| } | |
| #MainMenu {visibility: hidden;} | |
| footer {visibility: hidden;} | |
| header {visibility: hidden;} | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # Initialize Session Memory States | |
| if "messages" not in st.session_state: | |
| st.session_state.messages = [] | |
| if "thread_id" not in st.session_state: | |
| st.session_state.thread_id = None | |
| if "auth_token" not in st.session_state: | |
| st.session_state.auth_token = None | |
| if "username" not in st.session_state: | |
| st.session_state.username = None | |
| # 3. Sidebar Configuration (Authentication & Status Matrix) | |
| with st.sidebar: | |
| st.markdown("<br>", unsafe_allow_html=True) | |
| st.markdown("### π Natarajan AI") | |
| st.markdown("<p style='color:#64748B; font-size:12px; margin-top:-10px;'>Fluid Workspace v2.4</p>", unsafe_allow_html=True) | |
| st.markdown("---") | |
| # Context-Aware Authentication Panel | |
| if not st.session_state.auth_token: | |
| st.markdown("#### Identity Gateway") | |
| st.markdown('<div class="status-pill-error"><span style="width:6px; height:6px; background:#F43F5E; border-radius:50%;"></span> Unauthenticated (401)</div>', unsafe_allow_html=True) | |
| st.markdown("<br>", unsafe_allow_html=True) | |
| auth_mode = st.radio("Mode", ["Sign In", "Register"], label_visibility="collapsed") | |
| user_input = st.text_input("Username", key="auth_user", placeholder="Enter username") | |
| pass_input = st.text_input("Password", type="password", key="auth_pass", placeholder="Enter password") | |
| if st.button("Authenticate Token", use_container_width=True): | |
| endpoint = "/api/auth/register" if auth_mode == "Register" else "/api/auth/login" | |
| try: | |
| auth_resp = requests.post(f"{BACKEND_URL}{endpoint}", json={"username": user_input, "password": pass_input}) | |
| if auth_resp.status_code == 200 and "token" in auth_resp.json(): | |
| st.session_state.auth_token = auth_resp.json()["token"] | |
| st.session_state.username = user_input | |
| st.success("Identity verified.") | |
| st.rerun() | |
| else: | |
| st.error("Authentication rejected.") | |
| except Exception as e: | |
| st.error("Gateway offline.") | |
| else: | |
| # High-Contrast Fixed Telemetry View | |
| st.markdown(f"#### Welcome, **{st.session_state.username}**") | |
| st.markdown('<div class="status-pill"><span style="width:6px; height:6px; background:#10B981; border-radius:50%;"></span> Security Token Verified</div>', unsafe_allow_html=True) | |
| st.markdown(f""" | |
| <div class="sidebar-info-box"> | |
| <strong>Engine:</strong> Claude Opus 4.8<br><br> | |
| <strong>Routing:</strong> Puter AI Protocol | |
| </div> | |
| """, unsafe_allow_html=True) | |
| st.markdown("<br>", unsafe_allow_html=True) | |
| if st.button("π Revoke Token (Log Out)", use_container_width=True): | |
| st.session_state.auth_token = None | |
| st.session_state.username = None | |
| st.session_state.messages = [] | |
| st.session_state.thread_id = None | |
| st.rerun() | |
| st.markdown("---") | |
| if st.button("π Initialize New Session", use_container_width=True): | |
| st.session_state.messages = [] | |
| st.session_state.thread_id = None | |
| st.rerun() | |
| # 4. Main Workspace Canvas Layout | |
| main_container = st.container() | |
| with main_container: | |
| if len(st.session_state.messages) == 0: | |
| st.markdown("<br><br>", unsafe_allow_html=True) | |
| st.markdown("<h2 style='text-align: center; font-weight: 600; letter-spacing: -0.5px;'>Fluid Intelligence Sanctuary</h2>", unsafe_allow_html=True) | |
| st.markdown("<p style='text-align: center; color: #64748B; font-size: 14px;'>Run advanced architectural reasoning pipelines through Claude Opus 4.8 safely.</p>", unsafe_allow_html=True) | |
| st.markdown("<br>", unsafe_allow_html=True) | |
| col1, col2, col3 = st.columns(3) | |
| with col1: | |
| st.markdown('<div class="premium-card"><p style="font-weight:600; font-size:14px; margin-bottom:4px; color:#3B82F6;">β‘ Zero-Defect Code</p><p style="color:#64748B; font-size:12px; line-height:1.5;">Leverage 4.8\'s reasoning loop for generating complex production code and syntax mapping.</p></div>', unsafe_allow_html=True) | |
| with col2: | |
| st.markdown('<div class="premium-card"><p style="font-weight:600; font-size:14px; margin-bottom:4px; color:#8B5CF6;">π§ Deep Synthesis</p><p style="color:#64748B; font-size:12px; line-height:1.5;">Map multi-variable data tables or resolve dense algorithmic problems with ease.</p></div>', unsafe_allow_html=True) | |
| with col3: | |
| st.markdown('<div class="premium-card"><p style="font-weight:600; font-size:14px; margin-bottom:4px; color:#10B981;">π‘οΈ Persistent Sync</p><p style="color:#64748B; font-size:12px; line-height:1.5;">All logic trees automatically snapshot down to your decoupled Hugging Face backend matrix.</p></div>', unsafe_allow_html=True) | |
| # Custom rendered conversation streams instead of unstyled layout blocks | |
| for message in st.session_state.messages: | |
| if message["role"] == "user": | |
| st.markdown(f'<div class="chat-row-user">πββοΈ <b>You:</b><br>{message["content"]}</div>', unsafe_allow_html=True) | |
| elif message["role"] == "error": | |
| st.markdown(f'<div class="chat-row-error">{message["content"]}</div>', unsafe_allow_html=True) | |
| else: | |
| st.markdown(f'<div class="chat-row-assistant">π <b>Natarajan AI:</b><br>{message["content"]}</div>', unsafe_allow_html=True) | |
| # 5. Interactive Chat Pipeline | |
| if prompt := st.chat_input("Prompt the system cluster..."): | |
| if not st.session_state.auth_token: | |
| st.session_state.messages.append({"role": "user", "content": prompt}) | |
| st.session_state.messages.append({ | |
| "role": "error", | |
| "content": "β οΈ <b>Backend Gateway Interruption (401):</b> Security Interruption. You must verify your identity in the sidebar before prompt sync is authorized." | |
| }) | |
| st.rerun() | |
| else: | |
| st.session_state.messages.append({"role": "user", "content": prompt}) | |
| st.rerun() | |
| # Handle API synchronization logic if authenticated | |
| # (This segment triggers when processing verified tokens) |