Documentacion Tecnica
Referencia completa para integrar ltb-method en cualquier proyecto React o Next.js.
Basada en Context API de React. Dos niveles independientes: organizacion y cuenta (proyecto).
Desacoplado del backend mediante un adaptador intercambiable. Implementa la interfaz LTBApiAdapter.
Cada vista acepta un objeto LTBPermissions que controla que agentes son visibles e interactivos.
cp -r components/ltb-method/ your-project/components/./components/ltb-method.LTBPermissions— Controla la visibilidad e interaccion de cada vista
interface LTBPermissions {
canManage: boolean; // Crear / editar / eliminar etapas y agentes
canToggleAccountActions: boolean; // Activar / desactivar agentes por proyecto
}LTBApiAdapter— Interfaz que debe implementar tu capa de datos
interface LTBApiAdapter {
// Etapas
getStages(): Promise;
createStage(data: StageFormData): Promise;
updateStage(id: string, data: Partial): Promise;
deleteStage(id: string): Promise;
reorderStages(orderedIds: string[]): Promise;
// Agentes
getActions(): Promise;
createAction(data: ActionFormData): Promise;
updateAction(id: string, data: Partial): Promise;
deleteAction(id: string): Promise;
reorderActions(stageId: string, orderedIds: string[]): Promise;
// Agentes por cuenta
getAccountActions(accountId: string): Promise;
toggleAccountAction(
accountId: string,
actionId: string,
isActive: boolean
): Promise;
// Ejecuciones
executeAction(context: ExecutionContext): Promise;
getExecutionHistory(accountId: string, actionId?: string): Promise;
getAccountActionsWithExecutions(accountId: string): Promise;
} createApiAdapter valida que se implementen todos los metodos requeridos.import { createApiAdapter } from '@/components/ltb-method';
export const myApiAdapter = createApiAdapter({
getStages: () =>
fetch('/api/stages').then((r) => r.json()),
createStage: (data) =>
fetch('/api/stages', {
method: 'POST',
body: JSON.stringify(data),
}).then((r) => r.json()),
reorderStages: (orderedIds) =>
fetch('/api/stages/reorder', {
method: 'PUT',
body: JSON.stringify({ orderedIds }),
}).then((r) => r.json()),
getActions: () =>
fetch('/api/actions').then((r) => r.json()),
reorderActions: (stageId, orderedIds) =>
fetch('/api/actions/reorder', {
method: 'PUT',
body: JSON.stringify({ stageId, orderedIds }),
}).then((r) => r.json()),
getAccountActions: (accountId) =>
fetch('/api/accounts/' + accountId + '/actions').then((r) => r.json()),
toggleAccountAction: (accountId, actionId, isActive) =>
fetch('/api/accounts/' + accountId + '/actions/' + actionId, {
method: 'PATCH',
body: JSON.stringify({ isActive }),
}).then((r) => r.json()),
// ... resto de metodos
});LTBMethodProvider gestiona el nivel de organizacion y LTBAccountProvider el nivel de proyecto.import {
LTBMethodProvider,
LTBAccountProvider,
OrganizationView,
AccountView,
type LTBPermissions,
} from '@/components/ltb-method';
// Vista de Organizacion / Agencia
const orgPermissions: LTBPermissions = {
canManage: user.role === 'admin',
canToggleAccountActions: false,
};
// Vista de Proyecto (Account)
const accountPermissions: LTBPermissions = {
canManage: false,
canToggleAccountActions: user.permissions.includes('account:write'),
};
GET /api/accounts/{accountId}/actions
// Response 200
{
"stages": [
{
"id": "string",
"name": "string",
"order": 1,
"actions": [
{
"id": "string",
"stage_id": "string",
"name": "string",
"icon": "string", // nombre de icono Lucide
"description": "string",
"rich_description": "string | null", // HTML permitido
"agent_source": "claude | n8n", // fuente del agente
"agent_id": "string | null", // ID del agente
"order": 1, // orden dentro de la etapa
"is_active": true
}
]
}
]
}PUT /api/actions/reorder
// Request body
{
"stageId": "string",
"orderedIds": ["agent-1", "agent-3", "agent-2"]
}
// Response 200 - array de agentes reordenados
[
{
"id": "string",
"stage_id": "string",
"order": 1,
// ... resto de campos del agente
}
]@dnd-kit internamente.Callbacks en StagesTimeline
{ // orderedIds: string[] - nuevos IDs en orden await reorderStages(orderedIds); }} // Llamado cuando se reordena agentes dentro una etapa onReorderActions={(stageId, orderedIds) => { // stageId: string - etapa que contiene los agentes // orderedIds: string[] - nuevos IDs de agentes en orden await reorderActions(stageId, orderedIds); }} />
Comportamiento de reordenamiento
- Arrastra etapas verticalmente para cambiar su orden
- Arrastra agentes dentro de una etapa para reordenarlos
- Los cambios se persisten automaticamente en el backend
- El campo
orderse actualiza en la base de datos
Tipos de ejecucion
type ExecutionStatus = "pending" | "running" | "completed" | "failed";
interface ActionExecution {
id: string;
account_id: string;
action_id: string;
status: ExecutionStatus;
output?: string; // Resultado de la ejecucion
error?: string; // Mensaje de error si fallo
execution_time_ms?: number;
tokens_used?: number;
metadata?: Record;
started_at: string;
completed_at?: string;
created_at: string;
}
interface ActionWithExecutionStatus extends ActionWithStatus {
last_execution?: ActionExecution; // Ultima ejecucion
execution_count: number; // Total de ejecuciones
has_completed: boolean; // Si se completo al menos una vez
} Contexto de cuenta con ejecuciones
// El contexto de cuenta ahora incluye:
const {
stagesWithExecutions, // Etapas con estado de ejecucion
executionHistory, // Historial completo
completionPercentage, // % de agentes activos completados
executeAction, // Funcion para ejecutar un agente
refreshExecutions, // Refrescar datos de ejecucion
} = useLTBAccount();
// Ejecutar un agente
const result = await executeAction(action, userInput);
if (result.success) {
console.log('Resultado:', result.output);
}Visualizacion del progreso
- La vista de proyecto muestra barra de % Metodo Completado
- Los agentes completados muestran un icono de check verde
- El badge muestra numero de ejecuciones por agente
- El modal de detalle tiene pestanas para ver informacion y resultados
StagesTimelineProps
interface StagesTimelineProps {
// Datos - usar stages+actions O stagesWithActions
stages?: Stage[];
actions?: Action[];
stagesWithActions?: StageWithActions[];
// Estados
isLoading?: boolean;
// Permisos
canManageStages?: boolean; // derived from canManage
canManageActions?: boolean; // derived from canManage
canToggleActions?: boolean;
showActionToggle?: boolean;
showExecutionStatus?: boolean; // Mostrar estado de ejecucion
// Callbacks
onAddStage?: () => void;
onEditStage?: (stage: Stage) => void;
onDeleteStage?: (stage: Stage) => void;
onAddAction?: (stageId: string) => void;
onEditAction?: (action: Action | ActionWithStatus) => void;
onActionClick?: (action: Action | ActionWithStatus) => void;
onToggleAction?: (actionId: string, isActive: boolean) => void;
onReorderStages?: (orderedIds: string[]) => void;
onReorderActions?: (stageId: string, orderedIds: string[]) => void;
className?: string;
}ActionItemProps
interface ActionItemProps {
action: ActionWithStatus | Action | ActionWithExecutionStatus;
isActive?: boolean;
showToggle?: boolean;
canToggle?: boolean;
canClick?: boolean;
showExecutionStatus?: boolean; // Mostrar check y contador
onToggle?: (actionId: string, isActive: boolean) => void;
onClick?: (action: Action) => void;
className?: string;
}ActionDetailModalProps
interface ActionDetailModalProps {
action: Action | ActionWithStatus | ActionWithExecutionStatus | null;
isOpen: boolean;
onClose: () => void;
onExecute?: (userInput?: string) => void;
canExecute?: boolean;
isExecuting?: boolean;
executionResult?: string;
}Provider Props
interface LTBMethodProviderProps {
children: React.ReactNode;
permissions?: Partial;
apiAdapter?: LTBApiAdapter;
}
interface LTBAccountProviderProps {
children: React.ReactNode;
accountId: string;
permissions?: Partial;
apiAdapter?: LTBApiAdapter;
}