generateImages method

  1. @override
Future<ImageGenerationResponse> generateImages(
  1. ImageGenerationRequest request
)
override

Generate images from text prompts

Creates one or more images based on a text description.

Implementation

@override
Future<ImageGenerationResponse> generateImages(
  ImageGenerationRequest request,
) async {
  final requestBody = <String, dynamic>{
    'model': request.model ?? config.model,
    'prompt': request.prompt,
    if (request.negativePrompt != null)
      'negative_prompt': request.negativePrompt,
    if (request.size != null) 'size': request.size,
    if (request.count != null) 'n': request.count,
    if (request.seed != null) 'seed': request.seed,
    if (request.steps != null) 'num_inference_steps': request.steps,
    if (request.guidanceScale != null)
      'guidance_scale': request.guidanceScale,
    if (request.enhancePrompt != null)
      'prompt_enhancement': request.enhancePrompt,
    if (request.style != null) 'style': request.style,
    if (request.quality != null) 'quality': request.quality,
  };

  final responseData =
      await client.postJson('images/generations', requestBody);

  final data = responseData['data'] as List?;
  if (data == null) {
    throw ResponseFormatError(
      'Invalid response format from OpenAI image generation API: missing data field',
      responseData.toString(),
    );
  }

  // Extract images from response
  try {
    final images = data.map((item) {
      if (item is! Map<String, dynamic>) {
        throw ResponseFormatError(
          'Invalid image item format: expected Map<String, dynamic>',
          item.toString(),
        );
      }

      final itemMap = item;
      List<int>? imageData;

      // Safely decode base64 data if present
      if (itemMap['b64_json'] != null) {
        try {
          final b64String = itemMap['b64_json'] as String;
          imageData = base64Decode(b64String);
        } catch (e) {
          throw ResponseFormatError(
            'Failed to decode base64 image data: $e',
            itemMap['b64_json'].toString(),
          );
        }
      }

      return GeneratedImage(
        url: itemMap['url'] as String?,
        data: imageData,
        revisedPrompt: itemMap['revised_prompt'] as String?,
        format: 'png', // OpenAI DALL-E generates PNG images
      );
    }).toList();

    if (images.isEmpty) {
      throw const ResponseFormatError(
        'No images returned from OpenAI image generation API',
        'Empty data array',
      );
    }

    return ImageGenerationResponse(
      images: images,
      model: request.model ?? config.model,
      revisedPrompt: images.isNotEmpty ? images.first.revisedPrompt : null,
      usage: null, // OpenAI doesn't provide usage info for image generation
    );
  } catch (e) {
    if (e is LLMError) rethrow;
    throw ResponseFormatError(
      'Failed to parse image generation response: $e',
      responseData.toString(),
    );
  }
}