Triggers
Un trigger escucha el bus de eventos de wu y llama al modelo cuando ocurre algo. Es la mitad reactiva de wu.ai: la app se vuelve inteligente respondiendo a sus propios eventos.
wu.ai.trigger('cartAnalysis', { pattern: 'cart:updated', prompt: 'The cart was updated: {{data}}. Suggest complementary products.', debounce: 3000, priority: 'low', onResult: (result) => wu.emit('ai:suggestions', { text: result.content }),});function trigger(name: string, config: { pattern: string; prompt: string | ((eventData: object) => string); condition?: (eventData: object) => boolean | Promise<boolean>; debounce?: number; // ms, 1000 por defecto priority?: 'high' | 'medium' | 'low'; // 'medium' por defecto namespace?: string; // `trigger:<name>` por defecto systemPrompt?: string; onResult?: (result: object, eventData: object) => void | Promise<void>; enabled?: boolean; // true por defecto maxTokens?: number; temperature?: number;}): Wu;| Opción | Por defecto | Notas |
|---|---|---|
pattern |
— | 'cart:updated', 'cart:*' (* coincide dentro de un solo segmento) o '*' para todo |
prompt |
— | Una plantilla con {{event}}, {{data}}, {{timestamp}}, o una función del evento |
condition |
null |
Se permite async. Si lanza, se trata como false y el trigger se omite |
debounce |
1000 |
Gana el último evento. <= 0 dispara de inmediato |
priority |
'medium' |
Ver más abajo |
namespace |
trigger:<name> |
Historial de conversación propio, aislado de tu chat |
onResult |
null |
Los errores se tragan y se registran |
enabled |
true |
Se conmuta con setEnabled(name, bool) |
temperature |
— | Se lee con ??, así que temperature: 0 funciona como esperas |
Registrar un nombre existente desregistra primero el antiguo (y no cuenta contra el límite).
Prioridad
Sección titulada «Prioridad»| Prioridad | Camino |
|---|---|
high |
Disparo con debounce |
medium |
Disparo con debounce |
low |
Encolado y agrupado cada batchIntervalMs (2000 ms), deduplicado para que solo sobreviva el último evento por trigger |
Límites
Sección titulada «Límites»wu.ai.init({ triggers: { maxActiveTriggers: 10, batchIntervalMs: 1000, defaultDebounceMs: 500 } });| Ajuste | Por defecto |
|---|---|
enabled |
true (interruptor global) |
maxActiveTriggers |
20 |
defaultDebounceMs |
1000 |
batchIntervalMs |
2000 |
Gestionar triggers
Sección titulada «Gestionar triggers»wu.ai.trigger('x', { … });await wu.ai.fireTrigger('x', { data: { foo: 1 } }); // salta la coincidencia de eventos y el debounce
const ai = await wu.aiReady();ai._modules; // no es público — usa la superficie de estadísticaswu.ai.getStats().triggers; // { totalFired, totalSkipped, totalErrors, triggerCount, triggers: {…} }Cada trigger informa de pattern, priority, enabled, fireCount y lastFired.
Seguridad frente a bucles
Sección titulada «Seguridad frente a bucles»Esta es la parte que importa. Una acción puede emitir un evento; un evento puede disparar un trigger; un trigger llama al modelo, que puede llamar a una acción. Sin más, eso es un bucle infinito.
Wu lo cierra propagando la causalidad. Cuando el handler de una acción llama a api.emit(...), el evento lleva meta: { traceId, depth }. Un trigger que dispara con ese evento continúa la misma cadena: reutiliza el traceId y envía con depth + 1. La protección de bucles rechaza la llamada en cuanto la profundidad o el contador por cadena supera maxDepth (3 por defecto).
Un evento que no vino de la IA no tiene meta, así que el trigger inicia una cadena nueva a profundidad 0, como debe ser.
Una llamada de trigger bloqueada no lanza: la conversación devuelve content: '[blocked] …', que aterriza en onResult como cualquier otro resultado.
Errores y resultados
Sección titulada «Errores y resultados»Cada disparo emite ai:trigger:result con { trigger, pattern, result }. Un fallo emite ai:trigger:error con { trigger, error } y _executeTrigger devuelve null: un trigger nunca propaga una excepción al bus de eventos.
Un prompt vacío o falsy cuenta como omisión y no se hace ninguna llamada, lo que es una forma barata de filtrar dentro de una función de prompt:
wu.ai.trigger('bigOrders', { pattern: 'order:created', prompt: (e) => e.data.total > 1000 ? `Review this large order: ${JSON.stringify(e.data)}` : '',});Un trigger sobre un patrón ruidoso es una llamada al LLM por ventana de debounce, para siempre y sin que nadie mire. Antes de poner uno en producción:
- Prefiere prioridad
lowpara que los eventos se agrupen. - Pon un
debouncegeneroso: segundos, no milisegundos. - Usa
conditionpara filtrar antes de armar el temporizador de debounce. - Recuerda el límite global de peticiones: 20 peticiones/min en total, 10/min por namespace. Un trigger desbocado empezará a recibir
[blocked]en vez de generarte una factura, pero también dejará sin oxígeno a tus conversaciones reales.
