File size: 4,596 Bytes
31870e0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15b1ba5
67e1221
31870e0
 
 
15b1ba5
31870e0
 
 
 
 
67e1221
31870e0
 
 
 
 
 
 
15b1ba5
 
31870e0
 
15b1ba5
 
 
 
31870e0
15b1ba5
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
# En: app/app.py
import gradio as gr
import requests  # Para llamar a nuestra propia API de FastAPI
import os

# --- 1. Importa tu App de FastAPI ---
# (Aseg煤rate de que api/main.py exista en la carpeta 'api')
from api.main import app as fastapi_app

# --- 2. Define la URL de tu API ---
# Esto es CLAVE para que funcione en Hugging Face Spaces
# Busca la URL del Space y, si no la encuentra, usa la local.
BASE_URL = os.getenv("SPACE_URL", "http://127.0.0.1:7860")
API_PREDICT_URL = f"{BASE_URL}/api/predict"
API_COACH_URL = f"{BASE_URL}/api/coach"


# --- 3. L贸gica de la Interfaz Gradio ---
# Esta funci贸n es el "cerebro" de la UI.
# Llama a los endpoints FALSOS de FastAPI.

def chatbot_response(chat_message, chat_history, edad, sexo, asistencia, notas):
    """
    Funci贸n que Gradio ChatInterface llamar谩.
    Se comunica con la API (FastAPI) para obtener respuestas.
    """
    
    # --- Paso A: Llamar a /predict ---
    predict_payload = {
        "edad": edad,
        "sexo": sexo,
        "asistencia": asistencia,
        "notas": notas
    }
    
    try:
        # Llama al endpoint /predict de tu API
        response_predict = requests.post(API_PREDICT_URL, json=predict_payload)
        response_predict.raise_for_status() # Lanza un error si la API falla
        predict_data = response_predict.json()
        score = predict_data.get("score", 0.0)
        
    except requests.exceptions.RequestException as e:
        yield f"Error al conectar con el motor de riesgo (/predict): {e}"
        return

    # --- Paso B: Llamar a /coach ---
    coach_payload = {
        "consulta": chat_message,
        "riesgo": score
    }

    try:
        # Llama al endpoint /coach de tu API
        response_coach = requests.post(API_COACH_URL, json=coach_payload)
        response_coach.raise_for_status()
        coach_data = response_coach.json()
        
        # Formatear la respuesta del coach para el chat
        plan_texto = coach_data.get("plan", "No se pudo generar un plan.")
        citas = coach_data.get("citas", [])
        
        # Esta es la respuesta final que ve el usuario
        respuesta_final = f"**Riesgo Estimado: {score*100:.0f}%**\n\n{plan_texto}"
        
        if citas:
            respuesta_final += "\n\n**Fuentes (Mock):**\n"
            for cita in citas:
                respuesta_final += f"- `{cita}`\n"
        
        yield respuesta_final
        
    except requests.exceptions.RequestException as e:
        yield f"Error al conectar con el Coach RAG (/coach): {e}"


# --- 4. Definici贸n de la UI de Gradio ---
with gr.Blocks(theme=gr.themes.Soft(), title="Tutor Virtual") as demo:
    gr.Markdown("# 馃 Tutor Virtual Adaptativo (Demo)")
    gr.Markdown("Esta demo usa un backend **simulado (mock)** para pruebas.")
    
    with gr.Row():
        # --- Columna 1: El "Formulario" (Sidebar) ---
        with gr.Column(scale=1, min_width=350):
            with gr.Accordion("Perfil del Alumno", open=True):
                gr.Markdown("Ingrese los datos del alumno para la simulaci贸n.")
                input_edad = gr.Slider(10, 25, value=18, label="Edad")
                input_sexo = gr.Radio(["Masculino", "Femenino", "Otro"], value="Masculino", label="Sexo")
                input_asistencia = gr.Slider(0, 100, value=80, label="Asistencia (%)")
                input_notas = gr.Slider(1.0, 7.0, step=0.1, value=4.5, label="Promedio Notas")
            
            gr.Markdown("*(Nota: El puntaje de riesgo cambiar谩 si las notas son < 4.0)*")

      # --- Columna 2: El "Chat" (脕rea Principal) ---
      # --- Columna 2: El "Chat" (脕rea Principal) ---
        with gr.Column(scale=4):
            gr.ChatInterface(
                fn=chatbot_response,
                type="messages",  # <--- 1. A脩ADE ESTO (para el Warning)
                
                chatbot=gr.Chatbot(
                    height=500, 
                    label="Chat con Tutor", 
                    avatar_images=("user.png", "bot.png"),
                    type='messages'
                ),
                
                textbox=gr.Textbox(placeholder="Hola, 驴en qu茅 puedo ayudarte hoy?"),
                submit_btn="Enviar Consulta",
                additional_inputs=[input_edad, input_sexo, input_asistencia, input_notas] 
            )

# ... (m谩s abajo) ...

# --- 5. Montar y Lanzar (La Magia) ---

# 隆Esta es la sintaxis correcta para Gradio 4.0+!
# Vuelve a usar 'gr.mount_app'
app = gr.mount_app(demo, fastapi_app, path="/api")

# NOTA: No uses demo.launch(). 
# Hugging Face usar谩 la variable 'app' para lanzar el se