import streamlit as st import base64 import uuid import sys from io import StringIO from config import vector_collection from ingest_data import ingest_data from planning import generate_response, tool_selector from dotenv import load_dotenv # Load environment variables load_dotenv() # Set up page configuration st.set_page_config(page_title="Database Memory Agent", layout="wide") # Initialize session state variables if "session_id" not in st.session_state: st.session_state.session_id = str(uuid.uuid4())[:8] if "messages" not in st.session_state: st.session_state.messages = [] if "vector_index_ready" not in st.session_state: st.session_state.vector_index_ready = False if "data_ingested" not in st.session_state: st.session_state.data_ingested = False session_id = st.session_state.session_id def reset_chat(): """Reset chat history.""" st.session_state.messages = [] st.session_state.session_id = str(uuid.uuid4())[:8] def display_pdf(file): """Display PDF preview in sidebar.""" st.markdown("### PDF Preview") base64_pdf = base64.b64encode(file.read()).decode("utf-8") pdf_display = f"""""" st.markdown(pdf_display, unsafe_allow_html=True) def check_vector_index(): """Check if vector index exists and is ready.""" if st.session_state.vector_index_ready: return True try: existing_indexes = list(vector_collection.list_search_indexes("vector_index")) if existing_indexes and existing_indexes[0].get("queryable"): st.session_state.vector_index_ready = True return True except Exception as e: st.error(f"Error checking vector index: {e}") return False return False def process_pdf_upload(uploaded_file): """Process uploaded PDF and ingest into MongoDB.""" with st.spinner("🔄 Processing..."): try: old_stdout = sys.stdout sys.stdout = StringIO() try: ingest_data() finally: sys.stdout = old_stdout if check_vector_index(): st.session_state.data_ingested = True st.success("✅ Document processed and ready for queries!") return True return False except Exception as e: st.error(f"Error processing PDF: {str(e)}") return False def ingest_sample_data(): """Ingest sample MongoDB earnings report.""" try: with st.spinner("🔄 Processing..."): # Suppress print output from ingest_data() old_stdout = sys.stdout sys.stdout = StringIO() try: ingest_data() finally: sys.stdout = old_stdout # ingest_data() already creates the index, just check if it's ready if check_vector_index(): st.session_state.data_ingested = True st.success("✅ Sample data ingested and ready for queries!") return True return False except Exception as e: st.error(f"Error ingesting sample data: {str(e)}") return False # Sidebar for configuration and document upload with st.sidebar: st.header("🔧 Configuration") st.markdown("**Session ID:**") st.code(session_id) if st.button("🔄 New Session"): reset_chat() st.rerun() st.markdown("---") # Document upload section st.header("📄 Upload Document") st.markdown("Upload a PDF document or use sample data") col1, col2 = st.columns(2) with col1: if st.button("📊 Use Sample Data", use_container_width=True): ingest_sample_data() with col2: if st.button("🗑️ Clear Data", use_container_width=True): st.session_state.data_ingested = False st.session_state.vector_index_ready = False st.info("Data cleared. Upload a new document to continue.") uploaded_file = st.file_uploader("Or upload your PDF file", type="pdf") if uploaded_file: if process_pdf_upload(uploaded_file): display_pdf(uploaded_file) st.markdown("---") # System status st.header("📊 System Status") if st.session_state.data_ingested: st.success("🟢 Data Ready") else: st.info("🔵 No Data Loaded") if st.session_state.vector_index_ready: st.success("🟢 Vector Index Ready") else: st.warning("🟡 Vector Index Not Ready") # Main chat interface col1, col2 = st.columns([6, 1]) with col1: st.markdown('''
" "Database Memory Agent • Built with Streamlit, MongoDB Atlas Vector Search, and Voyage AI" "
", unsafe_allow_html=True )