Spaces:
Sleeping
Sleeping
import openai | |
import gradio as gr | |
import os | |
import pandas as pd | |
import time | |
# env | |
openai.api_key = os.environ.get('openai-api') | |
SHEET_ID = '119qz8UpCdwCu_gyPtayi7JmhSM0nUddolOyJcqsMnmA' | |
SHEET_NAME = 'MIW_Sources' | |
# Blocks | |
with gr.Blocks(theme=gr.themes.Glass()) as demo: | |
#Initialize data | |
url = f'https://docs.google.com/spreadsheets/d/{SHEET_ID}/gviz/tq?tqx=out:csv&sheet={SHEET_NAME}' | |
df = pd.read_csv(url) | |
def filter_and_concatenate(df, input_string): | |
# If input string is empty, return concatenation of all values | |
if input_string == "": | |
concatenated_string = "" | |
for _, row in df.iterrows(): | |
concatenated_string += '|'.join(str(value) for value in row.values) + '\n' | |
return concatenated_string | |
# Filter the dataframe based on the input string | |
filtered_df = df[df['category'] == input_string] | |
# Concatenate the values from other columns | |
concatenated_string = '' | |
for _, row in filtered_df.iterrows(): | |
concatenated_string += '|'.join(str(value) for value in row.values[1:]) + '\n' | |
return concatenated_string | |
def showall(code:str): | |
visibility = gr.update(visible = True) | |
invisibility = gr.update(visible = False) | |
tryagain = gr.update(value = None, placeholder = "Try again - 再試一次") | |
if code == os.environ.get('accesscode'): | |
return visibility, visibility, visibility, visibility, invisibility | |
else: | |
return invisibility, invisibility, invisibility, invisibility, tryagain | |
def refreshmode1(mode): | |
mode = gr.update(value= "mode1") | |
return mode | |
def refreshmode2(mode): | |
mode = gr.update(value="mode2") | |
return mode | |
def refreshmode3(mode): | |
mode = gr.update(value="mode3") | |
return mode | |
def answer(history): | |
for attempt in range(5): | |
try: | |
response = openai.ChatCompletion.create( | |
model='gpt-3.5-turbo', | |
messages=history, | |
temperature=0.5, | |
max_tokens=800, | |
top_p=1, | |
n=1, | |
frequency_penalty=0.9, | |
presence_penalty=0.9, | |
stop=None | |
) | |
result = response['choices'][0]['message']['content'] | |
break | |
except Exception as e: | |
print(f"Error occurred on attempt {attempt + 1}: {e}") | |
if attempt < 5: | |
time.sleep(10) | |
else: | |
raise e | |
return result | |
def init_history(language, messages_history1, messages_history2, messages_history3): #Reinitialize the state file | |
messages_history1 = [[None,languagedict[language]['whatcanidofirst']]] | |
messages_history2 = [[None,languagedict[language]['interviewquestionsfirst']]] | |
messages_history3 = [[None,languagedict[language]['helpfirst']]] | |
messages_history1 += {"role": "system", "content": themewhatcanido} | |
messages_history1 += {"role": "assistant", "content": languagedict[language]['whatcanidofirst']} | |
messages_history2 += {"role": "system", "content": themeinterviewquestions} | |
messages_history2 += {"role": "assistant", "content": languagedict[language]['interviewquestionsfirst']} | |
messages_history3 += {"role": "system", "content": themehelp} | |
messages_history3 += {"role": "assistant", "content": languagedict[language]['helpfirst']} | |
return messages_history1, messages_history2, messages_history3 | |
def getlist(df): | |
# Extract distinct values from the first column excluding the header | |
distinct_values = df.iloc[1:, 0].unique() | |
# Join the distinct values into a string separated by ", " | |
distinct_values_string = ", ".join(str(value) for value in distinct_values) | |
return distinct_values_string | |
def user(msg, chatbot, state, language: str, mode: str): | |
#Bot context | |
if mode == "mode1": | |
context = themewhatcanido | |
elif mode == "mode2": | |
context = themeinterviewquestions | |
else: | |
context = themehelp | |
#remind mission | |
if len(state) == 0: | |
state.append({'role':'system','content':f"Take notice of your mission:\n\n{context}"}) | |
elif len(state) > 10: | |
state.append({'role':'system','content':f"Remember your mission as briefed earlier:\n\n{context}"}) | |
chatbot.append([msg, None]) | |
#Specific for mode3 | |
if mode == 'mode3': | |
#Append instructions to msg | |
listvalues = getlist(df) | |
print(f'listvalues: {listvalues}') | |
queryforcategory = [{'role':'user','content':f"Out of this list of words/expressions separated by a comma:\n{listvalues}\n, which one corresponds the best to the theme in this message:\n{msg}\n\nThe result should be one of the elements from the list only. If there's absolutly no match, return an empty string ''\nHere is an example:\n if the list contains 'Skills,Finding work' and the message is 'I want to learn about Excel', just reply 'Skills' "}] | |
matchcat = answer(queryforcategory) | |
matchcat = matchcat.replace('.','') | |
matchcat = matchcat.strip() | |
print(f'matchcat: {matchcat}') | |
try: | |
instructions = filter_and_concatenate(df, matchcat) | |
except: | |
instructions = "" | |
print(f'instructions: {instructions}') | |
msg = msg + f"\n\nAnswer in {language}, keep it casual but respectful" | |
state.append({'role':'user','content':msg}) | |
if mode == 'mode3': | |
state.append({'role':'system','content':f"\n\nUse the following elements to document your answer:\n{instructions}"}) | |
print(f'state is\n{state}') | |
print(f'chatbot is\n{chatbot}') | |
return "", chatbot, state | |
def bot(chatbot, state): | |
response = answer(state) | |
chatbot.append([None, response]) | |
state.append({'role':'assistant','content':response}) | |
return chatbot, state | |
def refresh(language: str): | |
titleup = gr.update(value = languagedict[language]['welcome']) | |
input1up = gr.update(label = languagedict[language]['whatcanidolabel'], placeholder = languagedict[language]['whatcanidoph']) | |
input2up = gr.update(label = languagedict[language]['interviewquestionslabel'], placeholder = languagedict[language]['interviewquestionsph']) | |
input3up = gr.update(label = languagedict[language]['helplabel'], placeholder = languagedict[language]['helpph']) | |
chatbot1up = [[None,languagedict[language]['whatcanidofirst']]] | |
state1up = [{"role": "system", "content": themewhatcanido},{"role": "assistant", "content": languagedict[language]['whatcanidofirst']}] | |
chatbot2up = [[None,languagedict[language]['interviewquestionsfirst']]] | |
state2up = [{"role": "system", "content": themeinterviewquestions},{"role": "assistant", "content": languagedict[language]['interviewquestionsfirst']}] | |
chatbot3up = [[None,languagedict[language]['whatcanidofirst']]] | |
state3up = [{"role": "system", "content": themehelp},{"role": "assistant", "content": languagedict[language]['helpfirst']}] | |
return titleup, input1up, input2up, input3up, chatbot1up, chatbot2up, chatbot3up, state1up, state2up, state3up | |
languageoptions = ["English", "廣東話"] | |
languagedict = { | |
"English": { | |
"welcome": "Welcome to Make It Work App - Where you can get tailored help thanks to Artificial Intelligence", | |
"whatcanido": "What job can I do?", | |
"whatcanidofirst" : "Tell me about you.", | |
"whatcanidolabel": "Write your preferences and we can suggest some options", | |
"whatcanidoph": "I'm a 30 years old single mother, I have a 6 years old daughter. I can cook, take care of children and elderly and have been a waiter at a restaurant before.\nI have a high school degree.", | |
"interviewquestions": "How to prepare for interview?", | |
"interviewquestionsfirst": "What is the role you're interviewing for?", | |
"interviewquestionslabel": "Answer the questions for this virtual interview", | |
"interviewquestionsph": "I want to prepare for an interview as a receptionist.", | |
"help": "Where to get help?", | |
"helpfirst": "How can I help you?", | |
"helplabel": "Where do you need help?", | |
"helpph": "How can I have support to take care of my daughter during my work? / How can I get trained on Excel?" | |
}, | |
"廣東話": { | |
"welcome": "歡迎使用 Make It Work App - 借助人工智能,您可以獲得量身定制的幫助", | |
"whatcanido": "我可以做什麼工作?", | |
"whatcanidofirst" : "介紹一下你自己吧。", | |
"whatcanidolabel": "寫下您的喜好,我們可以建議一些選擇", | |
"whatcanidoph": "我是一個 30 歲的單身母親,我有一個 6 歲的女兒。我會做飯,照顧孩子和老人,以前在餐廳當過服務員。\n我有高中學歷。", | |
"interviewquestions": "如何準備面試?", | |
"interviewquestionsfirst": "你面試的角色是什麼?", | |
"interviewquestionslabel": "回答這位 AI 面試官的問題", | |
"interviewquestionsph": "我想以接待員的身份準備面試。", | |
"help": "去哪裡尋求幫助?", | |
"helpfirst": "我怎麼幫你", | |
"helplabel": "你在哪裡需要幫助?", | |
"helpph": "我如何在工作期間獲得支持來照顧我的女兒? / 我怎樣才能接受 Excel 培訓?" | |
} | |
} | |
url = "https://cdn.discordapp.com/attachments/1006389042608349264/1114545184080928849/Guiyom_cartoon_style_-_working_poors_in_Hong_Kong_seeking_advic_70131de8-1a0a-4f04-ac49-b99d7e020414.png" | |
# INTERFACE | |
mode = gr.Textbox(value = "mode1", visible = False, type = 'password') | |
accesscode = gr.Textbox(label = "Input access code", visible = True) | |
with gr.Row(): | |
with gr.Column(scale = 1): | |
visual = gr.Image(image = url, shape = [150,150]) | |
with gr.Column(scale = 3): | |
title = gr.Markdown(value=languagedict['English']['welcome']) | |
language = gr.Dropdown(languageoptions , value= "English", label="Choose language / 選擇語言", visible = False) | |
# REFERENCES | |
themewhatcanido = f""" | |
You are a career advisor for people in Hong Kong with relatively low skills job. | |
Your mission is to ask several questions to then help them identify what are their job options, taking into consideration: | |
- Their study level and domain | |
- Their level of confort with computer tools (typing, excel, word, ...) | |
- Their past working experiences (ex: hair dresser, street cleaner, old care support, restaurant aide, waiter) | |
- Their constraints (ex: time available per week, per day) | |
- Other relevant questions | |
Then, when you have enough information, you will thank them and suggest some options, for each of them: | |
- Explain the key skills needed | |
- Breakdown the potential challenges for them to anticipate | |
- Provide advice on how to overcome these challenges | |
IMPORTANT: write in {language}, in the style of a native. Keep it casual but respectful. | |
""" | |
themeinterviewquestions = f""" | |
You are an interviewer, interviewing a candidate for a role [the role will be specified to you]. | |
Your candidates have limited skills, please find ways to support them and ask all the questions. | |
Do a series of questions (only one by message) | |
- their experience on this job | |
- their skills | |
- their capacity to manage the stress related to this job | |
- any other relevant question related to the job, don't be afraid to be specific | |
After 5 to 10 questions, give a feedback to the interviewee: | |
[FEEDBACK] | |
- What they did well | |
- What they can do better | |
- Suggestions of reformulations | |
IMPORTANT: write in {language}, in the style of a native. Keep it casual but respectful. | |
""" | |
themehelp = f""" | |
You are a social worker, you need to provide some help to the user. He can ask questions relative to this categories, with a few examples | |
- Elderly: | |
o ex: I need help to take care with my grandma who lives with me | |
o ex: I am ageing, I don't know who can help when I grow older | |
- Health: | |
o ex: I have health issues, where can I get some help | |
- Housing: | |
o ex: I need help to find an apartment | |
- Parenting: | |
o ex: Who can help me to keep my daughter when I'm working? | |
- Food: | |
o ex: I don't have enough food for my children, where can I get support? | |
- Skills: | |
o ex: I want to learn Excel | |
o ex: I want to improve my English | |
- Job: | |
o ex: Where can I learn about job vacancies in Kowloon? | |
- Leisure: | |
o ex: I need some support to get my son to do some art. | |
o ex: I want to learn how to swim | |
If the question is not related to any of these topics, answer 'This is beyond my domain of competence, please ask a social worker.' | |
Always keep it relevant for Hong Kong, low-income persons. | |
IMPORTANT: write in {language}, in the style of a native. Keep it casual but respectful. | |
""" | |
#INTERFACE | |
with gr.Tab(f"{languagedict['English']['whatcanido']} / {languagedict['廣東話']['whatcanido']}"): | |
chatbot1 = gr.Chatbot([[None,languagedict['English']['whatcanidofirst']]]) | |
input1 = gr.Textbox(label = languagedict['English']['whatcanidolabel'], placeholder = languagedict['English']['whatcanidoph'], visible = False) | |
state1 = gr.State([{"role": "system", "content": themewhatcanido},{"role": "assistant", "content": languagedict['English']['whatcanidofirst']}]) | |
with gr.Tab(f"{languagedict['English']['interviewquestions']} / {languagedict['廣東話']['interviewquestions']}"): | |
chatbot2 = gr.Chatbot([[None,languagedict['English']['interviewquestionsfirst']]]) | |
input2 = gr.Textbox(label = languagedict['English']['interviewquestionslabel'], placeholder = languagedict['English']['interviewquestionsph'], visible = False) | |
state2 = gr.State([{"role": "system", "content": themeinterviewquestions},{"role": "assistant", "content": languagedict['English']['interviewquestionsfirst']}]) | |
with gr.Tab(f"{languagedict['English']['help']} / {languagedict['廣東話']['help']}"): | |
chatbot3 = gr.Chatbot([[None,languagedict['English']['helpfirst']]]) | |
input3 = gr.Textbox(label = languagedict['English']['helplabel'], placeholder = languagedict['English']['helpph'], visible = False) | |
state3 = gr.State([{"role": "system", "content": themehelp},{"role": "assistant", "content": languagedict['English']['helpfirst']}]) | |
clear = gr.Button('Clear') | |
# Launcher | |
input1.submit(refreshmode1, mode, mode).then(user, [input1, chatbot1, state1, language, mode], [input1, chatbot1, state1]).then(bot, [chatbot1, state1], [chatbot1, state1]) | |
input2.submit(refreshmode2, mode, mode).then(user, [input2, chatbot2, state2, language, mode], [input2, chatbot2, state2]).then(bot, [chatbot2, state2], [chatbot2, state2]) | |
input3.submit(refreshmode3, mode, mode).then(user, [input3, chatbot3, state3, language, mode], [input3, chatbot3, state3]).then(bot, [chatbot3, state3], [chatbot3, state3]) | |
clear.click(lambda: None, None, [chatbot1, chatbot2, chatbot3], queue=True).success(init_history, [language, state1, state2, state3], [state1, state2, state3]) | |
language.change(lambda: None, None, [chatbot1, chatbot2, chatbot3], queue=True).then(refresh, language, [title, input1, input2, input3, chatbot1, chatbot2, chatbot3, state1, state2, state3]) | |
accesscode.submit(showall, accesscode, [input1, input2, input3, language, accesscode]) | |
demo.queue() | |
demo.launch() |