import sys
import os
import streamlit as st
import configparser
import datetime
import atexit
import pickle
import streamlit.components.v1 as components
import uuid # Import the uuid module
import re
import base64
import streamlit.components.v1 as components
config = configparser.ConfigParser()
# Set page to wide mode
st.set_page_config(layout="wide")
from gradio.components import Textbox
from langchain_community.vectorstores import Chroma
from langchain.chains import ConversationalRetrievalChain
from langchain.text_splitter import CharacterTextSplitter
from langchain.memory import ConversationBufferMemory
from langchain_community.llms import OpenAI
from langchain_community.chat_models import ChatOpenAI
from langchain_community.embeddings import OpenAIEmbeddings
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
from langchain.prompts.prompt import PromptTemplate
from langchain.prompts import SystemMessagePromptTemplate
from langchain.prompts import HumanMessagePromptTemplate
from langchain.prompts import ChatMessagePromptTemplate
from langchain.prompts import ChatPromptTemplate
# Function to get base64 encoding of an image
def get_image_base64(path):
with open(path, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read()).decode()
return encoded_string
icon_base64 = get_image_base64("clipboard.png")
# Function to create a copy-to-clipboard button
def create_copy_button(text_to_copy):
button_uuid = str(uuid.uuid4()).replace("-", "")
button_id = re.sub('\D', '', button_uuid)
copy_js = f"""
"""
return copy_js
# Retrieve the API key from the environment variables
api_key = os.getenv("OPENAI_API_KEY")
# Check if the API key is available, if not, raise an error
if api_key is None:
raise ValueError("API key not found. Ensure that the OPENAI_API_KEY environment variable is set.")
# Use the API key as needed in your application
os.environ["OPENAI_API_KEY"] = api_key
# Create a Chroma database instance from the SQLite file
vectordb = Chroma(persist_directory="./data", embedding_function=OpenAIEmbeddings())
# Define the system message template
system_template = """Use only the following pieces of context to answer the question at the end.
If you don't know the answer, just say that you don't know. Don't try to make up an answer.
Always answer in Englsih. Split the answer into easily readable paragraphs. Use bullet points and number points where possible.
Include any useful URLs and/or contact details from the context provided whereever possible.
Always end by adding a carrage return and then saying: Thank you for your query to CitizensInformation.ie chat!
----------------
{context}"""
# Create the chat prompt templates
messages = [
SystemMessagePromptTemplate.from_template(system_template),
HumanMessagePromptTemplate.from_template("{question}")
]
qa_prompt = ChatPromptTemplate.from_messages(messages)
pdf_qa = ConversationalRetrievalChain.from_llm(
ChatOpenAI(temperature=0.9, model_name="gpt-3.5-turbo"),
vectordb.as_retriever(),return_source_documents=True,verbose=False,combine_docs_chain_kwargs={"prompt": qa_prompt})
chat_history = []
# Function to ask the chatbot and update chat history
def ask_alans_ai(query, vectordb, chat_history):
result = pdf_qa(
{"question": query, "chat_history": chat_history, "vectordb": vectordb})
chat_history.append((query, result["answer"]))
return result["answer"]
# Streamlit app
def main():
# Sidebar
st.sidebar.title("About Citizens Information Chatbot")
st.sidebar.write("""**Health, Social Welfare, Employment, Money and Tax, Moving Country, Returning to Ireland, Housing, Education and Training, Travel and Recreation, Environment, Government in Ireland, Consumer, Death and Bereavement, Family and Relationships, Justice**
**General Info Only:**
This chatbot gives basic information, not legal or professional advice.
**No Liability:**
We're not responsible for decisions made based on this chatbot's info. For personal advice, please consult a professional.
**No Personal Data:**
Don't share private or sensitive info with the chatbot. We aim to keep your data safe and secure.
**Automated Responses:**
The chatbot's answers are automatically created and might not be completely accurate. Double-check the info provided.
**External Links:**
We might give links to other websites for more info. These are just for help and not endorsed by us.
**Changes and Updates:**
We can change the chatbot's information anytime without notice.
**Using this chatbot means you accept these terms. For more detailed advice, consult the Citizens Information Website**""", unsafe_allow_html=True)
hide_decoration_bar_style = '''
'''
st.markdown(hide_decoration_bar_style, unsafe_allow_html=True)
# Apply custom CSS to reduce top margin
st.markdown("""
""", unsafe_allow_html=True)
# st.title("Citizens Information AI Chatbot")
# Display a user input field
with st.chat_message("assistant", avatar='./ci.png'):
st.write("**Welcome to Citizens Information chat. How can we help you today?**")
if 'chat_history' not in st.session_state:
st.session_state['chat_history'] = []
if 'user_query' not in st.session_state:
st.session_state['user_query'] = ""
# Text area for user input
user_query = st.text_area("**Question**", value=st.session_state['user_query'])
# Custom CSS to change the focus style of st.text_area
custom_css = """
"""
# Inject custom CSS with markdown
st.markdown(custom_css, unsafe_allow_html=True)
chat_history = [] # Initialize chat history
ai_response = "" # Initialize ai_response with a default value
if st.button("Ask"):
if user_query:
# Display the user's question in the chat interface
with st.chat_message("user", avatar='./user.png'):
st.write("**Question:**")
st.write(user_query)
with st.spinner('Thinking...'): # This shows the spinner
# Get the chatbot's response
ai_response = ask_alans_ai(user_query, vectordb, chat_history)
# Display the chatbot's response
with st.chat_message("assistant", avatar='./ci.png'):
st.write("**Answer:**")
st.write(ai_response)
combined_string = f"Question: {user_query}\nAnswer: {ai_response}"
# Create and display the copy button only if ai_response has content
if ai_response:
# Create and display the copy button
copy_button_html = create_copy_button(combined_string)
components.html(copy_button_html, height=24)
# Add a button to clear chat history
if st.button("Clear Chat"):
st.session_state['chat_history'] = [] # Reset the chat history
st.session_state['user_query'] = "" # Clear the input field
st.experimental_rerun() # Rerun the app to reflect the changes
# Run the Streamlit app
if __name__ == "__main__":
main()
# print("system_template is:", system_template, end="\n")
# print("pdf_qa is:", pdf_qa, end="\n")
# print("messages is:", messages, end="\n")
# print("qa_prompt is:", qa_prompt, end="\n")