Josedcape commited on
Commit
9b22f7b
·
verified ·
1 Parent(s): fa03cd5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +283 -349
app.py CHANGED
@@ -1,372 +1,306 @@
1
- import os
2
- from dotenv import load_dotenv
3
- from supabase import create_client, Client
4
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- # Cargar las claves API desde el archivo .env
 
 
 
 
7
  load_dotenv()
8
- supabase_url = os.getenv("SUPABASE_URL")
9
- supabase_key = os.getenv("SUPABASE_KEY")
10
-
11
- # Crear el cliente de Supabase
12
- supabase: Client = create_client(supabase_url, supabase_key)
13
-
14
- def obtener_datos():
15
- response = supabase.table('tu_tabla').select('*').execute()
16
- if response.status_code == 200:
17
- return response.data
18
- else:
19
- st.error(f"Error al obtener datos: {response.error.message}")
20
- return []
21
-
22
- def insertar_datos(datos):
23
- response = supabase.table('tu_tabla').insert(datos).execute()
24
- if response.status_code == 201:
25
- st.success("Datos insertados con éxito.")
26
- else:
27
- st.error(f"Error al insertar datos: {response.error.message}")
28
-
29
- def supabase_page():
30
- st.title("Acceso a Base de Datos en la Nube con Supabase")
31
-
32
- # Mostrar datos
33
- if st.button("Obtener Datos"):
34
- datos = obtener_datos()
35
- if datos:
36
- st.write(datos)
37
-
38
- # Insertar datos
39
- with st.form("insertar_datos_form"):
40
- columna1 = st.text_input("Valor para columna1")
41
- columna2 = st.text_input("Valor para columna2")
42
- submitted = st.form_submit_button("Insertar Datos")
43
- if submitted:
44
- datos = {
45
- "columna1": columna1,
46
- "columna2": columna2
47
- }
48
- insertar_datos(datos)
49
 
50
- def main():
51
- st.set_page_config(page_title="Galatea OMARDENT", layout="wide")
52
-
53
- # Inicializar el estado de la sesión
54
- if 'modelo' not in st.session_state:
55
- st.session_state['modelo'] = "gpt-3.5-turbo"
56
- if 'temperatura' not in st.session_state:
57
- st.session_state['temperatura'] = 0.5
58
- if 'mensajes_chat' not in st.session_state:
59
- st.session_state['mensajes_chat'] = []
60
- if 'transcripcion_voz' not in st.session_state:
61
- st.session_state['transcripcion_voz'] = ""
62
- if 'imagen_asistente' not in st.session_state:
63
- st.session_state['imagen_asistente'] = None
64
- if 'video_estado' not in st.session_state:
65
- st.session_state['video_estado'] = 'paused'
66
- if 'assistant_id' not in st.session_state:
67
- st.session_state['assistant_id'] = 'asst_4ZYvBvf4IUVQPjnugSZGLdV2'
68
- if 'presupuesto_texto' not in st.session_state:
69
- st.session_state['presupuesto_texto'] = ''
70
- if 'mostrar_chat' not in st.session_state:
71
- st.session_state['mostrar_chat'] = False
72
-
73
- # Barra lateral
74
- ruta_logo = os.path.join("assets", "Logo Omardent.png")
75
- if os.path.exists(ruta_logo):
76
- st.sidebar.image(ruta_logo, use_column_width=True)
77
- else:
78
- st.sidebar.warning(f"Error: No se pudo encontrar la imagen en la ruta: {ruta_logo}")
79
-
80
- st.sidebar.title("🤖 Galatea OMARDENT")
81
- st.sidebar.markdown("---")
82
- st.sidebar.subheader("🧠 Configuración del Modelo")
83
- st.session_state['modelo'] = st.sidebar.selectbox(
84
- "Selecciona el modelo:",
85
- ["gpt-3.5-turbo", "gpt-4", "gpt-4-32k", "gpt-4o"],
86
- index=0,
87
- key='modelo_selectbox', # Clave única
88
- help="Elige el modelo de lenguaje de OpenAI que prefieras."
89
- )
90
- st.sidebar.markdown("---")
91
- st.session_state['temperatura'] = st.sidebar.slider(
92
- "🌡️ Temperatura",
93
- min_value=0.0, max_value=1.0,
94
- value=st.session_state['temperatura'],
95
- step=0.1,
96
- key='temperatura_slider' # Clave única
97
- )
98
- assistant_id = st.sidebar.text_input("Assistant ID", key="assistant_id", help="Introduce el Assistant ID del playground de OpenAI")
99
-
100
- st.sidebar.markdown("---")
101
- st.sidebar.subheader("🌟 Navegación")
102
- lateral_page = st.sidebar.radio("Ir a", ["Página Principal", "Gestión de Trabajos", "Gestión de Insumos", "Registro de Radiografías", "Buscar Datos", "Notificaciones", "Recomendaciones", "Asistente de Presupuestos", "Comunicación", "Asistente de Agendamiento", "Supabase"])
103
-
104
- top_page = st.selectbox("Navegación Superior", ["Página Principal", "Galatea-Asistente"])
105
-
106
- if top_page == "Galatea-Asistente":
107
- mostrar_galatea_asistente()
108
- else:
109
- if lateral_page == "Página Principal":
110
- mostrar_pagina_principal()
111
- elif lateral_page == "Gestión de Trabajos":
112
- flujo_laboratorio()
113
- elif lateral_page == "Gestión de Insumos":
114
- flujo_insumos()
115
- elif lateral_page == "Registro de Radiografías":
116
- flujo_radiografias()
117
- elif lateral_page == "Buscar Datos":
118
- buscar_datos_guardados()
119
- elif lateral_page == "Notificaciones":
120
- generar_notificaciones_pendientes()
121
- elif lateral_page == "Recomendaciones":
122
- mostrar_recomendaciones()
123
- elif lateral_page == "Asistente de Presupuestos":
124
- flujo_presupuestos()
125
- elif lateral_page == "Comunicación":
126
- st.write("Página de Comunicación") # Implementar según sea necesario
127
- elif lateral_page == "Asistente de Agendamiento":
128
- st.write("Página de Agendamiento") # Implementar según sea necesario
129
- elif lateral_page == "Supabase":
130
- supabase_page()
131
-
132
- def mostrar_pagina_principal():
133
- st.title("VIRTUAL OMARDENT AI-BOTIDINAMIX")
134
- st.markdown(
135
- f"""
136
- <style>
137
- #video-container {{
138
- position: relative;
139
- width: 100%;
140
- padding-bottom: 56.25%;
141
- background-color: lightblue;
142
- overflow: hidden;
143
- }}
144
- #background-video {{
145
- position: absolute;
146
- top: 0;
147
- left: 0;
148
- width: 100%;
149
- height: 100%;
150
- }}
151
- </style>
152
- <div id="video-container">
153
- <video id="background-video" autoplay loop muted playsinline>
154
- <source src="https://cdn.leonardo.ai/users/645c3d5c-ca1b-4ce8-aefa-a091494e0d09/generations/0c4f0fe7-5937-4644-b984-bdbd95018990/0c4f0fe7-5937-4644-b984-bdbd95018990.mp4" type="video/mp4">
155
- </video>
156
- </div>
157
- """,
158
- unsafe_allow_html=True
159
- )
160
 
161
- archivo_pdf = st.file_uploader("📂 Cargar PDF", type='pdf', key='chat_pdf')
 
 
 
 
 
 
 
 
162
 
163
- col1, col2 = st.columns([3, 1])
164
- with col1:
165
- pregunta_usuario = st.text_input("Pregunta:", key='unique_chat_input_key', value=st.session_state['transcripcion_voz'])
166
- with col2:
167
- capturar_voz()
168
-
169
- if pregunta_usuario:
170
- manejar_pregunta_usuario(pregunta_usuario, archivo_pdf)
171
 
172
- def mostrar_galatea_asistente():
 
 
 
 
 
 
 
 
 
173
  st.markdown(
174
  """
175
  <style>
176
- #video-container {
177
- position: relative;
178
- width: 100%;
179
- height: 40vh;
180
- background-color: lightblue;
181
- overflow: hidden;
182
- display: flex;
183
- justify-content: center;
184
- align-items: center;
185
- }
186
- #background-video {
187
- width: 100%;
188
- height: auto;
189
- }
190
- #chat-container {
191
- margin-top: 20px;
192
- width: 100%;
193
- display: flex;
194
- flex-direction: column;
195
- justify-content: center;
196
- align-items: center;
197
- }
198
- .chat-message {
199
- background: rgba(255, 255, 255, 0.8);
200
- border-radius: 10px;
201
- padding: 10px;
202
- margin-bottom: 10px;
203
- max-width: 70%;
204
- }
205
- .chat-message.user {
206
- align-self: flex-start;
207
- }
208
- .chat-message.assistant {
209
- align-self: flex-end;
210
- background: rgba(0, 123, 255, 0.8);
211
- color: white;
212
- }
 
 
213
  </style>
214
- <div id="video-container">
215
- <video id="background-video" autoplay loop muted playsinline>
216
- <source src="https://cdn.leonardo.ai/users/645c3d5c-ca1b-4ce8-aefa-a091494e0d09/generations/aaa569a1-8952-4e8e-9c3c-71cc66e62f04/aaa569a1-8952-4e8e-9c3c-71cc66e62f04.mp4" type="video/mp4">
217
- </video>
218
- </div>
219
- <div id="chat-container">
220
  """,
221
- unsafe_allow_html=True
222
  )
223
 
224
- for mensaje in st.session_state['mensajes_chat']:
225
- clase = "user" if mensaje["role"] == "user" else "assistant"
226
- st.markdown(f'<div class="chat-message {clase}">{mensaje["content"]}</div>', unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
 
228
- pregunta_usuario = st.text_input("Escribe tu pregunta aquí:", key='unique_chat_input_key', value=st.session_state['transcripcion_voz'])
229
- if st.button("Enviar Pregunta"):
230
- manejar_pregunta_usuario(pregunta_usuario)
231
 
232
- st.markdown("</div>", unsafe_allow_html=True)
 
 
 
 
 
 
 
233
 
234
- if st.session_state['imagen_asistente']:
235
- st.image(st.session_state['imagen_asistente'], use_column_width=True)
236
- else:
237
- st.warning("No se ha cargado ninguna imagen. Por favor, carga una imagen en la página principal.")
 
 
 
 
 
 
 
 
 
 
 
 
238
 
239
- def manejar_pregunta_usuario(pregunta_usuario, archivo_pdf=None):
240
- st.session_state['mensajes_chat'].append({"role": "user", "content": pregunta_usuario})
241
- with st.chat_message("user"):
242
- st.markdown(pregunta_usuario)
 
243
 
244
- texto_preprocesado = ""
 
 
 
 
 
245
  if archivo_pdf:
246
- texto_pdf = extraer_texto_pdf(archivo_pdf)
247
- texto_preprocesado = preprocesar_texto(texto_pdf)
248
- else:
249
- with open("assets/instrucciones.pdf", "rb") as file:
250
- texto_pdf = extraer_texto_pdf(file)
251
- texto_preprocesado = preprocesar_texto(texto_pdf)
252
-
253
- # Obtener respuesta del modelo usando Assistant ID si está presente
254
- assistant_id = st.session_state.get('assistant_id', '')
255
- if assistant_id:
256
- prompt = f"{texto_preprocesado}\n\n{pregunta_usuario}"
257
- response = openai.ChatCompletion.create(
258
- model=st.session_state['modelo'],
259
- messages=[
260
- {"role": "system", "content": "You are a helpful assistant."},
261
- {"role": "user", "content": prompt}
262
- ],
263
- temperature=st.session_state['temperatura'],
264
- user=assistant_id
265
- )
266
- respuesta = response.choices[0].message['content'].strip()
267
- else:
268
- respuesta = obtener_respuesta(
269
- pregunta_usuario,
270
- texto_preprocesado,
271
- st.session_state['modelo'],
272
- st.session_state['temperatura'],
273
- assistant_id
274
- )
275
-
276
- st.session_state['mensajes_chat'].append({"role": "assistant", "content": respuesta})
277
- with st.chat_message("assistant"):
278
- st.markdown(respuesta)
279
-
280
- # Convertir la respuesta en voz
281
- client = texttospeech.TextToSpeechClient()
282
- synthesis_input = texttospeech.SynthesisInput(text=respuesta)
283
- voice = texttospeech.VoiceSelectionParams(language_code="es-ES", ssml_gender=texttospeech.SsmlVoiceGender.FEMALE)
284
- audio_config = texttospeech.AudioConfig(audio_encoding=texttospeech.AudioEncoding.MP3)
285
- response = client.synthesize_speech(input=synthesis_input, voice=voice, audio_config=audio_config)
286
-
287
- with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp_file:
288
- tmp_file.write(response.audio_content)
289
- audio_file_path = tmp_file.name
290
-
291
- # Incrustar el audio en la página y reproducirlo automáticamente
292
- audio_html = f"""
293
- <audio id="response-audio" src="data:audio/mp3;base64,{base64.b64encode(response.audio_content).decode()}" autoplay></audio>
294
- <script>
295
- document.getElementById('response-audio').onended = function() {{
296
- document.getElementById('background-video').pause();
297
- }};
298
- </script>
299
- """
300
- st.markdown(audio_html, unsafe_allow_html=True)
301
-
302
- # Reproducir el video solo cuando el chat está activo
303
- st.session_state['video_estado'] = 'playing'
304
- st.markdown(f"<script>document.getElementById('background-video').play();</script>", unsafe_allow_html=True)
305
-
306
- def capturar_voz():
307
- st.markdown(
308
- """
309
- <style>
310
- .assistant-button {
311
- display: flex;
312
- align-items: center;
313
- justify-content: center;
314
- background-color: #4CAF50;
315
- color: white;
316
- padding: 10px;
317
- border: none;
318
- border-radius: 5px;
319
- cursor: pointer;
320
- font-size: 16px;
321
- margin-top: 10px;
322
- }
323
- .assistant-button img {
324
- margin-right: 10px;
325
- }
326
- </style>
327
- <button class="assistant-button" onclick="startRecording()">
328
- <img src='https://img2.gratispng.com/20180808/cxq/kisspng-robotics-science-computer-icons-robot-technology-robo-to-logo-svg-png-icon-free-download-45527-5b6baa46a5e322.4713113715337825986795.jpg' alt='icon' width='20' height='20'/>
329
- Capturar Voz
330
- </button>
331
- <script>
332
- function startRecording() {
333
- const recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
334
- recognition.lang = 'es-ES';
335
- recognition.interimResults = false;
336
- recognition.maxAlternatives = 1;
337
- recognition.start();
338
- recognition.onresult = (event) => {
339
- const lastResult = event.results.length - 1;
340
- const text = event.results[lastResult][0].transcript;
341
- const customEvent = new CustomEvent('audioTranscription', { detail: text });
342
- document.dispatchEvent(customEvent);
343
- };
344
- recognition.onspeechend = () => {
345
- recognition.stop();
346
- };
347
- recognition.onerror = (event) => {
348
- console.error(event.error);
349
- };
350
- }
351
- document.addEventListener('audioTranscription', (event) => {
352
- const transcription = event.detail;
353
- document.querySelector("input[name='unique_chat_input_key']").value = transcription;
354
- // También puedes actualizar el estado de Streamlit aquí si es necesario
355
- fetch('/process_audio', {
356
- method: 'POST',
357
- headers: {
358
- 'Content-Type': 'application/json'
359
- },
360
- body: JSON.stringify({ transcription })
361
- }).then(response => response.json())
362
- .then(data => {
363
- // Manejo de la respuesta de Flask si es necesario
364
- });
365
- });
366
- </script>
367
- """,
368
- unsafe_allow_html=True
369
- )
370
 
371
  if __name__ == "__main__":
372
  main()
 
 
 
 
1
  import streamlit as st
2
+ import openai
3
+ from dotenv import load_dotenv
4
+ import nltk
5
+ import os
6
+ import tempfile
7
+ from nltk.tokenize import word_tokenize
8
+ from nltk.corpus import stopwords
9
+ from nltk.stem import SnowballStemmer
10
+ 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')
19
+ nltk.download('stopwords')
20
+
21
+ # Cargar la clave API desde el archivo .env
22
  load_dotenv()
23
+ os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "botidinamix-g.json"
24
+ openai.api_key = os.getenv("OPENAI_API_KEY")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
+ # Función para extraer texto del PDF
27
+ def extraer_texto_pdf(archivo):
28
+ texto = ""
29
+ if archivo:
30
+ with tempfile.NamedTemporaryFile(delete=False) as temp_file:
31
+ temp_file.write(archivo.read())
32
+ temp_file_path = temp_file.name
33
+ with open(temp_file_path, 'rb') as file:
34
+ reader = PyPDF2.PdfReader(file)
35
+ for page in range(len(reader.pages)):
36
+ texto += reader.pages[page].extract_text()
37
+ os.unlink(temp_file_path)
38
+ return texto
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
+ # Función para preprocesar texto
41
+ def preprocesar_texto(texto):
42
+ tokens = word_tokenize(texto, language='spanish')
43
+ tokens = [word.lower() for word in tokens if word.isalpha()]
44
+ stopwords_es = set(stopwords.words('spanish'))
45
+ tokens = [word for word in tokens if word not in stopwords_es]
46
+ stemmer = SnowballStemmer('spanish')
47
+ tokens = [stemmer.stem(word) for word in tokens]
48
+ return " ".join(tokens)
49
 
50
+ # Clase para procesar audio
51
+ class AudioProcessor(AudioProcessorBase):
52
+ def __init__(self):
53
+ self.audio_bytes = b''
 
 
 
 
54
 
55
+ def recv(self, frame):
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
+
129
+ def mostrar_chat():
130
+ # --- Botones de historial ---
131
+ if st.button("Buscar Historial"):
132
+ st.session_state.mostrar_historial = True
133
+ if st.button("Borrar Historial"):
134
+ st.session_state.mensajes = []
135
+ st.session_state.mostrar_historial = False
136
+ st.success("Historial borrado correctamente")
137
+
138
+ # --- Chatbot ---
139
+ if 'mensajes' not in st.session_state:
140
+ st.session_state.mensajes = cargar_historial()
141
 
142
+ for mensaje in st.session_state.mensajes:
143
+ with st.chat_message(mensaje["role"]):
144
+ st.markdown(mensaje["content"])
145
 
146
+ # Función para manejar la entrada de audio
147
+ def on_audio(audio_bytes):
148
+ with st.spinner("Transcribiendo..."):
149
+ transcript = openai.Audio.transcribe("whisper-1", audio_bytes)
150
+ pregunta_usuario = transcript["text"]
151
+ st.session_state.mensajes.append({"role": "user", "content": pregunta_usuario, "timestamp": time.time()})
152
+ with st.chat_message("user"):
153
+ st.markdown(pregunta_usuario)
154
 
155
+ st.subheader("🎤 Captura de voz")
156
+ st.info("Haz clic en el micrófono y comienza a hablar. Tu pregunta se transcribirá automáticamente.")
157
+ with st.container():
158
+ if st.button("Grabar 🎙️"):
159
+ st.session_state.run_webrtc = True
160
+ if st.session_state.get("run_webrtc", False):
161
+ webrtc_ctx = webrtc_streamer(
162
+ key="example",
163
+ mode=WebRtcMode.SENDONLY,
164
+ audio_receiver_size=256,
165
+ rtc_configuration={
166
+ "iceServers": [{"urls": ["stun:stun.l.google.com:19302"]}]
167
+ },
168
+ media_stream_constraints={"audio": True},
169
+ audio_processor_factory=AudioProcessor,
170
+ )
171
 
172
+ if webrtc_ctx.audio_receiver:
173
+ audio_frames = webrtc_ctx.audio_receiver.get_frames(timeout=1)
174
+ for audio_frame in audio_frames:
175
+ audio_bytes = audio_frame.to_ndarray().tobytes()
176
+ on_audio(audio_bytes)
177
 
178
+ st.markdown("---")
179
+ st.subheader("📄 Subir PDF")
180
+ st.info("Sube un archivo PDF y el asistente responderá en función de su contenido.")
181
+ archivo_pdf = st.file_uploader("Selecciona un archivo PDF", type=["pdf"])
182
+
183
+ texto_extraido = ""
184
  if archivo_pdf:
185
+ texto_extraido = extraer_texto_pdf(archivo_pdf)
186
+ st.success("Texto extraído del PDF exitosamente.")
187
+ st.text_area("Texto extraído", value=texto_extraido, height=200)
188
+
189
+ if not texto_extraido:
190
+ texto_extraido = st.text_area("Texto extraído", height=200)
191
+
192
+ texto_preprocesado = preprocesar_texto(texto_extraido)
193
+
194
+ # --- Opciones de entrada de usuario ---
195
+ st.markdown("---")
196
+ pregunta_usuario = st.text_input("Escribe tu pregunta:")
197
+ if st.button("Enviar"):
198
+ if pregunta_usuario:
199
+ st.session_state.mensajes.append({"role": "user", "content": pregunta_usuario, "timestamp": time.time()})
200
+ with st.chat_message("user"):
201
+ st.markdown(pregunta_usuario)
202
+
203
+ with st.spinner("Generando respuesta..."):
204
+ respuesta, audio_path = obtener_respuesta(pregunta_usuario, texto_preprocesado, modelo="gpt-4", temperatura=0.5)
205
+ st.session_state.mensajes.append({"role": "assistant", "content": respuesta, "timestamp": time.time()})
206
+ with st.chat_message("assistant"):
207
+ st.markdown(respuesta)
208
+ st.audio(audio_path, format="audio/mp3", start_time=0)
209
+
210
+ guardar_historial(st.session_state.mensajes)
211
+ else:
212
+ st.warning("Por favor, ingresa una pregunta antes de enviar.")
213
+
214
+ def mostrar_subir_pdf():
215
+ st.subheader("📄 Subir PDF")
216
+ st.info("Sube un archivo PDF y el asistente responderá en función de su contenido.")
217
+ archivo_pdf = st.file_uploader("Selecciona un archivo PDF", type=["pdf"])
218
+
219
+ texto_extraido = ""
220
+ if archivo_pdf:
221
+ texto_extraido = extraer_texto_pdf(archivo_pdf)
222
+ st.success("Texto extraído del PDF exitosamente.")
223
+ st.text_area("Texto extraído", value=texto_extraido, height=200)
224
+
225
+ if not texto_extraido:
226
+ texto_extraido = st.text_area("Texto extraído", height=200)
227
+
228
+ texto_preprocesado = preprocesar_texto(texto_extraido)
229
+
230
+ # --- Opciones de entrada de usuario ---
231
+ st.markdown("---")
232
+ pregunta_usuario = st.text_input("Escribe tu pregunta:")
233
+ if st.button("Enviar"):
234
+ if pregunta_usuario:
235
+ st.session_state.mensajes.append({"role": "user", "content": pregunta_usuario, "timestamp": time.time()})
236
+ with st.chat_message("user"):
237
+ st.markdown(pregunta_usuario)
238
+
239
+ with st.spinner("Generando respuesta..."):
240
+ respuesta, audio_path = obtener_respuesta(pregunta_usuario, texto_preprocesado, modelo="gpt-4", temperatura=0.5)
241
+ st.session_state.mensajes.append({"role": "assistant", "content": respuesta, "timestamp": time.time()})
242
+ with st.chat_message("assistant"):
243
+ st.markdown(respuesta)
244
+ st.audio(audio_path, format="audio/mp3", start_time=0)
245
+
246
+ guardar_historial(st.session_state.mensajes)
247
+ else:
248
+ st.warning("Por favor, ingresa una pregunta antes de enviar.")
249
+
250
+ def mostrar_agentes():
251
+ st.subheader("📋 Menú y Pedidos")
252
+ st.success("Menú cargado exitosamente. Listo para tomar pedidos.")
253
+ st.write(menu_df)
254
+
255
+ # Captura de pedido
256
+ st.markdown("Selecciona los items del menú:")
257
+ items_seleccionados = st.multiselect("Items", menu_df['item'].tolist())
258
+
259
+ if st.button("Tomar Pedido"):
260
+ if items_seleccionados:
261
+ pedido_usuario = ','.join(items_seleccionados)
262
+ confirmados = tomar_pedido_agente(pedido_usuario)
263
+ st.info(f"Pedido confirmado: {confirmados}")
264
+
265
+ total = procesar_orden_agente(','.join(confirmados))
266
+ st.success(f"Total del pedido: ${total}")
267
+
268
+ # Generar PDF de la orden
269
+ order_details = {item: {'price': menu_df[menu_df['item'] == item]['price'].values[0]} for item in confirmados}
270
+ pdf_path = generar_pdf_orden(order_details)
271
+ st.markdown(f"[Descargar PDF de la Orden]({pdf_path})", unsafe_allow_html=True)
272
+
273
+ # Generar mensaje automático
274
+ mensaje_automatico = generar_mensaje_automatico(confirmados)
275
+ st.session_state.mensajes_agente.append({"role": "assistant", "content": mensaje_automatico, "timestamp": time.time()})
276
+ with st.chat_message("assistant"):
277
+ st.markdown(mensaje_automatico)
278
+
279
+ # --- Chat para Agentes ---
280
+ st.subheader("Chat con Agentes")
281
+ if 'mensajes_agente' not in st.session_state:
282
+ st.session_state.mensajes_agente = []
283
+
284
+ for mensaje in st.session_state.mensajes_agente:
285
+ with st.chat_message(mensaje["role"]):
286
+ st.markdown(mensaje["content"])
287
+
288
+ agente_pregunta = st.text_input("Escribe tu pregunta para el agente:")
289
+ if st.button("Enviar al Agente"):
290
+ if agente_pregunta:
291
+ st.session_state.mensajes_agente.append({"role": "user", "content": agente_pregunta, "timestamp": time.time()})
292
+ with st.chat_message("user"):
293
+ st.markdown(agente_pregunta)
294
+
295
+ # Procesar la respuesta del agente
296
+ with st.spinner("El agente está respondiendo..."):
297
+ respuesta_agente, audio_path = obtener_respuesta(agente_pregunta, '', modelo="gpt-4", temperatura=0.5)
298
+ st.session_state.mensajes_agente.append({"role": "assistant", "content": respuesta_agente, "timestamp": time.time()})
299
+ with st.chat_message("assistant"):
300
+ st.markdown(respuesta_agente)
301
+ st.audio(audio_path, format="audio/mp3", start_time=0)
302
+ else:
303
+ st.warning("Por favor, ingresa una pregunta antes de enviar.")
 
 
 
 
 
304
 
305
  if __name__ == "__main__":
306
  main()