Josedcape commited on
Commit
ec9848d
·
verified ·
1 Parent(s): 1cbcaf3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +82 -220
app.py CHANGED
@@ -11,8 +11,6 @@ import PyPDF2
11
  import time
12
  from google.cloud import texttospeech
13
  from streamlit_webrtc import webrtc_streamer, WebRtcMode, AudioProcessorBase
14
- from Historial.historial_chat import cargar_historial, guardar_historial
15
- from agent_functions import menu_df, tomar_pedido_agente, procesar_orden_agente, generar_pdf_orden, obtener_respuesta, generar_mensaje_automatico
16
 
17
  # Configuración de NLTK
18
  nltk.download('punkt')
@@ -56,96 +54,103 @@ class AudioProcessor(AudioProcessorBase):
56
  self.audio_bytes += frame.to_ndarray().tobytes()
57
  return frame
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  # Main App
60
  def main():
61
  # --- Diseño general ---
62
- st.set_page_config(page_title="Asistente Virtual", page_icon="🤖")
63
 
64
  # --- Estilos CSS personalizados ---
65
  st.markdown(
66
  """
67
  <style>
68
  body {
69
- background: rgb(241,241,234);
70
- background: radial-gradient(circle, rgba(241,241,234,1) 4%, rgba(255,127,8,1) 36%, rgba(235,255,8,1) 94%, rgba(0,0,255,1) 99%);
71
- }
72
- h1, h2, h3, h4, h5, h6 {
73
- color: green !important;
74
- font-weight: bold !important;
75
- }
76
- .stChatFloatingInputContainer {
77
- background-color: rgba(255, 255, 255, 0.8);
78
- border-radius: 10px;
79
- }
80
- .stTextInput > div > div > input {
81
  color: #333;
82
  }
83
- [data-testid="stChatMessage"] {
84
- background-color: black !important;
85
- color: gold !important;
86
  border-radius: 10px;
87
  }
88
- [data-testid="stChatMessage"] p {
89
- color: gold !important;
 
90
  }
91
- ::-webkit-scrollbar {
92
- width: 16px;
 
93
  }
94
- ::-webkit-scrollbar-thumb {
95
- background-color: #FFD700;
 
96
  border-radius: 10px;
97
  }
98
- .st-spinner > div {
99
- border-top-color: transparent;
100
- border-right-color: transparent;
101
- animation: spin 1s linear infinite;
102
- }
103
- @keyframes spin {
104
- from { transform: rotate(0deg); }
105
- to { transform: rotate(360deg); }
106
  }
107
  </style>
108
  """,
109
  unsafe_allow_html=True,
110
  )
111
 
112
- # --- Barra lateral ---
113
- with st.sidebar:
114
- st.image("hamburguesa napolitana.jpg")
115
- st.title("🤖 RESTAURANTE SAZON BURGER 🍔✨-BOTIDINAMIX AI")
116
- st.markdown("---")
117
 
118
- # Opciones de navegación
119
- pagina = st.selectbox("Selecciona una página", ["Chat", "Subir PDF", "Agentes"])
 
 
120
 
121
- # --- Página principal ---
122
- if pagina == "Chat":
123
- mostrar_chat()
124
- elif pagina == "Subir PDF":
125
- mostrar_subir_pdf()
126
- elif pagina == "Agentes":
127
- mostrar_agentes()
128
- else:
129
- mostrar_principal()
130
 
131
- def mostrar_chat():
132
- # --- Botones de historial ---
133
- if st.button("Buscar Historial"):
134
- st.session_state.mostrar_historial = True
135
- if st.button("Borrar Historial"):
136
- st.session_state.mensajes = []
137
- st.session_state.mostrar_historial = False
138
- st.success("Historial borrado correctamente")
139
 
140
- # --- Chatbot ---
 
 
 
141
  if 'mensajes' not in st.session_state:
142
- st.session_state.mensajes = cargar_historial()
143
 
144
  for mensaje in st.session_state.mensajes:
145
  with st.chat_message(mensaje["role"]):
146
  st.markdown(mensaje["content"])
147
 
148
- # Función para manejar la entrada de audio
149
  def on_audio(audio_bytes):
150
  with st.spinner("Transcribiendo..."):
151
  transcript = openai.Audio.transcribe("whisper-1", audio_bytes)
@@ -156,46 +161,26 @@ def mostrar_chat():
156
 
157
  st.subheader("🎤 Captura de voz")
158
  st.info("Haz clic en el micrófono y comienza a hablar. Tu pregunta se transcribirá automáticamente.")
159
- with st.container():
160
- if st.button("Grabar 🎙️"):
161
- st.session_state.run_webrtc = True
162
- if st.session_state.get("run_webrtc", False):
163
- webrtc_ctx = webrtc_streamer(
164
- key="example",
165
- mode=WebRtcMode.SENDONLY,
166
- audio_receiver_size=256,
167
- rtc_configuration={
168
- "iceServers": [{"urls": ["stun:stun.l.google.com:19302"]}]
169
- },
170
- media_stream_constraints={"audio": True},
171
- audio_processor_factory=AudioProcessor,
172
- )
173
-
174
- if webrtc_ctx.audio_receiver:
175
- audio_frames = webrtc_ctx.audio_receiver.get_frames(timeout=1)
176
- for audio_frame in audio_frames:
177
- audio_bytes = audio_frame.to_ndarray().tobytes()
178
- on_audio(audio_bytes)
179
 
180
  st.markdown("---")
181
- st.subheader("📄 Subir PDF")
182
- st.info("Sube un archivo PDF y el asistente responderá en función de su contenido.")
183
- archivo_pdf = st.file_uploader("Selecciona un archivo PDF", type=["pdf"])
184
-
185
- texto_extraido = ""
186
- if archivo_pdf:
187
- texto_extraido = extraer_texto_pdf(archivo_pdf)
188
- st.success("Texto extraído del PDF exitosamente.")
189
- st.text_area("Texto extraído", value=texto_extraido, height=200)
190
-
191
- if not texto_extraido:
192
- texto_extraido = st.text_area("Texto extraído", height=200)
193
-
194
- texto_preprocesado = preprocesar_texto(texto_extraido)
195
-
196
- # --- Opciones de entrada de usuario ---
197
- st.markdown("---")
198
- pregunta_usuario = st.text_input("Escribe tu pregunta:")
199
  if st.button("Enviar"):
200
  if pregunta_usuario:
201
  st.session_state.mensajes.append({"role": "user", "content": pregunta_usuario, "timestamp": time.time()})
@@ -208,129 +193,6 @@ def mostrar_chat():
208
  with st.chat_message("assistant"):
209
  st.markdown(respuesta)
210
  st.audio(audio_path, format="audio/mp3", start_time=0, autoplay=True)
211
-
212
- # Reproducir video automáticamente
213
- st.video("https://www.canva.com/design/DAGJTK28LQ8/VJaWOIwiJcHVuEuTnVx_vA/edit?utm_content=DAGJTK28LQ8&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton", start_time=0)
214
-
215
- guardar_historial(st.session_state.mensajes)
216
- else:
217
- st.warning("Por favor, ingresa una pregunta antes de enviar.")
218
-
219
- def mostrar_subir_pdf():
220
- st.subheader("📄 Subir PDF")
221
- st.info("Sube un archivo PDF y el asistente responderá en función de su contenido.")
222
- archivo_pdf = st.file_uploader("Selecciona un archivo PDF", type=["pdf"])
223
-
224
- texto_extraido = ""
225
- if archivo_pdf:
226
- texto_extraido = extraer_texto_pdf(archivo_pdf)
227
- st.success("Texto extraído del PDF exitosamente.")
228
- st.text_area("Texto extraído", value=texto_extraido, height=200)
229
-
230
- if not texto_extraido:
231
- texto_extraido = st.text_area("Texto extraído", height=200)
232
-
233
- texto_preprocesado = preprocesar_texto(texto_extraido)
234
-
235
- # --- Opciones de entrada de usuario ---
236
- st.markdown("---")
237
- pregunta_usuario = st.text_input("Escribe tu pregunta:")
238
- if st.button("Enviar"):
239
- if pregunta_usuario:
240
- st.session_state.mensajes.append({"role": "user", "content": pregunta_usuario, "timestamp": time.time()})
241
- with st.chat_message("user"):
242
- st.markdown(pregunta_usuario)
243
-
244
- with st.spinner("Generando respuesta..."):
245
- respuesta, audio_path = obtener_respuesta(pregunta_usuario, texto_preprocesado, modelo="gpt-4", temperatura=0.5)
246
- st.session_state.mensajes.append({"role": "assistant", "content": respuesta, "timestamp": time.time()})
247
- with st.chat_message("assistant"):
248
- st.markdown(respuesta)
249
- st.audio(audio_path, format="audio/mp3", start_time=0, autoplay=True)
250
-
251
- guardar_historial(st.session_state.mensajes)
252
- else:
253
- st.warning("Por favor, ingresa una pregunta antes de enviar.")
254
-
255
- def mostrar_agentes():
256
- st.subheader("📋 Menú y Pedidos")
257
- st.success("Menú cargado exitosamente. Listo para tomar pedidos.")
258
- st.write(menu_df)
259
-
260
- # Captura de pedido
261
- st.markdown("Selecciona los items del menú:")
262
- items_seleccionados = st.multiselect("Items", menu_df['item'].tolist())
263
-
264
- if st.button("Tomar Pedido"):
265
- if items_seleccionados:
266
- pedido_usuario = ','.join(items_seleccionados)
267
- confirmados = tomar_pedido_agente(pedido_usuario)
268
- st.info(f"Pedido confirmado: {confirmados}")
269
-
270
- total = procesar_orden_agente(','.join(confirmados))
271
- st.success(f"Total del pedido: ${total}")
272
-
273
- # Generar PDF de la orden
274
- order_details = {item: {'price': menu_df[menu_df['item'] == item]['price'].values[0]} for item in confirmados}
275
- pdf_path = generar_pdf_orden(order_details)
276
- st.markdown(f"[Descargar PDF de la Orden]({pdf_path})", unsafe_allow_html=True)
277
-
278
- # Generar mensaje automático
279
- mensaje_automatico = generar_mensaje_automatico(confirmados)
280
- st.session_state.mensajes_agente.append({"role": "assistant", "content": mensaje_automatico, "timestamp": time.time()})
281
- with st.chat_message("assistant"):
282
- st.markdown(mensaje_automatico)
283
-
284
- # --- Chat para Agentes ---
285
- st.subheader("Chat con Agentes")
286
- if 'mensajes_agente' not in st.session_state:
287
- st.session_state.mensajes_agente = []
288
-
289
- for mensaje in st.session_state.mensajes_agente:
290
- with st.chat_message(mensaje["role"]):
291
- st.markdown(mensaje["content"])
292
-
293
- agente_pregunta = st.text_input("Escribe tu pregunta para el agente:")
294
- if st.button("Enviar al Agente"):
295
- if agente_pregunta:
296
- st.session_state.mensajes_agente.append({"role": "user", "content": agente_pregunta, "timestamp": time.time()})
297
- with st.chat_message("user"):
298
- st.markdown(agente_pregunta)
299
-
300
- # Procesar la respuesta del agente
301
- with st.spinner("El agente está respondiendo..."):
302
- respuesta_agente, audio_path = obtener_respuesta(agente_pregunta, '', modelo="gpt-4", temperatura=0.5)
303
- st.session_state.mensajes_agente.append({"role": "assistant", "content": respuesta_agente, "timestamp": time.time()})
304
- with st.chat_message("assistant"):
305
- st.markdown(respuesta_agente)
306
- st.audio(audio_path, format="audio/mp3", start_time=0, autoplay=True)
307
- else:
308
- st.warning("Por favor, ingresa una pregunta antes de enviar.")
309
-
310
- def mostrar_principal():
311
- st.subheader("🗣️ Asistente Virtual con Chat y Respuestas en Voz")
312
- st.video("", start_time=0)
313
-
314
- if 'mensajes' not in st.session_state:
315
- st.session_state.mensajes = []
316
-
317
- for mensaje in st.session_state.mensajes:
318
- with st.chat_message(mensaje["role"]):
319
- st.markdown(mensaje["content"])
320
-
321
- pregunta_usuario = st.text_input("Escribe tu pregunta:")
322
- if st.button("Enviar"):
323
- if pregunta_usuario:
324
- st.session_state.mensajes.append({"role": "user", "content": pregunta_usuario, "timestamp": time.time()})
325
- with st.chat_message("user"):
326
- st.markdown(pregunta_usuario)
327
-
328
- with st.spinner("Generando respuesta..."):
329
- respuesta, audio_path = obtener_respuesta(pregunta_usuario, '', modelo="gpt-4", temperatura=0.5)
330
- st.session_state.mensajes.append({"role": "assistant", "content": respuesta, "timestamp": time.time()})
331
- with st.chat_message("assistant"):
332
- st.markdown(respuesta)
333
- st.audio(audio_path, format="audio/mp3", start_time=0, autoplay=True)
334
  else:
335
  st.warning("Por favor, ingresa una pregunta antes de enviar.")
336
 
 
11
  import time
12
  from google.cloud import texttospeech
13
  from streamlit_webrtc import webrtc_streamer, WebRtcMode, AudioProcessorBase
 
 
14
 
15
  # Configuración de NLTK
16
  nltk.download('punkt')
 
54
  self.audio_bytes += frame.to_ndarray().tobytes()
55
  return frame
56
 
57
+ # Función para obtener respuestas
58
+ def obtener_respuesta(pregunta, contexto="", modelo="gpt-4", temperatura=0.5):
59
+ respuesta = openai.Completion.create(
60
+ engine=modelo,
61
+ prompt=f"Pregunta: {pregunta}\nContexto: {contexto}\nRespuesta:",
62
+ max_tokens=150,
63
+ temperature=temperatura,
64
+ ).choices[0].text.strip()
65
+
66
+ client = texttospeech.TextToSpeechClient()
67
+ synthesis_input = texttospeech.SynthesisInput(text=respuesta)
68
+ voice = texttospeech.VoiceSelectionParams(
69
+ language_code="es-ES",
70
+ ssml_gender=texttospeech.SsmlVoiceGender.NEUTRAL,
71
+ )
72
+ audio_config = texttospeech.AudioConfig(
73
+ audio_encoding=texttospeech.AudioEncoding.MP3,
74
+ )
75
+ response = client.synthesize_speech(
76
+ input=synthesis_input, voice=voice, audio_config=audio_config
77
+ )
78
+ audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name
79
+ with open(audio_path, "wb") as out:
80
+ out.write(response.audio_content)
81
+
82
+ return respuesta, audio_path
83
+
84
  # Main App
85
  def main():
86
  # --- Diseño general ---
87
+ st.set_page_config(page_title="Asistente Teológico", page_icon="📖")
88
 
89
  # --- Estilos CSS personalizados ---
90
  st.markdown(
91
  """
92
  <style>
93
  body {
94
+ background: #f2f3f5;
 
 
 
 
 
 
 
 
 
 
 
95
  color: #333;
96
  }
97
+ .stButton>button {
98
+ background-color: #4CAF50;
99
+ color: white;
100
  border-radius: 10px;
101
  }
102
+ .stTextInput>div>div>input {
103
+ border: 1px solid #4CAF50;
104
+ border-radius: 10px;
105
  }
106
+ .stMarkdown>div>p {
107
+ color: #4CAF50;
108
+ font-weight: bold;
109
  }
110
+ .stAudio {
111
+ margin-top: 20px;
112
+ border: 2px solid #4CAF50;
113
  border-radius: 10px;
114
  }
115
+ .stFileUploader>div>div>input {
116
+ border: 1px solid #4CAF50;
117
+ border-radius: 10px;
 
 
 
 
 
118
  }
119
  </style>
120
  """,
121
  unsafe_allow_html=True,
122
  )
123
 
124
+ # --- Encabezado ---
125
+ st.image("biblia.jpg")
126
+ st.title("📖 Asistente Teológico - BOTIDINAMIX AI")
127
+ st.markdown("Bienvenido al Asistente Teológico, donde puedes preguntar sobre interpretaciones y reflexiones bíblicas.")
 
128
 
129
+ # --- Subir PDF ---
130
+ st.subheader("📄 Subir PDF")
131
+ st.info("Sube un archivo PDF con contenido bíblico y el asistente responderá en función de su contenido.")
132
+ archivo_pdf = st.file_uploader("Selecciona un archivo PDF", type=["pdf"])
133
 
134
+ texto_extraido = ""
135
+ if archivo_pdf:
136
+ texto_extraido = extraer_texto_pdf(archivo_pdf)
137
+ st.success("Texto extraído del PDF exitosamente.")
138
+ st.text_area("Texto extraído", value=texto_extraido, height=200)
 
 
 
 
139
 
140
+ if not texto_extraido:
141
+ texto_extraido = st.text_area("Texto extraído", height=200)
 
 
 
 
 
 
142
 
143
+ texto_preprocesado = preprocesar_texto(texto_extraido)
144
+
145
+ # --- Chat ---
146
+ st.subheader("🗣️ Chat con el Asistente")
147
  if 'mensajes' not in st.session_state:
148
+ st.session_state.mensajes = []
149
 
150
  for mensaje in st.session_state.mensajes:
151
  with st.chat_message(mensaje["role"]):
152
  st.markdown(mensaje["content"])
153
 
 
154
  def on_audio(audio_bytes):
155
  with st.spinner("Transcribiendo..."):
156
  transcript = openai.Audio.transcribe("whisper-1", audio_bytes)
 
161
 
162
  st.subheader("🎤 Captura de voz")
163
  st.info("Haz clic en el micrófono y comienza a hablar. Tu pregunta se transcribirá automáticamente.")
164
+ if st.button("Grabar 🎙️"):
165
+ webrtc_ctx = webrtc_streamer(
166
+ key="example",
167
+ mode=WebRtcMode.SENDONLY,
168
+ audio_receiver_size=256,
169
+ rtc_configuration={
170
+ "iceServers": [{"urls": ["stun:stun.l.google.com:19302"]}]
171
+ },
172
+ media_stream_constraints={"audio": True},
173
+ audio_processor_factory=AudioProcessor,
174
+ )
175
+
176
+ if webrtc_ctx.audio_receiver:
177
+ audio_frames = webrtc_ctx.audio_receiver.get_frames(timeout=1)
178
+ for audio_frame in audio_frames:
179
+ audio_bytes = audio_frame.to_ndarray().tobytes()
180
+ on_audio(audio_bytes)
 
 
 
181
 
182
  st.markdown("---")
183
+ pregunta_usuario = st.text_input("Escribe tu pregunta sobre la Biblia:")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  if st.button("Enviar"):
185
  if pregunta_usuario:
186
  st.session_state.mensajes.append({"role": "user", "content": pregunta_usuario, "timestamp": time.time()})
 
193
  with st.chat_message("assistant"):
194
  st.markdown(respuesta)
195
  st.audio(audio_path, format="audio/mp3", start_time=0, autoplay=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  else:
197
  st.warning("Por favor, ingresa una pregunta antes de enviar.")
198