import streamlit as st from PyPDF2 import PdfReader import langchain from textwrap import dedent import pandas as pd from langchain_community.callbacks import StreamlitCallbackHandler from langchain_openai import ChatOpenAI from langchain_community.chat_models import ChatGooglePalm from langchain_community.embeddings import HuggingFaceEmbeddings from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.vectorstores.faiss import FAISS from langchain.prompts import PromptTemplate from langchain.memory import ConversationBufferMemory import tempfile from langchain.document_loaders.csv_loader import CSVLoader from langchain.document_loaders.pdf import PyPDFLoader from langchain.document_loaders.word_document import UnstructuredWordDocumentLoader from langchain.chains.question_answering import load_qa_chain from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler from langchain.agents import load_tools import os from io import BytesIO from langdetect import detect from gtts import gTTS from langchain.prompts import ( ChatPromptTemplate ) #api_key2 = st.secrets["OPENAI_API_KEY"] os.environ["GOOGLE_API_KEY"] = "AIzaSyD29fEos3V6S2L-AGSQgNu03GqZEIgJads" st.set_page_config(page_title='Personal Chatbot', page_icon='books') st.header('Knowledge Query Assistant') st.write("Upload your file to begin a chat, or ask any general questions you have") st.sidebar.title('Options') st.sidebar.subheader("Please Choose the AI Engine") use_google = st.sidebar.checkbox("Use Free AI", value =True) use_openai = st.sidebar.checkbox("Use OpenAI with your API Key") openai_api_key = st.sidebar.text_input("Enter your OpenAI API Key:", type="password") def choose_llm(): try: if use_google and use_openai: st.sidebar.warning("Please choose only one AI engine.") st.warning("Please choose only one AI engine.") elif use_google: llm = ChatGooglePalm(temperature=0.1) elif use_openai: if not openai_api_key: st.sidebar.warning("Please provide your OpenAI API Key.") st.warning("Please provide your OpenAI API Key.") llm = ChatOpenAI(api_key=openai_api_key, temperature=0.1) return llm except Exception as e: " " llm = choose_llm() if llm: st.sidebar.success("AI Engine selected") else: st.sidebar.warning("Please choose an AI engine.") @st.cache_resource(show_spinner=False) def processing_csv_pdf_docx(uploaded_file): with st.spinner(text="Embedding Your Files"): # Read text from the uploaded PDF file data = [] for file in uploaded_file: split_tup = os.path.splitext(file.name) file_extension = split_tup[1] if file_extension == ".pdf": with tempfile.NamedTemporaryFile(delete=False) as tmp_file1: tmp_file1.write(file.getvalue()) tmp_file_path1 = tmp_file1.name loader = PyPDFLoader(file_path=tmp_file_path1) documents = loader.load() text_splitter = RecursiveCharacterTextSplitter(chunk_size=2000, chunk_overlap=50) data += text_splitter.split_documents(documents) if file_extension == ".csv": with tempfile.NamedTemporaryFile(delete=False) as tmp_file: tmp_file.write(file.getvalue()) tmp_file_path = tmp_file.name loader = CSVLoader(file_path=tmp_file_path, encoding="utf-8", csv_args={ 'delimiter': ','}) documents = loader.load() text_splitter = RecursiveCharacterTextSplitter(chunk_size=2000, chunk_overlap=50) data += text_splitter.split_documents(documents) st.sidebar.header(f"Data-{file.name}") data1 = pd.read_csv(tmp_file_path) st.sidebar.dataframe(data1) if file_extension == ".docx": with tempfile.NamedTemporaryFile(delete=False) as tmp_file: tmp_file.write(file.getvalue()) tmp_file_path = tmp_file.name loader = UnstructuredWordDocumentLoader(file_path=tmp_file_path) documents = loader.load() text_splitter = RecursiveCharacterTextSplitter(chunk_size=2000, chunk_overlap=50) data += text_splitter.split_documents(documents) # Download embeddings from GooglePalm embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2") #embeddings = GooglePalmEmbeddings() #embeddings = OpenAIEmbeddings() # Create a FAISS index from texts and embeddings vectorstore = FAISS.from_documents(data, embeddings) #vectorstore.save_local("./faiss") return vectorstore with st.sidebar: uploaded_file = st.file_uploader("Upload your files", help="Multiple Files are Supported", type=['pdf', 'docx', 'csv'], accept_multiple_files= True) if not uploaded_file: st.warning("Upload your file(s) to start chatting!") if 'history' not in st.session_state: st.session_state['history'] = [] if "messages" not in st.session_state or st.sidebar.button("Clear conversation history"): st.session_state["messages"]= [] st.sidebar.subheader('Created by Engr. Muhammad Asadullah') # Adding links to social accounts st.sidebar.markdown("[LinkedIn](https://www.linkedin.com/in/asad18/)") st.sidebar.markdown("[GitHub](https://github.com/TechAsad)") st.sidebar.markdown("[Fiverr](https://www.fiverr.com/promptengr?source=gig_page&gigs=slug%3Acreate-streamlit-and-gradio-web-apps-for-ai-and-data-analysis%2Cpckg_id%3A1&is_choice=true)") st.sidebar.markdown("[Website](https://tenlancer.com/)") ########--Save PDF--######## def text_to_audio(response, lang): audio_buffer = BytesIO() audio_file = gTTS(text=response, lang=lang, slow=False) audio_file.write_to_fp(audio_buffer) audio_buffer.seek(0) return audio_buffer def main(): try: if (use_openai and openai_api_key) or use_google: if uploaded_file: db = processing_csv_pdf_docx(uploaded_file) for file in uploaded_file: st.success(f'Your File: {file.name} is Embedded', icon="✅") for msg in st.session_state.messages: st.chat_message(msg["role"]).write(msg["content"]) #if msg["role"] == "Assistant": # st.chat_message(msg["role"]).audio(msg["audio_content"], format='audio/wav') #st.audio(audio_msg, format='audio/mp3').audio(audio_msg) if prompt := st.chat_input(placeholder="Type your question!"): st.session_state.messages.append({"role": "user", "content": prompt}) st.chat_message("user").write(prompt) memory = ConversationBufferMemory(memory_key="chat_history", input_key="question", human_prefix= "", ai_prefix= "") user_message = {"role": "user", "content": prompt} for i in range(0, len(st.session_state.messages), 2): if i + 1 < len(st.session_state.messages): user_prompt = st.session_state.messages[i] ai_res = st.session_state.messages[i + 1] current_role = user_prompt["role"] current_content = user_prompt["content"] next_role = ai_res["role"] next_content = ai_res["content"] # Concatenate role and content for context and output user = f"{current_role}: {current_content}" ai = f"{next_role}: {next_content}" memory.save_context({"question": user}, {"output": ai}) # Get user input -> Generate the answer greetings = ['Hey', 'Hello', 'hi', 'hello', 'hey', 'helloo', 'hellooo', 'g morning', 'gmorning', 'good morning', 'morning', 'good day', 'good afternoon', 'good evening', 'greetings', 'greeting', 'good to see you', 'its good seeing you', 'how are you', "how're you", 'how are you doing', "how ya doin'", 'how ya doin', 'how is everything', 'how is everything going', "how's everything going", 'how is you', "how's you", 'how are things', "how're things", 'how is it going', "how's it going", "how's it goin'", "how's it goin", 'how is life been treating you', "how's life been treating you", 'how have you been', "how've you been", 'what is up', "what's up", 'what is cracking', "what's cracking", 'what is good', "what's good", 'what is happening', "what's happening", 'what is new', "what's new", 'what is neww', "g’day", 'howdy'] compliment = ['thank you', 'thanks', 'thanks a lot', 'thanks a bunch', 'great', 'ok', 'ok thanks', 'okay', 'great', 'awesome', 'nice'] prompt_template =dedent(r""" You are an informative chatbot designed to assist users with queries specifically related to the 2024 Summer Olympics in Paris. Your purpose is to provide accurate information sourced from a document with a vector database, ensuring relevance and reliability in your responses. Respond with humility and avoid speculative or hypothetical answers. Use the provided context to formulate concise responses, staying within 100 words, and refrain from adding unnecessary information. Ensure that your answers are directly related to the user's query and do not deviate from the provided context. this is the context from study material: --------- {context} --------- Current Conversation: --------- {chat_history} --------- Question: {question} Helpful Answer: """) PROMPT = PromptTemplate( template=prompt_template, input_variables=["context", "question", "chat_history"] ) # Run the question-answering chain # Load question-answering chain chain = load_qa_chain(llm=llm, verbose= True, prompt = PROMPT,memory=memory, chain_type="stuff") #chain = load_qa_chain(ChatOpenAI(temperature=0.9, model="gpt-3.5-turbo-0613", streaming=True) , verbose= True, prompt = PROMPT, memory=memory,chain_type="stuff") with st.chat_message("Assistant"): st_cb = StreamlitCallbackHandler(st.container()) if prompt.lower() in greetings: response = 'Hi, how are you? I am here to help you get information from your file. How can I assist you?' lang = "en" audio_buffer = text_to_audio(response, lang) #st.audio(audio_buffer, format='audio/mp3') st.session_state.messages.append({"role": "Assistant", "content": response}) #st.session_state.messages.append({"role": "Assistant", "content": response, "audio_content": audio_buffer}) elif prompt.lower() in compliment: response = 'My pleasure! If you have any more questions, feel free to ask.' lang = "en" audio_buffer = text_to_audio(response, lang) #st.audio(audio_buffer, format='audio/mp3') st.session_state.messages.append({"role": "Assistant", "content": response}) #st.session_state.messages.append({"role": "Assistant", "content": response, "audio_content": audio_buffer}) elif uploaded_file: with st.spinner('Bot is typing ...'): docs = db.similarity_search(prompt, k=5, fetch_k=10) response = chain.run(input_documents=docs, question=prompt) lang = detect(response) audio_buffer = text_to_audio(response, lang) # st.audio(audio_buffer, format='audio/mp3') #st.session_state.audio.append({"role": "Assistant", "audio": audio_buffer}) #st.session_state.messages.append({"role": "Assistant", "content": response, "audio_content": audio_buffer}) st.session_state.messages.append({"role": "Assistant", "content": response}) assistant_message = {"role": "assistant", "content": response} else: with st.spinner('Bot is typing ...'): prompt_chat = ChatPromptTemplate.from_template("you are a helpful assistant, Answer the question with your knowledge.\n\n current conversation: {chat_history} \n\n Question: {question} \n\n Answer:") chain = prompt_chat | llm response = chain.invoke({"chat_history": memory, "question": prompt}).content lang = detect(response) #audio_buffer = text_to_audio(response, lang) #st.audio(audio_buffer, format='audio/mp3') #st.session_state.audio.append({"role": "Assistant", "audio": audio_buffer}) #st.session_state.messages.append({"role": "Assistant", "content": response, "audio_content": audio_buffer}) st.session_state.messages.append({"role": "Assistant", "content": response}) assistant_message = {"role": "assistant", "content": response} st.write(response) #st.audio(audio_buffer, format='audio/wav') except Exception as e: "Sorry, there was a problem. A corrupted file or;" if use_google: "Google PaLM AI only take English Data and Questions. Or the AI could not find the answer in your provided document." elif use_openai: "Please check your OpenAI API key" hide_streamlit_style = """ """ st.markdown(hide_streamlit_style, unsafe_allow_html=True) if __name__ == '__main__': main()