Bot_C / app.py
Wanswan's picture
Update app.py
1aa23f1 verified
Raw
History Blame Contribute Delete
12.2 kB
import gradio as gr
from openai import OpenAI
import os
import random
import asyncio
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
DEFAULT_LANGUAGE = "English"
WELCOME_MESSAGE_EN = "Hi! I'm Robin, your dialogue partner.\nWe're about to begin a conversation that includes nine questions. Are you ready?\nPlease tell me which language you'd like to use."
# === Normal Question Bank ===
NORMAL_SET_I = [
"When was the last time you walked for more than an hour? Please describe what you saw.",
"What is the best gift you have ever received? Why?",
"If you had to leave your current city, where would you move to? What do you miss most about your current city?",
"How did you celebrate the New Year last year, if you still remember?",
"Do you read newspapers often? Why?",
"What is the ideal number of students to share a house with? Why?",
"If you could invent a new flavor of ice cream, what flavor would you create?",
"What is the best restaurant you have been to in the past month? Please describe it.",
"Please describe the pet you last got.",
"What is your favorite holiday? Why?",
"Can you tell me something funny that happened when you were spending time with a child?"
]
NORMAL_SET_II = [
"What gift did you get on your last birthday?",
"Please tell me something about your last trip to the zoo.",
"Is there someone in your family you feel especially close to? What makes your bond strong?",
"Imagine we were both stranded on a tropical island. What would be the first thing you would do?",
"Do you like to wake up early or stay up late? Has anything interesting ever happened to you because of this?",
"If you could choose to live anywhere, what city or environment would you choose?",
"What is your favorite subject in school and why?",
"What is your plan for the next holiday?",
"What gifts did you receive for Christmas or New Year last year?",
"Who is your favorite actor or actress? ",
"What was your impression of your university when you first came to it?",
"What is the best TV show you have seen in the past month? Please describe it a little bit.",
"Do you have a favorite season or time of year? Why do you like it?"
]
NORMAL_SET_III = [
"What do you remember most about your time in high school?",
"What is the best book you have read in the past three months? ",
"What country would you most like to visit? What attracts you to it?",
"Do you prefer digital or analog watches/clocks? Why?",
"Can you think of someone your mother or father is really close to? What do you think makes their friendship special?",
"What are the pros and cons of artificial Christmas trees?",
"How often do you get your hair cut? Have you ever had a bad haircut?",
"Did you have a class pet in elementary school? Do you remember its name?",
"Do you think left-handed people are more creative than right-handed people?",
"What was the last concert you attended? How was the concert?",
"What magazines do you subscribe to? What have you subscribed to in the past?",
"Have you ever participated in a school play? What role did you play? Did anything funny happen during the play?"
]
def generate_question_set():
return random.sample(NORMAL_SET_I, 3) + random.sample(NORMAL_SET_II, 3) + random.sample(NORMAL_SET_III, 3)
async def gpt_translate(text, target_lang):
if target_lang == "English":
return text
prompt = f"Translate the following into {target_lang}:\n\n{text}"
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}],
temperature=0.3
)
return response.choices[0].message.content.strip()
async def respond(user_input, history, step, language, questions, followup_mode):
history.append({"role": "user", "content": user_input})
if language == "":
user_language = user_input.strip().capitalize()
questions_en = generate_question_set()
translated_questions = [await gpt_translate(q, user_language) for q in questions_en]
welcome = await gpt_translate("Great! We will now continue in your selected language.", user_language)
history.append({"role": "assistant", "content": ""})
for c in f"{welcome}\n\n1. {translated_questions[0]}":
history[-1]["content"] += c
await asyncio.sleep(0.03)
return history, "", 1, user_language, translated_questions, False
if step >= len(questions):
thank_you = await gpt_translate("Thank you for your response! It was a pleasure talking with you. I hope you enjoyed the conversation.", language)
end_note = await gpt_translate("This concludes our questions. Please proceed with the rest of the survey. 📝", language)
for msg in [thank_you, end_note]:
history.append({"role": "assistant", "content": ""})
for c in msg:
history[-1]["content"] += c
await asyncio.sleep(0.03)
return history, "", step, language, questions, False
if followup_mode:
comment_prompt = [
{"role": "system", "content": f"Write a short, empathetic comment in {language} responding to the user's last answer."},
history[-2],
history[-1]
]
comment_response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=comment_prompt,
temperature=0.7
)
comment = comment_response.choices[0].message.content.strip()
rand = random.random()
if rand < 0.1:
followup_prompt = [
{"role": "system", "content": f"Ask one open-ended follow-up question in {language} based on the user's last answer."},
history[-2],
history[-1]
]
followup_response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=followup_prompt,
temperature=0.7
)
followup_question = followup_response.choices[0].message.content.strip()
history.append({"role": "assistant", "content": ""})
for c in comment:
history[-1]["content"] += c
await asyncio.sleep(0.03)
history.append({"role": "assistant", "content": ""})
for c in followup_question:
history[-1]["content"] += c
await asyncio.sleep(0.03)
return history, "", step, language, questions, True
else:
history.append({"role": "assistant", "content": ""})
for c in comment:
history[-1]["content"] += c
await asyncio.sleep(0.03)
next_question = f"{step+1}. {questions[step]}"
history.append({"role": "assistant", "content": ""})
for c in next_question:
history[-1]["content"] += c
await asyncio.sleep(0.03)
return history, "", step + 1, language, questions, False
comment_prompt = [
{"role": "system", "content": f"Write a short, personalized comment in {language} responding to the user's answer. Add a light emoji."},
history[-2],
history[-1]
]
comment_response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=comment_prompt,
temperature=0.7
)
comment = comment_response.choices[0].message.content.strip()
rand = random.random()
if rand < 0.4:
followup_prompt = [
{"role": "system", "content": f"Ask one open-ended follow-up question in {language} based on the user's answer."},
history[-2],
history[-1]
]
followup_response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=followup_prompt,
temperature=0.7
)
followup_question = followup_response.choices[0].message.content.strip()
history.append({"role": "assistant", "content": ""})
for c in comment:
history[-1]["content"] += c
await asyncio.sleep(0.03)
history.append({"role": "assistant", "content": ""})
for c in followup_question:
history[-1]["content"] += c
await asyncio.sleep(0.03)
return history, "", step, language, questions, True
else:
history.append({"role": "assistant", "content": ""})
for c in comment:
history[-1]["content"] += c
await asyncio.sleep(0.03)
next_question = f"{step+1}. {questions[step]}"
history.append({"role": "assistant", "content": ""})
for c in next_question:
history[-1]["content"] += c
await asyncio.sleep(0.03)
return history, "", step + 1, language, questions, False
def init():
return [{"role": "assistant", "content": WELCOME_MESSAGE_EN}], 0, "", [], False
with gr.Blocks(css="""
.send-btn {
background-color: #25D366 !important;
color: white !important;
border: none;
border-radius: 24px;
font-size: 20px;
padding: 8px 20px;
height: 48px;
width: 60px;
margin-left: 8px;
cursor: pointer;
}
#chatbox .avatar-container {
width: 54px !important;
height: 54px !important;
min-width: 54px !important;
min-height: 54px !important;
background-size: 100% 100% !important;
background-position: center center !important;
border-radius: 50% !important;
padding: 0 !important;
margin: 0 !important;
border: none !important;
box-shadow: none !important;
background-color: transparent !important;
}
#chatbox .message.user { background-color: #DCF8C6 !important; }
#chatbox .message {
display: inline-block !important;
font-size: 16px !important;
line-height: 1.3em !important;
min-width: 7ch !important;
max-width: 60ch !important;
padding: 2px 3px !important;
border-radius: 8px !important;
word-break: break-word !important;
white-space: normal !important;
}
@media screen and (max-width: 768px) {
#chatbox .message.user {
max-width: 90vw !important;
}
}
#chatbox .message.user {
background-color: #DCF8C6 !important;
min-width: 60px !important;
max-width: fit-content !important;
}
#chatbox .message.assistant { background-color: #ffffff !important; }
footer { display: none !important; }
.svelte-1ipelgc { display: none !important; }
.icon-button-wrapper {
display: none !important;
}
label.svelte-1to105q {
display: none !important;
}
""") as demo:
gr.HTML("""
<script>
const waitForChatbox = () => {
const chatbox = document.getElementById("chatbox");
if (chatbox) {
const observer = new MutationObserver(() => {
chatbox.scrollTop = chatbox.scrollHeight;
});
observer.observe(chatbox, { childList: true, subtree: true });
} else {
setTimeout(waitForChatbox, 500);
}
};
waitForChatbox();
</script>
""")
chatbot = gr.Chatbot(
elem_id="chatbox",
label="",
avatar_images=["user_avatar.jpg", "humanlike_avatar.png"],
bubble_full_width=False,
height=500,
show_copy_button=False,
type="messages"
)
with gr.Row():
user_input = gr.Textbox(
show_label=False,
placeholder="Type your message here and press send...",
container=True,
scale=10
)
send_btn = gr.Button(value="➤", elem_classes="send-btn")
state = gr.State([])
step = gr.State(0)
language = gr.State("")
questions = gr.State([])
followup_mode = gr.State(False)
demo.load(fn=init, outputs=[chatbot, step, language, questions, followup_mode])
user_input.submit(respond, [user_input, state, step, language, questions, followup_mode],
[chatbot, user_input, step, language, questions, followup_mode])
send_btn.click(respond, [user_input, state, step, language, questions, followup_mode],
[chatbot, user_input, step, language, questions, followup_mode])
demo.queue().launch()