- Removed hardcoded model defaults and the MODEL_CONFIG dictionary. - Updated get_model_config() to require an account parameter and raise clear errors if IntegrationSettings are not configured. - Eliminated unused helper functions: get_model(), get_max_tokens(), and get_temperature(). - Improved error handling to provide specific messages for missing account or model configurations. - Cleaned up orphan exports in __init__.py to maintain a streamlined codebase.
545 lines
19 KiB
Markdown
545 lines
19 KiB
Markdown
# IGNY8 AI Framework Implementation Reference
|
|
|
|
**Last Updated:** 2025-01-XX
|
|
**Purpose:** Complete AI framework implementation reference covering architecture, code structure, all 5 AI functions, execution flow, progress tracking, cost tracking, prompt management, and model 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**: `FUNCTION_ALIASES` - Function name aliases for backward compatibility
|
|
**Functions**:
|
|
- `get_model_config(function_name, account)` - Gets model config from IntegrationSettings (account required, no fallbacks)
|
|
- Raises `ValueError` if IntegrationSettings not configured
|
|
- Returns dict with `model`, `max_tokens`, `temperature`, `response_format`
|
|
|
|
---
|
|
|
|
## 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
|
|
|
|
### IntegrationSettings - Single Source of Truth
|
|
|
|
**IMPORTANT**: As of the refactoring completed in 2025-01-XX, the AI framework uses **IntegrationSettings only** for model configuration. There are no hardcoded defaults or fallbacks.
|
|
|
|
**IntegrationSettings Model**:
|
|
- `integration_type`: 'openai' or 'runware' (required)
|
|
- `account`: Account instance (required) - each account must configure their own models
|
|
- `is_active`: Boolean (must be True for configuration to be used)
|
|
- `config`: JSONField with model configuration (required)
|
|
- `model`: Model name (required) - e.g., 'gpt-4o-mini', 'gpt-4o', 'dall-e-3'
|
|
- `max_tokens`: Max tokens (optional, defaults to 4000)
|
|
- `temperature`: Temperature (optional, defaults to 0.7)
|
|
- `response_format`: Response format (optional, automatically set for JSON mode models)
|
|
|
|
### Model Configuration Function
|
|
|
|
**File**: `backend/igny8_core/ai/settings.py`
|
|
|
|
**Function**: `get_model_config(function_name: str, account) -> Dict[str, Any]`
|
|
|
|
**Behavior**:
|
|
- **Requires** `account` parameter (no longer optional)
|
|
- **Requires** IntegrationSettings to be configured for the account
|
|
- **Raises** `ValueError` with clear error messages if:
|
|
- Account not provided
|
|
- IntegrationSettings not found for account
|
|
- Model not configured in IntegrationSettings
|
|
- IntegrationSettings is inactive
|
|
|
|
**Error Messages**:
|
|
- Missing account: `"Account is required for model configuration"`
|
|
- Missing IntegrationSettings: `"OpenAI IntegrationSettings not configured for account {id}. Please configure OpenAI settings in the integration page."`
|
|
- Missing model: `"Model not configured in IntegrationSettings for account {id}. Please set 'model' in OpenAI integration settings."`
|
|
|
|
**Returns**:
|
|
```python
|
|
{
|
|
'model': str, # Model name from IntegrationSettings
|
|
'max_tokens': int, # From config or default 4000
|
|
'temperature': float, # From config or default 0.7
|
|
'response_format': dict, # JSON mode for supported models, or None
|
|
}
|
|
```
|
|
|
|
### Account-Specific Configuration
|
|
|
|
**Key Principle**: Each account must configure their own AI models. There are no global defaults.
|
|
|
|
**Configuration Steps**:
|
|
1. Navigate to Settings → Integrations
|
|
2. Configure OpenAI integration settings
|
|
3. Set `model` in the configuration (required)
|
|
4. Optionally set `max_tokens` and `temperature`
|
|
5. Ensure integration is active
|
|
|
|
**Supported Models**:
|
|
- Text generation: `gpt-4o-mini`, `gpt-4o`, `gpt-4-turbo`, etc.
|
|
- Image generation: `dall-e-3` (OpenAI) or `runware:97@1` (Runware)
|
|
- JSON mode: Automatically enabled for supported models (gpt-4o, gpt-4-turbo, etc.)
|
|
|
|
### Function Aliases
|
|
|
|
**File**: `backend/igny8_core/ai/settings.py`
|
|
|
|
**FUNCTION_ALIASES**: Dictionary mapping legacy function names to current names
|
|
- `cluster_keywords` → `auto_cluster`
|
|
- `auto_cluster_keywords` → `auto_cluster`
|
|
- `auto_generate_ideas` → `generate_ideas`
|
|
- `auto_generate_content` → `generate_content`
|
|
- `auto_generate_images` → `generate_images`
|
|
|
|
**Purpose**: Maintains backward compatibility with legacy function names.
|
|
|
|
### Removed Functions
|
|
|
|
The following helper functions were removed as part of the refactoring (they were never used):
|
|
- `get_model()` - Removed (use `get_model_config()['model']` instead)
|
|
- `get_max_tokens()` - Removed (use `get_model_config()['max_tokens']` instead)
|
|
- `get_temperature()` - Removed (use `get_model_config()['temperature']` instead)
|
|
|
|
**Rationale**: These functions were redundant - `get_model_config()` already returns all needed values.
|
|
|
|
---
|
|
|
|
## 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.
|
|
|