# Image Generation System - Comprehensive Gap Analysis **Date:** January 2026 **Status:** Audit Complete **Reviewer:** System Audit ## Executive Summary This document provides a comprehensive audit of the image generation system, analyzing the flow from model configuration to image delivery, both for manual and automation workflows. --- ## 1. System Architecture Overview ### Current Flow ``` User Selects Quality Tier (basic/quality/quality_option2/premium) ↓ AIModelConfig (database) → provider, model_name, landscape_size, square_size ↓ process_image_generation_queue (Celery task) ↓ ai_core.generate_image() → provider-specific handler ↓ _generate_image_openai() / _generate_image_runware() ↓ Downloaded to /frontend/public/images/ai-images/ ↓ Image record updated (Images model) ``` ### Image Count Determination ``` User sets max_images (1-8) in Site Settings ↓ AISettings.get_effective_max_images(account) ↓ generate_image_prompts.py: 1 featured + max_images in_article ↓ Images created with positions: featured(0) + in_article(0,1,2,3...) ``` --- ## 2. RESOLVED Issues (Previously Fixed) ### ✅ 2.1 Quality Tier Fallback - **Issue:** `get_effective_quality_tier()` was returning hardcoded 'basic' instead of default model's tier - **Fixed in:** `ai_settings.py` lines 196-232 - **Solution:** Now falls back to `AIModelConfig.is_default=True` model's `quality_tier` ### ✅ 2.2 Image Sizes from Database - **Issue:** `tasks.py` had hardcoded `MODEL_LANDSCAPE_SIZES` dict - **Fixed in:** `tasks.py` lines 242-260 - **Solution:** Now loads `landscape_size` and `square_size` from `AIModelConfig` ### ✅ 2.3 Settings Endpoint Default Tier - **Issue:** `settings_views.py` returned hardcoded 'basic' as default tier - **Fixed in:** `settings_views.py` lines 616-640 - **Solution:** Gets `default_tier` from `default_image_model.quality_tier` ### ✅ 2.4 Integration Views Dynamic Sizes - **Issue:** Two endpoints in `integration_views.py` had hardcoded size lookup - **Fixed:** Both endpoints now load from `AIModelConfig` --- ## 3. REMAINING Gaps (Action Required) ### 🔴 GAP-1: Hardcoded Size Constants in global_settings_models.py **Location:** `backend/igny8_core/modules/system/global_settings_models.py` lines 180-188 **Code:** ```python # Model-specific landscape sizes (square is always 1024x1024 for all models) MODEL_LANDSCAPE_SIZES = { 'runware:97@1': '1280x768', # Hi Dream Full landscape 'bria:10@1': '1344x768', # Bria 3.2 landscape (16:9) 'google:4@2': '1376x768', # Nano Banana landscape (16:9) } # Default square size (universal across all models) DEFAULT_SQUARE_SIZE = '1024x1024' ``` **Impact:** These constants are UNUSED but could cause confusion. They're legacy from before the AIModelConfig migration. **Recommendation:** - [ ] Remove unused `MODEL_LANDSCAPE_SIZES` dict - [ ] Remove unused `DEFAULT_SQUARE_SIZE` constant - [ ] Add deprecation comment if keeping for reference --- ### 🔴 GAP-2: Hardcoded Size Fallbacks in Tasks **Location:** `backend/igny8_core/ai/tasks.py` lines 254-260 **Code:** ```python else: # Fallback sizes if no model config (should never happen) model_landscape_size = '1792x1024' model_square_size = '1024x1024' logger.warning(f"[process_image_generation_queue] No model config, using fallback sizes") ``` **Impact:** LOW - Fallback only triggers if database is misconfigured. But the hardcoded sizes may not match actual model requirements. **Recommendation:** - [ ] Consider failing gracefully with clear error instead of using fallback - [ ] Or: Load fallback from a system default in database --- ### 🔴 GAP-3: Frontend VALID_SIZES_BY_MODEL Hardcoded **Location:** `frontend/src/components/common/ImageGenerationCard.tsx` lines 52-55 **Code:** ```tsx const VALID_SIZES_BY_MODEL: Record = { 'dall-e-3': ['1024x1024', '1024x1792', '1792x1024'], 'dall-e-2': ['256x256', '512x512', '1024x1024'], }; ``` **Impact:** MEDIUM - Test image generation card only shows OpenAI sizes, not Runware/Bytedance sizes. **Recommendation:** - [ ] Fetch valid_sizes from AIModelConfig via API - [ ] Or: Pass sizes from backend settings endpoint --- ### 🔴 GAP-4: Backend VALID_SIZES_BY_MODEL Hardcoded **Location:** `backend/igny8_core/ai/constants.py` lines 40-43 **Code:** ```python VALID_SIZES_BY_MODEL = { 'dall-e-3': ['1024x1024', '1024x1792', '1792x1024'], 'dall-e-2': ['256x256', '512x512', '1024x1024'], } ``` **Impact:** MEDIUM - Used for OpenAI validation only. Runware models bypass this validation. **Status:** PARTIAL - Only affects OpenAI validation. Runware has its own validation via provider-specific code. **Recommendation:** - [ ] Move validation to AIModelConfig.valid_sizes field - [ ] Validate against model's valid_sizes from database --- ### 🔴 GAP-5: Missing Runware Model Size Validation **Location:** `backend/igny8_core/ai/ai_core.py` lines 943-1050 **Code:** The `_generate_image_runware()` method does NOT validate sizes against `valid_sizes` from database. **Impact:** LOW - Runware API will reject invalid sizes anyway, but error message won't be clear. **Recommendation:** - [ ] Add validation: check `size` against `AIModelConfig.valid_sizes` before API call - [ ] Return clear error: "Size X is not valid for model Y" --- ### 🔴 GAP-6: Seedream Minimum Pixel Validation Hardcoded **Location:** `backend/igny8_core/ai/ai_core.py` lines 1018-1027 **Code:** ```python elif runware_model.startswith('bytedance:'): # Enforce minimum size for Seedream (min 3,686,400 pixels ~ 1920x1920) current_pixels = width * height if current_pixels < 3686400: # Use default Seedream square size inference_task['width'] = 2048 inference_task['height'] = 2048 ``` **Impact:** LOW - This hardcoded check works, but should come from database. **Recommendation:** - [ ] Add `min_pixels` field to AIModelConfig - [ ] Check model.min_pixels instead of hardcoded 3686400 --- ### 🔴 GAP-7: Provider-Specific Steps/CFGScale Hardcoded **Location:** `backend/igny8_core/ai/ai_core.py` lines 995-1040 **Code:** ```python if runware_model.startswith('bria:'): inference_task['steps'] = 20 # ... elif runware_model.startswith('runware:'): inference_task['steps'] = 20 inference_task['CFGScale'] = 7 ``` **Impact:** LOW - Works correctly but adding new models requires code changes. **Recommendation:** - [ ] Add `generation_params` JSON field to AIModelConfig - [ ] Store steps, CFGScale, etc. in database per model --- ### 🔴 GAP-8: Image Count Not Per-Content Configurable **Location:** System-wide setting only **Current Behavior:** - `max_images` is a global setting (site-wide) - All articles get the same number of in_article images **Impact:** MEDIUM - Users cannot set different image counts per article/keyword. **Recommendation:** - [ ] Add `images_count` field to Content model (nullable, inherits from site default) - [ ] Or: Add to Keywords model for keyword-level override --- ### 🟡 GAP-9: Legacy generate_images.py Function (Partially Dead Code) **Location:** `backend/igny8_core/ai/functions/generate_images.py` **Issue:** `generate_images_core()` function exists but appears to be legacy. Main flow uses `process_image_generation_queue()` in tasks.py. **Impact:** LOW - Code duplication, potential maintenance burden. **Recommendation:** - [ ] Audit if `generate_images.py` is actually used anywhere - [ ] If not: Add deprecation warning or remove - [ ] If used: Ensure it uses same dynamic config loading --- ### 🟡 GAP-10: No Validation of quality_tier Values **Location:** Multiple locations **Issue:** When user selects a quality_tier, there's no validation that: 1. The tier exists in AIModelConfig 2. The tier has an active model 3. The user's plan allows that tier **Impact:** MEDIUM - Could lead to runtime errors if tier doesn't exist. **Recommendation:** - [ ] Add validation in settings save endpoint - [ ] Return error if selected tier has no active model --- ## 4. Image Count Flow (Working Correctly) ### How image count works: 1. **User configures:** - `max_images` (1-8) in Site Settings → saved to AccountSettings 2. **Prompt generation:** ```python # generate_image_prompts.py max_images = AISettings.get_effective_max_images(account) # e.g., 4 # Creates: 1 featured + 4 in_article = 5 image prompts ``` 3. **Image types:** - `featured` - Always 1, position=0, landscape size - `in_article` - Up to max_images, positions 0,1,2,3..., alternating square/landscape 4. **Size determination:** ```python # tasks.py if image.image_type == 'featured': image_size = featured_image_size # landscape elif image.image_type == 'in_article': position = image.position or 0 if position % 2 == 0: # 0, 2 image_size = square_size else: # 1, 3 image_size = landscape_size ``` **STATUS:** ✅ Working correctly. No gaps identified in image count logic. --- ## 5. Automation Flow (Working Correctly) ### Stage 6: Image Generation **Location:** `automation_service.py` lines 1236-1400 **Flow:** 1. Query `Images.objects.filter(site=site, status='pending')` 2. For each image: `process_image_generation_queue.delay(image_ids=[image.id], ...)` 3. Monitor task completion 4. Update run progress **STATUS:** ✅ Uses same task as manual generation. Consistent behavior. --- ## 6. Model Provider Support Matrix | Provider | Models | Status | Gaps | |----------|--------|--------|------| | OpenAI | dall-e-3, dall-e-2 | ✅ Working | Valid sizes hardcoded | | Runware | runware:97@1 | ✅ Working | No size validation | | Runware | bria:10@1 | ✅ Working | Steps hardcoded | | Runware | google:4@2 | ✅ Working | Resolution param hardcoded | | Runware | bytedance:seedream@4.5 | ✅ Working | Min pixels hardcoded | --- ## 7. Priority Action Items ### High Priority 1. **GAP-4/5:** Implement database-driven size validation for all providers 2. **GAP-10:** Add quality_tier validation on save ### Medium Priority 3. **GAP-6/7:** Move provider-specific params to AIModelConfig.generation_params 4. **GAP-8:** Consider per-content image count override ### Low Priority 5. **GAP-1:** Clean up unused constants 6. **GAP-9:** Audit and deprecate legacy code 7. **GAP-3:** Fetch valid sizes from API in frontend --- ## 8. Recommendations Summary ### Short-term (Before Launch) - Ensure all hardcoded fallbacks are clearly logged - Test each model tier end-to-end ### Medium-term (Post-Launch) - Migrate all hardcoded params to AIModelConfig fields - Add model validation on quality_tier save ### Long-term (Future Enhancement) - Per-content image count override - Per-keyword image style override - Image regeneration without deleting existing --- ## Appendix: Key Files Reference | File | Purpose | |------|---------| | `ai/tasks.py` | Main image generation Celery task | | `ai/ai_core.py` | Provider-specific generation methods | | `ai/functions/generate_image_prompts.py` | Extract prompts from content | | `modules/system/ai_settings.py` | System defaults + account overrides | | `modules/system/settings_views.py` | Frontend settings API | | `business/billing/models.py` | AIModelConfig model | | `business/automation/services/automation_service.py` | Automation Stage 6 |