File size: 12,232 Bytes
ed1e7f2 a48d60e ed1e7f2 e59edb3 ed1e7f2 968d447 47b2c20 e59edb3 ed1e7f2 968d447 e59edb3 ed1e7f2 e59edb3 ed1e7f2 e59edb3 968d447 e59edb3 ed1e7f2 e59edb3 968d447 e59edb3 968d447 e59edb3 dcf6e29 ed1e7f2 e59edb3 ed1e7f2 3b220a6 ed1e7f2 e59edb3 ed1e7f2 e59edb3 ed1e7f2 e59edb3 ed1e7f2 b22e5b7 ed1e7f2 e87365c ed1e7f2 e87365c ed1e7f2 e87365c ed1e7f2 4afdc85 ed1e7f2 e87365c ed1e7f2 e87365c ed1e7f2 e87365c ed1e7f2 e87365c ed1e7f2 e87365c ed1e7f2 e87365c ed1e7f2 e87365c ed1e7f2 e87365c ed1e7f2 e87365c ed1e7f2 e87365c ed1e7f2 e87365c ed1e7f2 e87365c ed1e7f2 e87365c ed1e7f2 e87365c ed1e7f2 6198eaa ed1e7f2 6198eaa 1aa23f1 6198eaa 6a49eb1 52e5c0a 829fa32 ed1e7f2 e87365c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | 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() |