@decido/core
v4.1.0
Published
> Módulo central de ejecución secuencial, orquestación de sub-grafos y máquina de estados reactiva de **Decido OS**.
Downloads
221
Readme
@decido/core
Módulo central de ejecución secuencial, orquestación de sub-grafos y máquina de estados reactiva de Decido OS.
@decido/core es el núcleo computacional (Kernel) responsable de interpretar y ejecutar blueprints modulares. Utiliza un patrón de Inversión de Control (IoC) mediante plugins extensibles, posee aislamiento de memoria local para subflujos en una pila de llamadas (Call Stack) y proporciona persistencia reactiva atómica e inmune a leaks de memoria apoyada sobre IndexedDB.
📦 Instalación y Setup
Aprovisiona este paquete dentro del monorepo o consumelo como dependencia interna:
pnpm add @decido/core⚙️ Arquitectura y Modelo de Ejecución
El motor DecidoEngine procesa la lógica paso a paso delegando la resolución de nodos a los componentes registrados de tipo NodePlugin. A continuación se detalla su flujo de eventos, soporte a suspensiones reactivas y apilamiento de marcos de ejecución para subflujos:
sequenceDiagram
participant Host as Aplicación Host
participant Engine as DecidoEngine
participant Reg as PluginRegistry
participant Plugin as NodePlugin
Host->>Engine: start(blueprintId, initialInputs)
Note over Engine: Estado: RUNNING<br/>Inicia primer CallFrame
Engine-->>Host: Evento 'graph:start'
Host->>Engine: executeNode(node)
Engine->>Reg: get(node.type)
Reg-->>Engine: Plugin
Engine->>Plugin: execute(node.payload, context)
alt Completado Simple
Plugin->>Engine: context.dispatchCompletion(handle, outputs)
Note over Engine: Inyecta outputs en memory.session
Engine-->>Host: Evento 'node:complete'
else Suspensión Reactiva
Plugin->>Engine: context.dispatchSuspend(reason)
Note over Engine: Estado: SUSPENDED
Engine-->>Host: Evento 'engine:suspend'
Host->>Engine: resume(injectedVariables)
Note over Engine: Estado: RUNNING
Engine-->>Host: Evento 'engine:resume'
else Orquestación de Subflujo (Call Stack)
Plugin->>Engine: context.pushCallFrame(targetBlueprintId, startNodeId)
Note over Engine: Respalda memory.local del padre<br/>Limpia memory.local del hijo
Engine-->>Host: Evento 'engine:callframe_push'
Note over Engine: Ejecución del subflujo...
Plugin->>Engine: context.popCallFrame(outputs, handle)
Note over Engine: Restaura la memory.local del padre
Engine-->>Host: Evento 'engine:callframe_pop'
Engine-->>Host: Evento 'node:complete' (nodo padre)
end🛠️ APIs y Contratos Clave
| Símbolo | Tipo | Descripción |
| :--- | :--- | :--- |
| DecidoEngine | Clase | Implementación del motor central (DecidoKernel) con pila de llamadas y memoria de 3 niveles. |
| PluginRegistry | Objeto | Catálogo único (Singleton) para registrar y recuperar plugins contractuales de nodos. |
| DecidoKernel | Interfaz | Contrato que define la API operacional y eventos de ciclo de vida del motor. |
| DecidoPluginContext | Interfaz | Contexto IoC provisto a los plugins para despachar flujos (completion, suspend, callstack). |
| NodePlugin | Interfaz | Contrato para definir e implementar la lógica ejecutable asociada a un tipo de nodo. |
| EngineMemory | Interfaz | Estructura de almacenamiento reactivo dividida en ámbitos: global, session y local. |
| get, set, del, clear | Funciones | Capa de persistencia síncrona/asíncrona atómica optimizada mediante conexión Cached Singleton en IndexedDB. |
🚀 Ejemplos de Consumo Práctico
1. Definición y Registro de un Plugin de Conversación
Los plugins permiten encapsular lógica extendida e interactuar de forma segura con la pila y memoria del motor:
import { NodePlugin, DecidoPluginContext, PluginRegistry } from '@decido/core';
interface DialoguePayload {
prompt: string;
role: string;
}
// Implementación de un plugin interactivo con suspensión
export const DialoguePlugin: NodePlugin = {
type: 'ai:dialogue',
async execute(payload: unknown, context: DecidoPluginContext) {
const { prompt, role } = payload as DialoguePayload;
console.log(`[DialoguePlugin] Procesando prompt para rol ${role}: "${prompt}"`);
// Suspendemos la ejecución esperando interacción del usuario externo
context.dispatchSuspend('WAITING_USER');
}
};
// Registro del plugin en el catálogo global
PluginRegistry.register(DialoguePlugin);2. Orquestación e Invocación del Motor (DecidoEngine)
import { DecidoEngine } from '@decido/core';
const engine = new DecidoEngine();
// Suscripción reactiva a eventos del ciclo de vida
engine.on('graph:start', (payload) => {
console.log(`[Kernel] Flujo iniciado: ${payload.blueprintId}`);
});
engine.on('engine:suspend', (payload) => {
console.log(`[Kernel] Motor en Suspensión. Razón: ${payload.reason}`);
});
engine.on('node:complete', (payload) => {
console.log(`[Kernel] Nodo completado: ${payload.nodeId} con handle: ${payload.handle}`);
});
// Iniciamos la ejecución del blueprint
engine.start('chat-flow-root', { userId: 'user_9988' });
// Al recibir respuesta externa, reanudamos el motor con las nuevas variables
setTimeout(() => {
if (engine.state === 'SUSPENDED') {
engine.resume({ userResponse: '¡Hola! Quiero iniciar mi onboarding.' });
}
}, 1000);🧪 Robustez y Suite de Pruebas (Test Shield 100%)
El paquete @decido/core cuenta con un estricto blindaje de pruebas unitarias (Unit Test Shield) implementado con Vitest y V8, garantizando un 100% absoluto de cobertura en ramas lógicas, sentencias, funciones y líneas de código.
Para correr localmente las pruebas unitarias y verificar el estricto cumplimiento del Test Shield:
# Ejecutar todas las pruebas unitarias
pnpm --filter @decido/core test
# Generar y auditar la tabla de cobertura 100%
pnpm --filter @decido/core test:coverage🔐 Licencia y Privacidad
El código fuente de este paquete se encuentra protegido y auditado de forma corporativa.
Distribuido estrictamente bajo licencia UNLICENSED para uso exclusivo en el ecosistema de Decido OS.
