File size: 7,710 Bytes
afa7095 c321964 65980e4 bb2f632 afa7095 65980e4 c321964 e22364d afa7095 bb2f632 8bc2dab 7a8dbb2 bb2f632 afa7095 65980e4 0926898 afa7095 65980e4 bb2f632 65980e4 afa7095 65980e4 bb2f632 08f3f5d afa7095 bb2f632 2d1a4d4 65980e4 bb2f632 65980e4 bb2f632 1b45967 bb2f632 65980e4 bb2f632 afa7095 65980e4 e22364d bb2f632 e22364d bb2f632 afa7095 bb2f632 e22364d bb2f632 e22364d bb2f632 e22364d bb2f632 c321964 bb2f632 c321964 bb2f632 c321964 bb2f632 e22364d 2d1a4d4 e22364d 2d1a4d4 e22364d 2d1a4d4 e22364d bb2f632 e22364d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | import os
import time
import groq
from google.cloud import texttospeech_v1 as texttospeech
import streamlit as st
from dotenv import load_dotenv
import speech_recognition as sr
from datetime import datetime, timedelta
from streamlit_autorefresh import st_autorefresh
# Configurar la p谩gina de Streamlit
st.set_page_config(page_title="Galatea Asistente - OMARDENT", layout="wide")
# Estilo CSS para el fondo
st.markdown(
"""
<style>
.reportview-container {
background: radial-gradient(circle, rgba(209,238,174,1) 0%, rgba(11,135,128,1) 90%);
}
</style>
""",
unsafe_allow_html=True
)
# Agregar el logo
st.image("Logo icon.jpg", use_column_width=True) # Aseg煤rate de que el archivo icon.jpg est茅 en la misma carpeta
# Cargar las claves API desde el archivo .env
load_dotenv()
groq_api_key = os.getenv("GROQ_API_KEY")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "credentials/botidinamix-g.json"
# Verificar que la clave API de Groq est谩 configurada
if not groq_api_key:
st.error("No API key provided for Groq. Please set your API key in the .env file.")
else:
# Inicializar el cliente de Groq
client_groq = groq.Groq(api_key=groq_api_key)
# Funci贸n para obtener respuesta de Groq y generar audio con Google TTS
def obtener_respuesta_groq(pregunta, contexto="", modelo="llama3-8b-8192", temperatura=0.5):
if not pregunta:
st.error("La pregunta no puede estar vac铆a.")
return "Lo siento, la pregunta no puede estar vac铆a."
try:
with st.spinner('Evaluando su respuesta...'):
# Hacer la llamada a la API de Groq con el rol de Galatea
contexto = "Act煤as como Galatea, la asistente virtual de la cl铆nica odontol贸gica Omardent. Tu funci贸n es recordar citas y eventos de forma clara y profesional."
response = client_groq.chat.completions.create(
messages=[
{"role": "system", "content": contexto},
{"role": "user", "content": pregunta}
],
model=modelo
)
# Acceder al contenido de la respuesta de Groq
respuesta = response.choices[0].message.content.strip()
# Configurar la solicitud de s铆ntesis de voz (Google TTS)
client = texttospeech.TextToSpeechClient()
input_text = texttospeech.SynthesisInput(text=respuesta)
voice = texttospeech.VoiceSelectionParams(
language_code="es-ES", ssml_gender=texttospeech.SsmlVoiceGender.FEMALE
)
audio_config = texttospeech.AudioConfig(
audio_encoding=texttospeech.AudioEncoding.MP3
)
# Realizar la solicitud de s铆ntesis de voz
response_audio = client.synthesize_speech(
input=input_text, voice=voice, audio_config=audio_config
)
# Guardar el archivo de audio temporalmente
audio_file_path = f'tmp_respuesta_{int(time.time())}.mp3'
with open(audio_file_path, 'wb') as audio_file:
audio_file.write(response_audio.audio_content)
# Devolver la respuesta y la ruta del archivo de audio
return respuesta, audio_file_path
except Exception as e:
st.error(f"Error al generar la respuesta y el audio: {e}")
return "Lo siento, ocurri贸 un error al procesar tu solicitud.", None
# Funci贸n para manejar el chat del asistente
def mostrar_galatea_asistente():
st.title("馃Ψ Galatea - Asistente Virtual OMARDENT")
# Inicializa el historial del chat y el temporizador
if 'mensajes_chat' not in st.session_state:
st.session_state['mensajes_chat'] = []
if 'respuesta_programada' not in st.session_state:
st.session_state['respuesta_programada'] = None
# Mostrar los mensajes del chat
for mensaje in st.session_state['mensajes_chat']:
clase = "user" if mensaje["role"] == "user" else "assistant"
st.markdown(f'<div class="chat-message {clase}">{mensaje["content"]}</div>', unsafe_allow_html=True)
# Entrada de texto para la pregunta del usuario
pregunta_usuario = st.text_input("Escribe tu pregunta aqu铆:")
# Selector de intervalo de tiempo
intervalo = st.selectbox("Selecciona el intervalo de tiempo (minutos)", [1, 2, 5, 10, 15, 30, 60])
# Grabar y transcribir audio
if st.button("Grabar y Transcribir Audio"):
recognizer = sr.Recognizer()
with sr.Microphone() as source:
st.info("Grabando...")
audio = recognizer.listen(source, timeout=5)
st.info("Grabaci贸n completa")
try:
text = recognizer.recognize_google(audio, language="es-ES")
pregunta_usuario = text # Usar la transcripci贸n como la pregunta
except sr.UnknownValueError:
st.error("No se pudo entender el audio")
except sr.RequestError:
st.error("Error al solicitar el servicio de reconocimiento de voz")
# Programar la pregunta para ser respondida despu茅s del intervalo de tiempo seleccionado
if st.button("Programar Respuesta"):
if pregunta_usuario:
# Guardar la pregunta en el historial
st.session_state['mensajes_chat'].append({"role": "user", "content": pregunta_usuario})
# Calcular el tiempo en segundos
tiempo_en_segundos = intervalo * 60
tiempo_ejecucion = datetime.now() + timedelta(minutes=intervalo)
st.success(f"La respuesta se generar谩 a las {tiempo_ejecucion.strftime('%H:%M:%S')}")
# Guardar la informaci贸n de la respuesta programada
st.session_state['respuesta_programada'] = {
'pregunta': pregunta_usuario,
'tiempo_ejecucion': tiempo_ejecucion,
'tiempo_en_segundos': tiempo_en_segundos,
'audio_file_path': None,
'notificacion_reproducida': False # Para saber si se ha reproducido la notificaci贸n
}
# Actualizar la interfaz cada segundo para verificar si el tiempo ha pasado y mostrar el contador
st_autorefresh(interval=1000, key="data_refresh")
# Verificar si hay una respuesta programada que deba ejecutarse
if 'respuesta_programada' in st.session_state and st.session_state['respuesta_programada']:
respuesta_programada = st.session_state['respuesta_programada']
# Mostrar el contador del tiempo restante
tiempo_restante = respuesta_programada['tiempo_ejecucion'] - datetime.now()
if tiempo_restante.total_seconds() > 0:
minutos, segundos = divmod(int(tiempo_restante.total_seconds()), 60)
horas, minutos = divmod(minutos, 60)
tiempo_restante_str = f"{horas}h {minutos}m {segundos}s" if horas > 0 else f"{minutos}m {segundos}s"
st.info(f"Tiempo restante: {tiempo_restante_str}")
if st.session_state['respuesta_programada']['notificacion_reproducida'] and st.session_state['respuesta_programada']['audio_file_path'] is None:
respuesta, audio_file_path = obtener_respuesta_groq(respuesta_programada['pregunta'])
# Guardar la respuesta y el audio en el estado
st.session_state['mensajes_chat'].append({"role": "assistant", "content": respuesta})
st.session_state['respuesta_programada']['audio_file_path'] = audio_file_path
# Reproducir el audio si ya fue generado
if st.session_state['respuesta_programada']['audio_file_path']:
audio_file_path = st.session_state['respuesta_programada']['audio_file_path']
with open(audio_file_path, "rb") as audio_file:
st.audio(audio_file.read(), format="audio/mp3")
# Funci贸n principal
def main():
mostrar_galatea_asistente()
if __name__ == "__main__":
main() |