Sistema de Pipelines

Sistema modular y escalable para transformar contenido a través de múltiples servicios con tracking completo en base de datos.

Arquitectura

Input (Texto)
    ↓
[Pipeline Executor] → Crea ejecución en BD
    ↓
[Step 1: OpenAI Analyzer] → Extrae JSON estructurado
    ↓ (tracking en BD)
[Step 2: Pexels Fetcher] → Busca imágenes/videos
    ↓ (tracking en BD)
[Step 3: Apply Template] → Genera video JSON
    ↓
Output (Video JSON completo)

Cada paso se registra en la base de datos con:

  • Input/Output
  • Duración (ms)
  • Costo (USD)
  • Metadata (tokens, API calls, etc.)

Base de Datos

PipelineExecution

  • Registro de cada ejecución de pipeline
  • Estado global (PENDING, RUNNING, COMPLETED, FAILED)
  • Input original y output final
  • Duración y costo total

PipelineStep

  • Cada paso del pipeline
  • Input/output específico del paso
  • Duración y costo individual
  • Metadata del servicio (tokens, llamadas API, etc.)

Pipelines Disponibles

1. Press Release to Video (press-release-to-video)

Convierte una nota de prensa en un video narrado con imágenes y videos relevantes.

Input:

{
  text: "Texto de la nota de prensa...",
  // Opcional
  ttsProvider?: "polly" | "elevenlabs",
  voice?: string,
  languageCode?: string
}

Steps:

  1. analyze-content (OpenAI) - Extrae título, resumen, búsquedas, keywords
  2. fetch-media (Pexels) - Busca 3 videos (landscape)
  3. apply-template (Internal) - Aplica template 'narrated-content'

Output:

{
  title: "...",
  summary: "...",
  searchQueries: [...],
  keywords: [...],
  images: [...],
  videos: [...],
  videoJson: { output: {...}, timeline: [...] }
}

2. Press Release to Video Vertical (press-release-to-video-vertical)

Convierte una nota de prensa en un video vertical 9:16 para redes sociales.

Input:

{
  text: "Texto de la nota de prensa...",
  // Opcional
  ttsProvider?: "polly" | "elevenlabs",
  voice?: string,
  languageCode?: string
}

Steps:

  1. analyze-content (OpenAI) - Extrae título, resumen, búsquedas, keywords
  2. fetch-media (Pexels) - Busca 3 videos (portrait)
  3. apply-template (Internal) - Aplica template 'narrated-content-vertical'

Output: Igual que press-release-to-video pero en formato 9:16

3. Comunicae to Video (comunicae-to-video)

Convierte un artículo de Comunicae en un video narrado usando las imágenes del artículo.

Input:

{
  url: "https://comunicae.es/notas-de-prensa/{slug}",
  // Opcional
  ttsProvider?: "polly" | "elevenlabs",
  voice?: string,
  languageCode?: string
}

Steps:

  1. fetch-comunicae (Comunicae API) - Obtiene datos del artículo
  2. analyze-content (OpenAI) - Genera búsquedas para Pexels
  3. fetch-media (Pexels) - Busca 3 videos (landscape)
  4. apply-template (Internal) - Aplica template 'narrated-content'

Output:

{
  title: "...",
  text: "...",
  images: [...],  // Imágenes del artículo
  videos: [...],  // Videos de Pexels
  videoJson: { output: {...}, timeline: [...] }
}

4. Comunicae to Video Vertical (comunicae-to-video-vertical)

Convierte un artículo de Comunicae en un video vertical 9:16.

Input:

{
  url: "https://comunicae.es/notas-de-prensa/{slug}",
  // Opcional
  ttsProvider?: "polly" | "elevenlabs",
  voice?: string,
  languageCode?: string
}

Steps:

  1. fetch-comunicae (Comunicae API) - Obtiene datos del artículo
  2. analyze-content (OpenAI) - Genera búsquedas para Pexels
  3. fetch-media (Pexels) - Busca 3 videos (portrait)
  4. apply-template (Internal) - Aplica template 'narrated-content-vertical'

Output: Igual que comunicae-to-video pero en formato 9:16

Uso

Desde código

import { pipelineExecutor, pipelineRegistry } from '~/services/pipeline';

const pipeline = pipelineRegistry.get('press-release-to-video');

const result = await pipelineExecutor.execute(
  pipeline,
  { text: "Mi nota de prensa..." },
  { userId: "user_123" }
);

if (result.status === 'COMPLETED') {
  console.log('Video JSON:', result.output.videoJson);
  console.log('Total cost:', result.totalCost);
  console.log('Duration:', result.totalDuration, 'ms');
}

Desde API

POST /api/pipeline/test

Ejemplo 1: Press Release (texto)

{
  "pipelineId": "press-release-to-video",
  "input": {
    "text": "Comunicae anuncia el lanzamiento de su nueva plataforma...",
    "ttsProvider": "elevenlabs",
    "voice": "Rachel"
  },
  "userId": "user_123"
}

Ejemplo 2: Comunicae (URL)

{
  "pipelineId": "comunicae-to-video",
  "input": {
    "url": "https://comunicae.es/notas-de-prensa/globamatic-media-facilita-la-conservacion-de",
    "ttsProvider": "polly",
    "voice": "Lucia",
    "languageCode": "es-ES"
  },
  "userId": "user_123"
}

Response:

{
  "success": true,
  "result": {
    "executionId": "clxxx...",
    "status": "COMPLETED",
    "output": {
      "title": "...",
      "text": "...",
      "images": [...],
      "videos": [...],
      "videoJson": {...}
    },
    "totalDuration": 4523,
    "totalCost": 0.0124,
    "steps": [...]
  }
}

Ver estado de ejecución

import { pipelineTracker } from '~/services/pipeline';

const execution = await pipelineTracker.getExecution('exec_id');

console.log('Status:', execution.status);
console.log('Steps:', execution.steps.length);

// Estadísticas
const stats = await pipelineTracker.getExecutionStats('exec_id');
console.log('Completed steps:', stats.completedSteps);
console.log('Failed steps:', stats.failedSteps);
console.log('Total cost:', stats.totalCost);

Crear Nuevo Pipeline

1. Crear el Step (si es necesario)

// app/services/pipeline/steps/my-service.step.ts
import type { PipelineStepConfig } from '../types';

export function createMyServiceStep(config: MyConfig): PipelineStepConfig {
  return {
    name: 'my-step',
    service: 'my-service',

    async execute(input: any, context) {
      // Lógica del paso
      const result = await myService.process(input);

      return {
        output: result,
        metadata: { apiCalls: 1 },
        cost: 0.05,
      };
    },

    estimateCost(input) {
      return 0.05;
    },

    retryable: true,
    timeout: 30000,
  };
}

2. Crear el Pipeline

// app/services/pipeline/pipelines/my-pipeline.ts
import type { Pipeline } from '../types';
import { createOpenAIAnalyzerStep } from '../steps/openai-analyzer.step';
import { createMyServiceStep } from '../steps/my-service.step';

export const myPipeline: Pipeline = {
  id: 'my-pipeline',
  name: 'My Pipeline',
  description: 'Description...',
  version: '1.0.0',

  steps: [
    createOpenAIAnalyzerStep({ contentType: 'article' }),
    createMyServiceStep({ option: 'value' }),
  ],
};

3. Registrar en Registry

// app/services/pipeline/registry.server.ts
import { myPipeline } from './pipelines/my-pipeline';

constructor() {
  this.register(pressReleaseToVideoPipeline);
  this.register(myPipeline); // ← Añadir aquí
}

Steps Disponibles

createOpenAIAnalyzerStep

Analiza contenido con OpenAI y extrae JSON estructurado.

Config:

  • contentType: 'press-release' | 'ad' | 'social-post' | 'article'
  • model: 'gpt-4o' | 'gpt-4o-mini' (default: 'gpt-4o')
  • temperature: 0-1 (default: 0.3)

Input: { text: string }

Output: JSON estructurado según contentType

Costo: ~$0.01-0.03 por análisis (depende del tamaño)

createPexelsFetcherStep

Busca imágenes y videos en Pexels.

Config:

  • imageCount: número de imágenes (default: 5)
  • videoCount: número de videos (default: 3)
  • orientation: 'landscape' | 'portrait' | 'square'
  • size: 'large' | 'medium' | 'small'

Input: { searchQueries: string[] }

Output: { images: string[], videos: string[] }

Costo: Gratis (API de Pexels)

createApplyTemplateStep

Aplica un template de video con los datos.

Config:

  • templateId: ID del template (ej: 'narrated-content')
  • dataMapping: Mapeo de campos input → template

Input: Datos para el template

Output: { videoJson: {...} }

Costo: Gratis (proceso interno)

Monitorización

Todas las ejecuciones se guardan en la BD y puedes consultarlas:

// Ver todas las ejecuciones de un pipeline
const executions = await pipelineTracker.getExecutionsForPipeline(
  'press-release-to-video',
  50 // limit
);

// Ver estadísticas
for (const exec of executions) {
  const stats = await pipelineTracker.getExecutionStats(exec.id);
  console.log(`${exec.id}: ${stats.completedSteps}/${stats.totalSteps} steps, $${stats.totalCost}`);
}

Ejemplo Completo: Nota de Prensa → Video

const pressRelease = `
Comunicae anuncia el lanzamiento de VideoMaker AI, una revolucionaria
plataforma que permite crear videos profesionales a partir de texto usando
inteligencia artificial. La plataforma integra TTS, subtítulos automáticos
y búsqueda inteligente de contenido visual.
`;

const pipeline = pipelineRegistry.get('press-release-to-video');
const result = await pipelineExecutor.execute(
  pipeline,
  { text: pressRelease },
  { userId: 'user_123' }
);

// Resultado:
// {
//   executionId: "clxxx...",
//   status: "COMPLETED",
//   output: {
//     title: "Comunicae lanza VideoMaker AI",
//     summary: "Plataforma revolucionaria para crear videos con IA...",
//     searchQueries: ["AI video creation", "professional videos", "text to speech"],
//     keywords: ["videomaker", "AI", "TTS"],
//     images: [
//       "https://images.pexels.com/...",
//       "https://images.pexels.com/...",
//     ],
//     videos: [
//       "https://videos.pexels.com/...",
//     ],
//     videoJson: {
//       output: { width: 1920, height: 1080, fps: 30 },
//       timeline: [...]
//     }
//   },
//   totalDuration: 4523, // ms
//   totalCost: 0.0124,   // USD
//   steps: [
//     { name: "analyze-content", status: "COMPLETED", duration: 2341, cost: 0.0124 },
//     { name: "fetch-media", status: "COMPLETED", duration: 1895, cost: 0 },
//     { name: "apply-template", status: "COMPLETED", duration: 287, cost: 0 }
//   ]
// }

Precios Estimados

Pipeline Costo Promedio Duración
press-release-to-video $0.01-0.03 3-5s
press-release-to-video-vertical $0.01-0.03 3-5s
comunicae-to-video $0.01-0.03 3-5s
comunicae-to-video-vertical $0.01-0.03 3-5s

Desglose:

  • Comunicae API: $0 (gratis)
  • OpenAI GPT-5-mini: $0.01-0.03 (depende del texto)
  • Pexels API: $0 (gratis)
  • Template: $0 (interno)
  • TTS (Polly): Incluido en análisis
  • TTS (ElevenLabs): Variable según uso

Próximos Pipelines

Ideas para futuros pipelines:

  1. ad-to-social - Convierte anuncio en posts para redes sociales
  2. article-to-video - Artículo → video educativo
  3. product-to-ad - Descripción de producto → video publicitario
  4. text-to-podcast - Texto → podcast con múltiples voces