NatarajanRedefined / src /streamlit_app.py
goodgoals's picture
Create src/streamlit_app.py
476c0fd verified
Raw
History Blame Contribute Delete
10.4 kB
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)