removeing unneceary code
This commit is contained in:
@@ -1,107 +0,0 @@
|
||||
# Expected Response Structure for generate_images_from_prompts
|
||||
|
||||
## Function Flow
|
||||
|
||||
1. **Frontend calls**: `POST /v1/writer/images/generate_images/` with `{ ids: [1, 2, 3] }`
|
||||
2. **Backend ViewSet** (`ImagesViewSet.generate_images`):
|
||||
- Calls `run_ai_task` with `function_name='generate_images_from_prompts'`
|
||||
- Returns response with `queued_prompts` if in TEST MODE
|
||||
|
||||
3. **AIEngine.execute**:
|
||||
- Validates, prepares, builds prompt (placeholder), parses (placeholder)
|
||||
- Calls `save_output` which queues prompts (TEST MODE)
|
||||
|
||||
4. **GenerateImagesFromPromptsFunction.save_output**:
|
||||
- Returns dict with queued prompts
|
||||
|
||||
## Response Structure (TEST MODE)
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"count": 3,
|
||||
"images_generated": 0,
|
||||
"images_failed": 0,
|
||||
"total_images": 3,
|
||||
"queued_prompts": [
|
||||
{
|
||||
"image_id": 1,
|
||||
"index": 1,
|
||||
"image_type": "featured_image",
|
||||
"content_title": "Your Content Title",
|
||||
"provider": "openai",
|
||||
"model": "dall-e-2",
|
||||
"formatted_prompt": "Create a high-quality realistic image to use as a featured photo for a blog post titled \"Your Content Title\". The image should visually represent the theme, mood, and subject implied by the image prompt: [original prompt]. Focus on a realistic, well-composed scene that naturally communicates the topic without text or logos...",
|
||||
"negative_prompt": null,
|
||||
"prompt_length": 250
|
||||
},
|
||||
{
|
||||
"image_id": 2,
|
||||
"index": 2,
|
||||
"image_type": "in_article_1",
|
||||
"content_title": "Your Content Title",
|
||||
"provider": "openai",
|
||||
"model": "dall-e-2",
|
||||
"formatted_prompt": "...",
|
||||
"negative_prompt": null,
|
||||
"prompt_length": 245
|
||||
}
|
||||
],
|
||||
"test_mode": true,
|
||||
"provider": "openai",
|
||||
"model": "dall-e-2",
|
||||
"errors": null
|
||||
}
|
||||
```
|
||||
|
||||
## Response Structure (Production Mode - when AI calls are enabled)
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"count": 3,
|
||||
"images_generated": 3,
|
||||
"images_failed": 0,
|
||||
"total_images": 3,
|
||||
"errors": null
|
||||
}
|
||||
```
|
||||
|
||||
## Key Points
|
||||
|
||||
1. **TEST MODE** (current):
|
||||
- `images_generated: 0` (no actual images generated)
|
||||
- `queued_prompts` array contains all formatted prompts
|
||||
- `test_mode: true`
|
||||
- Each prompt includes the complete formatted prompt that would be sent to AI
|
||||
|
||||
2. **Production MODE** (when AI calls are uncommented):
|
||||
- `images_generated` will be > 0
|
||||
- `queued_prompts` will not be in response
|
||||
- `test_mode: false` or not present
|
||||
- Images will have `image_url` and `status='generated'`
|
||||
|
||||
## Console Logging
|
||||
|
||||
The function logs to console (if DEBUG_MODE=True):
|
||||
- `[generate_images_from_prompts] [TEST MODE] Queued prompt X/Y`
|
||||
- `[generate_images_from_prompts] [TEST MODE] Provider: openai, Model: dall-e-2`
|
||||
- `[generate_images_from_prompts] [TEST MODE] Prompt length: 250 chars`
|
||||
- `[generate_images_from_prompts] [TEST MODE] Prompt preview: ...`
|
||||
|
||||
## Frontend Console Output
|
||||
|
||||
When clicking "Generate Images", browser console will show:
|
||||
```
|
||||
[Generate Images] Request: { imageIds: [1, 2, 3], count: 3 }
|
||||
[Generate Images] Endpoint: /v1/writer/images/generate_images/
|
||||
[Generate Images] Full Response: { success: true, queued_prompts: [...], ... }
|
||||
[Generate Images] Queued Prompts (TEST MODE - NOT sent to AI): [...]
|
||||
[Generate Images] Provider: openai, Model: dall-e-2
|
||||
[Generate Images] Prompt 1/3:
|
||||
- Image Type: featured_image
|
||||
- Content: "Your Content Title"
|
||||
- Prompt Length: 250 chars
|
||||
- Full Prompt: "Create a high-quality realistic image..."
|
||||
```
|
||||
|
||||
@@ -84,8 +84,7 @@ class BaseAIFunction(ABC):
|
||||
original_data: Any,
|
||||
account=None,
|
||||
progress_tracker=None,
|
||||
step_tracker=None,
|
||||
console_tracker=None
|
||||
step_tracker=None
|
||||
) -> Dict:
|
||||
"""
|
||||
Save parsed results to database.
|
||||
|
||||
@@ -4,7 +4,7 @@ AI Engine - Central orchestrator for all AI functions
|
||||
import logging
|
||||
from typing import Dict, Any, Optional
|
||||
from igny8_core.ai.base import BaseAIFunction
|
||||
from igny8_core.ai.tracker import StepTracker, ProgressTracker, CostTracker, ConsoleStepTracker
|
||||
from igny8_core.ai.tracker import StepTracker, ProgressTracker, CostTracker
|
||||
from igny8_core.ai.ai_core import AICore
|
||||
from igny8_core.ai.settings import get_model_config
|
||||
|
||||
@@ -22,7 +22,6 @@ class AIEngine:
|
||||
self.account = account
|
||||
self.tracker = ProgressTracker(celery_task)
|
||||
self.step_tracker = StepTracker('ai_engine') # For Celery progress callbacks
|
||||
self.console_tracker = None # Will be initialized per function
|
||||
self.cost_tracker = CostTracker()
|
||||
|
||||
def _get_input_description(self, function_name: str, payload: dict, count: int) -> str:
|
||||
@@ -81,12 +80,6 @@ class AIEngine:
|
||||
total_images = 1 + max_images
|
||||
return f"Mapping Content for {total_images} Image Prompts"
|
||||
return f"Mapping Content for Image Prompts"
|
||||
elif function_name == 'generate_images_from_prompts':
|
||||
# Extract image count from data
|
||||
if isinstance(data, dict) and 'images' in data:
|
||||
total_images = len(data.get('images', []))
|
||||
return f"Preparing to generate {total_images} image{'s' if total_images != 1 else ''}"
|
||||
return f"Preparing image generation queue"
|
||||
return f"Preparing {count} item{'s' if count != 1 else ''}"
|
||||
|
||||
def _get_ai_call_message(self, function_name: str, count: int) -> str:
|
||||
@@ -99,8 +92,6 @@ class AIEngine:
|
||||
return f"Writing article{'s' if count != 1 else ''} with AI"
|
||||
elif function_name == 'generate_images':
|
||||
return f"Creating image{'s' if count != 1 else ''} with AI"
|
||||
elif function_name == 'generate_images_from_prompts':
|
||||
return f"Generating images with AI"
|
||||
return f"Processing with AI"
|
||||
|
||||
def _get_parse_message(self, function_name: str) -> str:
|
||||
@@ -131,8 +122,6 @@ class AIEngine:
|
||||
if in_article_count > 0:
|
||||
return f"Writing {in_article_count} In‑article Image Prompts"
|
||||
return "Writing In‑article Image Prompts"
|
||||
elif function_name == 'generate_images_from_prompts':
|
||||
return f"{count} image{'s' if count != 1 else ''} generated"
|
||||
return f"{count} item{'s' if count != 1 else ''} processed"
|
||||
|
||||
def _get_save_message(self, function_name: str, count: int) -> str:
|
||||
@@ -148,8 +137,6 @@ class AIEngine:
|
||||
elif function_name == 'generate_image_prompts':
|
||||
# Count is total prompts created
|
||||
return f"Assigning {count} Prompts to Dedicated Slots"
|
||||
elif function_name == 'generate_images_from_prompts':
|
||||
return f"Saving {count} image{'s' if count != 1 else ''}"
|
||||
return f"Saving {count} item{'s' if count != 1 else ''}"
|
||||
|
||||
def execute(self, fn: BaseAIFunction, payload: dict) -> dict:
|
||||
@@ -167,10 +154,6 @@ class AIEngine:
|
||||
function_name = fn.get_name()
|
||||
self.step_tracker.function_name = function_name
|
||||
|
||||
# Initialize console tracker for logging (Stage 3 requirement)
|
||||
self.console_tracker = ConsoleStepTracker(function_name)
|
||||
self.console_tracker.init(f"Starting {function_name} execution")
|
||||
|
||||
try:
|
||||
# Phase 1: INIT - Validation & Setup (0-10%)
|
||||
# Extract input data for user-friendly messages
|
||||
@@ -178,16 +161,12 @@ class AIEngine:
|
||||
input_count = len(ids) if ids else 0
|
||||
input_description = self._get_input_description(function_name, payload, input_count)
|
||||
|
||||
self.console_tracker.prep(f"Validating {input_description}")
|
||||
validated = fn.validate(payload, self.account)
|
||||
if not validated['valid']:
|
||||
self.console_tracker.error('ValidationError', validated['error'])
|
||||
return self._handle_error(validated['error'], fn)
|
||||
|
||||
# Build validation message with keyword names for auto_cluster
|
||||
validation_message = self._build_validation_message(function_name, payload, input_count, input_description)
|
||||
|
||||
self.console_tracker.prep("Validation complete")
|
||||
self.step_tracker.add_request_step("INIT", "success", validation_message)
|
||||
self.tracker.update("INIT", 10, validation_message, meta=self.step_tracker.get_meta())
|
||||
|
||||
@@ -207,26 +186,13 @@ class AIEngine:
|
||||
data_count = input_count
|
||||
|
||||
prep_message = self._get_prep_message(function_name, data_count, data)
|
||||
self.console_tracker.prep(prep_message)
|
||||
|
||||
# For image generation, build_prompt returns placeholder
|
||||
# Actual processing happens in save_output
|
||||
if function_name == 'generate_images_from_prompts':
|
||||
prompt = "Image generation queue prepared"
|
||||
else:
|
||||
prompt = fn.build_prompt(data, self.account)
|
||||
self.console_tracker.prep(f"Prompt built: {len(prompt)} characters")
|
||||
|
||||
self.step_tracker.add_request_step("PREP", "success", prep_message)
|
||||
self.tracker.update("PREP", 25, prep_message, meta=self.step_tracker.get_meta())
|
||||
|
||||
# Phase 3: AI_CALL - Provider API Call (25-70%)
|
||||
# For image generation, AI calls happen in save_output, so skip this phase
|
||||
if function_name == 'generate_images_from_prompts':
|
||||
# Skip AI_CALL phase - processing happens in save_output
|
||||
raw_response = {'content': 'Image generation queue ready'}
|
||||
parsed = {'processed': True}
|
||||
else:
|
||||
ai_core = AICore(account=self.account)
|
||||
function_name = fn.get_name()
|
||||
|
||||
@@ -263,10 +229,6 @@ class AIEngine:
|
||||
logger.info(f"[AIEngine] Model Configuration for {function_name}:")
|
||||
logger.info(f" - Model from get_model_config: {model}")
|
||||
logger.info(f" - Full model_config: {model_config}")
|
||||
self.console_tracker.ai_call(f"Model from settings: {model_from_integration or 'Not set'}")
|
||||
self.console_tracker.ai_call(f"Model selected for request: {model or 'default'}")
|
||||
self.console_tracker.ai_call(f"Calling {model or 'default'} model with {len(prompt)} char prompt")
|
||||
self.console_tracker.ai_call(f"Function ID: {function_id}")
|
||||
|
||||
# Track AI call start with user-friendly message
|
||||
ai_call_message = self._get_ai_call_message(function_name, data_count)
|
||||
@@ -274,8 +236,7 @@ class AIEngine:
|
||||
self.tracker.update("AI_CALL", 50, ai_call_message, meta=self.step_tracker.get_meta())
|
||||
|
||||
try:
|
||||
# Use centralized run_ai_request() with console logging (Stage 2 & 3 requirement)
|
||||
# Pass console_tracker for unified logging
|
||||
# Use centralized run_ai_request()
|
||||
raw_response = ai_core.run_ai_request(
|
||||
prompt=prompt,
|
||||
model=model,
|
||||
@@ -283,8 +244,7 @@ class AIEngine:
|
||||
temperature=model_config.get('temperature'),
|
||||
response_format=model_config.get('response_format'),
|
||||
function_name=function_name,
|
||||
function_id=function_id, # Pass function_id for tracking
|
||||
tracker=self.console_tracker # Pass console tracker for logging
|
||||
function_id=function_id # Pass function_id for tracking
|
||||
)
|
||||
except Exception as e:
|
||||
error_msg = f"AI call failed: {str(e)}"
|
||||
@@ -320,7 +280,6 @@ class AIEngine:
|
||||
# Phase 4: PARSE - Response Parsing (70-85%)
|
||||
try:
|
||||
parse_message = self._get_parse_message(function_name)
|
||||
self.console_tracker.parse(parse_message)
|
||||
response_content = raw_response.get('content', '')
|
||||
parsed = fn.parse_response(response_content, self.step_tracker)
|
||||
|
||||
@@ -338,7 +297,6 @@ class AIEngine:
|
||||
# Update parse message with count for better UX
|
||||
parse_message = self._get_parse_message_with_count(function_name, parsed_count)
|
||||
|
||||
self.console_tracker.parse(f"Successfully parsed {parsed_count} items from response")
|
||||
self.step_tracker.add_response_step("PARSE", "success", parse_message)
|
||||
self.tracker.update("PARSE", 85, parse_message, meta=self.step_tracker.get_meta())
|
||||
except Exception as parse_error:
|
||||
@@ -348,8 +306,7 @@ class AIEngine:
|
||||
return self._handle_error(error_msg, fn)
|
||||
|
||||
# Phase 5: SAVE - Database Operations (85-98%)
|
||||
# Pass step_tracker and console_tracker to save_output so it can add validation steps and log
|
||||
save_result = fn.save_output(parsed, data, self.account, self.tracker, step_tracker=self.step_tracker, console_tracker=self.console_tracker)
|
||||
save_result = fn.save_output(parsed, data, self.account, self.tracker, step_tracker=self.step_tracker)
|
||||
clusters_created = save_result.get('clusters_created', 0)
|
||||
keywords_updated = save_result.get('keywords_updated', 0)
|
||||
count = save_result.get('count', 0)
|
||||
@@ -362,7 +319,6 @@ class AIEngine:
|
||||
else:
|
||||
save_msg = self._get_save_message(function_name, data_count)
|
||||
|
||||
self.console_tracker.save(save_msg)
|
||||
self.step_tracker.add_request_step("SAVE", "success", save_msg)
|
||||
self.tracker.update("SAVE", 98, save_msg, meta=self.step_tracker.get_meta())
|
||||
|
||||
@@ -403,7 +359,6 @@ class AIEngine:
|
||||
|
||||
# Phase 6: DONE - Finalization (98-100%)
|
||||
success_msg = f"Task completed: {final_save_msg}" if 'final_save_msg' in locals() else "Task completed successfully"
|
||||
self.console_tracker.done(success_msg)
|
||||
self.step_tracker.add_request_step("DONE", "success", "Task completed successfully")
|
||||
self.tracker.update("DONE", 100, "Task complete!", meta=self.step_tracker.get_meta())
|
||||
|
||||
@@ -427,11 +382,6 @@ class AIEngine:
|
||||
"""Centralized error handling"""
|
||||
function_name = fn.get_name() if fn else 'unknown'
|
||||
|
||||
# Log to console tracker if available (Stage 3 requirement)
|
||||
if self.console_tracker:
|
||||
error_type = type(error).__name__ if isinstance(error, Exception) else 'Error'
|
||||
self.console_tracker.error(error_type, str(error), exception=error if isinstance(error, Exception) else None)
|
||||
|
||||
self.step_tracker.add_request_step("Error", "error", error, error=error)
|
||||
|
||||
error_meta = {
|
||||
|
||||
@@ -6,7 +6,6 @@ from igny8_core.ai.functions.generate_ideas import GenerateIdeasFunction
|
||||
from igny8_core.ai.functions.generate_content import GenerateContentFunction
|
||||
from igny8_core.ai.functions.generate_images import GenerateImagesFunction, generate_images_core
|
||||
from igny8_core.ai.functions.generate_image_prompts import GenerateImagePromptsFunction
|
||||
from igny8_core.ai.functions.generate_images_from_prompts import GenerateImagesFromPromptsFunction
|
||||
|
||||
__all__ = [
|
||||
'AutoClusterFunction',
|
||||
@@ -15,5 +14,4 @@ __all__ = [
|
||||
'GenerateImagesFunction',
|
||||
'generate_images_core',
|
||||
'GenerateImagePromptsFunction',
|
||||
'GenerateImagesFromPromptsFunction',
|
||||
]
|
||||
|
||||
@@ -1,472 +0,0 @@
|
||||
"""
|
||||
Generate Images from Prompts AI Function
|
||||
Generates actual images from existing image prompts using AI
|
||||
"""
|
||||
import logging
|
||||
from typing import Dict, List, Any
|
||||
from django.db import transaction
|
||||
from igny8_core.ai.base import BaseAIFunction
|
||||
from igny8_core.modules.writer.models import Images, Content
|
||||
from igny8_core.ai.ai_core import AICore
|
||||
from igny8_core.ai.validators import validate_ids
|
||||
from igny8_core.ai.prompts import PromptRegistry
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GenerateImagesFromPromptsFunction(BaseAIFunction):
|
||||
"""Generate actual images from image prompts using AI"""
|
||||
|
||||
def get_name(self) -> str:
|
||||
return 'generate_images_from_prompts'
|
||||
|
||||
def get_metadata(self) -> Dict:
|
||||
return {
|
||||
'display_name': 'Generate Images from Prompts',
|
||||
'description': 'Generate actual images from existing image prompts',
|
||||
'phases': {
|
||||
'INIT': 'Validating image prompts...',
|
||||
'PREP': 'Preparing image generation queue...',
|
||||
'AI_CALL': 'Generating images with AI...',
|
||||
'PARSE': 'Processing image URLs...',
|
||||
'SAVE': 'Saving image URLs...',
|
||||
'DONE': 'Images generated!'
|
||||
}
|
||||
}
|
||||
|
||||
def get_max_items(self) -> int:
|
||||
return 100 # Max images per batch
|
||||
|
||||
def validate(self, payload: dict, account=None) -> Dict:
|
||||
"""Validate image IDs exist and have prompts"""
|
||||
result = validate_ids(payload, max_items=self.get_max_items())
|
||||
if not result['valid']:
|
||||
return result
|
||||
|
||||
# Check images exist and have prompts
|
||||
image_ids = payload.get('ids', [])
|
||||
if image_ids:
|
||||
queryset = Images.objects.filter(id__in=image_ids)
|
||||
if account:
|
||||
queryset = queryset.filter(account=account)
|
||||
|
||||
images = list(queryset.select_related('content', 'task'))
|
||||
|
||||
if not images:
|
||||
return {
|
||||
'valid': False,
|
||||
'error': 'No images found with provided IDs'
|
||||
}
|
||||
|
||||
# Check all images have prompts
|
||||
images_without_prompts = [img.id for img in images if not img.prompt or not img.prompt.strip()]
|
||||
if images_without_prompts:
|
||||
return {
|
||||
'valid': False,
|
||||
'error': f'Images {images_without_prompts} do not have prompts'
|
||||
}
|
||||
|
||||
# Check all images are pending
|
||||
images_not_pending = [img.id for img in images if img.status != 'pending']
|
||||
if images_not_pending:
|
||||
return {
|
||||
'valid': False,
|
||||
'error': f'Images {images_not_pending} are not in pending status'
|
||||
}
|
||||
|
||||
return {'valid': True}
|
||||
|
||||
def prepare(self, payload: dict, account=None) -> Dict:
|
||||
"""Load images and image generation settings"""
|
||||
image_ids = payload.get('ids', [])
|
||||
|
||||
queryset = Images.objects.filter(id__in=image_ids, status='pending')
|
||||
if account:
|
||||
queryset = queryset.filter(account=account)
|
||||
|
||||
images = list(queryset.select_related('content', 'task', 'account', 'site', 'sector'))
|
||||
|
||||
if not images:
|
||||
raise ValueError("No pending images found with prompts")
|
||||
|
||||
# Get image generation settings - CHECK IF ENABLED
|
||||
image_settings = {}
|
||||
image_generation_enabled = False
|
||||
if account:
|
||||
try:
|
||||
from igny8_core.modules.system.models import IntegrationSettings
|
||||
integration = IntegrationSettings.objects.get(
|
||||
account=account,
|
||||
integration_type='image_generation'
|
||||
)
|
||||
image_generation_enabled = integration.is_active
|
||||
image_settings = integration.config or {}
|
||||
logger.info(f"[generate_images_from_prompts] Image generation settings: enabled={image_generation_enabled}, config_keys={list(image_settings.keys())}")
|
||||
except IntegrationSettings.DoesNotExist:
|
||||
logger.warning(f"[generate_images_from_prompts] Image generation integration not found for account {account.id}")
|
||||
raise ValueError("Image generation integration not configured")
|
||||
except Exception as e:
|
||||
logger.error(f"[generate_images_from_prompts] Failed to load image generation settings: {e}")
|
||||
raise ValueError(f"Failed to load image generation settings: {str(e)}")
|
||||
|
||||
if not image_generation_enabled:
|
||||
raise ValueError("Image generation is not enabled in settings")
|
||||
|
||||
# Get provider from image_generation settings
|
||||
provider = image_settings.get('provider') or image_settings.get('service', 'openai')
|
||||
logger.info(f"[generate_images_from_prompts] Provider from settings: {provider}")
|
||||
|
||||
# Get provider-specific settings (OpenAI or Runware) - CHECK IF ENABLED
|
||||
provider_api_key = None
|
||||
provider_enabled = False
|
||||
provider_model = None
|
||||
|
||||
if provider == 'openai':
|
||||
try:
|
||||
openai_settings = IntegrationSettings.objects.get(
|
||||
account=account,
|
||||
integration_type='openai'
|
||||
)
|
||||
provider_enabled = openai_settings.is_active
|
||||
provider_api_key = openai_settings.config.get('apiKey') if openai_settings.config else None
|
||||
provider_model = openai_settings.config.get('model') if openai_settings.config else None
|
||||
logger.info(f"[generate_images_from_prompts] OpenAI settings: enabled={provider_enabled}, has_key={bool(provider_api_key)}, model={provider_model}")
|
||||
except IntegrationSettings.DoesNotExist:
|
||||
logger.error(f"[generate_images_from_prompts] OpenAI integration not found")
|
||||
raise ValueError("OpenAI integration not configured")
|
||||
except Exception as e:
|
||||
logger.error(f"[generate_images_from_prompts] Error getting OpenAI settings: {e}")
|
||||
raise ValueError(f"Failed to load OpenAI settings: {str(e)}")
|
||||
elif provider == 'runware':
|
||||
try:
|
||||
runware_settings = IntegrationSettings.objects.get(
|
||||
account=account,
|
||||
integration_type='runware'
|
||||
)
|
||||
provider_enabled = runware_settings.is_active
|
||||
provider_api_key = runware_settings.config.get('apiKey') if runware_settings.config else None
|
||||
provider_model = runware_settings.config.get('model') if runware_settings.config else None
|
||||
logger.info(f"[generate_images_from_prompts] Runware settings: enabled={provider_enabled}, has_key={bool(provider_api_key)}, model={provider_model}")
|
||||
except IntegrationSettings.DoesNotExist:
|
||||
logger.error(f"[generate_images_from_prompts] Runware integration not found")
|
||||
raise ValueError("Runware integration not configured")
|
||||
except Exception as e:
|
||||
logger.error(f"[generate_images_from_prompts] Error getting Runware settings: {e}")
|
||||
raise ValueError(f"Failed to load Runware settings: {str(e)}")
|
||||
else:
|
||||
raise ValueError(f"Invalid provider: {provider}")
|
||||
|
||||
# Validate provider is enabled and has API key
|
||||
if not provider_enabled:
|
||||
raise ValueError(f"{provider.capitalize()} integration is not enabled")
|
||||
|
||||
if not provider_api_key:
|
||||
raise ValueError(f"{provider.capitalize()} API key not configured")
|
||||
|
||||
# Determine model: from provider settings, or image_generation settings, or default
|
||||
if provider_model:
|
||||
model = provider_model
|
||||
elif provider == 'runware':
|
||||
model = image_settings.get('model') or image_settings.get('runwareModel', 'runware:97@1')
|
||||
else:
|
||||
model = image_settings.get('model') or image_settings.get('imageModel', 'dall-e-3')
|
||||
|
||||
logger.info(f"[generate_images_from_prompts] Final settings: provider={provider}, model={model}, enabled={provider_enabled}, has_api_key={bool(provider_api_key)}")
|
||||
|
||||
# Get prompt templates
|
||||
image_prompt_template = PromptRegistry.get_image_prompt_template(account)
|
||||
negative_prompt = PromptRegistry.get_negative_prompt(account)
|
||||
|
||||
return {
|
||||
'images': images,
|
||||
'account': account,
|
||||
'provider': provider,
|
||||
'model': model,
|
||||
'api_key': provider_api_key, # Include API key
|
||||
'image_type': image_settings.get('image_type', 'realistic'),
|
||||
'image_format': image_settings.get('image_format', 'webp'),
|
||||
'image_prompt_template': image_prompt_template,
|
||||
'negative_prompt': negative_prompt,
|
||||
}
|
||||
|
||||
def build_prompt(self, data: Dict, account=None) -> str:
|
||||
"""
|
||||
Build prompt for AI_CALL phase.
|
||||
For image generation, we return a placeholder since we process images in save_output.
|
||||
"""
|
||||
# Return placeholder - actual processing happens in save_output
|
||||
return "Image generation queue prepared"
|
||||
|
||||
def parse_response(self, response: str, step_tracker=None) -> Dict:
|
||||
"""
|
||||
Parse response from AI_CALL.
|
||||
For image generation, we process images directly in save_output, so this is a placeholder.
|
||||
"""
|
||||
return {'processed': True}
|
||||
|
||||
def save_output(
|
||||
self,
|
||||
parsed: Dict,
|
||||
original_data: Dict,
|
||||
account=None,
|
||||
progress_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:
|
||||
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')
|
||||
api_key = original_data.get('api_key') # Get API key from prepare
|
||||
image_type = original_data.get('image_type', 'realistic')
|
||||
image_prompt_template = original_data.get('image_prompt_template', '')
|
||||
negative_prompt = original_data.get('negative_prompt', '')
|
||||
|
||||
# Validate API key is present
|
||||
if not api_key:
|
||||
error_msg = f"[{function_name}] API key not found for provider {provider}"
|
||||
if console_tracker:
|
||||
console_tracker.error('ConfigurationError', error_msg)
|
||||
raise ValueError(error_msg)
|
||||
|
||||
ai_core = AICore(account=account or original_data.get('account'))
|
||||
|
||||
total_images = len(images)
|
||||
images_generated = 0
|
||||
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):
|
||||
content_obj = img.content
|
||||
if not content_obj:
|
||||
if img.task:
|
||||
content_title = img.task.title
|
||||
else:
|
||||
content_title = "Content"
|
||||
else:
|
||||
content_title = content_obj.title or content_obj.meta_title or "Content"
|
||||
|
||||
image_queue.append({
|
||||
'image_id': img.id,
|
||||
'index': idx,
|
||||
'label': f"{img.image_type.replace('_', ' ').title()} Image",
|
||||
'content_title': content_title,
|
||||
'status': 'pending',
|
||||
'progress': 0,
|
||||
'image_url': None,
|
||||
'error': None
|
||||
})
|
||||
|
||||
# Send initial queue to frontend
|
||||
if progress_tracker:
|
||||
initial_meta = step_tracker.get_meta() if step_tracker else {}
|
||||
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 ''}")
|
||||
console_tracker.prep(f"[{function_name}] Provider: {provider}, Model: {model}, API Key: {'***' + api_key[-4:] if api_key and len(api_key) > 4 else 'NOT SET'}")
|
||||
|
||||
# Queue all prompts first (TEST MODE - don't send to AI)
|
||||
queued_prompts = []
|
||||
|
||||
# Process each image sequentially
|
||||
for index, image in enumerate(images, 1):
|
||||
queue_item = image_queue[index - 1]
|
||||
queue_item['status'] = 'processing'
|
||||
queue_item['progress'] = 0
|
||||
|
||||
try:
|
||||
# Get content title
|
||||
content = image.content
|
||||
if not content:
|
||||
# Fallback to task if no content
|
||||
if image.task:
|
||||
content_title = image.task.title
|
||||
else:
|
||||
content_title = "Content"
|
||||
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:
|
||||
formatted_prompt = image_prompt_template.format(
|
||||
post_title=content_title,
|
||||
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:
|
||||
prep_msg = f"Generating image {index} of {total_images}: {image.image_type}"
|
||||
step_tracker.add_request_step("PREP", "success", prep_msg)
|
||||
queue_item['progress'] = 10
|
||||
# Update queue in meta
|
||||
meta = step_tracker.get_meta()
|
||||
meta['image_queue'] = image_queue
|
||||
progress_pct = 10 + int((index - 1) / total_images * 15) # 10-25% for PREP
|
||||
progress_tracker.update("PREP", progress_pct, prep_msg, meta=meta)
|
||||
|
||||
# Generate image - update progress incrementally
|
||||
if progress_tracker and step_tracker:
|
||||
ai_msg = f"Generating {image.image_type} image {index} of {total_images} with AI"
|
||||
step_tracker.add_response_step("AI_CALL", "success", ai_msg)
|
||||
queue_item['progress'] = 25
|
||||
meta = step_tracker.get_meta()
|
||||
meta['image_queue'] = image_queue
|
||||
progress_pct = 25 + int((index - 1) / total_images * 45) # 25-70% for AI_CALL
|
||||
progress_tracker.update("AI_CALL", progress_pct, ai_msg, meta=meta)
|
||||
|
||||
# Update progress to 50% (simulating API call start)
|
||||
queue_item['progress'] = 50
|
||||
if progress_tracker and step_tracker:
|
||||
meta = step_tracker.get_meta()
|
||||
meta['image_queue'] = image_queue
|
||||
progress_tracker.update("AI_CALL", progress_pct, ai_msg, meta=meta)
|
||||
|
||||
# Queue the complete prompt (TEST MODE - don't send to AI yet)
|
||||
queued_prompts.append({
|
||||
'image_id': image.id,
|
||||
'index': index,
|
||||
'image_type': image.image_type,
|
||||
'content_title': content_title,
|
||||
'provider': provider,
|
||||
'model': model,
|
||||
'formatted_prompt': formatted_prompt,
|
||||
'negative_prompt': negative_prompt if provider == 'runware' else None,
|
||||
'prompt_length': len(formatted_prompt)
|
||||
})
|
||||
|
||||
if console_tracker:
|
||||
console_tracker.ai_call(f"[{function_name}] [TEST MODE] Queued prompt {index}/{total_images}: {image.image_type} for '{content_title}'")
|
||||
console_tracker.ai_call(f"[{function_name}] [TEST MODE] Provider: {provider}, Model: {model}")
|
||||
console_tracker.ai_call(f"[{function_name}] [TEST MODE] Prompt length: {len(formatted_prompt)} chars")
|
||||
console_tracker.ai_call(f"[{function_name}] [TEST MODE] Prompt preview: {formatted_prompt[:150]}...")
|
||||
|
||||
# TEMPORARY: Simulate result for testing (don't actually call AI)
|
||||
result = {
|
||||
'url': None,
|
||||
'error': None,
|
||||
'test_mode': True,
|
||||
'queued': True
|
||||
}
|
||||
|
||||
# ACTUAL AI CALL (COMMENTED OUT FOR TESTING)
|
||||
# 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,
|
||||
# model=model,
|
||||
# size='1024x1024',
|
||||
# n=1,
|
||||
# api_key=api_key, # Pass API key explicitly
|
||||
# negative_prompt=negative_prompt if provider == 'runware' else None,
|
||||
# function_name='generate_images_from_prompts'
|
||||
# )
|
||||
|
||||
# TEST MODE: Mark as queued (not actually generated)
|
||||
queue_item['status'] = 'completed'
|
||||
queue_item['progress'] = 100
|
||||
queue_item['image_url'] = None # No URL in test mode
|
||||
|
||||
if console_tracker:
|
||||
console_tracker.parse(f"[{function_name}] [TEST MODE] Prompt queued for image {index}/{total_images}")
|
||||
console_tracker.save(f"[{function_name}] [TEST MODE] Queued image {index}/{total_images} (ID: {image.id})")
|
||||
|
||||
# Update progress: SAVE phase
|
||||
if progress_tracker and step_tracker:
|
||||
save_msg = f"Queued prompt {index} of {total_images} (TEST MODE)"
|
||||
step_tracker.add_request_step("SAVE", "success", save_msg)
|
||||
meta = step_tracker.get_meta()
|
||||
meta['image_queue'] = image_queue
|
||||
progress_pct = 85 + int((index - 1) / total_images * 13) # 85-98% for SAVE
|
||||
progress_tracker.update("SAVE", progress_pct, save_msg, meta=meta)
|
||||
|
||||
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"[{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
|
||||
|
||||
# Log all queued prompts (TEST MODE)
|
||||
if console_tracker:
|
||||
console_tracker.save(f"[{function_name}] [TEST MODE] All prompts queued. Total: {len(queued_prompts)} prompts")
|
||||
console_tracker.save(f"[{function_name}] [TEST MODE] Provider: {provider}, Model: {model}")
|
||||
for qp in queued_prompts:
|
||||
console_tracker.save(f"[{function_name}] [TEST MODE] Image {qp['index']}: {qp['image_type']} - '{qp['content_title']}'")
|
||||
console_tracker.save(f"[{function_name}] [TEST MODE] Prompt ({qp['prompt_length']} chars): {qp['formatted_prompt'][:100]}...")
|
||||
|
||||
# Final progress update
|
||||
if progress_tracker and step_tracker:
|
||||
final_msg = f"Queued {len(queued_prompts)} prompts (TEST MODE - not sent to AI)"
|
||||
step_tracker.add_request_step("SAVE", "success", final_msg)
|
||||
meta = step_tracker.get_meta()
|
||||
meta['image_queue'] = image_queue
|
||||
meta['queued_prompts'] = queued_prompts # Include queued prompts in meta
|
||||
progress_tracker.update("SAVE", 98, final_msg, meta=meta)
|
||||
|
||||
if console_tracker:
|
||||
console_tracker.done(f"[{function_name}] [TEST MODE] Queued {len(queued_prompts)}/{total_images} prompts successfully (NOT sent to AI)")
|
||||
|
||||
return {
|
||||
'count': len(queued_prompts),
|
||||
'images_generated': 0, # 0 because we're in test mode
|
||||
'images_failed': 0,
|
||||
'total_images': total_images,
|
||||
'queued_prompts': queued_prompts, # Return queued prompts
|
||||
'test_mode': True,
|
||||
'provider': provider,
|
||||
'model': model,
|
||||
'errors': errors if errors else None
|
||||
}
|
||||
|
||||
@@ -94,15 +94,9 @@ def _load_generate_image_prompts():
|
||||
from igny8_core.ai.functions.generate_image_prompts import GenerateImagePromptsFunction
|
||||
return GenerateImagePromptsFunction
|
||||
|
||||
def _load_generate_images_from_prompts():
|
||||
"""Lazy loader for generate_images_from_prompts function"""
|
||||
from igny8_core.ai.functions.generate_images_from_prompts import GenerateImagesFromPromptsFunction
|
||||
return GenerateImagesFromPromptsFunction
|
||||
|
||||
register_lazy_function('auto_cluster', _load_auto_cluster)
|
||||
register_lazy_function('generate_ideas', _load_generate_ideas)
|
||||
register_lazy_function('generate_content', _load_generate_content)
|
||||
register_lazy_function('generate_images', _load_generate_images)
|
||||
register_lazy_function('generate_image_prompts', _load_generate_image_prompts)
|
||||
register_lazy_function('generate_images_from_prompts', _load_generate_images_from_prompts)
|
||||
|
||||
|
||||
@@ -40,12 +40,6 @@ MODEL_CONFIG = {
|
||||
"temperature": 0.7,
|
||||
"response_format": {"type": "json_object"},
|
||||
},
|
||||
"generate_images_from_prompts": {
|
||||
"model": "dall-e-3", # Default, overridden by IntegrationSettings
|
||||
"max_tokens": None, # Not used for images
|
||||
"temperature": None, # Not used for images
|
||||
"response_format": None, # Not used for images
|
||||
},
|
||||
}
|
||||
|
||||
# Function name aliases (for backward compatibility)
|
||||
|
||||
@@ -514,73 +514,6 @@ class ImagesViewSet(SiteSectorModelViewSet):
|
||||
'results': grouped_data
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
@action(detail=False, methods=['post'], url_path='generate_images', url_name='generate_images')
|
||||
def generate_images(self, request):
|
||||
"""Generate images from prompts for image records"""
|
||||
from igny8_core.ai.tasks import run_ai_task
|
||||
|
||||
account = getattr(request, 'account', None)
|
||||
ids = request.data.get('ids', [])
|
||||
|
||||
if not ids:
|
||||
return Response({
|
||||
'error': 'No IDs provided',
|
||||
'type': 'ValidationError'
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
account_id = account.id if account else None
|
||||
|
||||
# Queue Celery task
|
||||
try:
|
||||
if hasattr(run_ai_task, 'delay'):
|
||||
task = run_ai_task.delay(
|
||||
function_name='generate_images_from_prompts',
|
||||
payload={'ids': ids},
|
||||
account_id=account_id
|
||||
)
|
||||
return Response({
|
||||
'success': True,
|
||||
'task_id': str(task.id),
|
||||
'message': 'Image generation started'
|
||||
}, status=status.HTTP_200_OK)
|
||||
else:
|
||||
# Fallback to synchronous execution
|
||||
result = run_ai_task(
|
||||
function_name='generate_images_from_prompts',
|
||||
payload={'ids': ids},
|
||||
account_id=account_id
|
||||
)
|
||||
if result.get('success'):
|
||||
# Include queued prompts in response for TEST MODE
|
||||
response_data = {
|
||||
'success': True,
|
||||
'images_generated': result.get('images_generated', 0),
|
||||
'images_failed': result.get('images_failed', 0),
|
||||
'count': result.get('count', 0),
|
||||
'total_images': result.get('total_images', 0),
|
||||
'message': 'Images generated successfully'
|
||||
}
|
||||
# Add test mode data if available
|
||||
if result.get('queued_prompts'):
|
||||
response_data['queued_prompts'] = result.get('queued_prompts')
|
||||
response_data['test_mode'] = result.get('test_mode', False)
|
||||
response_data['provider'] = result.get('provider')
|
||||
response_data['model'] = result.get('model')
|
||||
|
||||
logger.info(f"[generate_images] Response: {response_data}")
|
||||
return Response(response_data, status=status.HTTP_200_OK)
|
||||
else:
|
||||
return Response({
|
||||
'error': result.get('error', 'Image generation failed'),
|
||||
'type': 'TaskExecutionError'
|
||||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
except Exception as e:
|
||||
return Response({
|
||||
'error': str(e),
|
||||
'type': 'ExecutionError'
|
||||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
|
||||
class ContentViewSet(SiteSectorModelViewSet):
|
||||
"""
|
||||
ViewSet for managing task content
|
||||
|
||||
@@ -221,6 +221,7 @@ export default function Images() {
|
||||
return;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
// STAGE 1: Open modal immediately with all progress bars
|
||||
setImageQueue(queue);
|
||||
setCurrentContentId(contentId);
|
||||
@@ -241,6 +242,26 @@ export default function Images() {
|
||||
} catch (error: any) {
|
||||
console.error('[Generate Images] Exception:', error);
|
||||
toast.error(`Failed to initialize image generation: ${error.message}`);
|
||||
=======
|
||||
const result = await generateImages(imageIds);
|
||||
if (result.success) {
|
||||
// Show toast message (no progress modal)
|
||||
const generated = result.images_generated || 0;
|
||||
const failed = result.images_failed || 0;
|
||||
if (generated > 0) {
|
||||
toast.success(`Images generated: ${generated} image${generated !== 1 ? 's' : ''} created${failed > 0 ? `, ${failed} failed` : ''}`);
|
||||
} else if (failed > 0) {
|
||||
toast.error(`Image generation failed: ${failed} image${failed !== 1 ? 's' : ''} failed`);
|
||||
} else {
|
||||
toast.success('Image generation completed');
|
||||
}
|
||||
loadImages(); // Reload to show new images
|
||||
} else {
|
||||
toast.error(result.error || 'Failed to generate images');
|
||||
}
|
||||
} catch (error: any) {
|
||||
toast.error(`Failed to generate images: ${error.message}`);
|
||||
>>>>>>> parent of e89eaab0 (some changes)
|
||||
}
|
||||
}, [toast, images, buildImageQueue]);
|
||||
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script for generate_images_from_prompts function
|
||||
Run this to test the function and see the response
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import django
|
||||
|
||||
# Setup Django
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'backend'))
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'igny8_core.settings')
|
||||
django.setup()
|
||||
|
||||
from igny8_core.ai.functions.generate_images_from_prompts import GenerateImagesFromPromptsFunction
|
||||
from igny8_core.ai.engine import AIEngine
|
||||
from igny8_core.modules.writer.models import Images
|
||||
from igny8_core.auth.models import Account
|
||||
|
||||
def test_generate_images_from_prompts():
|
||||
"""Test the generate_images_from_prompts function"""
|
||||
print("=" * 80)
|
||||
print("Testing generate_images_from_prompts function")
|
||||
print("=" * 80)
|
||||
|
||||
# Get first account
|
||||
try:
|
||||
account = Account.objects.first()
|
||||
if not account:
|
||||
print("ERROR: No accounts found in database")
|
||||
return
|
||||
print(f"Using account: {account.name} (ID: {account.id})")
|
||||
except Exception as e:
|
||||
print(f"ERROR: Failed to get account: {e}")
|
||||
return
|
||||
|
||||
# Get pending images with prompts
|
||||
try:
|
||||
images = Images.objects.filter(
|
||||
account=account,
|
||||
status='pending'
|
||||
).exclude(prompt__isnull=True).exclude(prompt='')[:3] # Get first 3
|
||||
|
||||
if not images.exists():
|
||||
print("ERROR: No pending images with prompts found")
|
||||
print("Please create some images with prompts first")
|
||||
return
|
||||
|
||||
image_ids = list(images.values_list('id', flat=True))
|
||||
print(f"\nFound {len(image_ids)} pending images: {image_ids}")
|
||||
|
||||
# Show image details
|
||||
for img in images:
|
||||
content_title = "Unknown"
|
||||
if img.content:
|
||||
content_title = img.content.title or img.content.meta_title or "No title"
|
||||
elif img.task:
|
||||
content_title = img.task.title or "No title"
|
||||
print(f" - Image ID {img.id}: {img.image_type} for '{content_title}'")
|
||||
print(f" Prompt: {img.prompt[:100] if img.prompt else 'None'}...")
|
||||
|
||||
except Exception as e:
|
||||
print(f"ERROR: Failed to get images: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return
|
||||
|
||||
# Create function instance
|
||||
try:
|
||||
fn = GenerateImagesFromPromptsFunction()
|
||||
print(f"\nFunction created: {fn.get_name()}")
|
||||
except Exception as e:
|
||||
print(f"ERROR: Failed to create function: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return
|
||||
|
||||
# Validate
|
||||
try:
|
||||
print("\n" + "=" * 80)
|
||||
print("Step 1: VALIDATE")
|
||||
print("=" * 80)
|
||||
validation = fn.validate({'ids': image_ids}, account=account)
|
||||
print(f"Validation result: {validation}")
|
||||
if not validation.get('valid'):
|
||||
print(f"ERROR: Validation failed: {validation.get('error')}")
|
||||
return
|
||||
except Exception as e:
|
||||
print(f"ERROR: Validation failed: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return
|
||||
|
||||
# Prepare
|
||||
try:
|
||||
print("\n" + "=" * 80)
|
||||
print("Step 2: PREPARE")
|
||||
print("=" * 80)
|
||||
prepared = fn.prepare({'ids': image_ids}, account=account)
|
||||
print(f"Prepared data keys: {list(prepared.keys())}")
|
||||
print(f"Provider: {prepared.get('provider')}")
|
||||
print(f"Model: {prepared.get('model')}")
|
||||
print(f"API Key: {'***' + prepared.get('api_key', '')[-4:] if prepared.get('api_key') and len(prepared.get('api_key', '')) > 4 else 'NOT SET'}")
|
||||
print(f"Images count: {len(prepared.get('images', []))}")
|
||||
print(f"Has prompt template: {bool(prepared.get('image_prompt_template'))}")
|
||||
print(f"Has negative prompt: {bool(prepared.get('negative_prompt'))}")
|
||||
except Exception as e:
|
||||
print(f"ERROR: Prepare failed: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return
|
||||
|
||||
# Build prompt (placeholder for this function)
|
||||
try:
|
||||
print("\n" + "=" * 80)
|
||||
print("Step 3: BUILD PROMPT")
|
||||
print("=" * 80)
|
||||
prompt = fn.build_prompt(prepared, account=account)
|
||||
print(f"Prompt (placeholder): {prompt}")
|
||||
except Exception as e:
|
||||
print(f"ERROR: Build prompt failed: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return
|
||||
|
||||
# Execute via AIEngine (simulated, no actual Celery)
|
||||
try:
|
||||
print("\n" + "=" * 80)
|
||||
print("Step 4: EXECUTE (via AIEngine - TEST MODE)")
|
||||
print("=" * 80)
|
||||
print("Note: This will queue prompts but NOT send to AI (TEST MODE)")
|
||||
|
||||
engine = AIEngine(account=account)
|
||||
result = engine.execute(fn, {'ids': image_ids})
|
||||
|
||||
print("\n" + "=" * 80)
|
||||
print("EXECUTION RESULT")
|
||||
print("=" * 80)
|
||||
print(f"Success: {result.get('success')}")
|
||||
print(f"Keys in result: {list(result.keys())}")
|
||||
|
||||
if result.get('success'):
|
||||
print(f"\nCount: {result.get('count', 0)}")
|
||||
print(f"Images generated: {result.get('images_generated', 0)}")
|
||||
print(f"Images failed: {result.get('images_failed', 0)}")
|
||||
print(f"Total images: {result.get('total_images', 0)}")
|
||||
print(f"Test mode: {result.get('test_mode', False)}")
|
||||
print(f"Provider: {result.get('provider')}")
|
||||
print(f"Model: {result.get('model')}")
|
||||
|
||||
queued_prompts = result.get('queued_prompts', [])
|
||||
if queued_prompts:
|
||||
print(f"\nQueued Prompts ({len(queued_prompts)}):")
|
||||
for idx, qp in enumerate(queued_prompts, 1):
|
||||
print(f"\n Prompt {idx}/{len(queued_prompts)}:")
|
||||
print(f" Image ID: {qp.get('image_id')}")
|
||||
print(f" Image Type: {qp.get('image_type')}")
|
||||
print(f" Content Title: {qp.get('content_title')}")
|
||||
print(f" Provider: {qp.get('provider')}")
|
||||
print(f" Model: {qp.get('model')}")
|
||||
print(f" Prompt Length: {qp.get('prompt_length')} chars")
|
||||
print(f" Full Prompt:")
|
||||
print(f" {qp.get('formatted_prompt', '')[:200]}...")
|
||||
if qp.get('negative_prompt'):
|
||||
print(f" Negative Prompt: {qp.get('negative_prompt')}")
|
||||
else:
|
||||
print(f"\nError: {result.get('error')}")
|
||||
print(f"Error type: {result.get('error_type')}")
|
||||
|
||||
print("\n" + "=" * 80)
|
||||
print("FULL RESULT JSON (for frontend)")
|
||||
print("=" * 80)
|
||||
import json
|
||||
print(json.dumps(result, indent=2, default=str))
|
||||
|
||||
except Exception as e:
|
||||
print(f"ERROR: Execution failed: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_generate_images_from_prompts()
|
||||
|
||||
Reference in New Issue
Block a user