|
import os |
|
import csv |
|
import time |
|
import openai |
|
import gradio as gr |
|
|
|
|
|
def get_countries(): |
|
""" |
|
Returns a list with the countries from a CSV |
|
""" |
|
with open('assets/data/paises.csv', encoding='utf-8') as file: |
|
reader = csv.reader(file) |
|
countries = [row[0] for row in reader] |
|
|
|
return countries |
|
|
|
|
|
def check_info(name: gr.Textbox, age: gr.Number, country: gr.Dropdown): |
|
""" |
|
Checks if the given info is complete (no empty strings) and if the |
|
user is old enough (> 18). If so, opens the chatbot, if not |
|
""" |
|
|
|
|
|
if name == '' or country == '' or not isinstance(age, float): |
|
new_image = 'assets/images/pregunta.jpg' |
|
keep_asking, keep_open, open_chat = True, True, False |
|
msg_history = [] |
|
|
|
|
|
elif age < 18: |
|
new_image = 'assets/images/despedida.jpg' |
|
keep_asking, keep_open, open_chat = False, True, False |
|
msg_history = [] |
|
|
|
|
|
else: |
|
new_image = 'assets/images/feliz.jpg' |
|
keep_asking, keep_open, open_chat = False, False, True |
|
msg_history = innit_bot() |
|
|
|
|
|
new_button = gr.Button.update(interactive=keep_asking) |
|
new_img = gr.Image.update(value=new_image) |
|
new_welcoming = gr.Row.update(visible=keep_open) |
|
new_chat = gr.Row.update(visible=open_chat) |
|
|
|
return new_button, new_img, new_welcoming, new_chat, msg_history |
|
|
|
|
|
def innit_bot(): |
|
""" |
|
Initialize the bot by adding the prompt from the txt file to the messages history |
|
""" |
|
openai.api_key = os.environ.get('API_KEY') |
|
|
|
with open('assets/data/prompt.txt', encoding='utf-8') as file: |
|
prompt = file.read() |
|
message_history = [{"role": "system", "content": prompt}] |
|
|
|
return message_history |
|
|
|
|
|
def call_api(msg_history: gr.State): |
|
""" |
|
Returns the APIs response |
|
""" |
|
response = openai.ChatCompletion.create( |
|
model="gpt-4", |
|
temperature=1, |
|
messages=msg_history |
|
) |
|
return response |
|
|
|
|
|
def handle_call(msg_history: gr.State): |
|
""" |
|
Returns the status of the response (False if there was an error, True otherwise), the response and |
|
waiting time of the AI. It also handles the possible errors |
|
""" |
|
tries, max_tries = 0, 9 |
|
while True: |
|
try: |
|
start_time = time.time() |
|
response = call_api(msg_history) |
|
end_time = time.time() |
|
break |
|
|
|
except Exception as e: |
|
print(e) |
|
|
|
if tries == max_tries: |
|
return True, '', '' |
|
|
|
tries += 1 |
|
time.sleep(20) |
|
|
|
needed_time = end_time - start_time |
|
return False, response, needed_time |
|
|
|
|
|
def get_ai_answer(msg: str, msg_history: gr.State): |
|
""" |
|
Returns the response given by the model, all the message history so far and the seconds |
|
the api took to retrieve such response. It can also return an empty string if there was an |
|
error |
|
""" |
|
msg_history.append({"role": "user", "content": msg}) |
|
error, response, needed_time = handle_call(msg_history) |
|
|
|
|
|
if error: |
|
return '', msg_history, -1 |
|
|
|
AI_response = response["choices"][0]["message"]["content"] |
|
msg_history.append({'role': 'assistant', 'content': AI_response}) |
|
|
|
return AI_response, msg_history, needed_time |
|
|
|
|
|
def get_answer(msg: str, msg_history: gr.State, chatbot_history: gr.Chatbot, waiting_time: gr.State): |
|
""" |
|
Cleans msg box, adds the new message to the message history, |
|
gets the answer from the bot and adds it to the chatbot history |
|
and gets the time needed to get such answer and saves it |
|
""" |
|
|
|
|
|
AI_response, msg_history, needed_time = get_ai_answer(msg, msg_history) |
|
|
|
|
|
if AI_response == '': |
|
waiting_time.append(needed_time) |
|
chatbot_history.append((msg, '')) |
|
return "", msg_history, chatbot_history, waiting_time, False |
|
|
|
|
|
if len(AI_response) > 260: |
|
new_msg = 'El mensaje esta muy largo. Da la misma idea (mandando el link, pregunta y/o promocion que hayas ' \ |
|
'dado) pero usando 40 palabras.' |
|
AI_response, msg_history, needed_time = get_ai_answer(new_msg, msg_history) |
|
|
|
|
|
if '?' not in AI_response: |
|
new_msg = 'Incluye 1 pregunta dentro del mensaje. Puede estar relacionada a lo que se hablo antes o algo nuevo.' |
|
AI_response, msg_history, needed_time = get_ai_answer(new_msg, msg_history) |
|
|
|
|
|
waiting_time.append(needed_time) |
|
|
|
|
|
chatbot_history.append((msg, AI_response)) |
|
|
|
return "", msg_history, chatbot_history, waiting_time, True |
|
|
|
|
|
def check_closing(is_working: gr.State): |
|
""" |
|
If is_working is False (it means the API had an error), then close the chat |
|
""" |
|
if is_working: |
|
return gr.Column.update(visible=True), gr.Column.update(visible=False) |
|
return gr.Column.update(visible=False), gr.Column.update(visible=True) |
|
|