import time import logging from pathlib import Path import streamlit as st import chat_engine from ingest_data_opens import process_and_index_pdf_page_by_page, save_uploaded_file from config import ( STREAM_CHAT, INDEX_NAME ) # Initialize session state def initialize_session_state(): if "max_tokens" not in st.session_state: st.session_state.max_tokens = 1024 if "temperature" not in st.session_state: st.session_state.temperature = 0.0 if "top_k" not in st.session_state: st.session_state.top_k = 3 if "top_n" not in st.session_state: st.session_state.top_n = 3 if "messages" not in st.session_state: st.session_state.messages = [] if "question_count" not in st.session_state: st.session_state.question_count = 0 if "enable_rag" not in st.session_state: st.session_state.enable_rag = True if "similarity" not in st.session_state: st.session_state.similarity = 0.5 initialize_session_state() st.logo("Oracle-Logo.png") # Set the configuration for the Streamlit app st.set_page_config(page_title="OpenSearch Chatbot Assistant", layout="wide", page_icon=":robot_face:") upload_dir = Path("data/unprocessed") upload_dir.mkdir(parents=True, exist_ok=True) # Title for the sidebar st.markdown("

OpenSearch Chatbot Assistant

", unsafe_allow_html=True) # Modify the conversation reset function to conditionally create the chat engine def reset_conversation(): st.session_state.messages = [] st.session_state.question_count = 0 # Function to handle form submission def handle_form_submission(): st.session_state.update({ "max_tokens": st.session_state.max_tokens, "temperature": st.session_state.temperature, "top_k": st.session_state.top_k, "top_n": st.session_state.top_n, "enable_rag": st.session_state.enable_rag, "similarity": st.session_state.similarity }) reset_conversation() # Streamlit sidebar form for adjusting model parameters def render_sidebar_forms(): with st.sidebar.form(key="input-form"): st.session_state.enable_rag = st.checkbox('Enable RAG', value=True, label_visibility="visible") st.session_state.max_tokens = st.number_input('Maximum Tokens', min_value=512, max_value=1024, step=25, value=st.session_state.max_tokens) st.session_state.temperature = st.number_input('Temperature', min_value=0.0, max_value=1.0, step=0.1, value=st.session_state.temperature) st.session_state.similarity = st.number_input('Similarity Score', min_value=0.0, max_value=1.0, step=0.05, value=st.session_state.similarity) st.session_state.top_k = st.slider("TOP_K", 1, 10, step=1, value=st.session_state.top_k) st.session_state.top_n = st.slider("TOP_N", 1, 10, step=1, value=st.session_state.top_n) submitted_sidebar = st.form_submit_button("Submit", type="primary", on_click=handle_form_submission, use_container_width=True) return submitted_sidebar # Render the sidebar forms render_sidebar_forms() # Display chat messages in the Streamlit app def display_chat_messages(): for message in st.session_state.messages: with st.chat_message(message["role"]): st.markdown(message["content"]) # Function to handle non-streaming output def no_stream_output(response): if st.session_state.enable_rag: output = response st.markdown(output) else: output = response return output # Function to handle streaming output def stream_output(response): text_placeholder = st.empty() output = "" for text in response: output += text text_placeholder.markdown(output, unsafe_allow_html=True) return output # Main function to run the Streamlit app def main(): _, c1 = st.columns([5, 2]) c1.button("Clear Chat History", type="primary", on_click=reset_conversation) with st.sidebar.form(key="file-uploader-form", clear_on_submit=True): uploaded_files = st.file_uploader("Upload PDF Document", accept_multiple_files=True, type=['pdf'], label_visibility="collapsed") upload_button = st.form_submit_button("Upload", type="primary", use_container_width=True, on_click=reset_conversation) if upload_button and uploaded_files: if not isinstance(uploaded_files, list): uploaded_files = [uploaded_files] logging.info("Uploading file") for uploaded_file in uploaded_files: # Save the uploaded file to a directory file_path = save_uploaded_file(uploaded_file, upload_dir) # Call the function to process and index the PDF process_and_index_pdf_page_by_page(file_path, INDEX_NAME) st.success(f"Uploaded and indexed {uploaded_file.name} successfully!") # Configure logging logger = logging.getLogger("ConsoleLogger") if not logger.handlers: logger.setLevel(logging.INFO) handler = logging.StreamHandler() handler.setLevel(logging.INFO) formatter = logging.Formatter("%(asctime)s - %(message)s") handler.setFormatter(formatter) logger.addHandler(handler) logger.propagate = False # Initialize session state if not already done if "messages" not in st.session_state: reset_conversation() display_chat_messages() # Input for the user question question = st.chat_input("Hello, how can I help you?") if question: st.chat_message("user").markdown(question) st.session_state.messages.append({"role": "user", "content": question}) try: logger.info("Calling RAG chain..") logger.info( f"top_k= {st.session_state.top_k},max_tokens= {st.session_state.max_tokens}, temperature= {st.session_state.temperature},top_n= {st.session_state.top_n},enable_rag= {st.session_state.enable_rag},similarity = {st.session_state.similarity}") with st.spinner("Waiting..."): time_start = time.time() st.session_state.question_count += 1 logger.info("") logger.info(f"Question no. {st.session_state.question_count} is {question}") # Generate response using the chat engine if st.session_state.enable_rag: if STREAM_CHAT: logger.info("response from STREAM_CHAT.") response = chat_engine.search_opensearch(question, INDEX_NAME, st.session_state.top_k) else: logger.info("response from without STREAM_CHAT.") response = chat_engine.search_opensearch(question, INDEX_NAME, st.session_state.top_k) else: logger.info("response without RAG..") response = chat_engine.llm_chat(question) # # Debug the response print(f"Response type: {type(response)}") if isinstance(response, dict): print(f"Response keys: {response.keys()}") time_elapsed = time.time() - time_start logger.info(f"Elapsed time: {round(time_elapsed, 1)} sec.") # Display response from the assistant with st.chat_message("assistant"): if st.session_state.enable_rag and STREAM_CHAT: output = stream_output(response) else: output = no_stream_output(response) st.session_state.messages.append({"role": "assistant", "content": output}) except Exception as e: logger.error("An error occurred: " + str(e)) st.error("An error occurred: " + str(e)) # Force Streamlit to immediately update the UI if not st.session_state.enable_rag: st.rerun() # Entry point for the script if __name__ == "__main__": main()