SAZONBURGUER / app.py
Josedcape's picture
Update app.py
1cbcaf3 verified
import streamlit as st
import openai
from dotenv import load_dotenv
import nltk
import os
import tempfile
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.stem import SnowballStemmer
import PyPDF2
import time
from google.cloud import texttospeech
from streamlit_webrtc import webrtc_streamer, WebRtcMode, AudioProcessorBase
from Historial.historial_chat import cargar_historial, guardar_historial
from agent_functions import menu_df, tomar_pedido_agente, procesar_orden_agente, generar_pdf_orden, obtener_respuesta, generar_mensaje_automatico
# Configuración de NLTK
nltk.download('punkt')
nltk.download('stopwords')
# Cargar la clave API desde el archivo .env
load_dotenv()
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "botidinamix-g.json"
openai.api_key = os.getenv("OPENAI_API_KEY")
# Función para extraer texto del PDF
def extraer_texto_pdf(archivo):
texto = ""
if archivo:
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
temp_file.write(archivo.read())
temp_file_path = temp_file.name
with open(temp_file_path, 'rb') as file:
reader = PyPDF2.PdfReader(file)
for page in range(len(reader.pages)):
texto += reader.pages[page].extract_text()
os.unlink(temp_file_path)
return texto
# Función para preprocesar texto
def preprocesar_texto(texto):
tokens = word_tokenize(texto, language='spanish')
tokens = [word.lower() for word in tokens if word.isalpha()]
stopwords_es = set(stopwords.words('spanish'))
tokens = [word for word in tokens if word not in stopwords_es]
stemmer = SnowballStemmer('spanish')
tokens = [stemmer.stem(word) for word in tokens]
return " ".join(tokens)
# Clase para procesar audio
class AudioProcessor(AudioProcessorBase):
def __init__(self):
self.audio_bytes = b''
def recv(self, frame):
self.audio_bytes += frame.to_ndarray().tobytes()
return frame
# Main App
def main():
# --- Diseño general ---
st.set_page_config(page_title="Asistente Virtual", page_icon="🤖")
# --- Estilos CSS personalizados ---
st.markdown(
"""
<style>
body {
background: rgb(241,241,234);
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%);
}
h1, h2, h3, h4, h5, h6 {
color: green !important;
font-weight: bold !important;
}
.stChatFloatingInputContainer {
background-color: rgba(255, 255, 255, 0.8);
border-radius: 10px;
}
.stTextInput > div > div > input {
color: #333;
}
[data-testid="stChatMessage"] {
background-color: black !important;
color: gold !important;
border-radius: 10px;
}
[data-testid="stChatMessage"] p {
color: gold !important;
}
::-webkit-scrollbar {
width: 16px;
}
::-webkit-scrollbar-thumb {
background-color: #FFD700;
border-radius: 10px;
}
.st-spinner > div {
border-top-color: transparent;
border-right-color: transparent;
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
</style>
""",
unsafe_allow_html=True,
)
# --- Barra lateral ---
with st.sidebar:
st.image("hamburguesa napolitana.jpg")
st.title("🤖 RESTAURANTE SAZON BURGER 🍔✨-BOTIDINAMIX AI")
st.markdown("---")
# Opciones de navegación
pagina = st.selectbox("Selecciona una página", ["Chat", "Subir PDF", "Agentes"])
# --- Página principal ---
if pagina == "Chat":
mostrar_chat()
elif pagina == "Subir PDF":
mostrar_subir_pdf()
elif pagina == "Agentes":
mostrar_agentes()
else:
mostrar_principal()
def mostrar_chat():
# --- Botones de historial ---
if st.button("Buscar Historial"):
st.session_state.mostrar_historial = True
if st.button("Borrar Historial"):
st.session_state.mensajes = []
st.session_state.mostrar_historial = False
st.success("Historial borrado correctamente")
# --- Chatbot ---
if 'mensajes' not in st.session_state:
st.session_state.mensajes = cargar_historial()
for mensaje in st.session_state.mensajes:
with st.chat_message(mensaje["role"]):
st.markdown(mensaje["content"])
# Función para manejar la entrada de audio
def on_audio(audio_bytes):
with st.spinner("Transcribiendo..."):
transcript = openai.Audio.transcribe("whisper-1", audio_bytes)
pregunta_usuario = transcript["text"]
st.session_state.mensajes.append({"role": "user", "content": pregunta_usuario, "timestamp": time.time()})
with st.chat_message("user"):
st.markdown(pregunta_usuario)
st.subheader("🎤 Captura de voz")
st.info("Haz clic en el micrófono y comienza a hablar. Tu pregunta se transcribirá automáticamente.")
with st.container():
if st.button("Grabar 🎙️"):
st.session_state.run_webrtc = True
if st.session_state.get("run_webrtc", False):
webrtc_ctx = webrtc_streamer(
key="example",
mode=WebRtcMode.SENDONLY,
audio_receiver_size=256,
rtc_configuration={
"iceServers": [{"urls": ["stun:stun.l.google.com:19302"]}]
},
media_stream_constraints={"audio": True},
audio_processor_factory=AudioProcessor,
)
if webrtc_ctx.audio_receiver:
audio_frames = webrtc_ctx.audio_receiver.get_frames(timeout=1)
for audio_frame in audio_frames:
audio_bytes = audio_frame.to_ndarray().tobytes()
on_audio(audio_bytes)
st.markdown("---")
st.subheader("📄 Subir PDF")
st.info("Sube un archivo PDF y el asistente responderá en función de su contenido.")
archivo_pdf = st.file_uploader("Selecciona un archivo PDF", type=["pdf"])
texto_extraido = ""
if archivo_pdf:
texto_extraido = extraer_texto_pdf(archivo_pdf)
st.success("Texto extraído del PDF exitosamente.")
st.text_area("Texto extraído", value=texto_extraido, height=200)
if not texto_extraido:
texto_extraido = st.text_area("Texto extraído", height=200)
texto_preprocesado = preprocesar_texto(texto_extraido)
# --- Opciones de entrada de usuario ---
st.markdown("---")
pregunta_usuario = st.text_input("Escribe tu pregunta:")
if st.button("Enviar"):
if pregunta_usuario:
st.session_state.mensajes.append({"role": "user", "content": pregunta_usuario, "timestamp": time.time()})
with st.chat_message("user"):
st.markdown(pregunta_usuario)
with st.spinner("Generando respuesta..."):
respuesta, audio_path = obtener_respuesta(pregunta_usuario, texto_preprocesado, modelo="gpt-4", temperatura=0.5)
st.session_state.mensajes.append({"role": "assistant", "content": respuesta, "timestamp": time.time()})
with st.chat_message("assistant"):
st.markdown(respuesta)
st.audio(audio_path, format="audio/mp3", start_time=0, autoplay=True)
# Reproducir video automáticamente
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)
guardar_historial(st.session_state.mensajes)
else:
st.warning("Por favor, ingresa una pregunta antes de enviar.")
def mostrar_subir_pdf():
st.subheader("📄 Subir PDF")
st.info("Sube un archivo PDF y el asistente responderá en función de su contenido.")
archivo_pdf = st.file_uploader("Selecciona un archivo PDF", type=["pdf"])
texto_extraido = ""
if archivo_pdf:
texto_extraido = extraer_texto_pdf(archivo_pdf)
st.success("Texto extraído del PDF exitosamente.")
st.text_area("Texto extraído", value=texto_extraido, height=200)
if not texto_extraido:
texto_extraido = st.text_area("Texto extraído", height=200)
texto_preprocesado = preprocesar_texto(texto_extraido)
# --- Opciones de entrada de usuario ---
st.markdown("---")
pregunta_usuario = st.text_input("Escribe tu pregunta:")
if st.button("Enviar"):
if pregunta_usuario:
st.session_state.mensajes.append({"role": "user", "content": pregunta_usuario, "timestamp": time.time()})
with st.chat_message("user"):
st.markdown(pregunta_usuario)
with st.spinner("Generando respuesta..."):
respuesta, audio_path = obtener_respuesta(pregunta_usuario, texto_preprocesado, modelo="gpt-4", temperatura=0.5)
st.session_state.mensajes.append({"role": "assistant", "content": respuesta, "timestamp": time.time()})
with st.chat_message("assistant"):
st.markdown(respuesta)
st.audio(audio_path, format="audio/mp3", start_time=0, autoplay=True)
guardar_historial(st.session_state.mensajes)
else:
st.warning("Por favor, ingresa una pregunta antes de enviar.")
def mostrar_agentes():
st.subheader("📋 Menú y Pedidos")
st.success("Menú cargado exitosamente. Listo para tomar pedidos.")
st.write(menu_df)
# Captura de pedido
st.markdown("Selecciona los items del menú:")
items_seleccionados = st.multiselect("Items", menu_df['item'].tolist())
if st.button("Tomar Pedido"):
if items_seleccionados:
pedido_usuario = ','.join(items_seleccionados)
confirmados = tomar_pedido_agente(pedido_usuario)
st.info(f"Pedido confirmado: {confirmados}")
total = procesar_orden_agente(','.join(confirmados))
st.success(f"Total del pedido: ${total}")
# Generar PDF de la orden
order_details = {item: {'price': menu_df[menu_df['item'] == item]['price'].values[0]} for item in confirmados}
pdf_path = generar_pdf_orden(order_details)
st.markdown(f"[Descargar PDF de la Orden]({pdf_path})", unsafe_allow_html=True)
# Generar mensaje automático
mensaje_automatico = generar_mensaje_automatico(confirmados)
st.session_state.mensajes_agente.append({"role": "assistant", "content": mensaje_automatico, "timestamp": time.time()})
with st.chat_message("assistant"):
st.markdown(mensaje_automatico)
# --- Chat para Agentes ---
st.subheader("Chat con Agentes")
if 'mensajes_agente' not in st.session_state:
st.session_state.mensajes_agente = []
for mensaje in st.session_state.mensajes_agente:
with st.chat_message(mensaje["role"]):
st.markdown(mensaje["content"])
agente_pregunta = st.text_input("Escribe tu pregunta para el agente:")
if st.button("Enviar al Agente"):
if agente_pregunta:
st.session_state.mensajes_agente.append({"role": "user", "content": agente_pregunta, "timestamp": time.time()})
with st.chat_message("user"):
st.markdown(agente_pregunta)
# Procesar la respuesta del agente
with st.spinner("El agente está respondiendo..."):
respuesta_agente, audio_path = obtener_respuesta(agente_pregunta, '', modelo="gpt-4", temperatura=0.5)
st.session_state.mensajes_agente.append({"role": "assistant", "content": respuesta_agente, "timestamp": time.time()})
with st.chat_message("assistant"):
st.markdown(respuesta_agente)
st.audio(audio_path, format="audio/mp3", start_time=0, autoplay=True)
else:
st.warning("Por favor, ingresa una pregunta antes de enviar.")
def mostrar_principal():
st.subheader("🗣️ Asistente Virtual con Chat y Respuestas en Voz")
st.video("", start_time=0)
if 'mensajes' not in st.session_state:
st.session_state.mensajes = []
for mensaje in st.session_state.mensajes:
with st.chat_message(mensaje["role"]):
st.markdown(mensaje["content"])
pregunta_usuario = st.text_input("Escribe tu pregunta:")
if st.button("Enviar"):
if pregunta_usuario:
st.session_state.mensajes.append({"role": "user", "content": pregunta_usuario, "timestamp": time.time()})
with st.chat_message("user"):
st.markdown(pregunta_usuario)
with st.spinner("Generando respuesta..."):
respuesta, audio_path = obtener_respuesta(pregunta_usuario, '', modelo="gpt-4", temperatura=0.5)
st.session_state.mensajes.append({"role": "assistant", "content": respuesta, "timestamp": time.time()})
with st.chat_message("assistant"):
st.markdown(respuesta)
st.audio(audio_path, format="audio/mp3", start_time=0, autoplay=True)
else:
st.warning("Por favor, ingresa una pregunta antes de enviar.")
if __name__ == "__main__":
main()