TanDooriCodEs/FAQ-Agentic-RAG-ChatBot
0
1import os2from pathlib import Path3import streamlit as st4import google.generativeai as genai5from google.generativeai.types import HarmCategory, HarmBlockThreshold6 7is not os.path.exists("data"):8 os.mkdir("data")9 10# Configure Google API11api_key = os.getenv("GOOGLE_API_KEY")12genai.configure(api_key=api_key)13 14# Initialize Gemini Pro model15model = genai.GenerativeModel('gemini-pro')16 17# Function to load FAQ from a text file18@st.cache_data19def load_faq(file_path):20 faq = {}21 with open(file_path, 'r') as f:22 content = f.read().split('\n\n')23 for item in content:24 if '?' in item:25 question, answer = item.split('\n', 1)26 faq[question.strip()] = answer.strip()27 return faq28 29# Function to format FAQ for display30def format_faq_for_display(faq):31 formatted_faq = ""32 for question, answer in faq.items():33 formatted_faq += f"**Q: {question}**\n\n{answer}\n\n---\n\n"34 return formatted_faq35 36# Function to generate response using Gemini Pro37def generate_response(query, context):38 prompt = f"""39 Context: {context}40 41 Human: {query}42 43 Assistant: Analyze the human's input and respond accordingly:44 1. If it's a question that cannot be answered based on the given context, respond exactly with: 'cannot response'45 2. If it's a greeting (e.g., "Hi", "Hello"), respond with: "Hello! How may I help you today?"46 3. If it's a short affirmation or acknowledgment (e.g., "Nice", "Okay", "Thanks"), respond with: "I'm glad I could assist you. Is there anything else you'd like to know?"47 4. If it's a question that can be answered based on the context, provide a concise and relevant answer.48 5. If it's any other respose then answer with: "I'm here to help. What would you like to know?"49 """50 51 response = model.generate_content(prompt)52 return response.text53 54# Function to answer questions55def answer_question(user_query, faq):56 # Combine all FAQ content for context57 context = "\n".join([f"Q: {q}\nA: {a}" for q, a in faq.items()])58 59 # Generate response using Gemini Pro60 answer = generate_response(user_query, context)61 62 if "don't have enough information" in answer.lower():63 return None64 return answer65 66# WhatsApp fallback function67def whatsapp_fallback(query):68 whatsapp_link = "https://wa.link/m8ghvf" # Replace with your actual WhatsApp Link69 return f"I not able to answer your question: '{query}'. Please contact our support via WhatsApp link: {whatsapp_link}."70 71# Streamlit app72def main():73 st.title("FAQ Chatbot")74 75 # Load FAQ76 faq_path = Path('data/FAQ.txt')77 if not faq_path.exists():78 st.error(f"Error: FAQ file not found at {faq_path}. Please make sure the file exists.")79 return80 81 faq = load_faq(faq_path)82 83 # Display FAQ in sidebar84 st.sidebar.title("Frequently Asked Questions")85 formatted_faq = format_faq_for_display(faq)86 st.sidebar.markdown(formatted_faq)87 88 # Initialize chat history89 if "messages" not in st.session_state:90 st.session_state.messages = []91 92 # Display chat messages from history on app rerun93 for message in st.session_state.messages:94 with st.chat_message(message["role"]):95 st.markdown(message["content"])96 97 # React to user input98 if prompt := st.chat_input("What is your question?"):99 # Display user message in chat message container100 st.chat_message("user").markdown(prompt)101 # Add user message to chat history102 st.session_state.messages.append({"role": "user", "content": prompt})103 104 response = answer_question(prompt, faq)105 106 if response != "cannot response":107 # Display assistant response in chat message container108 with st.chat_message("assistant"):109 st.markdown(response)110 # Add assistant response to chat history111 st.session_state.messages.append({"role": "assistant", "content": response})112 else:113 fallback_message = whatsapp_fallback(prompt)114 # Display fallback message in chat message container115 with st.chat_message("assistant"):116 st.markdown(fallback_message)117 # Add fallback message to chat history118 st.session_state.messages.append({"role": "assistant", "content": fallback_message})119 120if __name__ == "__main__":121 main()