| | 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 |
| |
|
| | |
| | st.set_page_config(page_title="Galatea Asistente - OMARDENT", layout="wide") |
| |
|
| | |
| | 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 |
| | ) |
| |
|
| | |
| | st.image("Logo icon.jpg", use_column_width=True) |
| |
|
| | |
| | load_dotenv() |
| | groq_api_key = os.getenv("GROQ_API_KEY") |
| | os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "credentials/botidinamix-g.json" |
| |
|
| | |
| | if not groq_api_key: |
| | st.error("No API key provided for Groq. Please set your API key in the .env file.") |
| | else: |
| | |
| | client_groq = groq.Groq(api_key=groq_api_key) |
| |
|
| | |
| | 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...'): |
| | |
| | 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 |
| | ) |
| | |
| | |
| | respuesta = response.choices[0].message.content.strip() |
| |
|
| | |
| | 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 |
| | ) |
| |
|
| | |
| | response_audio = client.synthesize_speech( |
| | input=input_text, voice=voice, audio_config=audio_config |
| | ) |
| |
|
| | |
| | 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) |
| | |
| | |
| | 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 |
| |
|
| | |
| | def mostrar_galatea_asistente(): |
| | st.title("馃Ψ Galatea - Asistente Virtual OMARDENT") |
| |
|
| | |
| | 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 |
| |
|
| | |
| | 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) |
| |
|
| | |
| | pregunta_usuario = st.text_input("Escribe tu pregunta aqu铆:") |
| |
|
| | |
| | intervalo = st.selectbox("Selecciona el intervalo de tiempo (minutos)", [1, 2, 5, 10, 15, 30, 60]) |
| |
|
| | |
| | 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 |
| | 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") |
| |
|
| | |
| | if st.button("Programar Respuesta"): |
| | if pregunta_usuario: |
| | |
| | st.session_state['mensajes_chat'].append({"role": "user", "content": pregunta_usuario}) |
| |
|
| | |
| | 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')}") |
| |
|
| | |
| | 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 |
| | } |
| |
|
| | |
| | st_autorefresh(interval=1000, key="data_refresh") |
| |
|
| | |
| | if 'respuesta_programada' in st.session_state and st.session_state['respuesta_programada']: |
| | respuesta_programada = st.session_state['respuesta_programada'] |
| |
|
| | |
| | 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']) |
| |
|
| | |
| | st.session_state['mensajes_chat'].append({"role": "assistant", "content": respuesta}) |
| | st.session_state['respuesta_programada']['audio_file_path'] = audio_file_path |
| |
|
| | |
| | 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") |
| |
|
| | |
| | def main(): |
| | mostrar_galatea_asistente() |
| |
|
| | if __name__ == "__main__": |
| | main() |