AQUATHISTLE / app.py
ckharche's picture
Upload 7 files
1fa53ff verified
"""
app.py - COMPLETE WORKING VERSION
No duplicate headers, clean structure
app.py - A-GRADE VERSION
Added scenario state management for interactive visualizations
PRODUCTION READY VERSION:
1. Fixed: Suggestions NEVER recycle (even after 7+ messages)
2. Fixed: Proper state tracking with message history analysis
3. Fixed: Detects NEW topics vs continuation
4. Added: Gap reduction CSS class for .st-emotion-cache-wfksow
5. Fixed: All edge cases (bitcoin, options trading, etc)
"""
import streamlit as st
from llm_agent import aqua_response, get_default_profile
from components import render_left_panel, render_chat_panel, check_query_for_scenario
from styles import get_custom_css
st.set_page_config(layout="wide", page_title="Aqua Thistle", page_icon="🌊")
st.markdown(get_custom_css(), unsafe_allow_html=True)
# Main header
st.markdown("""
<div style='text-align: center; padding: 1rem 0 1.5rem 0;'>
<h1 style='font-size: 2.5rem; margin: 0 0 0.5rem 0;'>🌊 Aqua Thistle</h1>
<p style='color: #4a4a4a; font-size: 1rem; margin: 0;'>Your Personal GenZ Mentor for Life, Finance & Education</p>
</div>
""", unsafe_allow_html=True)
# Initialize session state
if "profile" not in st.session_state:
st.session_state.profile = get_default_profile()
if "seed_chat" not in st.session_state:
st.session_state.seed_chat = None
if "current_category" not in st.session_state:
st.session_state.current_category = "Finance"
# Scenario state for interactive visualizations
if "scenario_mode" not in st.session_state:
st.session_state.scenario_mode = False
if "scenario_profile" not in st.session_state:
st.session_state.scenario_profile = None
if "whatif_mode" not in st.session_state:
st.session_state.whatif_mode = False
# Initialize chat histories for each category
categories_list = ["Finance", "Education", "Family", "Friends", "Weekend/Vacation"]
for cat in categories_list:
if f"chat_{cat}" not in st.session_state:
st.session_state[f"chat_{cat}"] = []
# Category icons
category_icons = {
"Finance": "πŸ’°",
"Education": "πŸ“š",
"Family": "πŸ‘¨β€πŸ‘©β€πŸ‘§",
"Friends": "πŸ‘₯",
"Weekend/Vacation": "πŸ–οΈ"
}
# Category selector
st.markdown("### 🎯 Focus Area")
selected = st.selectbox(
"cat",
categories_list,
index=categories_list.index(st.session_state.current_category),
format_func=lambda x: f"{category_icons[x]} {x}",
key="cat_select",
label_visibility="collapsed"
)
if selected != st.session_state.current_category:
st.session_state.current_category = selected
# Reset scenario mode when switching categories
st.session_state.scenario_mode = False
st.session_state.whatif_mode = False
st.session_state.scenario_profile = None
st.rerun()
category = st.session_state.current_category
st.markdown("---")
# Two-column layout
left_col, right_col = st.columns([2, 3])
with left_col:
render_left_panel(st.session_state, category)
with right_col:
chat_key = f"chat_{category}"
# Render chat panel (includes header, reset, messages, quick actions)
render_chat_panel(chat_key, category)
# Chat input
prompt = st.chat_input(f"Ask about {category.lower()}...")
# Handle seed chat (from Quick Actions or Ask buttons)
if st.session_state.seed_chat:
prompt = st.session_state.seed_chat
st.session_state.seed_chat = None
# Process user message
if prompt:
# Check if query contains a scenario (what-if question)
scenario_profile = check_query_for_scenario(prompt, st.session_state.profile)
if scenario_profile:
# Enter scenario mode
st.session_state.scenario_mode = True
st.session_state.scenario_profile = scenario_profile
# Add to chat history
st.session_state[chat_key].append({"role": "user", "content": prompt})
with st.spinner("🌊 Thinking..."):
ai_response = aqua_response(prompt, st.session_state.profile, category)
st.session_state[chat_key].append({"role": "assistant", "content": ai_response})
st.rerun()
# Footer
st.markdown("---")
st.markdown("<div style='text-align: center; color: #4a4a4a; font-size: 0.875rem;'><p>Built with πŸ’™ for GenZ</p></div>", unsafe_allow_html=True)