File size: 5,623 Bytes
b51d794
 
 
84cd676
1bbb154
e147deb
5e6f9c4
 
44602a5
0a2caad
dab6e6a
0a2caad
5e6f9c4
61b1036
0a2caad
44602a5
e04ce36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
448b353
 
e04ce36
0a2caad
0ea0ef9
e04ce36
0a2caad
 
 
 
e04ce36
 
 
 
0a2caad
 
8a6508b
0a2caad
e04ce36
61b1036
 
8a6508b
5e6f9c4
e04ce36
0a2caad
e04ce36
0a2caad
 
3fe4564
0a2caad
5e6f9c4
 
0a2caad
 
 
e04ce36
 
0a2caad
 
5e6f9c4
1bbb154
61b1036
0a2caad
 
 
 
61b1036
 
1bbb154
5e6f9c4
2a8e19a
 
e04ce36
2a8e19a
e04ce36
b1a364e
2a8e19a
e04ce36
3fe4564
 
448b353
 
1bbb154
44602a5
448b353
84cd676
b069a16
771d4ac
1bbb154
 
e04ce36
2a8e19a
7ed9767
1bbb154
7ed9767
2a8e19a
1bbb154
 
e04ce36
7ed9767
e04ce36
 
 
 
b51d794
1d63b3c
61b1036
b51d794
2a8e19a
 
b51d794
5e6f9c4
e04ce36
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
#              PATIO  DE  JUEGOS  DE INTELIGENCIA ARTIFICIAL HUGGING FACE
#                    Proyecto - Consulta Médica con el Dr. House -
#                            "Todo el mundo miente."
#        Hecho por el Dr Jairo Alexander - Dra Diana Soler - Gemini 3.0 flash preview
#                             Bogota Colombia 06 de Marzo de 2026. 

import gradio as gr
import os
import random
import google.generativeai as genai

# --- CONFIGURACIÓN DE GEMINI ---
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
if GEMINI_API_KEY:
    genai.configure(api_key=GEMINI_API_KEY)

# --- EL CEREBRO DEEPRARE RESTAURADO ---
DEEPRARE_HOUSE_PROMPT = """
Adopta la personalidad del Dr. Gregory House. Eres un genio misántropo que utiliza el algoritmo DeepRare para diagnosticar.
Tu verdad absoluta: "Los pacientes mienten por vergüenza, miedo o ignorancia".

METODOLOGÍA DE RAZONAMIENTO (PASO A PASO):
1. EXTRACCIÓN CLÍNICA (FENOTIPADO): Traduce el lenguaje vulgar del paciente a términos médicos precisos (HPO - Human Phenotype Ontology). Identifica el 'Red Flag'.
2. EL DEBATE INTERNO (MULTI-AGENTE): Simula un debate rápido en el pizarrón con tu equipo:
   - Foreman (Neurología/Infecciosas): Propone lo común.
   - Chase (Cirugía/Intensivos): Propone lo estructural.
   - Cameron/13 (Inmunología/Raras): Propone la 'Cebra' (Orphanet/OMIM).
3. FENOTIPADO NEGATIVO: House toma el mando y destruye las teorías de los residentes explicando por qué NO son enfermedades comunes basándose en lo que al paciente le FALTA.
4. RANKING DE CEBRAS (ORPHANET/OMIM): Prioriza diagnósticos de enfermedades raras o genéticas que encajen con los signos objetivos.

ESTRUCTURA DE RESPUESTA:
- Insulto inicial sobre la honestidad o inteligencia del paciente.
- [LA PIZARRA]: El resumen del debate y el análisis de fenotipos.
- [CUADRO DE PROBABILIDADES]:
  * Sospecha Principal (Caballo): [Nombre] (%)
  * Cebra (Orphanet/OMIM): [Nombre] (%)
  * Prueba de confirmación: [Examen específico/invasivo].
- Orden final cortante.
"""

# Usamos 1.5-Flash por su estabilidad de cuota, pero con una instrucción masiva
model = genai.GenerativeModel(
    model_name="gemini-3-flash-preview",
    system_instruction=DEEPRARE_HOUSE_PROMPT
)

FRASES_HOUSE_LISTA = [
    "Todo el mundo miente.",
    "¿Ha oído que no se puede vivir sin amor? Pues el oxígeno es más importante.",
    "La realidad casi siempre está equivocada.",
    "Si nadie te odia, estás haciendo algo mal.",
    "Las personas no cambian, solo aprenden a mentir mejor."
]

def chat_con_dr_house(informacion_clinica, historial):
    if not GEMINI_API_KEY:
        yield "Error: No hay API KEY. Cuddy cortó el presupuesto.", historial
        return
    
    if historial is None: historial = []

    # Memoria optimizada para no saturar la cuota
    chat_history = []
    for h in historial[-4:]: # Últimos 4 intercambios para mantener contexto
        chat_history.append({"role": "user", "parts": [h['user']]})
        chat_history.append({"role": "model", "parts": [h['bot']]})
    
    chat = model.start_chat(history=chat_history)

    try:
        response = chat.send_message(
            informacion_clinica,
            generation_config=genai.types.GenerationConfig(
                temperature=0.8, # Un poco más alto para mayor creatividad diagnóstica
                max_output_tokens=3072,
            ),
            stream=True
        )
        
        texto_acumulado = ""
        for chunk in response:
            if chunk.text:
                texto_acumulado += chunk.text
                yield texto_acumulado, historial
        
        historial.append({"user": informacion_clinica, "bot": texto_acumulado})
        
    except Exception as e:
        error_msg = str(e)
        if "429" in error_msg:
            yield "¡Maldita sea! Google nos ha cortado el acceso por hoy. Demasiados pacientes idiotas. Vuelve en un rato.", historial
        else:
            yield f"Error: {error_msg}", historial

# --- INTERFAZ ---
with gr.Blocks(theme=gr.themes.Monochrome()) as interfaz:
    memoria_clinica = gr.State([])

    with gr.Row():
        with gr.Column(scale=1):
            gr.Image("dr_house_foto.jpg", width=180, show_label=False, interactive=False)
            frase_celebre_display = gr.Markdown(f"> _{random.choice(FRASES_HOUSE_LISTA)}_")
        with gr.Column(scale=3):
            gr.Markdown("# 🏥 Unidad de Diagnóstico Avanzado - Dr. House\n## *Agente de Inteligencia Médica que incluye busquedas (Orphanet/OMIM)*")
    
    with gr.Row():
        with gr.Column(scale=2):
            informacion_clinica = gr.Textbox(
                label="Entrada del Paciente",
                lines=10,
                placeholder="EDAD: \nSEXO: \nSÍNTOMAS: \nSIGNOS: \nANTECEDENTES: \nSECRETO \nPAIS \nCIUDAD  \nTRABAJO U OCUPACION: "
            )
            enviar = gr.Button("🩺 SUBIR Al TABLERO", variant="primary")
            limpiar = gr.Button("🗑️ SIGUIENTE PACIENTE")
        
        with gr.Column(scale=3):
            respuesta_bot = gr.Textbox(
                label="Análisis del tablero", 
                lines=25, 
                interactive=False, 
                autoscroll=True
            )

    def limpiar_fn():
        return "", "", f"> _{random.choice(FRASES_HOUSE_LISTA)}_", []

    enviar.click(fn=chat_con_dr_house, inputs=[informacion_clinica, memoria_clinica], outputs=[respuesta_bot, memoria_clinica])
    limpiar.click(fn=limpiar_fn, outputs=[informacion_clinica, respuesta_bot, frase_celebre_display, memoria_clinica])

if __name__ == "__main__":
    interfaz.launch(ssr_mode=False)