Enhance image generation functionality: Add console tracking to monitor progress and errors during image processing, and include image queue in response metadata for better integration.
This commit is contained in:
@@ -146,15 +146,24 @@ class GenerateImagesFromPromptsFunction(BaseAIFunction):
|
||||
original_data: Dict,
|
||||
account=None,
|
||||
progress_tracker=None,
|
||||
step_tracker=None
|
||||
step_tracker=None,
|
||||
console_tracker=None
|
||||
) -> Dict:
|
||||
"""
|
||||
Process all images sequentially and generate them.
|
||||
This method handles the loop and makes AI calls directly.
|
||||
"""
|
||||
function_name = self.get_name()
|
||||
|
||||
if console_tracker:
|
||||
console_tracker.save(f"[{function_name}] Starting image generation queue")
|
||||
|
||||
images = original_data.get('images', [])
|
||||
if not images:
|
||||
raise ValueError("No images to process")
|
||||
error_msg = "[{function_name}] No images to process"
|
||||
if console_tracker:
|
||||
console_tracker.error('ValidationError', error_msg)
|
||||
raise ValueError(error_msg)
|
||||
|
||||
provider = original_data.get('provider', 'openai')
|
||||
model = original_data.get('model', 'dall-e-3')
|
||||
@@ -169,6 +178,9 @@ class GenerateImagesFromPromptsFunction(BaseAIFunction):
|
||||
images_failed = 0
|
||||
errors = []
|
||||
|
||||
if console_tracker:
|
||||
console_tracker.prep(f"[{function_name}] Preparing {total_images} image{'s' if total_images != 1 else ''} for generation")
|
||||
|
||||
# Initialize image queue in meta for frontend
|
||||
image_queue = []
|
||||
for idx, img in enumerate(images, 1):
|
||||
@@ -198,6 +210,9 @@ class GenerateImagesFromPromptsFunction(BaseAIFunction):
|
||||
initial_meta['image_queue'] = image_queue
|
||||
progress_tracker.update("PREP", 10, f"Preparing to generate {total_images} image{'s' if total_images != 1 else ''}", meta=initial_meta)
|
||||
|
||||
if console_tracker:
|
||||
console_tracker.prep(f"[{function_name}] Image queue initialized with {total_images} image{'s' if total_images != 1 else ''}")
|
||||
|
||||
# Process each image sequentially
|
||||
for index, image in enumerate(images, 1):
|
||||
queue_item = image_queue[index - 1]
|
||||
@@ -216,6 +231,9 @@ class GenerateImagesFromPromptsFunction(BaseAIFunction):
|
||||
else:
|
||||
content_title = content.title or content.meta_title or "Content"
|
||||
|
||||
if console_tracker:
|
||||
console_tracker.prep(f"[{function_name}] Processing image {index}/{total_images}: {image.image_type} for '{content_title}'")
|
||||
|
||||
# Format prompt using template
|
||||
if image_prompt_template:
|
||||
try:
|
||||
@@ -224,12 +242,18 @@ class GenerateImagesFromPromptsFunction(BaseAIFunction):
|
||||
image_prompt=image.prompt,
|
||||
image_type=image_type
|
||||
)
|
||||
if console_tracker:
|
||||
console_tracker.prep(f"[{function_name}] Formatted prompt using template (length: {len(formatted_prompt)})")
|
||||
except KeyError as e:
|
||||
logger.warning(f"Template formatting error: {e}, using simple format")
|
||||
formatted_prompt = f"Create a high-quality {image_type} image: {image.prompt}"
|
||||
if console_tracker:
|
||||
console_tracker.prep(f"[{function_name}] Template formatting error, using fallback prompt")
|
||||
else:
|
||||
# Fallback template
|
||||
formatted_prompt = f"Create a high-quality {image_type} image: {image.prompt}"
|
||||
if console_tracker:
|
||||
console_tracker.prep(f"[{function_name}] Using fallback prompt template")
|
||||
|
||||
# Update progress: PREP phase for this image
|
||||
if progress_tracker and step_tracker:
|
||||
@@ -261,6 +285,9 @@ class GenerateImagesFromPromptsFunction(BaseAIFunction):
|
||||
|
||||
# Generate image (this is the actual API call)
|
||||
# Frontend will simulate smooth progress from 50% to 95% while waiting
|
||||
if console_tracker:
|
||||
console_tracker.ai_call(f"[{function_name}] Calling {provider}/{model} API for image {index}/{total_images}")
|
||||
|
||||
result = ai_core.generate_image(
|
||||
prompt=formatted_prompt,
|
||||
provider=provider,
|
||||
@@ -286,11 +313,14 @@ class GenerateImagesFromPromptsFunction(BaseAIFunction):
|
||||
image.status = 'failed'
|
||||
image.save(update_fields=['status', 'updated_at'])
|
||||
|
||||
error_msg = f"Image {index} failed: {result['error']}"
|
||||
error_msg = f"[{function_name}] Image {index}/{total_images} failed: {result['error']}"
|
||||
errors.append(error_msg)
|
||||
images_failed += 1
|
||||
logger.error(f"Image generation failed for image {image.id}: {result['error']}")
|
||||
|
||||
if console_tracker:
|
||||
console_tracker.error('ImageGenerationError', error_msg)
|
||||
|
||||
if progress_tracker and step_tracker:
|
||||
parse_msg = f"Image {index} failed: {result['error']}"
|
||||
step_tracker.add_response_step("PARSE", "error", parse_msg)
|
||||
@@ -311,11 +341,14 @@ class GenerateImagesFromPromptsFunction(BaseAIFunction):
|
||||
image.status = 'failed'
|
||||
image.save(update_fields=['status', 'updated_at'])
|
||||
|
||||
error_msg = f"Image {index} failed: No URL returned"
|
||||
error_msg = f"[{function_name}] Image {index}/{total_images} failed: No URL returned"
|
||||
errors.append(error_msg)
|
||||
images_failed += 1
|
||||
logger.error(f"No image URL returned for image {image.id}")
|
||||
|
||||
if console_tracker:
|
||||
console_tracker.error('ImageGenerationError', error_msg)
|
||||
|
||||
if progress_tracker and step_tracker:
|
||||
parse_msg = f"Image {index} failed: No URL returned"
|
||||
step_tracker.add_response_step("PARSE", "error", parse_msg)
|
||||
@@ -336,6 +369,9 @@ class GenerateImagesFromPromptsFunction(BaseAIFunction):
|
||||
progress_pct = 70 + int((index - 1) / total_images * 15) # 70-85% for PARSE
|
||||
progress_tracker.update("PARSE", progress_pct, parse_msg, meta=meta)
|
||||
|
||||
if console_tracker:
|
||||
console_tracker.parse(f"[{function_name}] Image {index}/{total_images} generated successfully: {image_url[:50]}...")
|
||||
|
||||
# Update image record
|
||||
with transaction.atomic():
|
||||
image.image_url = image_url
|
||||
@@ -349,6 +385,9 @@ class GenerateImagesFromPromptsFunction(BaseAIFunction):
|
||||
images_generated += 1
|
||||
logger.info(f"Image {image.id} ({image.image_type}) generated successfully: {image_url}")
|
||||
|
||||
if console_tracker:
|
||||
console_tracker.save(f"[{function_name}] Saved image {index}/{total_images} to database (ID: {image.id})")
|
||||
|
||||
# Update progress: SAVE phase
|
||||
if progress_tracker and step_tracker:
|
||||
save_msg = f"Saved image {index} of {total_images}"
|
||||
@@ -360,21 +399,40 @@ class GenerateImagesFromPromptsFunction(BaseAIFunction):
|
||||
|
||||
except Exception as e:
|
||||
# Mark as failed
|
||||
queue_item['status'] = 'failed'
|
||||
queue_item['progress'] = 100
|
||||
queue_item['error'] = str(e)
|
||||
with transaction.atomic():
|
||||
image.status = 'failed'
|
||||
image.save(update_fields=['status', 'updated_at'])
|
||||
|
||||
error_msg = f"Image {index} failed: {str(e)}"
|
||||
error_msg = f"[{function_name}] Image {index}/{total_images} exception: {str(e)}"
|
||||
errors.append(error_msg)
|
||||
images_failed += 1
|
||||
logger.error(f"Exception generating image {image.id}: {str(e)}", exc_info=True)
|
||||
|
||||
if console_tracker:
|
||||
console_tracker.error('Exception', error_msg)
|
||||
|
||||
continue
|
||||
|
||||
# Final progress update
|
||||
if progress_tracker and step_tracker:
|
||||
final_msg = f"Generated {images_generated} of {total_images} images"
|
||||
step_tracker.add_request_step("SAVE", "success", final_msg)
|
||||
progress_tracker.update("SAVE", 98, final_msg, meta=step_tracker.get_meta())
|
||||
meta = step_tracker.get_meta()
|
||||
meta['image_queue'] = image_queue
|
||||
progress_tracker.update("SAVE", 98, final_msg, meta=meta)
|
||||
|
||||
if console_tracker:
|
||||
if images_generated > 0:
|
||||
console_tracker.save(f"[{function_name}] SUCCESS: Generated {images_generated}/{total_images} image{'s' if images_generated != 1 else ''} successfully")
|
||||
if images_failed > 0:
|
||||
console_tracker.error('ImageGenerationError', f"[{function_name}] FAILED: {images_failed}/{total_images} image{'s' if images_failed != 1 else ''} failed")
|
||||
if images_generated == total_images:
|
||||
console_tracker.done(f"[{function_name}] All {total_images} image{'s' if total_images != 1 else ''} generated successfully")
|
||||
else:
|
||||
console_tracker.done(f"[{function_name}] Completed: {images_generated} succeeded, {images_failed} failed out of {total_images} total")
|
||||
|
||||
return {
|
||||
'count': images_generated,
|
||||
|
||||
Reference in New Issue
Block a user