diff --git a/backend/igny8_core/ai/functions/generate_image_prompts.py b/backend/igny8_core/ai/functions/generate_image_prompts.py index e8990d20..e2c7a9c0 100644 --- a/backend/igny8_core/ai/functions/generate_image_prompts.py +++ b/backend/igny8_core/ai/functions/generate_image_prompts.py @@ -218,27 +218,35 @@ class GenerateImagePromptsFunction(BaseAIFunction): # Helper methods def _get_max_in_article_images(self, account) -> int: - """Get max_in_article_images from AWS account IntegrationSettings only""" + """ + Get max_in_article_images from settings. + Tries aws-admin IntegrationSettings first, falls back to GlobalIntegrationSettings. + """ from igny8_core.modules.system.models import IntegrationSettings + from igny8_core.modules.system.global_settings_models import GlobalIntegrationSettings from igny8_core.auth.models import Account - # Only use system account (aws-admin) settings - system_account = Account.objects.get(slug='aws-admin') - settings = IntegrationSettings.objects.get( - account=system_account, - integration_type='image_generation', - is_active=True - ) - max_images = settings.config.get('max_in_article_images') - - if max_images is None: - raise ValueError( - "max_in_article_images not configured in aws-admin image_generation settings. " - "Please set this value in the Integration Settings page." + # Try aws-admin IntegrationSettings first (legacy pattern) + try: + system_account = Account.objects.get(slug='aws-admin') + settings = IntegrationSettings.objects.get( + account=system_account, + integration_type='image_generation', + is_active=True ) + max_images = settings.config.get('max_in_article_images') + + if max_images is not None: + max_images = int(max_images) + logger.info(f"Using max_in_article_images={max_images} from aws-admin IntegrationSettings") + return max_images + except (Account.DoesNotExist, IntegrationSettings.DoesNotExist): + logger.debug("aws-admin IntegrationSettings not found, falling back to GlobalIntegrationSettings") - max_images = int(max_images) - logger.info(f"Using max_in_article_images={max_images} from aws-admin account") + # Fall back to GlobalIntegrationSettings + global_settings = GlobalIntegrationSettings.get_instance() + max_images = global_settings.max_in_article_images + logger.info(f"Using max_in_article_images={max_images} from GlobalIntegrationSettings") return max_images def _extract_content_elements(self, content: Content, max_images: int) -> Dict: diff --git a/backend/igny8_core/ai/functions/generate_images.py b/backend/igny8_core/ai/functions/generate_images.py index f202f4a7..f95e65f9 100644 --- a/backend/igny8_core/ai/functions/generate_images.py +++ b/backend/igny8_core/ai/functions/generate_images.py @@ -67,32 +67,42 @@ class GenerateImagesFunction(BaseAIFunction): if not tasks: raise ValueError("No tasks found") - # Get image generation settings from aws-admin account only (global settings) + # Get image generation settings + # Try aws-admin IntegrationSettings first (legacy), fall back to GlobalIntegrationSettings from igny8_core.modules.system.models import IntegrationSettings + from igny8_core.modules.system.global_settings_models import GlobalIntegrationSettings from igny8_core.auth.models import Account - system_account = Account.objects.get(slug='aws-admin') - integration = IntegrationSettings.objects.get( - account=system_account, - integration_type='image_generation', - is_active=True - ) - image_settings = integration.config or {} + image_settings = {} + try: + system_account = Account.objects.get(slug='aws-admin') + integration = IntegrationSettings.objects.get( + account=system_account, + integration_type='image_generation', + is_active=True + ) + image_settings = integration.config or {} + logger.info("Using image settings from aws-admin IntegrationSettings") + except (Account.DoesNotExist, IntegrationSettings.DoesNotExist): + logger.info("aws-admin IntegrationSettings not found, using GlobalIntegrationSettings") - # Extract settings with defaults - provider = image_settings.get('provider') or image_settings.get('service', 'openai') + # Fall back to GlobalIntegrationSettings for missing values + global_settings = GlobalIntegrationSettings.get_instance() + + # Extract settings with defaults from global settings + provider = image_settings.get('provider') or image_settings.get('service') or global_settings.default_image_service if provider == 'runware': - model = image_settings.get('model') or image_settings.get('runwareModel', 'runware:97@1') + model = image_settings.get('model') or image_settings.get('runwareModel') or global_settings.runware_model else: - model = image_settings.get('model', 'dall-e-3') + model = image_settings.get('model') or global_settings.dalle_model return { 'tasks': tasks, 'account': account, 'provider': provider, 'model': model, - 'image_type': image_settings.get('image_type', 'realistic'), - 'max_in_article_images': int(image_settings.get('max_in_article_images')), + 'image_type': image_settings.get('image_type') or global_settings.image_style, + 'max_in_article_images': int(image_settings.get('max_in_article_images') or global_settings.max_in_article_images), 'desktop_enabled': image_settings.get('desktop_enabled', True), 'mobile_enabled': image_settings.get('mobile_enabled', True), } diff --git a/backend/igny8_core/ai/tasks.py b/backend/igny8_core/ai/tasks.py index a4105b73..f00f3946 100644 --- a/backend/igny8_core/ai/tasks.py +++ b/backend/igny8_core/ai/tasks.py @@ -181,10 +181,13 @@ def process_image_generation_queue(self, image_ids: list, account_id: int = None failed = 0 results = [] - # Get image generation settings from IntegrationSettings - # Always use system account settings (aws-admin) for global configuration - logger.info("[process_image_generation_queue] Step 1: Loading image generation settings from aws-admin") + # Get image generation settings + # Try aws-admin IntegrationSettings first (legacy), fall back to GlobalIntegrationSettings + logger.info("[process_image_generation_queue] Step 1: Loading image generation settings") from igny8_core.auth.models import Account + from igny8_core.modules.system.global_settings_models import GlobalIntegrationSettings + + config = {} try: system_account = Account.objects.get(slug='aws-admin') image_settings = IntegrationSettings.objects.get( @@ -192,30 +195,35 @@ def process_image_generation_queue(self, image_ids: list, account_id: int = None integration_type='image_generation', is_active=True ) - logger.info(f"[process_image_generation_queue] Using system account (aws-admin) settings") + logger.info(f"[process_image_generation_queue] Using system account (aws-admin) IntegrationSettings") config = image_settings.config or {} except (Account.DoesNotExist, IntegrationSettings.DoesNotExist): - logger.error("[process_image_generation_queue] ERROR: Image generation settings not found in aws-admin account") - return {'success': False, 'error': 'Image generation settings not found in aws-admin account'} + logger.info("[process_image_generation_queue] aws-admin IntegrationSettings not found, using GlobalIntegrationSettings") except Exception as e: logger.error(f"[process_image_generation_queue] ERROR loading image generation settings: {e}", exc_info=True) return {'success': False, 'error': f'Error loading image generation settings: {str(e)}'} + # Fall back to GlobalIntegrationSettings for missing values + global_settings = GlobalIntegrationSettings.get_instance() + logger.info(f"[process_image_generation_queue] Image generation settings loaded. Config keys: {list(config.keys())}") logger.info(f"[process_image_generation_queue] Full config: {config}") - # Get provider and model from config (respect user settings) - provider = config.get('provider', 'openai') - # Get model - try 'model' first, then 'imageModel' as fallback - model = config.get('model') or config.get('imageModel') or 'dall-e-3' + # Get provider and model from config with global fallbacks + provider = config.get('provider') or global_settings.default_image_service + if provider == 'runware': + model = config.get('model') or config.get('imageModel') or global_settings.runware_model + else: + model = config.get('model') or config.get('imageModel') or global_settings.dalle_model + logger.info(f"[process_image_generation_queue] Using PROVIDER: {provider}, MODEL: {model} from settings") - image_type = config.get('image_type', 'realistic') + image_type = config.get('image_type') or global_settings.image_style image_format = config.get('image_format', 'webp') desktop_enabled = config.get('desktop_enabled', True) mobile_enabled = config.get('mobile_enabled', True) # Get image sizes from config, with fallback defaults featured_image_size = config.get('featured_image_size') or ('1280x832' if provider == 'runware' else '1024x1024') - desktop_image_size = config.get('desktop_image_size') or '1024x1024' + desktop_image_size = config.get('desktop_image_size') or global_settings.desktop_image_size in_article_image_size = config.get('in_article_image_size') or '512x512' # Default to 512x512 logger.info(f"[process_image_generation_queue] Settings loaded:") @@ -228,7 +236,7 @@ def process_image_generation_queue(self, image_ids: list, account_id: int = None # Get provider API key (using same approach as test image generation) # Note: API key is stored as 'apiKey' (camelCase) in IntegrationSettings.config - # Normal users use system account settings (aws-admin) via fallback + # Normal users use system account settings (aws-admin) via fallback, or GlobalIntegrationSettings logger.info(f"[process_image_generation_queue] Step 2: Loading {provider.upper()} API key") try: provider_settings = IntegrationSettings.objects.get( @@ -240,7 +248,6 @@ def process_image_generation_queue(self, image_ids: list, account_id: int = None except IntegrationSettings.DoesNotExist: # Fallback to system account (aws-admin) settings logger.info(f"[process_image_generation_queue] No {provider.upper()} settings for account {account.id}, falling back to system account") - from igny8_core.auth.models import Account try: system_account = Account.objects.get(slug='aws-admin') provider_settings = IntegrationSettings.objects.get( @@ -250,19 +257,34 @@ def process_image_generation_queue(self, image_ids: list, account_id: int = None ) logger.info(f"[process_image_generation_queue] Using system account (aws-admin) {provider.upper()} settings") except (Account.DoesNotExist, IntegrationSettings.DoesNotExist): - logger.error(f"[process_image_generation_queue] ERROR: {provider.upper()} integration settings not found in system account either") - return {'success': False, 'error': f'{provider.upper()} integration not found or not active'} + # Final fallback: use GlobalIntegrationSettings API key + logger.info(f"[process_image_generation_queue] No {provider.upper()} IntegrationSettings found, will use GlobalIntegrationSettings API key") + provider_settings = None # Signal to use global settings below + except Exception as e: + logger.error(f"[process_image_generation_queue] ERROR getting {provider.upper()} API key from aws-admin: {e}", exc_info=True) + return {'success': False, 'error': f'Error retrieving {provider.upper()} API key: {str(e)}'} except Exception as e: logger.error(f"[process_image_generation_queue] ERROR getting {provider.upper()} API key: {e}", exc_info=True) return {'success': False, 'error': f'Error retrieving {provider.upper()} API key: {str(e)}'} - # Extract API key from provider settings - logger.info(f"[process_image_generation_queue] {provider.upper()} config keys: {list(provider_settings.config.keys()) if provider_settings.config else 'None'}") + # Extract API key from provider settings or global settings + if provider_settings: + logger.info(f"[process_image_generation_queue] {provider.upper()} config keys: {list(provider_settings.config.keys()) if provider_settings.config else 'None'}") + api_key = provider_settings.config.get('apiKey') if provider_settings.config else None + else: + # Use GlobalIntegrationSettings API key + logger.info(f"[process_image_generation_queue] Using {provider.upper()} API key from GlobalIntegrationSettings") + if provider == 'runware': + api_key = global_settings.runware_api_key + elif provider == 'openai': + api_key = global_settings.dalle_api_key or global_settings.openai_api_key + else: + api_key = None - api_key = provider_settings.config.get('apiKey') if provider_settings.config else None if not api_key: - logger.error(f"[process_image_generation_queue] {provider.upper()} API key not found in config") - logger.error(f"[process_image_generation_queue] {provider.upper()} config: {provider_settings.config}") + logger.error(f"[process_image_generation_queue] {provider.upper()} API key not found in config or GlobalIntegrationSettings") + if provider_settings: + logger.error(f"[process_image_generation_queue] {provider.upper()} config: {provider_settings.config}") return {'success': False, 'error': f'{provider.upper()} API key not configured'} # Log API key presence (but not the actual key for security)