Saltar al contenido principal

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

FuncionDescripcion
local_pccntr8203403_aitutor_send_messageEnvia un mensaje del usuario al tutor IA externo y retorna la respuesta sanitizada. Tipo write, ajax: true, requiere login.

Parametros de entrada

ParametroTipoDescripcion
messagePARAM_TEXTTexto del mensaje del usuario
courseidPARAM_INTID del curso actual
cmidPARAM_INTID del modulo de curso (0 si no esta en una actividad)
currenturlPARAM_URLURL de la pagina actual (se elimina el query string antes de enviar)
scormcmiPARAM_RAWDatos CMI de SCORM codificados en JSON (vacio si no aplica)

Retorno

CampoTipoDescripcion
replyPARAM_RAWHTML sanitizado de la respuesta del tutor
sessionidPARAM_RAWIdentificador 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:use en el contexto del curso.
  • La capacidad tiene RISK_PERSONAL porque 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_configpasswordunmask en 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 sesskey o tokens.
  • Respuesta HTML del tutor: se pasa por clean_text($html, FORMAT_HTML) (HTMLPurifier de Moodle) para eliminar <script>, event handlers y URLs javascript:.
  • 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.

AjusteClaveTipoPor defectoDescripcion
URL del servidorserverurlURL (HTTPS)(vacio)URL base del servicio externo. HTTPS obligatorio.
Token de autenticaciontokenPassword(vacio)Token Bearer para el servicio externo.
Limite de frecuenciaratelimitEntero2Segundos minimos entre peticiones por usuario (0 = desactivado).
Tiempo de esperatimeoutEntero60Timeout de cURL en segundos (rango valido: 5-120).

Cache MUC

DefinicionModoTTLProposito
ratelimitMODE_APPLICATION120 sAlmacena 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_cdigital renderiza el Drawer IA e invoca el modulo AMD aitutor.js que 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.