""" AI Settings - Centralized model configurations and limits Uses global settings with optional per-account overrides. """ from typing import Dict, Any import logging logger = logging.getLogger(__name__) # Function name aliases (for backward compatibility) FUNCTION_ALIASES = { "cluster_keywords": "auto_cluster", "auto_cluster_keywords": "auto_cluster", "auto_generate_ideas": "generate_ideas", "auto_generate_content": "generate_content", "auto_generate_images": "generate_images", } def get_model_config(function_name: str, account) -> Dict[str, Any]: """ Get model configuration for AI function. Architecture: - API keys: ALWAYS from GlobalIntegrationSettings (platform-wide) - Model/params: From IntegrationSettings if account has override, else from global - Free plan: Cannot override, uses global defaults - Starter/Growth/Scale: Can override model, temperature, max_tokens, etc. Args: function_name: Name of the AI function account: Account instance (required) Returns: dict: Model configuration with 'model', 'max_tokens', 'temperature', 'api_key' Raises: ValueError: If account not provided or settings not configured """ if not account: raise ValueError("Account is required for model configuration") # Resolve function alias actual_name = FUNCTION_ALIASES.get(function_name, function_name) try: from igny8_core.modules.system.global_settings_models import GlobalIntegrationSettings from igny8_core.modules.system.models import IntegrationSettings # Get global settings (for API keys and defaults) global_settings = GlobalIntegrationSettings.get_instance() if not global_settings.openai_api_key: raise ValueError( "Platform OpenAI API key not configured. " "Please configure GlobalIntegrationSettings in Django admin." ) # Start with global defaults model = global_settings.openai_model temperature = global_settings.openai_temperature max_tokens = global_settings.openai_max_tokens api_key = global_settings.openai_api_key # ALWAYS from global # Check if account has overrides (only for Starter/Growth/Scale plans) # Free plan users cannot create IntegrationSettings records try: account_settings = IntegrationSettings.objects.get( account=account, integration_type='openai', is_active=True ) config = account_settings.config or {} # Override model if specified (NULL = use global) if config.get('model'): model = config['model'] # Override temperature if specified if config.get('temperature') is not None: temperature = config['temperature'] # Override max_tokens if specified if config.get('max_tokens'): max_tokens = config['max_tokens'] except IntegrationSettings.DoesNotExist: # No account override, use global defaults (already set above) pass except Exception as e: logger.error(f"Could not load OpenAI settings for account {account.id}: {e}") raise ValueError( f"Could not load OpenAI configuration for account {account.id}. " f"Please configure GlobalIntegrationSettings." ) # Validate model is in our supported list (optional validation) try: from igny8_core.utils.ai_processor import MODEL_RATES if model not in MODEL_RATES: logger.warning( f"Model '{model}' for account {account.id} is not in supported list. " f"Supported models: {list(MODEL_RATES.keys())}" ) except ImportError: pass # Build response format based on model (JSON mode for supported models) response_format = None try: from igny8_core.ai.constants import JSON_MODE_MODELS if model in JSON_MODE_MODELS: response_format = {"type": "json_object"} except ImportError: pass return { 'model': model, 'max_tokens': max_tokens, 'temperature': temperature, 'response_format': response_format, }