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()