Spaces:
Paused
Paused
Update src/streamlit_app.py
Browse files- src/streamlit_app.py +68 -125
src/streamlit_app.py
CHANGED
|
@@ -86,49 +86,6 @@ st.markdown("""
|
|
| 86 |
text-align: center;
|
| 87 |
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
| 88 |
}
|
| 89 |
-
.tech-stack-popup {
|
| 90 |
-
position: fixed;
|
| 91 |
-
top: 20px;
|
| 92 |
-
right: 20px;
|
| 93 |
-
z-index: 1000;
|
| 94 |
-
background: rgba(255, 255, 255, 0.95);
|
| 95 |
-
border-radius: 8px;
|
| 96 |
-
padding: 0.8rem;
|
| 97 |
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
| 98 |
-
border-left: 4px solid #1f4e79;
|
| 99 |
-
max-width: 300px;
|
| 100 |
-
animation: slideIn 0.5s ease-out;
|
| 101 |
-
}
|
| 102 |
-
@keyframes slideIn {
|
| 103 |
-
from { transform: translateX(100%); opacity: 0; }
|
| 104 |
-
to { transform: translateX(0); opacity: 1; }
|
| 105 |
-
}
|
| 106 |
-
.tech-stack-mini {
|
| 107 |
-
display: flex;
|
| 108 |
-
gap: 0.3rem;
|
| 109 |
-
flex-wrap: wrap;
|
| 110 |
-
margin-top: 0.5rem;
|
| 111 |
-
}
|
| 112 |
-
.tech-item-mini {
|
| 113 |
-
padding: 0.2rem 0.4rem;
|
| 114 |
-
border-radius: 6px;
|
| 115 |
-
font-size: 0.65rem;
|
| 116 |
-
font-weight: bold;
|
| 117 |
-
color: white;
|
| 118 |
-
display: flex;
|
| 119 |
-
align-items: center;
|
| 120 |
-
gap: 0.2rem;
|
| 121 |
-
}
|
| 122 |
-
.tech-available {
|
| 123 |
-
background-color: #28a745;
|
| 124 |
-
}
|
| 125 |
-
.tech-demo {
|
| 126 |
-
background-color: #ffc107;
|
| 127 |
-
color: #000;
|
| 128 |
-
}
|
| 129 |
-
.tech-unavailable {
|
| 130 |
-
background-color: #6c757d;
|
| 131 |
-
}
|
| 132 |
.role-badge {
|
| 133 |
background-color: #28a745;
|
| 134 |
color: white;
|
|
@@ -194,97 +151,89 @@ st.markdown("""
|
|
| 194 |
padding: 0.25rem 0;
|
| 195 |
border-bottom: 1px solid #dee2e6;
|
| 196 |
}
|
| 197 |
-
.tech-status-toggle {
|
| 198 |
-
position: fixed;
|
| 199 |
-
bottom: 20px;
|
| 200 |
-
right: 20px;
|
| 201 |
-
z-index: 999;
|
| 202 |
-
background: #1f4e79;
|
| 203 |
-
color: white;
|
| 204 |
-
border: none;
|
| 205 |
-
border-radius: 50%;
|
| 206 |
-
width: 50px;
|
| 207 |
-
height: 50px;
|
| 208 |
-
cursor: pointer;
|
| 209 |
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
| 210 |
-
font-size: 1.2rem;
|
| 211 |
-
}
|
| 212 |
-
.tech-status-toggle:hover {
|
| 213 |
-
background: #2d5aa0;
|
| 214 |
-
transform: scale(1.05);
|
| 215 |
-
}
|
| 216 |
</style>
|
| 217 |
""", unsafe_allow_html=True)
|
| 218 |
|
| 219 |
-
def
|
| 220 |
-
"""Display
|
| 221 |
# Initialize popup state
|
| 222 |
-
if '
|
| 223 |
-
st.session_state.
|
| 224 |
-
st.session_state.
|
| 225 |
|
| 226 |
-
# Auto-hide
|
| 227 |
-
if st.session_state.
|
| 228 |
current_time = time.time()
|
| 229 |
-
if current_time - st.session_state.
|
| 230 |
-
st.session_state.
|
| 231 |
st.rerun()
|
| 232 |
|
| 233 |
-
# Show
|
| 234 |
-
if st.session_state.
|
| 235 |
tech_status = check_tech_stack()
|
| 236 |
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 244 |
|
| 245 |
for component, info in tech_status.items():
|
| 246 |
if info['available']:
|
| 247 |
if component == 'fastapi':
|
| 248 |
-
css_class = "tech-demo"
|
| 249 |
icon = "π"
|
| 250 |
else:
|
| 251 |
-
css_class = "tech-available"
|
| 252 |
icon = "β
"
|
| 253 |
else:
|
| 254 |
-
css_class = "tech-unavailable"
|
| 255 |
icon = "β οΈ"
|
| 256 |
|
| 257 |
component_names = {
|
| 258 |
'python': 'Python',
|
| 259 |
'streamlit': 'Streamlit',
|
| 260 |
-
'vector_store': 'Vector Store',
|
| 261 |
'llm': 'LLM',
|
| 262 |
'fastapi': 'FastAPI'
|
| 263 |
}
|
| 264 |
|
| 265 |
-
|
| 266 |
-
<div class="tech-item-mini {css_class}">
|
| 267 |
-
{icon} {component_names.get(component, component)}
|
| 268 |
-
</div>
|
| 269 |
-
"""
|
| 270 |
-
|
| 271 |
-
popup_html += """
|
| 272 |
-
</div>
|
| 273 |
-
<div style="font-size: 0.6rem; color: #666; margin-top: 0.5rem; text-align: center;">
|
| 274 |
-
Auto-hiding in 4 seconds...
|
| 275 |
-
</div>
|
| 276 |
-
</div>
|
| 277 |
-
"""
|
| 278 |
-
|
| 279 |
-
st.markdown(popup_html, unsafe_allow_html=True)
|
| 280 |
-
|
| 281 |
-
def display_tech_status_toggle():
|
| 282 |
-
"""Display floating button to show tech status"""
|
| 283 |
-
st.markdown("""
|
| 284 |
-
<button class="tech-status-toggle" onclick="window.parent.location.reload();" title="Show Tech Stack Status">
|
| 285 |
-
π§
|
| 286 |
-
</button>
|
| 287 |
-
""", unsafe_allow_html=True)
|
| 288 |
|
| 289 |
def initialize_session_state():
|
| 290 |
"""Initialize session state variables"""
|
|
@@ -332,11 +281,11 @@ def demo_role_switch():
|
|
| 332 |
st.markdown('</div>', unsafe_allow_html=True)
|
| 333 |
|
| 334 |
def login_page():
|
| 335 |
-
"""Display enhanced login page with
|
| 336 |
st.markdown('<div class="main-header"><h1>π€ FinSolve AI Assistant</h1><p>Complete Tech Stack Implementation</p></div>', unsafe_allow_html=True)
|
| 337 |
|
| 338 |
-
# Display
|
| 339 |
-
|
| 340 |
|
| 341 |
col1, col2, col3 = st.columns([1, 2, 1])
|
| 342 |
|
|
@@ -354,9 +303,9 @@ def login_page():
|
|
| 354 |
st.session_state.authenticated = True
|
| 355 |
st.session_state.username = username
|
| 356 |
st.session_state.user_role = auth_system.get_user_role(username)
|
| 357 |
-
# Reset
|
| 358 |
-
st.session_state.
|
| 359 |
-
st.session_state.
|
| 360 |
st.success(f"Welcome {username}! Your role: {st.session_state.user_role}")
|
| 361 |
st.rerun()
|
| 362 |
else:
|
|
@@ -450,21 +399,12 @@ def display_system_metrics():
|
|
| 450 |
system_health = "π’ Healthy" if status.get('system_initialized') else "π΄ Error"
|
| 451 |
st.markdown(f"**Status:** {system_health}")
|
| 452 |
|
| 453 |
-
# Tech stack details
|
| 454 |
-
tech_stack = status.get('tech_stack', {})
|
| 455 |
-
st.markdown("**π§ Tech Stack:**")
|
| 456 |
-
for component, status_text in tech_stack.items():
|
| 457 |
-
st.markdown(f"β’ **{component.title()}**: {status_text}")
|
| 458 |
-
|
| 459 |
st.markdown('</div>', unsafe_allow_html=True)
|
| 460 |
|
| 461 |
def main_app():
|
| 462 |
"""Enhanced main application interface"""
|
| 463 |
-
# Display
|
| 464 |
-
|
| 465 |
-
|
| 466 |
-
# Display floating tech status toggle button
|
| 467 |
-
display_tech_status_toggle()
|
| 468 |
|
| 469 |
# Initialize Enhanced RAG system if not done
|
| 470 |
if st.session_state.enhanced_rag_system is None:
|
|
@@ -472,7 +412,7 @@ def main_app():
|
|
| 472 |
st.session_state.enhanced_rag_system = EnhancedRAGSystem()
|
| 473 |
st.session_state.enhanced_rag_system.initialize_system()
|
| 474 |
|
| 475 |
-
# Header without tech stack status (now in
|
| 476 |
col1, col2, col3 = st.columns([3, 2, 1])
|
| 477 |
with col1:
|
| 478 |
st.markdown('<div class="main-header"><h1>π€ FinSolve AI Assistant</h1><p>Complete Tech Stack RAG System</p></div>', unsafe_allow_html=True)
|
|
@@ -564,6 +504,9 @@ def main_app():
|
|
| 564 |
# System metrics for all users
|
| 565 |
st.markdown("---")
|
| 566 |
display_system_metrics()
|
|
|
|
|
|
|
|
|
|
| 567 |
|
| 568 |
# Main chat interface
|
| 569 |
st.header("π¬ AI-Powered Chat with Complete RAG")
|
|
|
|
| 86 |
text-align: center;
|
| 87 |
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
| 88 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 89 |
.role-badge {
|
| 90 |
background-color: #28a745;
|
| 91 |
color: white;
|
|
|
|
| 151 |
padding: 0.25rem 0;
|
| 152 |
border-bottom: 1px solid #dee2e6;
|
| 153 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
</style>
|
| 155 |
""", unsafe_allow_html=True)
|
| 156 |
|
| 157 |
+
def display_tech_stack_notification():
|
| 158 |
+
"""Display tech stack status as a Streamlit notification"""
|
| 159 |
# Initialize popup state
|
| 160 |
+
if 'show_tech_notification' not in st.session_state:
|
| 161 |
+
st.session_state.show_tech_notification = True
|
| 162 |
+
st.session_state.notification_start_time = time.time()
|
| 163 |
|
| 164 |
+
# Auto-hide notification after 5 seconds
|
| 165 |
+
if st.session_state.show_tech_notification:
|
| 166 |
current_time = time.time()
|
| 167 |
+
if current_time - st.session_state.notification_start_time > 5:
|
| 168 |
+
st.session_state.show_tech_notification = False
|
| 169 |
st.rerun()
|
| 170 |
|
| 171 |
+
# Show notification if enabled
|
| 172 |
+
if st.session_state.show_tech_notification:
|
| 173 |
tech_status = check_tech_stack()
|
| 174 |
|
| 175 |
+
# Create a container for the notification
|
| 176 |
+
with st.container():
|
| 177 |
+
st.info("ποΈ **Tech Stack Status** - Auto-hiding in 5 seconds...")
|
| 178 |
+
|
| 179 |
+
# Create columns for status items
|
| 180 |
+
cols = st.columns(5)
|
| 181 |
+
|
| 182 |
+
component_names = {
|
| 183 |
+
'python': 'Python',
|
| 184 |
+
'streamlit': 'Streamlit',
|
| 185 |
+
'vector_store': 'Vector Store',
|
| 186 |
+
'llm': 'LLM',
|
| 187 |
+
'fastapi': 'FastAPI'
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
for i, (component, info) in enumerate(tech_status.items()):
|
| 191 |
+
with cols[i]:
|
| 192 |
+
if info['available']:
|
| 193 |
+
if component == 'fastapi':
|
| 194 |
+
icon = "π"
|
| 195 |
+
color = "orange"
|
| 196 |
+
else:
|
| 197 |
+
icon = "β
"
|
| 198 |
+
color = "green"
|
| 199 |
+
else:
|
| 200 |
+
icon = "β οΈ"
|
| 201 |
+
color = "red"
|
| 202 |
+
|
| 203 |
+
st.markdown(f"""
|
| 204 |
+
<div style="text-align: center; padding: 0.5rem;">
|
| 205 |
+
<div style="font-size: 1.2rem;">{icon}</div>
|
| 206 |
+
<div style="font-size: 0.8rem; font-weight: bold;">{component_names.get(component, component)}</div>
|
| 207 |
+
<div style="font-size: 0.7rem; color: {color};">{info['status']}</div>
|
| 208 |
+
</div>
|
| 209 |
+
""", unsafe_allow_html=True)
|
| 210 |
+
|
| 211 |
+
def display_tech_status_sidebar():
|
| 212 |
+
"""Display tech status in sidebar"""
|
| 213 |
+
with st.sidebar:
|
| 214 |
+
st.markdown("---")
|
| 215 |
+
st.markdown("### π§ Tech Stack")
|
| 216 |
+
|
| 217 |
+
tech_status = check_tech_stack()
|
| 218 |
|
| 219 |
for component, info in tech_status.items():
|
| 220 |
if info['available']:
|
| 221 |
if component == 'fastapi':
|
|
|
|
| 222 |
icon = "π"
|
| 223 |
else:
|
|
|
|
| 224 |
icon = "β
"
|
| 225 |
else:
|
|
|
|
| 226 |
icon = "β οΈ"
|
| 227 |
|
| 228 |
component_names = {
|
| 229 |
'python': 'Python',
|
| 230 |
'streamlit': 'Streamlit',
|
| 231 |
+
'vector_store': 'Vector Store',
|
| 232 |
'llm': 'LLM',
|
| 233 |
'fastapi': 'FastAPI'
|
| 234 |
}
|
| 235 |
|
| 236 |
+
st.markdown(f"{icon} **{component_names.get(component, component)}**: {info['status']}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 237 |
|
| 238 |
def initialize_session_state():
|
| 239 |
"""Initialize session state variables"""
|
|
|
|
| 281 |
st.markdown('</div>', unsafe_allow_html=True)
|
| 282 |
|
| 283 |
def login_page():
|
| 284 |
+
"""Display enhanced login page with tech stack notification"""
|
| 285 |
st.markdown('<div class="main-header"><h1>π€ FinSolve AI Assistant</h1><p>Complete Tech Stack Implementation</p></div>', unsafe_allow_html=True)
|
| 286 |
|
| 287 |
+
# Display tech stack notification
|
| 288 |
+
display_tech_stack_notification()
|
| 289 |
|
| 290 |
col1, col2, col3 = st.columns([1, 2, 1])
|
| 291 |
|
|
|
|
| 303 |
st.session_state.authenticated = True
|
| 304 |
st.session_state.username = username
|
| 305 |
st.session_state.user_role = auth_system.get_user_role(username)
|
| 306 |
+
# Reset notification for next page
|
| 307 |
+
st.session_state.show_tech_notification = True
|
| 308 |
+
st.session_state.notification_start_time = time.time()
|
| 309 |
st.success(f"Welcome {username}! Your role: {st.session_state.user_role}")
|
| 310 |
st.rerun()
|
| 311 |
else:
|
|
|
|
| 399 |
system_health = "π’ Healthy" if status.get('system_initialized') else "π΄ Error"
|
| 400 |
st.markdown(f"**Status:** {system_health}")
|
| 401 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 402 |
st.markdown('</div>', unsafe_allow_html=True)
|
| 403 |
|
| 404 |
def main_app():
|
| 405 |
"""Enhanced main application interface"""
|
| 406 |
+
# Display tech stack notification on app entry
|
| 407 |
+
display_tech_stack_notification()
|
|
|
|
|
|
|
|
|
|
| 408 |
|
| 409 |
# Initialize Enhanced RAG system if not done
|
| 410 |
if st.session_state.enhanced_rag_system is None:
|
|
|
|
| 412 |
st.session_state.enhanced_rag_system = EnhancedRAGSystem()
|
| 413 |
st.session_state.enhanced_rag_system.initialize_system()
|
| 414 |
|
| 415 |
+
# Header without tech stack status (now in notification)
|
| 416 |
col1, col2, col3 = st.columns([3, 2, 1])
|
| 417 |
with col1:
|
| 418 |
st.markdown('<div class="main-header"><h1>π€ FinSolve AI Assistant</h1><p>Complete Tech Stack RAG System</p></div>', unsafe_allow_html=True)
|
|
|
|
| 504 |
# System metrics for all users
|
| 505 |
st.markdown("---")
|
| 506 |
display_system_metrics()
|
| 507 |
+
|
| 508 |
+
# Tech stack status in sidebar
|
| 509 |
+
display_tech_status_sidebar()
|
| 510 |
|
| 511 |
# Main chat interface
|
| 512 |
st.header("π¬ AI-Powered Chat with Complete RAG")
|