@sentinel-sdk
v1.0.3

Instalación

npm
npm install @sentinel-sdk/typescript

Requerimientos

RequerimientoVersión
TypeScript>= 5.0
Node.js>= 18
MóduloESM y CJS

Primeros Pasos

El SDK utiliza el patrón de resultados — nunca lanza excepciones. Siempre desestructura { data, error } y verifica error primero.

Con contexto de sesión (recomendado)

Sincroniza el mensaje con el servidor, recupera el historial completo de la sesión y lo analiza a través del motor multicapa.

index.ts
import { Sentinel } from "@sentinel-sdk/typescript";

const sentinel = new Sentinel({ apiKey: process.env.SENTINEL_API_KEY! });

const { data, error } = await sentinel.analyze(
  "oye quieres ganar lana haciendo unos mandados",
  "session-uuid",
  "user-uuid"
);

if (error) {
  console.error(error.code, error.message);
} else {
  console.log(data.risk);               // "HIGH"
  console.log(data.stage);              // "CAPTACION"
  console.log(data.ux_recommendation);  // "SOFT_BLOCK"
}

Análisis Local (Sin conexión)

Análisis local instantáneo sin llamadas a la API. Útil para prefiltrado o entornos sin conexión.

index.ts
const { data, error } = sentinel.localAnalyze([
  { text: "te mando lana si me ayudas con un jale" },
  { text: "trato de 300 pesos por noche" },
  { text: "es solo un jale, nomas es entregar un pakete" }
]);

if (!error) {
  console.log(data.score);        // numeric score
  console.log(data.risk);         // "MEDIUM"
  console.log(data.velocityFlag); // false
  console.log(data.layers.v3.terms); // ["REC-005"]
}

Manejo de recomendaciones UX

index.ts
const { data, error } = await sentinel.analyze(text, sessionId, userId);
if (error) return;

switch (data.ux_recommendation) {
  case "NONE":            break;
  case "SOFT_NUDGE":      showSafetyTip(); break;
  case "WARNING_OVERLAY": showWarning(data.stage); break;
  case "SOFT_BLOCK":      pauseConversation(); break;
  case "HARD_BLOCK":      blockAndReport(sessionId); break;
}

Generar API Key

Para utilizar las capacidades completas de análisis y escalación de Sentinel, necesitas autenticar el SDK utilizando una API Key.

Fase Beta Gratuita: Sentinel se encuentra actualmente en fase Early Access. La generación y uso de API Keys es completamente gratuita para propósitos de desarrollo, evaluación y proyectos sin fines de lucro.

¿Cómo obtener tu API Key?

Genera una clave de acceso instantánea para tus pruebas de desarrollo. Esta clave de prueba no requiere inicio de sesión ni validación de correo.

Nota: Durante la fase beta gratuita, se aplican límites de tasa (rate limits) predeterminados para asegurar la disponibilidad del servicio. Si requieres mayor capacidad para tu plataforma, contacta a nuestro equipo de soporte.

Sentinel

La clase principal exportada por el SDK. Orquesta el pipeline del motor local, la sincronización de sesiones API y la escalada a la API de Sentinel.

Import
import { Sentinel } from "@sentinel-sdk/typescript";

constructor

Signature
new Sentinel(config: SentinelConfig)
ParámetroTipoDescripción
configSentinelConfigObjeto de configuración. Actualmente requiere solo apiKey.

analyze()

Análisis completo de la sesión. Sincroniza el mensaje con la API, recupera el historial de la sesión, ejecuta el motor de 3 capas y escala a la IA si es necesario.

Signature
analyze(
  text: string,
  sessionId: string,
  userId: string
): Promise<SentinelResult<ApiAnalysisResponse>>
ParámetroTipoDescripción
textstringrequiredEl mensaje de texto a analizar.
sessionIdstringrequiredIdentificador único de la sesión de conversación.
userIdstringrequiredIdentificador del usuario que está siendo monitoreado.

RetornaPromise<SentinelResult<ApiAnalysisResponse>>

localAnalyze()

Análisis local de una lista de mensajes. Sin llamadas de red, sin contexto de sesión. Retorna el resultado del motor. Síncrono.

Signature
localAnalyze(text: string): SentinelResult<SentinelAnalysisResponse>
Parámetro Tipo Descripción
messages Message[] required Lista de mensajes a analizar. Si timestamps no son proporcionados, serán generados automáticamente.

RetornaSentinelResult<SentinelAnalysisResponse>

localAnalyze() es síncrono y retorna SentinelAnalysisResponse (el resultado del motor con desglose de capas), mientras que analyze() es asíncrono y retorna ApiAnalysisResponse (enriquecido con etapa, confianza y recomendación UX de la API).

SentinelResult<T>

El tipo de retorno para todos los métodos del SDK. Sigue el patrón Result — el SDK nunca lanza excepciones. Siempre verifica error antes de acceder a data.

SentinelResult.ts
type SentinelResult<T> =
  | { data: T;error: null }   // success
  | { data: null; error: SentinelError }; // failure
Success
const { data, error } = result;
if (!error) {
  data.risk; // guaranteed
}
Failure
const { data, error } = result;
if (error) {
  error.code;    // error code
  error.message; // description
}

Se exportan dos funciones de conveniencia para construir resultados:

helpers
import { ok, err } from "@sentinel-sdk/typescript";

ok(data)    // → { data, error: null }
err(error)  // → { data: null, error }

SentinelConfig

SentinelConfig.ts
interface SentinelConfig {
  apiKey: string;
}
PropertyTypeDescription
apiKeystringTu API key de Sentinel. Se utiliza para autenticar las solicitudes de escalamiento.

ApiAnalysisResponse

Resultado enriquecido retornado por analyze() desde la API de Sentinel cuando ocurre una escalación, o el resultado calculado localmente para sesiones de bajo/alto puntaje.

SentinelAnalysisResult.ts
interface ApiAnalysisResponse {
  ux_recommendation: UXRecommendation;
  stage:             Stage;
  confidence:        number;  // 0–1
  summary:           string;  // human-readable explanation
  false_positive:    boolean;
  messages_analyzed: number;
  current_message:   string;
}
PropiedadTipoDescripción
ux_recommendationUXRecommendationLa acción de UI que tu aplicación debe tomar.
stageStageEtapa de reclutamiento detectada de la conversación.
confidencenumberScore de confianza 0–1.
summarystringDescripción legible por humanos del patrón de riesgo detectado.
false_positivebooleanSi la API determinó que fue un falso positivo.
messages_analyzednumberNúmero de mensajes en la sesión que fueron analizados.
current_messagestringEl mensaje que activó el análisis.

SentinelAnalysisResponse

Retornado por localAnalyze(). El resultado crudo del motor con el desglose completo por capa para auditoría y depuración.

SentinelAnalysisResult.ts
interface SentinelAnalysisResponse {
  score:            number;
  risk:             RiskLevel;
  escalate:         boolean;
  velocityFlag:     boolean;
  velocityWindow:   number;   // seconds
  messagesAnalyzed: number;
  uniqueCategories: string[];
  layers: {
    normalizer: { score: number; features: string[]; triggeredRules: string[]; transformations: string[] };
    v3: { score: number; terms: string[]; categories: string[]; triggeredRules: string[] };
    v4: { score: number; features: string[]; triggeredRules: string[]; explicitSignals: string[] };
  };
}
PropiedadTipoDescripción
scorenumberPuntaje acumulado total en todas las capas. Se aplica un bonus de velocidad cuando corresponde.
riskRiskLevelNivel de riesgo resuelto.
escalatebooleanSi el motor determinó que esta sesión debe ser enviada a la API.
velocityFlagbooleantrue si ocurrieron 3 o más detecciones dentro de 5 minutos.
velocityWindownumberVentana de tiempo medida en segundos (0 si no se activó la velocidad).
uniqueCategoriesstring[]Categorías de riesgo deduplicadas entre las capas V3 y V4.
layersobjectDesglose por capa: normalizador, v3, v4. Cada uno incluye su propio puntaje, ítems coincidentes y reglas activadas.

SentinelError

La clase de error devuelta en el campo error de un SentinelResult. Hereda el Error nativo.

SentinelError.ts
type SentinelErrorCode =
  | "API_ERROR"
  | "VALIDATION_ERROR"
  | "UNKNOWN_ERROR";

class SentinelError extends Error {
  code:        SentinelErrorCode;
  statusCode?: number;
  details?:    string;
}
CódigoCausa
VALIDATION_ERRORFaltan parámetros requeridos (text, sessionId, userId).
API_ERRORLa API de Sentinel devolvió una respuesta que no es 2xx. Se establecerá statusCode.
UNKNOWN_ERRORExcepción inesperada detectada internamente.

Otros Tipos

RiskLevel

SentinelEngine.ts
type RiskLevel = "LOW" | "MEDIUM" | "HIGH" | "CRITICAL";
ValorScoreDescripción
LOW0–11Sin riesgo significativo. No se realiza llamada a la API.
MEDIUM12–19Ambiguo. Activa la escalación a IA.
HIGH20–24Indicadores fuertes o velocidad + regla activa.
CRITICAL≥ 25Múltiples reglas activadas. Acción inmediata requerida.

Stage

SentinelAnalysisResult.ts
type Stage =
  | "NINGUNA"
  | "CAPTACION"
  | "INDUCCION/COOPTACION"
  | "INCUBACION"
  | "UTILIZACION/INSTRUMENTALIZACION";

UXRecommendation

SentinelAnalysisResult.ts
type UXRecommendation =
  | "NONE"
  | "SOFT_NUDGE"
  | "WARNING_OVERLAY"
  | "SOFT_BLOCK"
  | "HARD_BLOCK";

Message

SentinelEngine.ts
interface Message {
  text:      string;
  timestamp: number; // Unix ms — required for velocity detection
}

ApiMessage

SentinelEngine.ts
interface ApiMessage {
  id:         string;
  user_id:    string;
  session_id: string;
  content:    string;
  timestamp:  number;
}

Arquitectura del Motor

El motor procesa cada conversación a través de un pipeline de 3 capas antes de decidir si escalarla a IA. La mayoría de los mensajes se resuelven localmente en milisegundos, minimizando el costo y la latencia.

LAYER 0
NormalizerLayer
Limpia el texto informal antes de cualquier coincidencia de patrones. Expande emojis, abreviaturas de chat y errores fonéticos. Detecta características N0 y reglas de combinación en texto normalizado.
sentinel_dataset_normalizer_v2.json
↓ texto normalizado
LAYER 1
V3Layer
Búsqueda de concordancia exacta de términos contra el vocabulario de riesgo documentado. Cada término coincidente aporta su peso al puntaje. Evalúa reglas de escalación multimodales (MCR).
sentinel_dataset_v3.json
LAYER 2
V4Layer
Detección de características abstractas y señales explícitas de alta precisión. Características basadas en léxico con lógica de negación opcional. Las reglas de combinación (CR-*) recompensan la coocurrencia de señales.
sentinel_dataset_v4.json
↓ todas las coincidencias de todas las capas
VELOCITY
VelocityDetector
Verifica si ocurrieron 3 o más coincidencias de cualquier capa dentro de una ventana de 5 minutos. Si es así, y si alguna regla está activa, el puntaje total se multiplica por 1.2×.

Capa Normalizadora

Normaliza el texto del mensaje crudo a través de un pipeline de múltiples pasos antes de pasarlo a las capas V3 y V4. Esto permite que el motor detecte lenguaje de reclutamiento ofuscado, deletreado fonéticamente o codificado con emojis.

PasoQué haceEjemplo
1. Expansión de emojisExpande emojis y símbolos a texto canónico📦 → paquete
2. Remoción de acentosNormalización NFD, eliminación de diacríticoscanción → cancion
3. Colapso de repeticiones3 o más caracteres repetidos → 2jaleeeee → jalee
4. Mapa de errores tipográficosCorrecciones comunes de errores tipográficospakete → paquete
5. AbreviacionesAbreviaciones de chat → forma canónicak → que
6. Reglas fonéticasSustituciones fonéticas basadas en expresiones regularesq → cu

Capa V3

Escanea los mensajes normalizados en busca de términos de coincidencia exacta del vocabulario de riesgo de Sentinel. Cada término tiene un weight y una category. Los términos se deduplican por sesión — un término repetido solo se cuenta una vez.

Después de escanear, evalúa las Reglas Multicategoría (MCR): reglas que se activan cuando aparecen combinaciones específicas de categorías de riesgo en la sesión con suficientes mensajes. Dos o más reglas MCR activadas = CRITICAL.

Capa V4

Detecta señales conductuales abstractas que la capa V3 basada en términos no detectaría. Funciona a través de dos mecanismos:

MecanismoDescripción
Características abstractasCaracterísticas basadas en léxico, opcionalmente negadas. Ej. ambiguous_opportunity se activa cuando coincide un léxico pero no hay contexto de seguridad presente.
Señales explícitasCoincidencia de patrones de alta precisión para frases de reclutamiento específicas. Mayor peso que las características abstractas.
Reglas de combinación (CR-*)Puntaje de bonificación cuando múltiples características abstractas co-ocurren en la misma sesión.

Detector de Velocidad

Toma la lista combinada de coincidencias de las 3 capas y verifica la actividad de ráfaga.

Default Configuration
new VelocityDetector(
  windowSeconds = 300,  // 5-minute window
  minHits       = 3     // minimum hits to flag
)

Cuando velocityFlag = true y al menos una regla está activa en cualquier capa, el puntaje total se multiplica por 1.2× y el riesgo se eleva al menos a HIGH.

Puntuación y Riesgo

El puntaje total es la suma de todos los puntajes de las capas (normalizador + V3 + V4), con un bono de velocidad del 20% aplicado cuando sea aplicable. El motor luego resuelve un RiskLevel y determina si escalar.

0–11
Bajo
Se devuelve inmediatamente. No se realiza llamada a la API.
12–19
Medio
Se escala a la API de Sentinel + Groq LLaMA.
20–24
Alto
Indicadores fuertes o velocidad + regla.
≥ 25
Crítico
≥2 reglas activadas o puntaje extremo.
Risk resolution logic (engine.ts)
if (score >= 25 || totalRules >= 2)                       return "CRITICAL";
if (score >= 20 || (velocityFlag && totalRules > 0))   return "HIGH";
if (score >= sessionThreshold)                         return "MEDIUM";
return "LOW";

Donde totalRules = reglas MCR activadas (V3) + reglas de combinación (V4) + reglas de combinación (Normalizador).

Etapas de Reclutamiento

Las etapas son asignadas por la API de Sentinel (análisis de Groq LLaMA) durante la escalada, o inferidas localmente a partir de los umbrales de puntuación para respuestas inmediatas.

1
NINGUNA puntuación ≤ 11 (local)
No hay señales de reclutamiento. La conversación es segura.
2
CAPTACIÓN puntuación > 19 (local fallback)
El perpetrador está estableciendo contacto inicial y construyendo una falsa confianza para atraer al menor.
3
INDUCCIÓN / COOPTACIÓN API
El perpetrador está influenciando creencias o comportamientos, creando dependencia emocional.
4
INCUBACIÓN API
Desensibilización gradual a contenido o peticiones inapropiadas.
5
UTILIZACIÓN / INSTRUMENTALIZACIÓN puntuación > 24 (local fallback)
Explotación activa. Mayor severidad — dispara la recomendación HARD_BLOCK.

Recomendaciones UX

El campo ux_recommendation le dice a su aplicación exactamente qué acción de UI tomar. La escala es proporcional: evite alarmar a los usuarios innecesariamente sin dejar de protegerlos.

ValorRiesgoIntrusividadQué hacer
NONE NINGUNO Ninguna Proceda con normalidad.
SOFT_NUDGE MEDIUM Baja Tarjeta de seguridad pasiva en el chat con un enlace de ayuda. No interrumpa el flujo de mensajes.
WARNING_OVERLAY MEDIUM Medio Modal que se puede cerrar. Incluya una opción "Estoy bien". Registre todas las omisiones.
SOFT_BLOCK HIGH Alta Bloquea el envío hasta que el usuario reconozca la indicación o se comunique con un tutor.
HARD_BLOCK CRITICAL Total Termina la sesión inmediatamente. Notifica al tutor. Marca para revisión humana. No se permite la dismisión.

Manejo de Errores

El SDK utiliza el patrón Result en todas partes. Nunca lanza excepciones, nunca rechaza promesas inesperadamente. Todos los errores aparecen a través del campo error.

Ejemplo completo
import { Sentinel } from "@sentinel-sdk/typescript";

const sentinel = new Sentinel({ apiKey: process.env.SENTINEL_API_KEY! });

const { data, error } = await sentinel.analyze(text, sessionId, userId);

if (error) {
  switch (error.code) {
    case "VALIDATION_ERROR":
      console.warn("Missing parameters:", error.message);
      break;
    case "API_ERROR":
      console.error(`API returned ${error.statusCode}`);
      break;
    default:
      console.error(error.message);
  }
  return;
}

// data is fully typed and guaranteed here
console.log(data.ux_recommendation);