# IGNY8 AI Functions Documentation

**Last Updated:** 2025-01-XX  
**Purpose:** Complete AI functions documentation covering architecture, all 5 AI functions, execution flow, and configuration.

---

## Table of Contents

1. [AI Framework Overview](#ai-framework-overview)
2. [Common Architecture](#common-architecture)
3. [AI Function Execution Flow](#ai-function-execution-flow)
4. [AI Functions](#ai-functions)
5. [Progress Tracking](#progress-tracking)
6. [Cost Tracking](#cost-tracking)
7. [Prompt Management](#prompt-management)
8. [Model Configuration](#model-configuration)

---

## AI Framework Overview

The IGNY8 AI framework provides a unified interface for all AI operations. All AI functions inherit from `BaseAIFunction` and are orchestrated by `AIEngine`, ensuring consistent execution, progress tracking, error handling, and cost tracking.

### Key Components

- **BaseAIFunction**: Abstract base class for all AI functions
- **AIEngine**: Central orchestrator managing lifecycle, progress, logging, cost tracking
- **AICore**: Centralized AI request handler for all AI operations
- **PromptRegistry**: Centralized prompt management with hierarchical resolution
- **Function Registry**: Lazy-loaded function registry
- **Progress Tracking**: Real-time progress updates via Celery
- **Cost Tracking**: Automatic cost and token tracking

### AI Functions

1. **Auto Cluster Keywords**: Group related keywords into semantic clusters
2. **Generate Ideas**: Generate content ideas from keyword clusters
3. **Generate Content**: Generate blog post and article content
4. **Generate Image Prompts**: Extract image prompts from content
5. **Generate Images**: Generate images using OpenAI DALL-E or Runware

---

## Common Architecture

### Core Framework Files

#### Entry Point
**File**: `backend/igny8_core/ai/tasks.py`
**Function**: `run_ai_task`
**Purpose**: Unified Celery task entrypoint for all AI functions
**Parameters**: `function_name` (str), `payload` (dict), `account_id` (int)
**Flow**: Loads function from registry → Creates AIEngine → Executes function

#### Engine Orchestrator
**File**: `backend/igny8_core/ai/engine.py`
**Class**: `AIEngine`
**Purpose**: Central orchestrator managing lifecycle, progress, logging, cost tracking
**Methods**:
- `execute` - Main execution pipeline (6 phases: INIT, PREP, AI_CALL, PARSE, SAVE, DONE)
- `_handle_error` - Centralized error handling
- `_log_to_database` - Logs to AITaskLog model

#### Base Function Class
**File**: `backend/igny8_core/ai/base.py`
**Class**: `BaseAIFunction`
**Purpose**: Abstract base class defining interface for all AI functions
**Abstract Methods**:
- `get_name` - Returns function name (e.g., 'auto_cluster')
- `prepare` - Loads and prepares data
- `build_prompt` - Builds AI prompt
- `parse_response` - Parses AI response
- `save_output` - Saves results to database
**Optional Methods**:
- `get_metadata` - Returns display name, description, phases
- `get_max_items` - Returns max items limit (or None)
- `validate` - Validates input payload (default: checks for 'ids')
- `get_model` - Returns model override (default: None, uses account default)

#### Function Registry
**File**: `backend/igny8_core/ai/registry.py`
**Functions**:
- `register_function` - Registers function class
- `register_lazy_function` - Registers lazy loader
- `get_function` - Gets function class by name (lazy loads if needed)
- `get_function_instance` - Gets function instance by name
- `list_functions` - Lists all registered functions

#### AI Core Handler
**File**: `backend/igny8_core/ai/ai_core.py`
**Class**: `AICore`
**Purpose**: Centralized AI request handler for all AI operations (text and image generation)
**Methods**:
- `run_ai_request` - Makes API call to OpenAI/Runware for text generation
- `generate_image` - Makes API call to OpenAI DALL-E or Runware for image generation
- `extract_json` - Extracts JSON from response (handles markdown code blocks)

#### Prompt Registry
**File**: `backend/igny8_core/ai/prompts.py`
**Class**: `PromptRegistry`
**Purpose**: Centralized prompt management with hierarchical resolution
**Method**: `get_prompt` - Gets prompt with resolution order:
1. Task-level prompt_override (if exists)
2. DB prompt for (account, function)
3. Default fallback from DEFAULT_PROMPTS registry
**Prompt Types**:
- `clustering` - For auto_cluster function
- `ideas` - For generate_ideas function
- `content_generation` - For generate_content function
- `image_prompt_extraction` - For extract_image_prompts function
- `image_prompt_template` - Template for formatting image prompts
- `negative_prompt` - Negative prompt for Runware image generation

#### Model Settings
**File**: `backend/igny8_core/ai/settings.py`
**Constants**: `MODEL_CONFIG` - Model configurations per function (model, max_tokens, temperature, response_format)
**Functions**:
- `get_model_config` - Gets model config for function (reads from IntegrationSettings if account provided)
- `get_model` - Gets model name for function
- `get_max_tokens` - Gets max tokens for function
- `get_temperature` - Gets temperature for function

---

## AI Function Execution Flow

### Complete Execution Pipeline

```
1. API Endpoint (views.py)
   ↓
2. run_ai_task (tasks.py)
   - Gets account from account_id
   - Gets function instance from registry
   - Creates AIEngine
   ↓
3. AIEngine.execute (engine.py)
   Phase 1: INIT (0-10%)
   - Calls function.validate()
   - Updates progress tracker
   ↓
   Phase 2: PREP (10-25%)
   - Calls function.prepare()
   - Calls function.build_prompt()
   - Updates progress tracker
   ↓
   Phase 3: AI_CALL (25-70%)
   - Gets model config from settings
   - Calls AICore.run_ai_request() or AICore.generate_image()
   - Tracks cost and tokens
   - Updates progress tracker
   ↓
   Phase 4: PARSE (70-85%)
   - Calls function.parse_response()
   - Updates progress tracker
   ↓
   Phase 5: SAVE (85-98%)
   - Calls function.save_output()
   - Logs credit usage
   - Updates progress tracker
   ↓
   Phase 6: DONE (98-100%)
   - Logs to AITaskLog
   - Returns result
```

### Progress Updates

**Progress Endpoint**: `/api/v1/system/settings/task_progress/{task_id}/`

**Response Format**:
- `state`: Task state (PENDING, PROGRESS, SUCCESS, FAILURE)
- `meta`: Progress metadata
  - `phase`: Current phase (INIT, PREP, AI_CALL, PARSE, SAVE, DONE)
  - `percentage`: Progress percentage (0-100)
  - `message`: User-friendly message
  - `request_steps`: Array of request steps
  - `response_steps`: Array of response steps
  - `cost`: API cost in USD
  - `tokens`: Token count

---

## AI Functions

### 1. Auto Cluster Keywords

**Purpose**: Group related keywords into semantic clusters using AI

**Function Class**: `AutoClusterFunction`
**File**: `backend/igny8_core/ai/functions/auto_cluster.py`

**API Endpoint**:
- **ViewSet**: `KeywordViewSet`
- **Action**: `auto_cluster`
- **Method**: POST
- **URL Path**: `/v1/planner/keywords/auto_cluster/`
- **Payload**: `ids` (list[int]) - Keyword IDs

**Function Methods**:
- `get_name()`: Returns `'auto_cluster'`
- `validate(payload, account)`: Validates keyword IDs exist
- `prepare(payload, account)`: Loads keywords from database
- `build_prompt(data, account)`: Builds clustering prompt with keyword data
- `parse_response(response, step_tracker)`: Parses cluster JSON response
- `save_output(parsed, original_data, account, progress_tracker, step_tracker)`: Creates Cluster records and links keywords

**Input**: List of keyword IDs
**Output**: Cluster records created, keywords linked to clusters

**Progress Messages**:
- INIT: "Validating keywords"
- PREP: "Preparing keyword clustering"
- AI_CALL: "Analyzing keyword relationships"
- PARSE: "Processing cluster data"
- SAVE: "Creating clusters"

### 2. Generate Ideas

**Purpose**: Generate content ideas from keyword clusters

**Function Class**: `GenerateIdeasFunction`
**File**: `backend/igny8_core/ai/functions/generate_ideas.py`

**API Endpoint**:
- **ViewSet**: `ClusterViewSet`
- **Action**: `auto_generate_ideas`
- **Method**: POST
- **URL Path**: `/v1/planner/clusters/auto_generate_ideas/`
- **Payload**: `ids` (list[int]) - Cluster IDs

**Function Methods**:
- `get_name()`: Returns `'generate_ideas'`
- `validate(payload, account)`: Validates cluster IDs exist
- `prepare(payload, account)`: Loads clusters and keywords
- `build_prompt(data, account)`: Builds idea generation prompt with cluster data
- `parse_response(response, step_tracker)`: Parses ideas JSON response
- `save_output(parsed, original_data, account, progress_tracker, step_tracker)`: Creates ContentIdeas records

**Input**: List of cluster IDs
**Output**: ContentIdeas records created

**Progress Messages**:
- INIT: "Verifying cluster integrity"
- PREP: "Loading cluster keywords"
- AI_CALL: "Generating ideas with Igny8 Semantic AI"
- PARSE: "{count} high-opportunity idea(s) generated"
- SAVE: "Content Outline for Ideas generated"

### 3. Generate Content

**Purpose**: Generate blog post and article content from tasks

**Function Class**: `GenerateContentFunction`
**File**: `backend/igny8_core/ai/functions/generate_content.py`

**API Endpoint**:
- **ViewSet**: `TasksViewSet`
- **Action**: `auto_generate_content`
- **Method**: POST
- **URL Path**: `/v1/writer/tasks/auto_generate_content/`
- **Payload**: `ids` (list[int]) - Task IDs (max 50)

**Function Methods**:
- `get_name()`: Returns `'generate_content'`
- `get_max_items()`: Returns `50` (max tasks per batch)
- `validate(payload, account)`: Validates task IDs exist
- `prepare(payload, account)`: Loads tasks with related data
- `build_prompt(data, account)`: Builds content generation prompt with task data
- `parse_response(response, step_tracker)`: Parses content (JSON or plain text)
- `save_output(parsed, original_data, account, progress_tracker, step_tracker)`: Creates/updates Content records

**Input**: List of task IDs
**Output**: Content records created/updated with HTML content

**Progress Messages**:
- INIT: "Initializing content generation"
- PREP: "Loading tasks and building prompts"
- AI_CALL: "Generating content with AI"
- PARSE: "Processing content"
- SAVE: "Saving content"

### 4. Generate Image Prompts

**Purpose**: Extract image prompts from content for generating images

**Function Class**: `GenerateImagePromptsFunction`
**File**: `backend/igny8_core/ai/functions/generate_image_prompts.py`

**API Endpoint**:
- **ViewSet**: `TasksViewSet` (via content)
- **Action**: `generate_image_prompts`
- **Method**: POST
- **URL Path**: `/v1/writer/content/generate_image_prompts/`
- **Payload**: `ids` (list[int]) - Content IDs

**Function Methods**:
- `get_name()`: Returns `'generate_image_prompts'`
- `validate(payload, account)`: Validates content IDs exist
- `prepare(payload, account)`: Loads content records
- `build_prompt(data, account)`: Builds prompt extraction prompt with content HTML
- `parse_response(response, step_tracker)`: Parses image prompts JSON
- `save_output(parsed, original_data, account, progress_tracker, step_tracker)`: Updates Images records with prompts

**Input**: List of content IDs
**Output**: Images records updated with prompts (featured, in-article)

**Progress Messages**:
- INIT: "Validating content"
- PREP: "Preparing image prompt extraction"
- AI_CALL: "Extracting image prompts"
- PARSE: "Processing image prompts"
- SAVE: "Saving image prompts"

### 5. Generate Images

**Purpose**: Generate images using AI (OpenAI DALL-E or Runware) based on prompts

**Function Class**: `GenerateImagesFunction`
**File**: `backend/igny8_core/ai/functions/generate_images.py`

**API Endpoint**:
- **ViewSet**: `ImagesViewSet`
- **Action**: `generate_images`
- **Method**: POST
- **URL Path**: `/v1/writer/images/generate_images/`
- **Payload**: `ids` (list[int]) - Image IDs

**Function Methods**:
- `get_name()`: Returns `'generate_images'`
- `validate(payload, account)`: Validates image IDs exist and have prompts
- `prepare(payload, account)`: Loads images with prompts
- `build_prompt(data, account)`: Formats image prompt with context
- `parse_response(response, step_tracker)`: Parses image URL from API response
- `save_output(parsed, original_data, account, progress_tracker, step_tracker)`: Updates Images records with image URLs

**Input**: List of image IDs (with prompts)
**Output**: Images records updated with image URLs

**Image Generation Settings**:
- Provider: 'openai' or 'runware'
- Model: Model name (e.g., 'dall-e-3', 'runware:97@1')
- Image Type: 'realistic', 'artistic', 'cartoon'
- Max In-Article Images: Max images per content
- Image Format: 'webp', 'jpg', 'png'
- Desktop/Mobile: Boolean flags

**Progress Messages**:
- INIT: "Validating image prompts"
- PREP: "Preparing image generation"
- AI_CALL: "Creating image(s) with AI"
- PARSE: "Processing image response"
- SAVE: "Saving generated image(s)"

---

## Progress Tracking

### Progress Phases

All AI functions follow the same 6-phase execution:

1. **INIT** (0-10%): Validation phase
2. **PREP** (10-25%): Data preparation phase
3. **AI_CALL** (25-70%): AI API call phase
4. **PARSE** (70-85%): Response parsing phase
5. **SAVE** (85-98%): Database save phase
6. **DONE** (98-100%): Completion phase

### Progress Updates

**Frontend Polling**: Frontend polls `/api/v1/system/settings/task_progress/{task_id}/` every 1-2 seconds

**Progress Response**:
- `state`: Task state
- `meta`: Progress metadata
  - `phase`: Current phase
  - `percentage`: Progress percentage
  - `message`: User-friendly message
  - `request_steps`: Request steps array
  - `response_steps`: Response steps array
  - `cost`: API cost
  - `tokens`: Token count

### Step Tracking

**Request Steps**: Tracked during prompt building and AI call
**Response Steps**: Tracked during response parsing

**Purpose**: Provides detailed logging for debugging and transparency

---

## Cost Tracking

### Cost Calculation

**Text Generation**:
- Cost calculated based on model pricing (input tokens + output tokens)
- Tracked per request
- Stored in `CostTracker`

**Image Generation**:
- Cost calculated based on provider pricing
- OpenAI DALL-E: Fixed cost per image
- Runware: Variable cost per image
- Tracked per image

### Cost Storage

**AITaskLog Model**:
- `cost`: Total cost for task
- `tokens`: Total tokens used

**CreditUsageLog Model**:
- `cost_usd`: Cost in USD
- `credits_used`: Credits deducted

---

## Prompt Management

### Prompt Resolution Order

1. **Task-Level Override**: If task has `prompt_override`, use it
2. **Database Prompt**: If account has custom prompt in database, use it
3. **Default Prompt**: Use default prompt from `DEFAULT_PROMPTS` registry

### Prompt Customization

**Per Account**: Custom prompts stored in `AIPrompt` model
**Per Function**: Different prompts for each function type
**Context Variables**: Prompts support context placeholders:
- `[IGNY8_KEYWORDS]` - Keyword list
- `[IGNY8_CLUSTERS]` - Cluster list
- `[IGNY8_CLUSTER_KEYWORDS]` - Cluster keywords
- `[IGNY8_IDEA]` - Idea data
- `[IGNY8_CLUSTER]` - Cluster data

---

## Model Configuration

### Model Settings

**Default Models**:
- Clustering: `gpt-4o-mini`
- Ideas: `gpt-4o-mini`
- Content: `gpt-4o`
- Image Prompts: `gpt-4o-mini`
- Images: `dall-e-3` (OpenAI) or `runware:97@1` (Runware)

### Per-Account Override

**IntegrationSettings Model**:
- `integration_type`: 'openai' or 'runware'
- `config`: JSONField with model configuration
  - `model`: Model name
  - `max_tokens`: Max tokens
  - `temperature`: Temperature
  - `response_format`: Response format

### Model Configuration

**File**: `backend/igny8_core/ai/settings.py`

**MODEL_CONFIG**: Dictionary mapping function names to model configurations

**Functions**:
- `get_model_config(function_name, account=None)`: Gets model config (checks IntegrationSettings if account provided)
- `get_model(function_name, account=None)`: Gets model name
- `get_max_tokens(function_name, account=None)`: Gets max tokens
- `get_temperature(function_name, account=None)`: Gets temperature

---

## Summary

The IGNY8 AI framework provides:

1. **Unified Interface**: All AI functions use the same execution pipeline
2. **Consistent Execution**: All functions follow the same 6-phase flow
3. **Progress Tracking**: Real-time progress updates via Celery
4. **Cost Tracking**: Automatic cost and token tracking
5. **Error Handling**: Centralized error handling in AIEngine
6. **Prompt Management**: Hierarchical prompt resolution
7. **Model Configuration**: Per-account model overrides
8. **Database Logging**: Automatic logging to AITaskLog
9. **Extensibility**: Easy to add new AI functions
10. **Reliability**: Retry logic and error recovery

This architecture ensures consistency, maintainability, and extensibility while providing a robust foundation for all AI operations in the IGNY8 platform.

