JairoCesar's picture
Update app.py
ef7104e verified
# ========================================================================================================================================
# PROYECTO DE ATENCION MÉDICA PERSONALIZADA
# Bogotá Colombia 2024
#
# --- ADAPTADO PARA USAR GOOGLE GEMINI API ---
# ========================================================================================================================================
import streamlit as st
import google.generativeai as genai
import os
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
st.set_page_config(
page_title="Consulta Médica Colombiana IA",
page_icon="🩺",
layout="wide"
)
st.title("🩺 Consulta Médica Colombiana IA")
st.caption("Desarrollado con Google Gemini")
# --- CONFIGURACIÓN Gemini ---
# Carga la API key desde los secretos de Streamlit o variables de entorno
GEMINI_API_KEY = st.secrets.get("GEMINI_API_KEY", os.getenv("GEMINI_API_KEY"))
if not GEMINI_API_KEY:
st.error("GEMINI_API_KEY no encontrada. Por favor configúrala en tus secretos de Streamlit o variables de entorno.")
logger.error("GEMINI_API_KEY no encontrada.")
st.stop()
try:
genai.configure(api_key=GEMINI_API_KEY)
logger.info("✅ Configuración de Gemini API realizada.")
except Exception as e:
error_msg = f"❌ Error al configurar Gemini API: {str(e)}"
logger.error(error_msg)
st.error(error_msg)
st.stop()
# --- CARGA DEL MODELO ---
@st.cache_resource
def get_gemini_model():
"""Carga y cachea el modelo generativo de Gemini."""
logger.info("🔄 Cargando modelo Gemini...")
# NOTA: "gemini-2.5-flash-lite" puede ser un nombre de modelo no disponible públicamente aún.
# Un modelo rápido y común es "gemini-1.5-flash-latest".
# Si el nombre que pusiste da error, prueba a cambiarlo por "gemini-1.5-flash-latest".
try:
model = genai.GenerativeModel("gemini-2.5-flash-lite") # Cambiado a un modelo conocido. Usa "gemini-2.5-flash-lite" si estás seguro de su disponibilidad.
logger.info("✅ Modelo Gemini cargado correctamente.")
return model
except Exception as e:
error_msg = f"❌ Error al inicializar modelo Gemini: {str(e)}"
logger.error(error_msg)
st.error(error_msg)
return None
model = get_gemini_model()
if model is None:
st.stop()
# --- INICIALIZACIÓN DEL CHAT EN LA SESIÓN ---
# Se inicializa el historial para mostrar en la UI y el objeto de chat de Gemini
if "history" not in st.session_state:
st.session_state.history = []
if "chat" not in st.session_state:
# El historial del chat de Gemini se inicializa con un prompt de sistema
# para darle a la IA su rol y sus instrucciones.
system_prompt = (
"Eres un asistente médico virtual diseñado para Colombia. Tu principal objetivo es "
"proporcionar orientación general y educativa sobre temas de salud, siempre en español. "
"puedes proporcionar diagnósticos médicos, pero solo recomedar examenes o tratamientos "
"ejemplo tus sintomas pueden corresponde a un dengue clasico "
"Tu función es informativa. Debes adaptar la complejidad de tu lenguaje al nivel de estudio "
"del usuario y considerar su ubicación (departamento) si es relevante. Siempre, al final de "
"tu respuesta, incluye una advertencia clara: 'Recuerda que esta es una IA y no reemplaza "
"la consulta con un médico real. En caso de emergencia, contacta a un profesional de la salud.'"
)
st.session_state.chat = model.start_chat(history=[
{'role': 'user', 'parts': [system_prompt]},
{'role': 'model', 'parts': ["Entendido. Estoy listo para ayudar como asistente médico virtual informativo para Colombia."]}
])
# --- INTERFAZ DE USUARIO ---
with st.sidebar:
st.header("Información del Paciente")
nivel_estudio = st.selectbox("Nivel de estudio:", ["Primaria", "Secundaria", "Técnico", "Pregrado", "Posgrado"])
departamento = st.selectbox("Departamento de Colombia:", ["Bogotá DC","Amazonas", "Antioquia", "Arauca", "Atlántico", "Bolívar", "Boyacá", "Caldas", "Caquetá", "Casanare", "Cauca", "Cesar", "Chocó", "Córdoba", "Cundinamarca", "Guainía", "Guaviare", "Huila", "La Guajira", "Magdalena", "Meta", "Nariño", "Norte de Santander", "Putumayo", "Quindío", "Risaralda", "San Andrés y Providencia", "Santander", "Sucre", "Tolima", "Valle del Cauca", "Vaupés", "Vichada"])
st.warning("Esta IA no reemplaza a un profesional médico.")
if st.button("Limpiar Conversación"):
st.session_state.history = []
st.session_state.chat = model.start_chat(history=[]) # Reinicia el chat de Gemini
st.rerun()
for message in st.session_state.history:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# Capturar la entrada del usuario
if prompt := st.chat_input("Describe tus síntomas o consulta médica... (edad, sexo, duración, antecedentes, etc.)"):
# Construir el prompt completo para enviar al modelo
full_prompt = (
f"Contexto del usuario: Nivel de estudio '{nivel_estudio}', vive en el departamento de '{departamento}'.\n\n"
f"Consulta del usuario: {prompt}"
)
# Añadir y mostrar el mensaje del usuario en la UI
st.session_state.history.append({"role": "user", "content": full_prompt})
with st.chat_message("user"):
st.markdown(prompt) # Mostramos solo la consulta, no el contexto interno
# Generar y mostrar la respuesta de la IA
with st.chat_message("assistant"):
message_placeholder = st.empty()
full_response = ""
try:
# Enviar el prompt al chat de Gemini y obtener la respuesta en streaming
responses = st.session_state.chat.send_message(
full_prompt,
stream=True,
generation_config=genai.types.GenerationConfig(
# Puedes ajustar estos parámetros
temperature=0.7,
max_output_tokens=1024
)
)
for response in responses:
# Quita los mensajes de seguridad del stream si los hubiera
if response.parts:
full_response += response.text
message_placeholder.markdown(full_response + "▌") # Muestra un cursor parpadeante
message_placeholder.markdown(full_response)
logger.info(f"Respuesta generada para: {prompt[:50]}...")
except Exception as e:
full_response = f"Lo siento, ocurrió un error al procesar tu solicitud: {str(e)}"
message_placeholder.error(full_response)
logger.error(f"Error en la llamada a Gemini API: {str(e)}")
# Añadir la respuesta completa de la IA al historial de la UI
st.session_state.history.append({"role": "assistant", "content": full_response})