Spaces:
Sleeping
Sleeping
Fix embedding tokens: soft blue instead of viridis black/green; make toggles, sidebar button, checkboxes more visible in light mode
850edb3
| import streamlit as st | |
| from streamlit_option_menu import option_menu | |
| import os | |
| import sys | |
| import base64 | |
| from pathlib import Path | |
| # Import the page modules. | |
| from attribution_analysis.attribution_analysis_page import show_attribution_analysis | |
| from function_vectors.function_vectors_page import show_function_vectors_page | |
| from circuit_analysis.circuit_trace_page import show_circuit_trace_page | |
| from utilities.welcome_page import show_welcome_page | |
| from utilities.utils import set_seed | |
| from utilities.localization import initialize_localization, tr, language_selector | |
| from utilities.feedback_survey import get_next_participant_id | |
| # Import functions with persisted cache to clear them when needed. | |
| from attribution_analysis.attribution_analysis_page import ( | |
| get_influential_docs, | |
| _cached_explain_heatmap as attr_explain_heatmap, | |
| generate_all_attribution_analyses | |
| ) | |
| from circuit_analysis.circuit_trace_page import explain_circuit_visualization | |
| from function_vectors.function_vectors_page import ( | |
| _perform_analysis as fv_perform_analysis, | |
| _explain_with_llm as fv_explain_llm | |
| ) | |
| # Set the page configuration. | |
| st.set_page_config( | |
| page_title="LLM Analysis Suite", | |
| page_icon="π§ ", | |
| layout="wide", | |
| initial_sidebar_state="expanded" | |
| ) | |
| # Set TOKENIZERS_PARALLELISM to false to avoid warnings. | |
| os.environ["TOKENIZERS_PARALLELISM"] = "false" | |
| # Suppress a harmless error on macOS. | |
| os.environ["OBJC_DISABLE_INITIALIZE_FORK_SAFETY"] = "YES" | |
| # Initialize theme in session state | |
| if 'theme_mode' not in st.session_state: | |
| st.session_state.theme_mode = 'dark' | |
| _is_light = st.session_state.theme_mode == 'light' | |
| # ββ Shared CSS (both themes) ββββββββββββββββββββββββββββββββββββββββββββββ | |
| st.markdown(""" | |
| <style> | |
| [data-testid="stToolbar"] { visibility: hidden; } | |
| .main-header { | |
| font-size: 3rem; | |
| text-align: center; | |
| margin-bottom: 2rem; | |
| } | |
| .stButton > button { | |
| background-color: #2f3f70; | |
| color: #f5f7fb; | |
| border-radius: 20px; | |
| border: none; | |
| padding: 0.5rem 2rem; | |
| font-weight: bold; | |
| box-shadow: 0 10px 20px rgba(47, 63, 112, 0.25); | |
| } | |
| .stButton > button:hover { | |
| background-color: #3a4c86; | |
| color: #ffffff; | |
| } | |
| .stTextArea > div > div > textarea { border-radius: 10px; } | |
| .attribution-info { | |
| background-color: rgba(47, 63, 112, 0.82); | |
| color: #f5f7fb; | |
| padding: 1rem; | |
| border-radius: 10px; | |
| margin: 1rem 0; | |
| border-left: 4px solid #dcae36; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # ββ Light-mode CSS overrides ββββββββββββββββββββββββββββββββββββββββββββββ | |
| if _is_light: | |
| st.markdown(""" | |
| <style> | |
| /* ββ Streamlit chrome ββββββββββββββββββββββββββββββββββββββ */ | |
| [data-testid="stAppViewContainer"], | |
| [data-testid="stApp"], | |
| .main .block-container { | |
| background-color: #ffffff !important; | |
| color: #1b1b2f !important; | |
| } | |
| [data-testid="stSidebar"], | |
| [data-testid="stSidebar"] > div:first-child { | |
| background-color: #f0f2f6 !important; | |
| color: #1b1b2f !important; | |
| } | |
| [data-testid="stHeader"] { | |
| background-color: #ffffff !important; | |
| } | |
| /* ββ Global text color reset βββββββββββββββββββββββββββββββ */ | |
| .main-header { color: #1b1b2f !important; } | |
| h1, h2, h3, h4, h5, h6 { color: #1b1b2f !important; } | |
| [data-testid="stMarkdownContainer"], | |
| [data-testid="stMarkdownContainer"] p, | |
| [data-testid="stMarkdownContainer"] li, | |
| [data-testid="stMarkdownContainer"] strong, | |
| [data-testid="stMarkdownContainer"] em, | |
| [data-testid="stMetricValue"], | |
| [data-testid="stMetricLabel"], | |
| [data-testid="stMetricDelta"], | |
| label, .stSelectbox label, .stRadio label { | |
| color: #1b1b2f !important; | |
| } | |
| /* ββ Inputs & widgets ββββββββββββββββββββββββββββββββββββββ */ | |
| .stTextInput > div > div > input, | |
| .stTextArea > div > div > textarea, | |
| [data-baseweb="select"], | |
| [data-baseweb="select"] > div, | |
| .stSelectbox > div > div, | |
| .stMultiSelect > div > div { | |
| background-color: #ffffff !important; | |
| color: #1b1b2f !important; | |
| border-color: #c8cdd5 !important; | |
| } | |
| [data-baseweb="select"] span, | |
| [data-baseweb="select"] div { | |
| color: #1b1b2f !important; | |
| } | |
| /* dropdown lists */ | |
| [data-baseweb="popover"], | |
| [data-baseweb="menu"], | |
| ul[role="listbox"], | |
| ul[role="listbox"] li { | |
| background-color: #ffffff !important; | |
| color: #1b1b2f !important; | |
| } | |
| ul[role="listbox"] li:hover { | |
| background-color: #e8eaee !important; | |
| } | |
| /* ββ Tabs ββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .stTabs [data-baseweb="tab-list"] { | |
| background-color: transparent !important; | |
| } | |
| .stTabs [data-baseweb="tab"] { | |
| color: #1b1b2f !important; | |
| } | |
| /* ββ Expanders βββββββββββββββββββββββββββββββββββββββββββββ */ | |
| [data-testid="stExpander"], | |
| [data-testid="stExpander"] summary, | |
| [data-testid="stExpander"] > div { | |
| background-color: #f5f6fa !important; | |
| color: #1b1b2f !important; | |
| } | |
| /* ββ option_menu sidebar override ββββββββββββββββββββββββββ */ | |
| .nav-link { color: #1b1b2f !important; } | |
| .nav-link.active, .nav-link:hover { | |
| background-color: #2f3f70 !important; | |
| color: #ffffff !important; | |
| } | |
| /* ββ Plotly charts ββββββββββββββββββββββββββββββββββββββββββ */ | |
| .js-plotly-plot .main-svg { | |
| background-color: transparent !important; | |
| } | |
| /* ββ Info & attribution boxes βββββββββββββββββββββββββββββββ */ | |
| .attribution-info { | |
| background-color: rgba(47, 63, 112, 0.08) !important; | |
| color: #1b1b2f !important; | |
| } | |
| /* ββ Chat messages ββββββββββββββββββββββββββββββββββββββββββ */ | |
| [data-testid="stChatMessage"] { | |
| background-color: #f5f6fa !important; | |
| color: #1b1b2f !important; | |
| } | |
| /* ββ Buttons (light override) ββββββββββββββββββββββββββββββ */ | |
| .stButton > button { | |
| background-color: #e8ecf6 !important; | |
| color: #2f3f70 !important; | |
| border: 1px solid #c8cdd5 !important; | |
| box-shadow: 0 2px 6px rgba(0,0,0,0.06) !important; | |
| } | |
| .stButton > button:hover { | |
| background-color: #d8dff0 !important; | |
| color: #2f3f70 !important; | |
| } | |
| /* ββ Download buttons ββββββββββββββββββββββββββββββββββββββ */ | |
| .stDownloadButton > button { | |
| background-color: #e8ecf6 !important; | |
| color: #2f3f70 !important; | |
| border: 1px solid #c8cdd5 !important; | |
| box-shadow: 0 2px 6px rgba(0,0,0,0.06) !important; | |
| } | |
| .stDownloadButton > button:hover { | |
| background-color: #d8dff0 !important; | |
| color: #2f3f70 !important; | |
| } | |
| /* ββ Chat input bar & bottom container βββββββββββββββββββ */ | |
| [data-testid="stBottom"], | |
| [data-testid="stBottom"] > div, | |
| [data-testid="stChatFloatingInputContainer"], | |
| .stChatFloatingInputContainer { | |
| background-color: #ffffff !important; | |
| } | |
| [data-testid="stChatInput"], | |
| [data-testid="stChatInput"] textarea, | |
| [data-testid="stChatInput"] > div { | |
| background-color: #f5f6fa !important; | |
| color: #1b1b2f !important; | |
| border-color: #c8cdd5 !important; | |
| } | |
| /* ββ Toggle switches ββββββββββββββββββββββββββββββββββββββββ */ | |
| [data-testid="stToggle"] label, | |
| [data-testid="stToggle"] span { | |
| color: #1b1b2f !important; | |
| } | |
| [data-testid="stToggle"] [role="checkbox"] { | |
| border: 2px solid #2f3f70 !important; | |
| } | |
| /* ββ Sidebar collapse button ββββββββββββββββββββββββββββββββ */ | |
| [data-testid="stSidebar"] button[kind="header"], | |
| [data-testid="collapsedControl"] button, | |
| button[data-testid="stBaseButton-headerNoPadding"] { | |
| color: #1b1b2f !important; | |
| background-color: #e8ecf6 !important; | |
| border: 1px solid #c8cdd5 !important; | |
| border-radius: 8px !important; | |
| } | |
| /* ββ Slider thumb & track βββββββββββββββββββββββββββββββββββ */ | |
| [data-testid="stSlider"] label { | |
| color: #1b1b2f !important; | |
| } | |
| /* ββ Checkbox βββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .stCheckbox label span { | |
| color: #1b1b2f !important; | |
| } | |
| /* ββ Option menu (sidebar nav) ββββββββββββββββββββββββββββββ */ | |
| [data-testid="stSidebar"] iframe + div, | |
| [data-testid="stSidebar"] .nav { | |
| background-color: #f0f2f6 !important; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| def main(): | |
| # Main function to run the app. | |
| set_seed() | |
| initialize_localization() | |
| # The language selector is now on the welcome page. | |
| # We don't need it in the sidebar of the main app. | |
| # Check if the user has submitted the welcome form. | |
| if "user_info" not in st.session_state or not st.session_state.user_info.get("form_submitted"): | |
| show_welcome_page() | |
| else: | |
| # If the form is submitted, show the main application. | |
| # Assign a participant ID if one doesn't exist. | |
| if 'participant_id' not in st.session_state: | |
| st.session_state.participant_id = get_next_participant_id() | |
| # Initialize session state for feedback forms. | |
| if 'attr_feedback_submitted' not in st.session_state: | |
| st.session_state.attr_feedback_submitted = False | |
| if 'fv_feedback_submitted' not in st.session_state: | |
| st.session_state.fv_feedback_submitted = False | |
| logo_path = Path(__file__).parent / "LOGO" / "Logo.png" | |
| if logo_path.exists(): | |
| with open(logo_path, "rb") as logo_file: | |
| logo_base64 = base64.b64encode(logo_file.read()).decode("utf-8") | |
| st.markdown( | |
| f""" | |
| <div style="text-align: center; margin-bottom: 2rem;"> | |
| <img src="data:image/png;base64,{logo_base64}" alt="{tr('llm_analysis_suite')}" style="max-width: 320px; width: 60%; min-width: 200px;" /> | |
| </div> | |
| """, | |
| unsafe_allow_html=True | |
| ) | |
| else: | |
| st.markdown(f"<h1 class='main-header'>{tr('llm_analysis_suite')}</h1>", unsafe_allow_html=True) | |
| with st.sidebar: | |
| # Theme toggle switch at the top of sidebar | |
| light_on = st.toggle( | |
| tr('light_mode'), | |
| value=(st.session_state.theme_mode == 'light'), | |
| key="theme_toggle" | |
| ) | |
| new_mode = 'light' if light_on else 'dark' | |
| if new_mode != st.session_state.theme_mode: | |
| st.session_state.theme_mode = new_mode | |
| st.rerun() | |
| _menu_styles = { | |
| "container": {"background-color": "#f0f2f6"}, | |
| "icon": {"color": "#4a5568"}, | |
| "nav-link": {"color": "#1b1b2f", "--hover-color": "#e2e4ea"}, | |
| "nav-link-selected": {"background-color": "#2f3f70", "color": "#ffffff"}, | |
| "menu-title": {"color": "#1b1b2f"}, | |
| "menu-icon": {"color": "#4a5568"}, | |
| } if _is_light else {} | |
| selected_page = option_menu( | |
| menu_title=tr('main_menu'), | |
| options=[tr('attribution_analysis'), tr('function_vectors'), tr('circuit_tracing')], | |
| icons=['search', 'cpu', 'diagram-3'], | |
| menu_icon='cast', | |
| default_index=0, | |
| styles=_menu_styles | |
| ) | |
| if selected_page == tr('attribution_analysis'): | |
| show_attribution_analysis() | |
| elif selected_page == tr('function_vectors'): | |
| show_function_vectors_page() | |
| elif selected_page == tr('circuit_tracing'): | |
| show_circuit_trace_page() | |
| if __name__ == "__main__": | |
| main() |