File size: 16,555 Bytes
2ea70ce
 
bd587b5
f84c4a3
efc09d9
2ea70ce
 
 
f84c4a3
 
2ea70ce
 
 
 
ab04f17
f84c4a3
 
 
 
 
 
 
 
 
 
1d8b004
f84c4a3
 
1d8b004
f84c4a3
 
 
 
 
1d8b004
b8309d3
131e9e4
 
 
932e94b
b8309d3
35136af
 
b8309d3
afe085e
5fbc2f5
afe085e
 
 
5fbc2f5
afe085e
 
 
5fbc2f5
afe085e
 
 
7ea25f4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ed72fea
afe085e
97923cc
 
 
 
afe085e
97923cc
c7fbf62
97923cc
c7fbf62
97923cc
afe085e
f84c4a3
 
8002983
 
f84c4a3
 
8002983
f84c4a3
 
 
5fbc2f5
afe085e
 
 
 
c7fbf62
afe085e
c7fbf62
afe085e
 
133f749
afe085e
03e6b4b
5fbc2f5
f84c4a3
d48a0fa
f4a8916
f84c4a3
 
d48a0fa
a55f290
f84c4a3
a1269f9
ee0aeab
d48a0fa
7ec6c5a
 
 
 
d48a0fa
f84c4a3
5fbc2f5
a1269f9
 
26a2217
 
5fbc2f5
 
 
afe085e
03e6b4b
133f749
afe085e
 
b10ef8c
afe085e
6294bfb
 
 
4f68195
2f318bc
4f68195
2f318bc
4f68195
f84c4a3
7db5477
9227a2f
2ea70ce
 
 
 
c740c0d
2ea70ce
 
6294bfb
2ea70ce
 
 
6294bfb
2ea70ce
 
1020857
6294bfb
2ea70ce
 
 
c740c0d
2ea70ce
 
6294bfb
2ea70ce
 
 
6294bfb
2ea70ce
 
1020857
6294bfb
2ea70ce
301e95e
8172b6d
 
 
0a8e976
260e940
b8309d3
5de2187
6294bfb
ab04f17
 
5de2187
 
b8309d3
5de2187
 
d6112d1
5de2187
 
 
 
 
 
 
 
d6112d1
5de2187
 
 
 
 
f84c4a3
5de2187
 
 
 
 
e1f58c4
6efb716
 
 
 
 
e1f58c4
6efb716
 
 
 
 
5de2187
f84c4a3
5de2187
 
 
a11d2f1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5de2187
a11d2f1
 
f84c4a3
5de2187
 
 
 
 
b8309d3
8338a7e
5de2187
 
b8309d3
8338a7e
5de2187
 
b8309d3
f84c4a3
5de2187
d6112d1
2ea70ce
5fbc2f5
 
 
4944c2c
2f318bc
b8309d3
2ea70ce
 
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
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()