AskJesus0.3 / app.py
CenterFor's picture
Update app.py
4d0b512
Raw History Blame Contribute Delete
12.2 kB
#
# 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"))
)