# # AskJesus v0.32 RAG # Dec 5, 2023 # # Version Log: # 0.21 # 1. send only the last question and answer via email # 2. add a pay-it-forward link to the email. # # 0.3 # 1. Add UB References, without the controls # # 0.31 # 1. Increase queue parameters for Gradio performance: max_size, GRADIO_DEFAULT_CONCURRENCY_LIMIT=20 # See: https://www.gradio.app/guides/setting-up-a-demo-for-maximum-performance # # 0.32 # remove the character-by-character yield call to improve performace. It may be clogging the websocket. import os import tweepy import gradio as gr import time import argparse from langchain.chat_models import ChatOpenAI from langchain.prompts.chat import ( ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate, ) from langchain.schema import HumanMessage, SystemMessage import smtplib # To send emails via GMAIL from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart """ Only needed on private local deployment from dotenv import load_dotenv load_dotenv() """ from social_sharing import send_email_mailchimp, send_tweet, send_to_airtable from AskJesus_RAG import run_question # This code is used both in a private local deployment, with a local persisted ChromaDB # and on HuggingFace, by loading the ChromaDB from a dataset. # In either case, the ChromaDB is used to create a Chroma LangChain. private_local_deployemnt = os.getenv("PRIVATE_LOCAL_DEPLOYMENT") == "True" # # ChatGPT # # Select the system prompt from the command line parser = argparse.ArgumentParser(description='Select a system message.') parser.add_argument('--msgnum', type=int, help='The number of the system message to use') args = parser.parse_args() # Define the system message. Optionally choose a system prompt from the command line #selected_prompt = os.getenv(f'CHAT_GPT_SYSTEM_MESSAGE{args.msgnum}') #if selected_prompt is None: # print(f"Using default ChatGPT system message.") # selected_prompt = os.getenv("CHAT_GPT_DEFAULT_SYSTEM_MESSAGE") #system_message_content = selected_prompt # Select the system prompt from a dropdown menu # NOTE: system message selection is only available in the private local deployment. # The Gradio component will not be visible. if private_local_deployemnt : system_messages = { "Default": os.getenv("CHAT_GPT_DEFAULT_SYSTEM_MESSAGE"), "None" : "", "Option 1": os.getenv("CHAT_GPT_SYSTEM_MESSAGE1"), "Option 2": os.getenv("CHAT_GPT_SYSTEM_MESSAGE2"), "Option 3": os.getenv("CHAT_GPT_SYSTEM_MESSAGE3"), "Option 4": os.getenv("CHAT_GPT_SYSTEM_MESSAGE4"), "Option 5": os.getenv("CHAT_GPT_SYSTEM_MESSAGE5") # Add more options as needed } else : system_messages = { "Default": os.getenv("CHAT_GPT_DEFAULT_SYSTEM_MESSAGE") } # Initialize with the default system message current_system_message = system_messages["Default"] # Select the chatGPT model with a radio button # NOTE: GPT model selection is only available in the private local deployment. # The Gradio component will not be visible. if private_local_deployemnt : gpt_models = { "Default": os.getenv("CHAT_GPT_3_5_MODEL"), "3.5": os.getenv("CHAT_GPT_3_5_MODEL"), "4.0": os.getenv("CHAT_GPT_4_0_MODEL") # Add more options as needed } else : gpt_models = { "Default": os.getenv("CHAT_GPT_3_5_MODEL") } # Initialize with the default GPT model current_gpt_model = gpt_models["Default"] # Select the RAG option with a radio button current_RAG_option = True # Initialize the chat model chat = ChatOpenAI( model=os.getenv("CHAT_GPT_MODEL"), temperature=os.getenv("CHAT_GPT_TEMPERATURE") ) """ # deprecated version from v0.2 # # Create templates # # before runtime selection of system message #system_template = system_message_content #print (f"\nSYSTEM message:\n{system_template}\n") #system_message_prompt = SystemMessagePromptTemplate.from_template(system_template) # runtime selection of system message system_template = "{system_message}" system_message_prompt = SystemMessagePromptTemplate.from_template(system_template) human_template = "{question}" human_message_prompt = HumanMessagePromptTemplate.from_template(human_template) # Build a chat prompt template chat_prompt = ChatPromptTemplate.from_messages( [system_message_prompt, human_message_prompt] ) """ # Initialize an empty list to store the chat history chat_history = [] with gr.Blocks(title=f"AskJesus Chatbot {os.getenv('ASKJESUS_CHATBOT_VERSION')}") as demo: # Gradio UI with gr.Row(): gr.Label( "Ask", show_label=False, scale=1 ) msg = gr.Textbox( label="Question:", placeholder="Enter question here", scale=4 ) new_features = gr.Markdown( """ ## NEW feature: Urantia Book references Based on your question, the chatbot chooses relevant paragraphs from the Urantia Book. """ ) add_UB_references = gr.Radio( ["Yes", "No"], label="Include Urantia Book references in the answer.", info="Select Yes to for the chatbot to choose relevant paragraphs from the Urantia Book, making the answer sound a bit more academic. We encourage you to try both options.", value="Yes", scale=4, visible=private_local_deployemnt ) # NOTE: GPT model selection is only available in the private local deployment chat_gpt_model = gr.Radio( ["3.5", "4.0"], label="ChatGPT version", value="3.5", visible=private_local_deployemnt, scale=2 ) with gr.Row(): chatbot = gr.Chatbot( label=f"AskJesus Chatbot {os.getenv('ASKJESUS_CHATBOT_VERSION')}", scale=8 ) clear = gr.ClearButton( [msg, chatbot], value="Clear log", scale=2 ) with gr.Row(): gr.Label( "Share", show_label=False, scale=1 ) email_input = gr.Textbox( label="Email:", placeholder="Enter your email here", scale=8 ) send_email_button = gr.Button( value="Send email", variant="primary", scale=1 ) tweet_button = gr.Button( value="Tweet last Q&A", scale=1 ) # NOTE: system message selection is only available in the private local deployment with gr.Row(): system_message_display = gr.Textbox( label="Current system message:", value=current_system_message, lines=6, interactive=False, scale=10, visible=private_local_deployemnt ) system_message_dropdown = gr.Dropdown( choices=list(system_messages.keys()), value=list(system_messages.values()), label="Select System Message", interactive=True, scale=2, visible=private_local_deployemnt ) # NOTE: system message selection is only available in the private local deployment def update_system_message(selected_option): global current_system_message current_system_message = system_messages[selected_option] print (f"\nCurrent system message:\n{current_system_message}\n") return current_system_message # NOTE: GPT model selection is only available in the private local deployment def update_gpt_model(selected_option): global current_gpt_model current_gpt_model = gpt_models[selected_option] print (f"\nCurrent ChatGPT model:\n{current_gpt_model}\n") return current_gpt_model def update_RAG_option(selected_option): global current_RAG_option current_RAG_option = True if selected_option == "Yes" else False print (f"\nCurrent RAG option:\n{current_RAG_option}\n") return current_RAG_option def user(user_message, history): # Append the user's message to the chat history chat_history.append({"Question": user_message, "AskJesus chatbot": None}) return gr.update(value="", interactive=False), history + [[user_message, None]] def bot(history): # Get a chat completion from the formatted messages and the current system message global current_system_message # deprecated version from 0.2 #messages = chat_prompt.format_prompt(question=history[-1][0], system_message=current_system_message).to_messages() #response = chat(messages) #bot_message = response.content # assuming response is an AIMessage # assuming response is an str bot_message = run_question( question=history[-1][0], system_message=current_system_message, gpt_model=current_gpt_model, use_RAG=current_RAG_option ) answer_scrolling_speed = float(os.getenv("ANSWER_SCROLLING_SPEED")) # Update the chat history with the bot's message chat_history[-1]["AskJesus chatbot"] = bot_message history[-1][1] = bot_message yield history #for character in bot_message: # history[-1][1] += character # time.sleep(answer_scrolling_speed) # yield history # Send the question and answer to Airtable send_to_airtable( history[-1][0], history[-1][1], current_system_message, current_gpt_model, current_RAG_option ) def email_session(email): if not email: print("No email address provided. Cannot send email.") raise gr.Error("Please provide email.") return # Convert the chat history to a string format history_str = "\n".join([f"Question: {entry['Question']}\nAskJesus chatbot: {entry['AskJesus chatbot']}\n\n" for entry in chat_history]) send_email_mailchimp(email, history_str) def email_last_qa(email): if not email: print("No email address provided. Cannot send email.") raise gr.Error("Please provide email.") return # Convert the last question and answer to a string format history_str = "\n".join([f"Question: {chat_history[-1]['Question']}\nAskJesus chatbot: {chat_history[-1]['AskJesus chatbot']}\n\n"]) if send_email_mailchimp(email, history_str) == True : gr.Info("Email sent.") else : raise gr.Error("Error: email not sent.") def tweet_last_qa(): last_qa = chat_history[-1] tweet_link = f"Someone just asked the AskJesus chatbot:\n\n{last_qa['Question']}\n\nWhat would you ask?\n\n#AskJesus #JesusBeforeChristianity {os.getenv('ASKJESUS_CFU_PAGE')}" if send_tweet(tweet_link) == True : gr.Info("Tweet sent.") else : raise gr.Error("Failed to tweet.") response = msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then( bot, chatbot, chatbot ) response.then(lambda: gr.update(interactive=True), None, [msg], queue=False) # send_email_button.click(email_session, [email_input]) - for the entire session send_email_button.click(email_last_qa, [email_input]) tweet_button.click(tweet_last_qa) # NOTE: system message selection is only available in the private local deployment system_message_dropdown.input(fn=update_system_message, inputs=system_message_dropdown, outputs=system_message_display) # NOTE: GPT model selection is only available in the private local deployment chat_gpt_model.input(fn=update_gpt_model, inputs=chat_gpt_model) add_UB_references.input(fn=update_RAG_option, inputs=add_UB_references) demo.queue(max_size=int(os.getenv("GRADIO_MAX_SIZE"))) demo.launch( show_error=True, max_threads=int(os.getenv("GRADIO_MAX_THREADS")) )