local_pccntr8203403_aitutor
Tipo: local plugin
Ubicacion: public/local/pccntr8203403_aitutor/
Version: 0.1.0 (2026062300)
Requiere: Moodle 5.0+ (2025092600)
Madurez: ALPHA
Alcance: 3 -- Agente IA
Estado: En desarrollo
Proposito
Proxy del lado servidor entre la interfaz conversacional del Drawer IA (renderizada por theme_cdigital) y un servicio externo de tutoria IA. El plugin recibe el mensaje del estudiante via AJAX, enriquece el contexto con datos del curso y la actividad actual, y reenvia la peticion al endpoint externo (POST v1/campus/tutor). El token de autenticacion del servicio externo nunca se expone al navegador.
Arquitectura
El plugin implementa una unica funcion externa (send_message) que actua como proxy. No almacena datos en la base de datos de Moodle ni crea tablas propias. Todo el procesamiento es sin estado (stateless): cada peticion es independiente.
Navegador (AMD aitutor.js)
|
| AJAX (core/ajax)
v
local_pccntr8203403_aitutor_send_message
|
| cURL + token Bearer
v
Servicio externo (v1/campus/tutor)
|
| JSON { reply_html, suggested_actions, risk_level_detected }
v
Respuesta sanitizada -> navegador
Funcion externa
| Funcion | Descripcion |
|---|---|
local_pccntr8203403_aitutor_send_message | Envia un mensaje del usuario al tutor IA externo y retorna la respuesta sanitizada. Tipo write, ajax: true, requiere login. |
Parametros de entrada
| Parametro | Tipo | Descripcion |
|---|---|---|
message | PARAM_TEXT | Texto del mensaje del usuario |
courseid | PARAM_INT | ID del curso actual |
cmid | PARAM_INT | ID del modulo de curso (0 si no esta en una actividad) |
currenturl | PARAM_URL | URL de la pagina actual (se elimina el query string antes de enviar) |
scormcmi | PARAM_RAW | Datos CMI de SCORM codificados en JSON (vacio si no aplica) |
Retorno
| Campo | Tipo | Descripcion |
|---|---|---|
reply | PARAM_RAW | HTML sanitizado de la respuesta del tutor |
sessionid | PARAM_RAW | Identificador de sesion (mdl_sess_ + hash parcial del sesskey) |
Payload enviado al servicio externo
El plugin construye un objeto JSON con la siguiente estructura:
{
"session_id": "mdl_sess_abc123def456",
"user": {
"moodle_user_id": 42,
"role": "student"
},
"context": {
"course_id": 3,
"course_name": "Evaluar para avanzar",
"current_url": "/mod/scorm/player.php",
"activity_id": 105,
"activity_name": "Modulo 1",
"activity_type": "scorm",
"section_name": "Introduccion",
"completion_pct": 45,
"scorm_cmi": { "lesson_location": "page3", "completion_status": "incomplete" }
},
"message": "No entiendo este tema"
}
El contexto de la actividad (activity_name, activity_type, section_name, completion_pct) se enriquece del lado del servidor usando las APIs de Moodle (get_fast_modinfo, completion_info), no desde el navegador.
Seguridad
Autenticacion y autorizacion
- Requiere login en el curso (
require_login($course)). - Verifica la capacidad
local/pccntr8203403_aitutor:useen el contexto del curso. - La capacidad tiene
RISK_PERSONALporque transmite datos del usuario al exterior. - Roles autorizados por defecto:
student,teacher,editingteacher,manager.
Proteccion del token
- El token del servicio externo se almacena como
admin_setting_configpasswordunmasken la configuracion del plugin. Solo el administrador lo ve. - El encabezado de autenticacion se envia unicamente desde el servidor, nunca desde el navegador.
- Se requiere HTTPS en la URL del servidor; las URLs HTTP se rechazan.
Rate limiting
Control de frecuencia por usuario via cache MUC (ratelimit). Configurable en los ajustes del plugin (por defecto 2 segundos entre peticiones). Valor 0 desactiva el limite.
Sanitizacion de entrada y salida
- SCORM CMI: se valida tamano (max 4096 bytes), profundidad (max 8 niveles), y se aplica whitelist de claves (
lesson_location,completion_status). - URL actual: se elimina el query string para evitar fugas de
sesskeyo tokens. - Respuesta HTML del tutor: se pasa por
clean_text($html, FORMAT_HTML)(HTMLPurifier de Moodle) para eliminar<script>, event handlers y URLsjavascript:. - cURL: redirecciones deshabilitadas (
FOLLOWLOCATION = 0) para prevenir SSRF via open-redirect.
Privacidad (GDPR)
El plugin declara un privacy\provider que informa que se envian datos personales a un servicio externo: ID de usuario, rol, ID de curso, URL de pagina, ID de actividad, datos SCORM y el texto del mensaje. No se almacena informacion personal en la base de datos de Moodle.
Configuracion
Accesible en Administracion del sitio > Plugins > Plugins locales > Tutor IA.
| Ajuste | Clave | Tipo | Por defecto | Descripcion |
|---|---|---|---|---|
| URL del servidor | serverurl | URL (HTTPS) | (vacio) | URL base del servicio externo. HTTPS obligatorio. |
| Token de autenticacion | token | Password | (vacio) | Token Bearer para el servicio externo. |
| Limite de frecuencia | ratelimit | Entero | 2 | Segundos minimos entre peticiones por usuario (0 = desactivado). |
| Tiempo de espera | timeout | Entero | 60 | Timeout de cURL en segundos (rango valido: 5-120). |
Cache MUC
| Definicion | Modo | TTL | Proposito |
|---|---|---|---|
ratelimit | MODE_APPLICATION | 120 s | Almacena la marca de tiempo de la ultima peticion por usuario para el rate limiting |
Tests
El plugin incluye un test PHPUnit en tests/external/send_message_test.php que valida:
- Parametros de la funcion externa.
- Sanitizacion de la respuesta HTML.
- Sanitizacion y whitelist de SCORM CMI.
- Rechazo de URLs HTTP (solo HTTPS permitido).
Dependencias
- Ninguna dependencia en
version.php. - Requiere que el servicio externo de tutoria IA este disponible y configurado.
theme_cdigitalrenderiza el Drawer IA e invoca el modulo AMDaitutor.jsque llama a esta funcion externa via AJAX.
Contrato con el servicio externo
El endpoint consume POST {serverurl}/v1/campus/tutor con autenticacion via encabezado Authentication: Bearer {token} (nota: el encabezado es Authentication, no Authorization, por contrato del endpoint del servicio externo).
Respuesta esperada:
{
"reply_html": "<p>Respuesta del tutor...</p>",
"suggested_actions": [],
"risk_level_detected": "bajo"
}
Relacion con ADR-001
Este plugin es independiente de la capa de Web Services planeada en ADR-001. ADR-001 describe funciones externas de solo lectura para que un agente IA externo consulte datos del campus. Este plugin resuelve el flujo inverso: que el estudiante envie mensajes al tutor IA desde Moodle. La decision de separar este plugin del local_pccntr8203403_dashboard se documenta en ADR-003.
Historial de cambios
Ver CHANGELOG.md en la raiz del sitio de documentacion.