Spaces:
Paused
Paused
andreinigo
commited on
Commit
•
e1835d3
1
Parent(s):
a1cc0a4
Upload 3 files
Browse files- app.py +122 -0
- requirements.txt +2 -0
- utils.py +110 -0
app.py
ADDED
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import openai
|
3 |
+
import json
|
4 |
+
import time
|
5 |
+
from utils import get_trip
|
6 |
+
import os
|
7 |
+
|
8 |
+
openai.api_key = "sk-"+os.environ["OPENAI_API_KEY"]
|
9 |
+
|
10 |
+
# Tu función get_trip aquí
|
11 |
+
|
12 |
+
context = [{'role': 'system', 'content': """
|
13 |
+
Eres CegaperGPT, un servicio automatizado para recomendar la mejor opción de transporte de la compañía Cegaper y ayudar a los usuarios a comprar sus tickets.
|
14 |
+
Cegaper es una compañía de transporte terrestre (autobuses, vans y camiones) que opera en México.
|
15 |
+
Primero, saludas al cliente diciendo tu nombre, luego preguntas por los detalles del viaje y después solicitas la información personal del comprador.
|
16 |
+
Esperas hasta recopilar todo el pedido, luego lo resumes y verificas.
|
17 |
+
Finalmente, recoges el pago.
|
18 |
+
Asegúrate de aclarar todas las opciones para seleccionar el viaje correcto para el usuario.
|
19 |
+
Respondes en un estilo amigable, conversacional y breve. \
|
20 |
+
"""}]
|
21 |
+
|
22 |
+
|
23 |
+
def get_completion_from_messages(messages, temperature=0.1):
|
24 |
+
functions = [{
|
25 |
+
"name": "get_trip",
|
26 |
+
"description": "Encuentra el mejor plan de viaje desde el origen hasta el destino en un rango de fechas dado.",
|
27 |
+
"parameters": {
|
28 |
+
"type": "object",
|
29 |
+
"properties": {
|
30 |
+
"origin": {
|
31 |
+
"type": "string",
|
32 |
+
"description": "La dirección de origen, debe cumplir con el estándar de Google Maps.",
|
33 |
+
},
|
34 |
+
"destination": {
|
35 |
+
"type": "string",
|
36 |
+
"description": "La dirección de origen, debe cumplir con el estándar de Google Maps.",
|
37 |
+
},
|
38 |
+
"date_from": {
|
39 |
+
"type": "string",
|
40 |
+
"description": "La fecha de inicio del rango a considerar para el viaje en formato YYYY-MM-DD",
|
41 |
+
},
|
42 |
+
"date_to": {
|
43 |
+
"type": "string",
|
44 |
+
"description": "La fecha de fin del rango a considerar para el viaje en formato YYYY-MM-DD",
|
45 |
+
},
|
46 |
+
"pax": {
|
47 |
+
"type": "integer",
|
48 |
+
"description": "El número de pasajeros para el viaje",
|
49 |
+
},
|
50 |
+
"round_trip": {
|
51 |
+
"type": "boolean",
|
52 |
+
"description": "Si el viaje debe ser de ida y vuelta o no. Si es verdadero, se requiere date_to.",
|
53 |
+
}
|
54 |
+
},
|
55 |
+
"required": ["origin", "destination", "date_from", "pax"],
|
56 |
+
}
|
57 |
+
}]
|
58 |
+
|
59 |
+
response = openai.ChatCompletion.create(
|
60 |
+
model="gpt-4-0613",
|
61 |
+
messages=messages,
|
62 |
+
functions=functions,
|
63 |
+
function_call="auto",
|
64 |
+
)
|
65 |
+
response_message = response["choices"][0]["message"]
|
66 |
+
|
67 |
+
if response_message.get("function_call"):
|
68 |
+
available_functions = {
|
69 |
+
"get_trip": get_trip,
|
70 |
+
}
|
71 |
+
function_name = response_message["function_call"]["name"]
|
72 |
+
function_to_call = available_functions[function_name]
|
73 |
+
function_args = json.loads(
|
74 |
+
response_message["function_call"]["arguments"])
|
75 |
+
function_response = function_to_call(
|
76 |
+
origin=function_args.get("origin"),
|
77 |
+
destination=function_args.get("destination"),
|
78 |
+
date_from=function_args.get("date_from"),
|
79 |
+
date_to=function_args.get("date_to"),
|
80 |
+
round_trip=function_args.get("round_trip"),
|
81 |
+
pax=function_args.get("pax"),
|
82 |
+
)
|
83 |
+
|
84 |
+
messages.append(response_message)
|
85 |
+
messages.append(
|
86 |
+
{
|
87 |
+
"role": "function",
|
88 |
+
"name": function_name,
|
89 |
+
"content": function_response,
|
90 |
+
}
|
91 |
+
)
|
92 |
+
second_response = openai.ChatCompletion.create(
|
93 |
+
model="gpt-4-0613",
|
94 |
+
messages=messages
|
95 |
+
)
|
96 |
+
|
97 |
+
if 'second_response' not in locals():
|
98 |
+
messages.append(response_message)
|
99 |
+
second_response = openai.ChatCompletion.create(
|
100 |
+
model="gpt-4-0613",
|
101 |
+
messages=messages
|
102 |
+
)
|
103 |
+
return second_response.choices[0].message["content"]
|
104 |
+
|
105 |
+
|
106 |
+
def respuesta_chatbot(message, chat_history):
|
107 |
+
context.append({'role': 'user', 'content': f"{message}"})
|
108 |
+
response = get_completion_from_messages(context)
|
109 |
+
context.append({'role': 'assistant', 'content': f"{response}"})
|
110 |
+
chat_history.append((message, response))
|
111 |
+
time.sleep(2)
|
112 |
+
return "", chat_history
|
113 |
+
|
114 |
+
|
115 |
+
with gr.Blocks() as demo:
|
116 |
+
chatbot = gr.Chatbot()
|
117 |
+
msg = gr.Textbox()
|
118 |
+
clear = gr.ClearButton([msg, chatbot])
|
119 |
+
|
120 |
+
msg.submit(respuesta_chatbot, [msg, chatbot], [msg, chatbot])
|
121 |
+
|
122 |
+
demo.launch(title="Cegaper GPT", description="¡Bienvenido a Cegaper GPT! Soy CegaperGPT, un servicio automatizado para recomendar la mejor opción de transporte de la compañía Cegaper y ayudarte a comprar tus tickets.")
|
requirements.txt
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
googlemaps==4.10.0
|
2 |
+
openai==0.27.8
|
utils.py
ADDED
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import googlemaps
|
2 |
+
import datetime
|
3 |
+
import os
|
4 |
+
|
5 |
+
# Crear un cliente de la API de Google Maps
|
6 |
+
gmaps = googlemaps.Client(key=os.environ["GOOGLE_MAPS_API_KEY"])
|
7 |
+
|
8 |
+
|
9 |
+
class Trip:
|
10 |
+
def __init__(self, origin, destination, departure_date, return_date, cost, car_type, pax):
|
11 |
+
self.origin = origin
|
12 |
+
self.destination = destination
|
13 |
+
self.departure_date = departure_date
|
14 |
+
self.return_date = return_date # esto puede ser None ahora
|
15 |
+
self.cost = cost
|
16 |
+
self.car_type = car_type
|
17 |
+
self.pax = pax
|
18 |
+
|
19 |
+
def to_dict(self):
|
20 |
+
trip_dict = {
|
21 |
+
'origin': self.origin,
|
22 |
+
'destination': self.destination,
|
23 |
+
'cost': self.cost,
|
24 |
+
'car_type': self.car_type,
|
25 |
+
'departure_date': self.departure_date.isoformat(),
|
26 |
+
'pax': self.pax
|
27 |
+
}
|
28 |
+
if self.return_date is not None:
|
29 |
+
trip_dict['return_date'] = self.return_date.isoformat()
|
30 |
+
return trip_dict
|
31 |
+
|
32 |
+
|
33 |
+
def determine_car_type(pax):
|
34 |
+
if 0 < pax < 6:
|
35 |
+
return "Transporter"
|
36 |
+
elif pax < 16:
|
37 |
+
return "Crafter"
|
38 |
+
elif pax < 23:
|
39 |
+
return "Minibus"
|
40 |
+
elif pax < 50:
|
41 |
+
return "Bus"
|
42 |
+
else:
|
43 |
+
return "Invalid"
|
44 |
+
|
45 |
+
|
46 |
+
def get_distance(origin: str, destination: str):
|
47 |
+
matrix = gmaps.distance_matrix(origin, destination)
|
48 |
+
distance_meters = matrix['rows'][0]['elements'][0]['distance']['value']
|
49 |
+
return distance_meters / 1000
|
50 |
+
|
51 |
+
|
52 |
+
def calculate_cost(distance, car_type):
|
53 |
+
base_cost_per_km = {
|
54 |
+
"Transporter": 50,
|
55 |
+
"Crafter": 75,
|
56 |
+
"Minibus": 100,
|
57 |
+
"Bus": 150
|
58 |
+
}
|
59 |
+
cost = distance * base_cost_per_km[car_type]
|
60 |
+
return round(max(500, min(20000, cost)))
|
61 |
+
|
62 |
+
|
63 |
+
def generate_trip_data(origin: str, destination: str, date_from: datetime, date_to: datetime, car_type: str, pax: int):
|
64 |
+
distance = get_distance(origin, destination)
|
65 |
+
base_cost = calculate_cost(distance, car_type)
|
66 |
+
trip = Trip(origin, destination, date_from,
|
67 |
+
date_to, base_cost, car_type, pax)
|
68 |
+
return trip
|
69 |
+
|
70 |
+
|
71 |
+
def get_trip(origin: str, destination: str, date_from: str, date_to=None, pax=1, round_trip: bool = False):
|
72 |
+
date_from = datetime.datetime.strptime(date_from, "%Y-%m-%d")
|
73 |
+
|
74 |
+
if date_to is not None:
|
75 |
+
date_to = datetime.datetime.strptime(date_to, "%Y-%m-%d")
|
76 |
+
|
77 |
+
car_type = determine_car_type(pax)
|
78 |
+
|
79 |
+
trip_origin = generate_trip_data(
|
80 |
+
origin, destination, date_from, date_to if round_trip else None, car_type, pax)
|
81 |
+
|
82 |
+
trip_return = None
|
83 |
+
if round_trip and date_to is not None:
|
84 |
+
trip_return = generate_trip_data(
|
85 |
+
destination, origin, date_to, None, car_type, pax)
|
86 |
+
|
87 |
+
trip_origin_dict = trip_origin.to_dict()
|
88 |
+
|
89 |
+
trip_info = "The trip to your destination is from " + trip_origin_dict['origin'] + " to " + trip_origin_dict['destination'] + " with a cost of " + str(
|
90 |
+
trip_origin_dict['cost']) + " and a car type of " + trip_origin_dict['car_type'] + ". "
|
91 |
+
|
92 |
+
if trip_return is not None:
|
93 |
+
trip_return_dict = trip_return.to_dict()
|
94 |
+
trip_info += "The return trip is from " + trip_return_dict['origin'] + " to " + trip_return_dict['destination'] + " with a cost of " + str(
|
95 |
+
trip_return_dict['cost']) + " and a car type of " + trip_return_dict['car_type'] + "."
|
96 |
+
|
97 |
+
return trip_info
|
98 |
+
|
99 |
+
|
100 |
+
def get_trip_info(trip_origin: Trip, trip_return: Trip = None):
|
101 |
+
trip_origin = trip_origin.to_dict()
|
102 |
+
trip_info = "The trip to your destination is from " + trip_origin['origin'] + " to " + trip_origin['destination'] + " with a cost of " + str(
|
103 |
+
trip_origin['cost']) + " and a car type of " + trip_origin['car_type'] + ". "
|
104 |
+
|
105 |
+
if trip_return is not None:
|
106 |
+
trip_return = trip_return.to_dict()
|
107 |
+
trip_info += "The return trip is from " + trip_return['origin'] + " to " + trip_return['destination'] + " with a cost of " + str(
|
108 |
+
trip_return['cost']) + " and a car type of " + trip_return['car_type'] + "."
|
109 |
+
|
110 |
+
return trip_info
|