Josedcape commited on
Commit
d9fd372
·
verified ·
1 Parent(s): 7611752

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +139 -136
app.py CHANGED
@@ -11,14 +11,51 @@ import PyPDF2
11
  import time
12
  from google.cloud import texttospeech
13
  from streamlit_webrtc import webrtc_streamer, WebRtcMode
14
- from Historial.historial_chat import cargar_historial, guardar_historial # Importa las funciones
15
- from data_manager import PedidoAgent, CalculoPedidoAgent
 
 
16
 
17
  # Configuración de NLTK
18
  nltk.download('punkt')
19
  nltk.download('stopwords')
20
 
21
- # Función para cargar el texto del PDF
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  def extraer_texto_pdf(archivo):
23
  texto = ""
24
  if archivo:
@@ -42,14 +79,6 @@ def preprocesar_texto(texto):
42
  tokens = [stemmer.stem(word) for word in tokens]
43
  return " ".join(tokens)
44
 
45
- # Cargar la clave API desde el archivo .env
46
- load_dotenv()
47
- os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "botidinamix-g.json" # Reemplaza 'key.json' con el nombre de tu archivo de credenciales
48
- openai.api_key = os.getenv("OPENAI_API_KEY")
49
-
50
- # Instancia el cliente de Text-to-Speech
51
- client = texttospeech.TextToSpeechClient()
52
-
53
  # Función para obtener respuesta de OpenAI usando el modelo GPT y convertir a audio
54
  def obtener_respuesta(pregunta, texto_preprocesado, modelo, temperatura=0.5):
55
  try:
@@ -91,6 +120,32 @@ def obtener_respuesta(pregunta, texto_preprocesado, modelo, temperatura=0.5):
91
  st.error(f"Error al comunicarse con OpenAI: {e}")
92
  return "Lo siento, no puedo procesar tu solicitud en este momento."
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  def main():
95
  # --- Diseño general ---
96
  st.set_page_config(page_title="Asistente Virtual", page_icon="🤖")
@@ -106,25 +161,25 @@ def main():
106
  """
107
  <style>
108
  body {
109
- background-image: linear-gradient(to right, #FFA500, #FFD700); /* Fondo degradado amarillo y naranja */
110
  }
111
  h1, h2, h3, h4, h5, h6 {
112
- color: green !important; /* Color verde para títulos */
113
- font-weight: bold !important; /* Negrilla */
114
  }
115
- .stChatFloatingInputContainer { /* Estilos para el contenedor del input del chat */
116
- background-color: rgba(255, 255, 255, 0.8); /* Fondo blanco con opacidad */
117
- border-radius: 10px; /* Bordes redondeados */
118
  }
119
- .stTextInput > div > div > input { /* Input de texto del chat */
120
- color: #333; /* Color de texto más oscuro */
121
  }
122
- [data-testid="stChatMessage"] { /* Burbujas de chat */
123
- background-color: black !important; /* Color de fondo negro */
124
- color: gold !important; /* Color de texto dorado */
125
  border-radius: 10px;
126
  }
127
- [data-testid="stChatMessage"] p { /* Párrafos dentro de las burbujas */
128
  color: gold !important;
129
  }
130
  </style>
@@ -163,130 +218,78 @@ def main():
163
  if st.button("Grabar 🎙️"):
164
  st.session_state.run_webrtc = True
165
  if st.session_state.get("run_webrtc", False):
166
- webrtc_streamer(
167
- key="speech-to-text",
168
- mode=WebRtcMode.SENDONLY,
169
- rtc_configuration={"iceServers": [{"urls": ["stun:stun.l.google.com:19302"]}]},
170
- media_stream_constraints={"video": False, "audio": True},
171
- on_audio=on_audio,
172
  )
173
- st.session_state["run_webrtc"] = False
174
-
175
- # Mostrar historial si el botón fue presionado
176
- if st.session_state.get("mostrar_historial", False):
177
- st.subheader("Historial de Chat:")
178
- if st.session_state.mensajes:
179
- for mensaje in st.session_state.mensajes:
180
- with st.chat_message(mensaje["role"]):
181
- st.markdown(mensaje["content"])
182
- else:
183
- st.info("No hay mensajes en el historial.")
184
- else:
185
- for mensaje in st.session_state.mensajes:
186
- with st.chat_message(mensaje["role"]):
187
- st.markdown(mensaje["content"])
188
-
189
- # Selección de modelo de lenguaje
190
- st.subheader("🧠 Configuración del Modelo")
191
- modelo = st.selectbox(
192
- "Selecciona el modelo:",
193
- ["gpt-3.5-turbo", "gpt-4"],
194
- index=0,
195
- help="Elige el modelo de lenguaje de OpenAI que prefieras."
196
- )
197
 
198
- # --- Opciones adicionales ---
199
- st.markdown("---")
200
- temperatura = st.slider("🌡️ Temperatura", min_value=0.0, max_value=1.0, value=0.5, step=0.1)
201
-
202
- # --- Video de fondo ---
203
- with st.container():
204
- st.markdown(
205
- f"""
206
- <style>
207
- #video-container {{
208
- position: relative;
209
- width: 100%;
210
- padding-bottom: 56.25%;
211
- background-color: lightblue;
212
- overflow: hidden;
213
- }}
214
- #background-video {{
215
- position: absolute;
216
- top: 0;
217
- left: 0;
218
- width: 100%;
219
- height: 100%;
220
- object-fit: cover;
221
- z-index: -1;
222
- }}
223
- </style>
224
- <div id="video-container">
225
- <video id="background-video" autoplay loop muted>
226
- <source src="https://path/to/your/video.mp4" type="video/mp4">
227
- </video>
228
- </div>
229
- """,
230
- unsafe_allow_html=True
231
- )
232
-
233
- st.markdown("---")
234
- st.subheader("📄 Subir PDF")
235
- st.info("Sube un archivo PDF y el asistente responderá en función de su contenido.")
236
- archivo_pdf = st.file_uploader("Selecciona un archivo PDF", type=["pdf"])
237
 
238
- texto_extraido = ""
239
- if archivo_pdf:
240
- texto_extraido = extraer_texto_pdf(archivo_pdf)
241
- st.success("Texto extraído del PDF exitosamente.")
242
- st.text_area("Texto extraído", value=texto_extraido, height=200)
243
 
244
- if not texto_extraido:
245
- texto_extraido = st.text_area("Texto extraído", height=200)
246
 
247
- texto_preprocesado = preprocesar_texto(texto_extraido)
248
 
249
- # --- Opciones de entrada de usuario ---
250
- st.markdown("---")
251
- pregunta_usuario = st.text_input("Escribe tu pregunta:")
252
- if st.button("Enviar"):
253
- if pregunta_usuario:
254
- st.session_state.mensajes.append({"role": "user", "content": pregunta_usuario, "timestamp": time.time()})
255
- with st.chat_message("user"):
256
- st.markdown(pregunta_usuario)
257
-
258
- respuesta = obtener_respuesta(pregunta_usuario, texto_preprocesado, modelo, temperatura)
259
- st.session_state.mensajes.append({"role": "assistant", "content": respuesta, "timestamp": time.time()})
260
- with st.chat_message("assistant"):
261
- st.markdown(respuesta)
262
-
263
- guardar_historial(st.session_state.mensajes)
264
- else:
265
- st.warning("Por favor, ingresa una pregunta antes de enviar.")
266
 
267
- # Instancia del agente de pedido
268
- pedido_agent = PedidoAgent()
 
 
269
 
270
- # --- Interacciones del agente de pedidos ---
271
- st.subheader("🚀 Consultar pedidos")
272
- id_pedido = st.text_input("ID del Pedido")
273
- if st.button("Consultar Pedido"):
274
- if id_pedido:
275
- st.info(pedido_agent.consultar_pedido(id_pedido))
276
  else:
277
- st.warning("Por favor, ingresa un ID de pedido.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
 
279
- # Instancia del agente de cálculo de pedidos
280
- calculo_pedido_agent = CalculoPedidoAgent()
281
 
282
- # --- Interacciones del agente de cálculo de pedidos ---
283
- st.subheader("📊 Calcular Pedido")
284
- descripcion_pedido = st.text_area("Descripción del Pedido")
285
- if st.button("Calcular"):
286
- if descripcion_pedido:
287
- st.info(calculo_pedido_agent.calcular_pedido(descripcion_pedido))
288
- else:
289
- st.warning("Por favor, ingresa la descripción del pedido.")
 
290
 
291
  if __name__ == "__main__":
292
  main()
 
11
  import time
12
  from google.cloud import texttospeech
13
  from streamlit_webrtc import webrtc_streamer, WebRtcMode
14
+ from Historial.historial_chat import cargar_historial, guardar_historial
15
+ from reportlab.lib.pagesizes import letter
16
+ from reportlab.pdfgen import canvas
17
+ import csv
18
 
19
  # Configuración de NLTK
20
  nltk.download('punkt')
21
  nltk.download('stopwords')
22
 
23
+ # Cargar la clave API desde el archivo .env
24
+ load_dotenv()
25
+ os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "botidinamix-g.json"
26
+ openai.api_key = os.getenv("OPENAI_API_KEY")
27
+
28
+ # Instancia el cliente de Text-to-Speech
29
+ client = texttospeech.TextToSpeechClient()
30
+
31
+ # Función para leer el archivo CSV del menú
32
+ def leer_menu_csv(filepath):
33
+ menu = {}
34
+ with open(filepath, mode='r', encoding='utf-8-sig') as file:
35
+ reader = csv.DictReader(file)
36
+ for row in reader:
37
+ item = row['item']
38
+ price = float(row['price'])
39
+ description = row['description']
40
+ menu[item] = {'price': price, 'description': description}
41
+ return menu
42
+
43
+ # Función para generar el PDF de la orden
44
+ def generar_pdf_orden(order_details, filepath='orden_compra.pdf'):
45
+ c = canvas.Canvas(filepath, pagesize=letter)
46
+ width, height = letter
47
+ c.drawString(100, height - 100, "Orden de Compra")
48
+ y = height - 120
49
+ total = 0
50
+ for item, details in order_details.items():
51
+ c.drawString(100, y, f"{item}: ${details['price']}")
52
+ y -= 20
53
+ total += details['price']
54
+ c.drawString(100, y - 20, f"Total: ${total}")
55
+ c.save()
56
+ return filepath
57
+
58
+ # Función para extraer texto del PDF
59
  def extraer_texto_pdf(archivo):
60
  texto = ""
61
  if archivo:
 
79
  tokens = [stemmer.stem(word) for word in tokens]
80
  return " ".join(tokens)
81
 
 
 
 
 
 
 
 
 
82
  # Función para obtener respuesta de OpenAI usando el modelo GPT y convertir a audio
83
  def obtener_respuesta(pregunta, texto_preprocesado, modelo, temperatura=0.5):
84
  try:
 
120
  st.error(f"Error al comunicarse con OpenAI: {e}")
121
  return "Lo siento, no puedo procesar tu solicitud en este momento."
122
 
123
+ # Definición de Agentes
124
+ class PedidoAgent:
125
+ def __init__(self, menu):
126
+ self.menu = menu
127
+
128
+ def tomar_pedido(self, pedido_usuario):
129
+ detalles_pedido = {}
130
+ for item in pedido_usuario.split(","):
131
+ item = item.strip()
132
+ if item in self.menu:
133
+ detalles_pedido[item] = self.menu[item]
134
+ else:
135
+ return f"El ítem '{item}' no está en el menú."
136
+ detalles = "\n".join([f"{item}: ${details['price']}" for item, details in detalles_pedido.items()])
137
+ return f"Detalles del pedido:\n{detalles}"
138
+
139
+ class CalculoPedidoAgent:
140
+ def __init__(self):
141
+ pass
142
+
143
+ def calcular_y_generar_pdf(self, detalles_pedido):
144
+ total = sum(details['price'] for details in detalles_pedido.values())
145
+ filepath = generar_pdf_orden(detalles_pedido)
146
+ return total, filepath
147
+
148
+ # Main App
149
  def main():
150
  # --- Diseño general ---
151
  st.set_page_config(page_title="Asistente Virtual", page_icon="🤖")
 
161
  """
162
  <style>
163
  body {
164
+ background-image: linear-gradient(to right, #FFA500, #FFD700);
165
  }
166
  h1, h2, h3, h4, h5, h6 {
167
+ color: green !important;
168
+ font-weight: bold !important;
169
  }
170
+ .stChatFloatingInputContainer {
171
+ background-color: rgba(255, 255, 255, 0.8);
172
+ border-radius: 10px;
173
  }
174
+ .stTextInput > div > div > input {
175
+ color: #333;
176
  }
177
+ [data-testid="stChatMessage"] {
178
+ background-color: black !important;
179
+ color: gold !important;
180
  border-radius: 10px;
181
  }
182
+ [data-testid="stChatMessage"] p {
183
  color: gold !important;
184
  }
185
  </style>
 
218
  if st.button("Grabar 🎙️"):
219
  st.session_state.run_webrtc = True
220
  if st.session_state.get("run_webrtc", False):
221
+ webrtc_ctx = webrtc_streamer(
222
+ key="example", mode=WebRtcMode.SENDONLY,
223
+ in_audio=True, on_audio_frame=on_audio,
 
 
 
224
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
 
226
+ st.markdown("---")
227
+ st.subheader("📄 Subir PDF")
228
+ st.info("Sube un archivo PDF y el asistente responderá en función de su contenido.")
229
+ archivo_pdf = st.file_uploader("Selecciona un archivo PDF", type=["pdf"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
 
231
+ texto_extraido = ""
232
+ if archivo_pdf:
233
+ texto_extraido = extraer_texto_pdf(archivo_pdf)
234
+ st.success("Texto extraído del PDF exitosamente.")
235
+ st.text_area("Texto extraído", value=texto_extraido, height=200)
236
 
237
+ if not texto_extraido:
238
+ texto_extraido = st.text_area("Texto extraído", height=200)
239
 
240
+ texto_preprocesado = preprocesar_texto(texto_extraido)
241
 
242
+ # --- Opciones de entrada de usuario ---
243
+ st.markdown("---")
244
+ pregunta_usuario = st.text_input("Escribe tu pregunta:")
245
+ if st.button("Enviar"):
246
+ if pregunta_usuario:
247
+ st.session_state.mensajes.append({"role": "user", "content": pregunta_usuario, "timestamp": time.time()})
248
+ with st.chat_message("user"):
249
+ st.markdown(pregunta_usuario)
 
 
 
 
 
 
 
 
 
250
 
251
+ respuesta = obtener_respuesta(pregunta_usuario, texto_preprocesado, modelo="gpt-4", temperatura=0.5)
252
+ st.session_state.mensajes.append({"role": "assistant", "content": respuesta, "timestamp": time.time()})
253
+ with st.chat_message("assistant"):
254
+ st.markdown(respuesta)
255
 
256
+ guardar_historial(st.session_state.mensajes)
 
 
 
 
 
257
  else:
258
+ st.warning("Por favor, ingresa una pregunta antes de enviar.")
259
+
260
+ # --- Lectura del menú desde CSV y creación de agentes ---
261
+ st.subheader("📋 Menú y Pedidos")
262
+ menu_csv = st.file_uploader("Sube el archivo CSV del menú", type=["csv"])
263
+
264
+ if menu_csv:
265
+ menu = leer_menu_csv(menu_csv)
266
+ st.success("Menú cargado exitosamente. Listo para tomar pedidos.")
267
+ st.write(menu)
268
+
269
+ # Crear instancia de PedidoAgent
270
+ pedido_agent = PedidoAgent(menu)
271
+
272
+ # Captura de pedido
273
+ pedido_usuario = st.text_input("Ingresa tu pedido (separado por comas):")
274
+ if st.button("Tomar Pedido"):
275
+ if pedido_usuario:
276
+ detalles_pedido = pedido_agent.tomar_pedido(pedido_usuario)
277
+ st.info(detalles_pedido)
278
+ else:
279
+ st.warning("Por favor, ingresa el pedido antes de continuar.")
280
 
281
+ # Crear instancia de CalculoPedidoAgent
282
+ calculo_pedido_agent = CalculoPedidoAgent()
283
 
284
+ # Cálculo y generación de PDF
285
+ if st.button("Calcular y Generar PDF"):
286
+ detalles_pedido = pedido_agent.tomar_pedido(pedido_usuario)
287
+ if isinstance(detalles_pedido, str):
288
+ st.warning("Primero toma el pedido correctamente.")
289
+ else:
290
+ total, filepath = calculo_pedido_agent.calcular_y_generar_pdf(detalles_pedido)
291
+ st.success(f"Total del pedido: ${total}")
292
+ st.markdown(f"[Descargar PDF de la Orden]({filepath})", unsafe_allow_html=True)
293
 
294
  if __name__ == "__main__":
295
  main()