Funciones Disponibles

Servicios IA: GET /api/atenea/ai/services
Generar IA: POST /api/atenea/ai/generate
Estado Job: GET /api/atenea/ai/job/{jobId}
Servicios Stock: GET /api/atenea/stock/services
Buscar Stock: POST /api/atenea/stock/search
Portales Externos: GET /api/atenea/portals/list

🎨 Generación de Imágenes con IA

Crea imágenes únicas usando los modelos de IA disponibles a través de la plataforma Atenea:

Flujo de Trabajo

1

Obtener Servicios Disponibles

Consulta qué modelos de IA están disponibles actualmente

GET /api/atenea/ai/services
2

Generar Imagen

Usa uno de los servicios disponibles para generar tu imagen

POST /api/atenea/ai/generate
3

Verificar Estado (Opcional)

Para procesos asíncronos, consulta el estado del job

GET /api/atenea/ai/job/{jobId}

1. Obtener Servicios Disponibles

Antes de generar imágenes, consulta qué servicios de IA están disponibles:

cURL
curl -X GET https://limbo.lefebvre.es/api/atenea/ai/services \
  -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."

Respuesta de ejemplo:

{
  "success": true,
  "data": [
    "dall-e-2",
    "dall-e-3", 
    "freepik-classic",
    "freepik-mystic"
  ],
  "message": "Available AI services",
  "httpCode": 200
}

2. Generar Imagen con IA

Usa uno de los servicios disponibles para generar tu imagen:

cURL
curl -X POST https://limbo.lefebvre.es/api/atenea/ai/generate \
  -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "service": "dall-e-3",
    "prompt": "A modern office workspace with plants and natural lighting, minimalist style",
    "size": "1024x1024",
    "quality": "hd",
    "n": 1
  }'
JavaScript
// Usando las APIs del componente Limbo
import { getAiServices, generateAiImage } from './services/aiApi.js';

class LimboAIService {
    constructor(apiKey, prod = false) {
        this.apiKey = apiKey;
        this.prod = prod;
    }

    async getAvailableServices() {
        try {
            const response = await getAiServices(this.apiKey, this.prod);
            return response.data; // Array de servicios disponibles
        } catch (error) {
            console.error('Error obteniendo servicios IA:', error);
            throw error;
        }
    }

    async generateImage(options) {
        const {
            service = 'dall-e-3',
            prompt,
            size = '1024x1024',
            quality = 'standard',
            n = 1
        } = options;

        try {
            const response = await generateAiImage(this.apiKey, {
                service,
                prompt,
                size,
                quality,
                n
            }, this.prod);

            return response;
        } catch (error) {
            console.error('Error generando imagen:', error);
            throw error;
        }
    }
}

// Uso
const aiService = new LimboAIService('your-api-key', false);

// 1. Obtener servicios disponibles
const availableServices = await aiService.getAvailableServices();
console.log('Servicios disponibles:', availableServices);

// 2. Generar imagen
const result = await aiService.generateImage({
    service: availableServices[0], // Usar primer servicio disponible
    prompt: 'Modern office workspace with plants',
    quality: 'hd'
});

console.log('Imagen generada:', result.data.images);
                    prompt,
                    model,
                    size,
                    style,
                    quality,
                    negative_prompt: negativePrompt,
                    num_images: numImages
                })
            });

            if (!response.ok) {
                throw new Error(`AI generation failed: ${response.statusText}`);
            }

            const result = await response.json();
            return result;

        } catch (error) {
            console.error('AI generation error:', error);
            throw error;
        }
    }

    async enhanceImage(assetId, options = {}) {
        const {
            enhancement = 'upscale',
            factor = 2,
            style = 'auto'
        } = options;

        try {
            const response = await fetch(`${this.apiUrl}/ai/enhance`, {
                method: 'POST',
                headers: {
                    'Authorization': `Bearer ${await this.authService.getValidToken()}`,
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    asset_id: assetId,
                    enhancement,
                    factor,
                    style
                })
            });

            if (!response.ok) {
                throw new Error(`AI enhancement failed: ${response.statusText}`);
            }

            return await response.json();

        } catch (error) {
            console.error('AI enhancement error:', error);
            throw error;
        }
    }

    async analyzeImage(assetId) {
        try {
            const response = await fetch(`${this.apiUrl}/ai/analyze`, {
                method: 'POST',
                headers: {
                    'Authorization': `Bearer ${await this.authService.getValidToken()}`,
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    asset_id: assetId
                })
            });

            if (!response.ok) {
                throw new Error(`AI analysis failed: ${response.statusText}`);
            }

            return await response.json();

        } catch (error) {
            console.error('AI analysis error:', error);
            throw error;
        }
    }

    async generateTags(assetId, options = {}) {
        const { language = 'es', maxTags = 10 } = options;

        try {
            const response = await fetch(`${this.apiUrl}/ai/tag`, {
                method: 'POST',
                headers: {
                    'Authorization': `Bearer ${await this.authService.getValidToken()}`,
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    asset_id: assetId,
                    language,
                    max_tags: maxTags
                })
            });

            if (!response.ok) {
                throw new Error(`AI tagging failed: ${response.statusText}`);
            }

            return await response.json();

        } catch (error) {
            console.error('AI tagging error:', error);
            throw error;
        }
    }
}

// Uso
const aiService = new LimboAIService(authService, 'https://limbo.lefebvre.es');

// Generar imagen
const generateButton = document.getElementById('generate-btn');
generateButton.addEventListener('click', async () => {
    const prompt = document.getElementById('prompt').value;
    
    try {
        showLoading('Generando imagen...');
        
        const result = await aiService.generateImage({
            prompt: prompt,
            model: 'dall-e-3',
            quality: 'hd'
        });

        displayGeneratedImages(result.data.images);
        hideLoading();

    } catch (error) {
        showError('Error generando imagen: ' + error.message);
        hideLoading();
    }
});

// Análisis automático al subir imagen
async function onImageUpload(assetId) {
    try {
        // Analizar imagen
        const analysis = await aiService.analyzeImage(assetId);
        displayAnalysis(analysis.data);

        // Generar tags automáticamente
        const tags = await aiService.generateTags(assetId);
        suggestTags(tags.data.tags);

    } catch (error) {
        console.error('Auto-analysis failed:', error);
    }
}
PHP
httpClient = $httpClient;
        $this->authService = $authService;
        $this->apiUrl = $apiUrl;
    }

    public function generateImage(array $options): array
    {
        $token = $this->authService->getValidToken();
        
        $defaultOptions = [
            'model' => 'dall-e-3',
            'size' => '1024x1024',
            'style' => 'natural',
            'quality' => 'standard',
            'num_images' => 1
        ];

        $params = array_merge($defaultOptions, $options);

        $response = $this->httpClient->request('POST', $this->apiUrl . '/ai/generate', [
            'headers' => [
                'Authorization' => 'Bearer ' . $token,
                'Content-Type' => 'application/json'
            ],
            'json' => $params
        ]);

        if ($response->getStatusCode() !== 200) {
            throw new \Exception('AI generation failed: ' . $response->getContent(false));
        }

        return $response->toArray();
    }

    public function enhanceImage(string $assetId, array $options = []): array
    {
        $token = $this->authService->getValidToken();
        
        $defaultOptions = [
            'enhancement' => 'upscale',
            'factor' => 2,
            'style' => 'auto'
        ];

        $params = array_merge($defaultOptions, $options, ['asset_id' => $assetId]);

        $response = $this->httpClient->request('POST', $this->apiUrl . '/ai/enhance', [
            'headers' => [
                'Authorization' => 'Bearer ' . $token,
                'Content-Type' => 'application/json'
            ],
            'json' => $params
        ]);

        if ($response->getStatusCode() !== 200) {
            throw new \Exception('AI enhancement failed: ' . $response->getContent(false));
        }

        return $response->toArray();
    }

    public function analyzeImage(string $assetId): array
    {
        $token = $this->authService->getValidToken();

        $response = $this->httpClient->request('POST', $this->apiUrl . '/ai/analyze', [
            'headers' => [
                'Authorization' => 'Bearer ' . $token,
                'Content-Type' => 'application/json'
            ],
            'json' => ['asset_id' => $assetId]
        ]);

        if ($response->getStatusCode() !== 200) {
            throw new \Exception('AI analysis failed: ' . $response->getContent(false));
        }

        return $response->toArray();
    }

    public function generateTags(string $assetId, array $options = []): array
    {
        $token = $this->authService->getValidToken();
        
        $defaultOptions = [
            'language' => 'es',
            'max_tags' => 10
        ];

        $params = array_merge($defaultOptions, $options, ['asset_id' => $assetId]);

        $response = $this->httpClient->request('POST', $this->apiUrl . '/ai/tag', [
            'headers' => [
                'Authorization' => 'Bearer ' . $token,
                'Content-Type' => 'application/json'
            ],
            'json' => $params
        ]);

        if ($response->getStatusCode() !== 200) {
            throw new \Exception('AI tagging failed: ' . $response->getContent(false));
        }

        return $response->toArray();
    }

    public function batchProcessImages(array $assetIds, array $operations = []): array
    {
        $results = [];
        
        foreach ($assetIds as $assetId) {
            try {
                $assetResults = ['asset_id' => $assetId];
                
                if (in_array('analyze', $operations)) {
                    $assetResults['analysis'] = $this->analyzeImage($assetId);
                }
                
                if (in_array('tags', $operations)) {
                    $assetResults['tags'] = $this->generateTags($assetId);
                }
                
                if (in_array('enhance', $operations)) {
                    $assetResults['enhanced'] = $this->enhanceImage($assetId);
                }
                
                $results[] = $assetResults;
                
            } catch (\Exception $e) {
                $results[] = [
                    'asset_id' => $assetId,
                    'error' => $e->getMessage()
                ];
            }
        }
        
        return $results;
    }
}

// Uso en controlador
class AIController extends AbstractController
{
    public function __construct(private LimboAIService $aiService)
    {
    }

    #[Route('/admin/ai/generate', methods: ['POST'])]
    public function generateImage(Request $request): JsonResponse
    {
        $data = json_decode($request->getContent(), true);
        
        try {
            $result = $this->aiService->generateImage([
                'prompt' => $data['prompt'],
                'model' => $data['model'] ?? 'dall-e-3',
                'quality' => $data['quality'] ?? 'standard'
            ]);
            
            return $this->json(['success' => true, 'data' => $result]);
            
        } catch (\Exception $e) {
            return $this->json(['success' => false, 'error' => $e->getMessage()], 400);
        }
    }
}

Respuesta de Generación

JSON Response
{
  "success": true,
  "data": {
    "generation_id": "gen_abc123def456",
    "model": "dall-e-3",
    "prompt": "A modern office workspace with plants and natural lighting",
    "images": [
      {
        "id": "img_789xyz123",
        "url": "https://limbo.lefebvre.es/assets/generated/img_789xyz123/view",
        "thumbnail_url": "https://limbo.lefebvre.es/assets/generated/img_789xyz123/thumbnail",
        "size": "1024x1024",
        "format": "png",
        "estimated_cost": 0.04,
        "generation_time": 8.2,
        "metadata": {
          "style": "natural",
          "quality": "hd",
          "safety_rating": "safe",
          "content_tags": ["office", "workspace", "plants", "modern", "professional"]
        }
      }
    ],
    "usage": {
      "tokens_used": 156,
      "estimated_cost": 0.04,
      "generation_time_seconds": 8.2
    },
    "created_at": "2024-01-15T14:35:18Z"
  }
}

📷 Banco de Imágenes Stock

Acceso a imágenes de stock a través de los proveedores integrados en la plataforma Atenea:

Flujo de Trabajo

1

Obtener Servicios de Stock

Consulta qué proveedores de stock están disponibles

GET /api/atenea/stock/services
2

Buscar Imágenes

Busca imágenes usando criterios específicos

POST /api/atenea/stock/search
3

Descargar Imagen

Descarga la imagen seleccionada para tu proyecto

POST /api/atenea/stock/download

🚀 Próximos Pasos