This commit is contained in:
Desktop
2025-11-12 05:05:54 +05:00
parent 584233a7b2
commit 84111f5ad6
2 changed files with 79 additions and 18 deletions

View File

@@ -485,6 +485,12 @@ class AICore:
"""Generate image using OpenAI DALL-E""" """Generate image using OpenAI DALL-E"""
print(f"[AI][{function_name}] Provider: OpenAI") print(f"[AI][{function_name}] Provider: OpenAI")
# CRITICAL: Truncate prompt to OpenAI's 1000 character limit BEFORE any processing
if len(prompt) > 1000:
print(f"[AI][{function_name}][Warning] Prompt too long ({len(prompt)} chars), truncating to 1000")
prompt = prompt[:997].rsplit(' ', 1)[0] + "..."
print(f"[AI][{function_name}] Truncated prompt length: {len(prompt)}")
api_key = api_key or self._openai_api_key api_key = api_key or self._openai_api_key
if not api_key: if not api_key:
error_msg = 'OpenAI API key not configured' error_msg = 'OpenAI API key not configured'

View File

@@ -276,16 +276,51 @@ def process_image_generation_queue(self, image_ids: list, account_id: int = None
# Format template with image prompt from database # Format template with image prompt from database
# Template has placeholders: {image_type}, {post_title}, {image_prompt} # Template has placeholders: {image_type}, {post_title}, {image_prompt}
# CRITICAL: OpenAI has strict 1000 character limit for prompts
try: try:
# Get template length to calculate available space
template_placeholder_length = len(image_prompt_template.replace('{image_type}', '').replace('{post_title}', '').replace('{image_prompt}', ''))
# Truncate post_title aggressively (max 100 chars to leave room)
post_title = content.title or content.meta_title or f"Content #{content.id}"
if len(post_title) > 100:
post_title = post_title[:97] + "..."
# Calculate max image_prompt length: 1000 - template_text - post_title - safety margin
# Assume template adds ~200 chars, post_title max 100, safety margin 50 = ~650 chars for image_prompt
image_prompt = image.prompt or ""
max_image_prompt_length = 650
if len(image_prompt) > max_image_prompt_length:
logger.warning(f"Image prompt too long ({len(image_prompt)} chars), truncating to {max_image_prompt_length}")
image_prompt = image_prompt[:max_image_prompt_length].rsplit(' ', 1)[0] + "..."
formatted_prompt = image_prompt_template.format( formatted_prompt = image_prompt_template.format(
image_type=image_type, image_type=image_type,
post_title=content.title or content.meta_title or f"Content #{content.id}", post_title=post_title,
image_prompt=image.prompt # Read directly from database field image_prompt=image_prompt
) )
# CRITICAL: Final safety check - ALWAYS truncate to 1000 chars max
if len(formatted_prompt) > 1000:
logger.warning(f"Formatted prompt too long ({len(formatted_prompt)} chars), truncating to 1000")
formatted_prompt = formatted_prompt[:997].rsplit(' ', 1)[0] + "..."
# Double-check after truncation
if len(formatted_prompt) > 1000:
logger.error(f"Prompt still too long after truncation ({len(formatted_prompt)} chars), forcing hard truncate")
formatted_prompt = formatted_prompt[:1000]
except Exception as e: except Exception as e:
# Fallback if template formatting fails # Fallback if template formatting fails
logger.warning(f"Prompt template formatting failed: {e}, using image prompt directly") logger.warning(f"Prompt template formatting failed: {e}, using image prompt directly")
formatted_prompt = image.prompt formatted_prompt = image.prompt or ""
# CRITICAL: Truncate to 1000 chars even in fallback
if len(formatted_prompt) > 1000:
logger.warning(f"Fallback prompt too long ({len(formatted_prompt)} chars), truncating to 1000")
formatted_prompt = formatted_prompt[:997].rsplit(' ', 1)[0] + "..."
# Final hard truncate if still too long
if len(formatted_prompt) > 1000:
formatted_prompt = formatted_prompt[:1000]
# Generate image (using same approach as test image generation) # Generate image (using same approach as test image generation)
logger.info(f"[process_image_generation_queue] Generating image {index}/{total_images} (ID: {image_id})") logger.info(f"[process_image_generation_queue] Generating image {index}/{total_images} (ID: {image_id})")
@@ -307,31 +342,51 @@ def process_image_generation_queue(self, image_ids: list, account_id: int = None
# Check for errors # Check for errors
if result.get('error'): if result.get('error'):
logger.error(f"Image generation failed for {image_id}: {result.get('error')}") error_message = result.get('error', 'Unknown error')
logger.error(f"Image generation failed for {image_id}: {error_message}")
# Truncate error message to avoid database field length issues
# Some database fields may have 200 char limit, so truncate to 180 to be safe
truncated_error = error_message[:180] if len(error_message) > 180 else error_message
# Update image record: failed # Update image record: failed
image.status = 'failed' try:
image.save(update_fields=['status']) image.status = 'failed'
image.save(update_fields=['status'])
except Exception as save_error:
logger.error(f"Failed to save image status to database: {save_error}", exc_info=True)
# Continue even if save fails
results.append({ results.append({
'image_id': image_id, 'image_id': image_id,
'status': 'failed', 'status': 'failed',
'error': result.get('error') 'error': truncated_error
}) })
failed += 1 failed += 1
else: else:
logger.info(f"Image generation successful for {image_id}") logger.info(f"Image generation successful for {image_id}")
# Update image record: success # Update image record: success
image.image_url = result.get('url') try:
image.status = 'generated' image.image_url = result.get('url')
image.save(update_fields=['image_url', 'status']) image.status = 'generated'
image.save(update_fields=['image_url', 'status'])
results.append({ except Exception as save_error:
'image_id': image_id, logger.error(f"Failed to save image URL/status to database: {save_error}", exc_info=True)
'status': 'completed', # Continue even if save fails, but mark as failed in results
'image_url': result.get('url'), results.append({
'revised_prompt': result.get('revised_prompt') 'image_id': image_id,
}) 'status': 'failed',
completed += 1 'error': f'Database save error: {str(save_error)[:200]}'
})
failed += 1
else:
results.append({
'image_id': image_id,
'status': 'completed',
'image_url': result.get('url'),
'revised_prompt': result.get('revised_prompt')
})
completed += 1
except Exception as e: except Exception as e:
logger.error(f"Error processing image {image_id}: {str(e)}", exc_info=True) logger.error(f"Error processing image {image_id}: {str(e)}", exc_info=True)