Files
igny8/docs/IMAGE_GENERATION_CHANGELOG.md
2025-11-12 04:32:42 +05:00

16 KiB

Image Generation Implementation Changelog

Stage 1: Pre-Queue Modal Display - Completed

Date: 2025-01-XX
Status: Completed
Goal: Open modal immediately showing all progress bars before any API calls


Changes Made

1. Frontend Components

Created: frontend/src/components/common/ImageQueueModal.tsx

  • Purpose: Display image generation queue with individual progress bars
  • Features:
    • Shows all images that will be generated with individual progress bars
    • Displays queue number, label, content title, status, and progress percentage
    • Includes thumbnail placeholder for generated images
    • Supports 4 states: pending, processing, completed, failed
    • Styled similar to WP plugin's image-queue-processor.js modal
    • Responsive design with dark mode support
    • Prevents closing while processing
    • Shows completion summary in footer

Key Props:

  • isOpen: Boolean to control modal visibility
  • onClose: Callback when modal is closed
  • queue: Array of ImageQueueItem objects
  • totalImages: Total number of images in queue
  • onUpdateQueue: Optional callback to update queue state

ImageQueueItem Interface:

{
  imageId: number | null;
  index: number;
  label: string;
  type: 'featured' | 'in_article';
  position?: number;
  contentTitle: string;
  status: 'pending' | 'processing' | 'completed' | 'failed';
  progress: number; // 0-100
  imageUrl: string | null;
  error: string | null;
}

Updated: frontend/src/pages/Writer/Images.tsx

  • Added Imports:

    • fetchImageGenerationSettings from ../../services/api
    • ImageQueueModal and ImageQueueItem from ../../components/common/ImageQueueModal
  • Added State:

    const [isQueueModalOpen, setIsQueueModalOpen] = useState(false);
    const [imageQueue, setImageQueue] = useState<ImageQueueItem[]>([]);
    const [currentContentId, setCurrentContentId] = useState<number | null>(null);
    
  • Added Function: buildImageQueue()

    • Builds image queue structure from content images
    • Includes featured image (if pending and has prompt)
    • Includes in-article images (up to max_in_article_images from settings)
    • Sorts in-article images by position
    • Returns array of ImageQueueItem objects
  • Updated Function: handleGenerateImages()

    • Stage 1 Implementation:
      1. Fetches image generation settings to get max_in_article_images
      2. Builds image queue using buildImageQueue()
      3. Opens modal immediately with all progress bars at 0%
      4. Collects image IDs for future API call (Stage 2)
      5. Logs Stage 1 completion
  • Added Modal Component:

    • Renders ImageQueueModal at end of component
    • Handles modal close with image reload
    • Passes queue state and update callback

2. API Services

Updated: frontend/src/services/api.ts

  • Added Interface: ImageGenerationSettings

    {
      success: boolean;
      config: {
        provider: string;
        model: string;
        image_type: string;
        max_in_article_images: number;
        image_format: string;
        desktop_enabled: boolean;
        mobile_enabled: boolean;
      };
    }
    
  • Added Function: fetchImageGenerationSettings()

    • Fetches image generation settings from backend
    • Endpoint: /v1/system/integrations/image_generation/
    • Returns settings including max_in_article_images

3. Backend API

Updated: backend/igny8_core/modules/system/integration_views.py

  • Added Method: get_image_generation_settings()
    • Action decorator: @action(detail=False, methods=['get'], url_path='image_generation')
    • Gets account from request (with fallbacks)
    • Retrieves IntegrationSettings for image_generation type
    • Returns formatted config with defaults if not found
    • Default values:
      • provider: 'openai'
      • model: 'dall-e-3'
      • image_type: 'realistic'
      • max_in_article_images: 2
      • image_format: 'webp'
      • desktop_enabled: True
      • mobile_enabled: True

Updated: backend/igny8_core/modules/system/urls.py

  • Added URL Route:
    path('integrations/image_generation/', integration_image_gen_settings_viewset, name='integration-image-gen-settings')
    
  • Added ViewSet:
    integration_image_gen_settings_viewset = IntegrationSettingsViewSet.as_view({
        'get': 'get_image_generation_settings',
    })
    

How It Works

User Flow:

  1. User clicks "Generate Images" button on Images page
  2. System fetches max_in_article_images from IntegrationSettings
  3. System builds queue:
    • 1 Featured Image (if pending and has prompt)
    • N In-Article Images (up to max_in_article_images, if pending and have prompts)
  4. Modal opens immediately showing all progress bars at 0%
  5. Each progress bar displays:
    • Queue number (1, 2, 3...)
    • Label (Featured Image, In-Article Image 1, etc.)
    • Content title
    • Status: " Pending"
    • Progress: 0%
    • Thumbnail placeholder: "No image"

Queue Calculation:

Total Images = 1 (featured) + min(pending_in_article_count, max_in_article_images)

Example:

  • Settings: max_in_article_images = 3
  • Content has: 1 featured (pending), 5 in-article (pending)
  • Queue: 1 featured + 3 in-article = 4 total progress bars

Files Modified

Frontend:

  1. frontend/src/components/common/ImageQueueModal.tsx (NEW)
  2. frontend/src/pages/Writer/Images.tsx (UPDATED)
  3. frontend/src/services/api.ts (UPDATED)

Backend:

  1. backend/igny8_core/modules/system/integration_views.py (UPDATED)
  2. backend/igny8_core/modules/system/urls.py (UPDATED)

Testing Checklist

  • Modal opens immediately when "Generate Images" button is clicked
  • Modal shows correct number of progress bars (1 featured + N in-article)
  • Progress bars display correct labels and content titles
  • All progress bars start at 0% with "Pending" status
  • Modal can be closed (when not processing)
  • API endpoint returns correct max_in_article_images value
  • Queue respects max_in_article_images setting
  • Only pending images with prompts are included in queue

Next Steps (Stage 2)

Planned Features:

  1. Start Actual Generation

    • Call generateImages() API with image IDs
    • Handle async task response with task_id
  2. Real-Time Progress Updates

    • Poll task progress or use WebSocket
    • Update individual progress bars as images are generated
    • Implement progressive loading (0-50% in 7s, 50-75% in 5s, etc.)
  3. Sequential Processing

    • Process images one at a time (sequential)
    • Update status: pending → processing → completed/failed
    • Update progress percentage for each image
  4. Error Handling

    • Mark failed images with error message
    • Continue processing other images if one fails
    • Display error in queue item
  5. Completion Handling

    • Show generated image thumbnails
    • Update all statuses to completed/failed
    • Reload images list on modal close

Notes

  • Stage 1 focuses on immediate visual feedback - modal opens instantly
  • No API calls are made in Stage 1 (only settings fetch)
  • Queue structure is built client-side from existing image data
  • Modal is ready to receive progress updates in Stage 2
  • Design matches WP plugin's image-queue-processor.js modal

  • Reference Implementation: igny8-ai-seo-wp-plugin/assets/js/image-queue-processor.js
  • Implementation Plan: docs/IMAGE_GENERATION_IMPLEMENTATION_PLAN.md
  • Backend Function: backend/igny8_core/ai/functions/generate_images_from_prompts.py


Stage 1 Updates: Modal Styling Improvements

Date: 2025-01-XX
Status: Completed

Changes Made:

  1. Updated Modal Background

    • Changed from bg-black bg-opacity-50 to standard modal backdrop
    • Now uses Modal component with bg-gray-400/50 backdrop-blur-[32px] (standard glass effect)
    • Matches all other modals in the system
  2. Replaced Emojis with React Icons

    • Header: Replaced 🎨 emoji with FileIcon component
    • Pending status: Replaced emoji with TimeIcon component
    • Processing status: Added spinning SVG icon
    • Completed status: Uses CheckCircleIcon component
    • Failed status: Uses ErrorIcon component
  3. Standard Modal Width

    • Changed from custom width to max-w-4xl (standard modal width)
    • Uses Modal component which provides consistent styling across system

Files Modified:

  • frontend/src/components/common/ImageQueueModal.tsx (UPDATED)

Visual Improvements:

  • Modal now has proper blur/glass backdrop effect
  • Icons are consistent with system design
  • Modal width matches other modals in the system
  • Better visual hierarchy with icon in header

End of Stage 1 Changelog


Stage 2 & 3: Image Generation Execution & Real-Time Progress - Completed

Date: 2025-01-XX
Status: Completed
Goal: Execute image generation sequentially and update progress in real-time


Changes Made

1. Backend API

Updated: backend/igny8_core/modules/writer/views.py

  • Added Method: generate_images()
    • Action decorator: @action(detail=False, methods=['post'], url_path='generate_images')
    • Accepts ids (image IDs array) and content_id (optional)
    • Queues process_image_generation_queue Celery task
    • Returns task_id for progress tracking
    • Handles validation errors and execution errors

2. Celery Task

Updated: backend/igny8_core/ai/tasks.py

  • Added Task: process_image_generation_queue()
    • Decorator: @shared_task(bind=True, name='igny8_core.ai.tasks.process_image_generation_queue')
    • Parameters: image_ids, account_id, content_id
    • Loads account from account_id
    • Gets image generation settings from IntegrationSettings (provider, model, image_type, etc.)
    • Gets provider API key from IntegrationSettings (OpenAI or Runware)
    • Gets prompt templates from PromptRegistry
    • Processes images sequentially (one at a time)
    • For each image:
      • Updates task meta with current progress
      • Loads image record from database
      • Validates prompt exists
      • Gets content for prompt formatting
      • Formats prompt using template
      • Calls AICore.generate_image()
      • Updates Images model: image_url, status
      • Handles errors per image (continues on failure)
    • Returns final result with counts and per-image results

3. Frontend API

Updated: frontend/src/services/api.ts

  • Updated Function: generateImages()
    • Added contentId parameter (optional)
    • Sends both ids and content_id to backend
    • Returns task response with task_id

4. Frontend Components

Updated: frontend/src/pages/Writer/Images.tsx

  • Added State:
    • taskId: Stores Celery task ID for polling
  • Updated Function: handleGenerateImages()
    • Stage 2: Calls generateImages() API after opening modal
    • Stores task_id in state
    • Handles API errors
  • Updated Modal Props:
    • Passes taskId to ImageQueueModal

Updated: frontend/src/components/common/ImageQueueModal.tsx

  • Added Prop: taskId
    • Optional string for Celery task ID
  • Added Polling Mechanism:
    • useEffect hook polls task status every 1 second
    • Endpoint: /api/v1/system/settings/task_progress/{taskId}/
    • Stops polling when task completes (SUCCESS/FAILURE)
  • Added Function: updateQueueFromTaskMeta()
    • Updates queue items from task meta data
    • Maps current_image, completed, failed, results to queue items
    • Updates status, progress, imageUrl, error for each item
  • Added Function: updateQueueFromTaskResult()
    • Updates queue items from final task result
    • Sets final status and image URLs
    • Handles completion state

5. Backend Task Status Endpoint

Existing: backend/igny8_core/modules/system/integration_views.py

  • Method: task_progress()
    • Already exists and handles Celery task status polling
    • Returns task state (PENDING, PROGRESS, SUCCESS, FAILURE)
    • Returns task meta for progress updates
    • Returns task result on completion

How It Works

User Flow:

  1. User clicks "Generate Images" button
  2. Stage 1: Modal opens immediately with all progress bars
  3. Stage 2: Frontend calls generate_images() API
  4. Backend queues process_image_generation_queue Celery task
  5. Stage 3: Frontend polls task status every 1 second
  6. Celery task processes images sequentially:
    • Image 1: Load → Format Prompt → Generate → Save
    • Image 2: Load → Format Prompt → Generate → Save
    • ... (continues for all images)
  7. Task updates meta with progress after each image
  8. Frontend receives updates and updates modal progress bars
  9. On completion, modal shows final status for all images
  10. User closes modal → Images list reloads

Data Flow:

Frontend (Images.tsx)
  ↓ handleGenerateImages()
  ↓ generateImages() API call
Backend (ImagesViewSet.generate_images)
  ↓ process_image_generation_queue.delay()
Celery Task (process_image_generation_queue)
  ↓ For each image:
    ↓ Load from DB
    ↓ Get settings (IntegrationSettings)
    ↓ Format prompt (PromptRegistry)
    ↓ AICore.generate_image()
    ↓ Update Images model (image_url, status)
    ↓ Update task meta
Frontend (ImageQueueModal)
  ↓ Poll task_progress endpoint
  ↓ Update queue from meta/result
  ↓ Display progress bars

Progress Updates:

  • Task Meta Structure:
    • current_image: Index of image being processed
    • total_images: Total images in queue
    • completed: Number of completed images
    • failed: Number of failed images
    • results: Array of per-image results
  • Per-Image Result:
    • image_id: Image record ID
    • status: 'completed' or 'failed'
    • image_url: Generated image URL (if successful)
    • error: Error message (if failed)

Files Modified

Backend:

  1. backend/igny8_core/modules/writer/views.py (UPDATED)

    • generate_images() method
  2. backend/igny8_core/ai/tasks.py (UPDATED)

    • process_image_generation_queue() task

Frontend:

  1. frontend/src/services/api.ts (UPDATED)

    • generateImages() function
  2. frontend/src/pages/Writer/Images.tsx (UPDATED)

    • handleGenerateImages() function
    • taskId state
    • Modal props
  3. frontend/src/components/common/ImageQueueModal.tsx (UPDATED)

    • taskId prop
    • Polling mechanism
    • updateQueueFromTaskMeta() function
    • updateQueueFromTaskResult() function

Integration Points

Settings Integration:

  • IntegrationSettings Model:
    • image_generation type: Provider, model, image_type, max_in_article_images, etc.
    • openai type: API key, model
    • runware type: API key, model

Prompt Templates:

  • PromptRegistry:
    • get_image_prompt_template(): Formats prompt with post_title, image_prompt, image_type
    • get_negative_prompt(): Returns negative prompt for Runware

Image Storage:

  • Images Model:
    • image_url: Updated with generated image URL
    • status: Updated to 'generated' or 'failed'
    • prompt: Used for generation (already set)

Testing Checklist

  • API endpoint accepts image IDs and content ID
  • Celery task queues successfully
  • Task processes images sequentially
  • Task reads settings from IntegrationSettings
  • Task formats prompts using PromptRegistry
  • Task calls AICore.generate_image() correctly
  • Task updates Images model with URLs and status
  • Task updates meta with progress
  • Frontend polls task status correctly
  • Modal updates progress bars in real-time
  • Modal shows generated image thumbnails
  • Modal handles errors per image
  • Modal shows completion summary
  • Images list reloads after modal close

Notes

  • Images are processed sequentially (one at a time) to respect API rate limits
  • Each image failure is handled independently (doesn't stop other images)
  • Progress updates are sent via Celery task meta (polled every 1 second)
  • Task status endpoint already exists and is reused
  • Integration settings are read from database (not hardcoded)
  • Prompt templates support fallback if formatting fails
  • Image URLs are saved directly to Images model
  • Status is updated to 'generated' or 'failed' per image

End of Stage 2 & 3 Changelog