diff --git a/backend/igny8_core/ai/functions/generate_images.py b/backend/igny8_core/ai/functions/generate_images.py index 5c394e2e..7cdb3357 100644 --- a/backend/igny8_core/ai/functions/generate_images.py +++ b/backend/igny8_core/ai/functions/generate_images.py @@ -122,8 +122,10 @@ class GenerateImagesFunction(BaseAIFunction): } ) - # Get model config - model_config = get_model_config('extract_image_prompts') + # Get model config (requires account) + if not account_obj: + raise ValueError("Account is required for model configuration") + model_config = get_model_config('extract_image_prompts', account=account_obj) # Call AI to extract prompts using centralized request handler result = ai_core.run_ai_request( diff --git a/backend/igny8_core/ai/settings.py b/backend/igny8_core/ai/settings.py index 5bb73134..8c0759d1 100644 --- a/backend/igny8_core/ai/settings.py +++ b/backend/igny8_core/ai/settings.py @@ -1,46 +1,11 @@ """ AI Settings - Centralized model configurations and limits +Uses IntegrationSettings only - no hardcoded defaults or fallbacks. """ from typing import Dict, Any +import logging -# Model configurations for each AI function -MODEL_CONFIG = { - "auto_cluster": { - "model": "gpt-4o-mini", - "max_tokens": 3000, - "temperature": 0.7, - "response_format": {"type": "json_object"}, # Auto-enabled for JSON mode models - }, - "generate_ideas": { - "model": "gpt-4.1", - "max_tokens": 4000, - "temperature": 0.7, - "response_format": {"type": "json_object"}, # JSON output - }, - "generate_content": { - "model": "gpt-4.1", - "max_tokens": 8000, - "temperature": 0.7, - "response_format": {"type": "json_object"}, # JSON output - }, - "generate_images": { - "model": "dall-e-3", - "size": "1024x1024", - "provider": "openai", - }, - "extract_image_prompts": { - "model": "gpt-4o-mini", - "max_tokens": 1000, - "temperature": 0.7, - "response_format": {"type": "json_object"}, - }, - "generate_image_prompts": { - "model": "gpt-4o-mini", - "max_tokens": 2000, - "temperature": 0.7, - "response_format": {"type": "json_object"}, - }, -} +logger = logging.getLogger(__name__) # Function name aliases (for backward compatibility) FUNCTION_ALIASES = { @@ -52,71 +17,81 @@ FUNCTION_ALIASES = { } -def get_model_config(function_name: str, account=None) -> Dict[str, Any]: +def get_model_config(function_name: str, account) -> Dict[str, Any]: """ - Get model configuration for an AI function. - Reads model from IntegrationSettings if account is provided, otherwise uses defaults. + Get model configuration from IntegrationSettings only. + No fallbacks - account must have IntegrationSettings configured. Args: - function_name: AI function name (e.g., 'auto_cluster', 'generate_ideas') - account: Optional account object to read model from IntegrationSettings + function_name: Name of the AI function + account: Account instance (required) Returns: - Dict with model, max_tokens, temperature, etc. + dict: Model configuration with 'model', 'max_tokens', 'temperature' + + Raises: + ValueError: If account not provided or IntegrationSettings not configured """ - # Check aliases first + if not account: + raise ValueError("Account is required for model configuration") + + # Resolve function alias actual_name = FUNCTION_ALIASES.get(function_name, function_name) - # Get base config - config = MODEL_CONFIG.get(actual_name, {}).copy() + # Get IntegrationSettings for OpenAI + try: + from igny8_core.modules.system.models import IntegrationSettings + integration_settings = IntegrationSettings.objects.get( + integration_type='openai', + account=account, + is_active=True + ) + except IntegrationSettings.DoesNotExist: + raise ValueError( + f"OpenAI IntegrationSettings not configured for account {account.id}. " + f"Please configure OpenAI settings in the integration page." + ) - # Try to get model from IntegrationSettings if account is provided - model_from_settings = None - if account: - try: - from igny8_core.modules.system.models import IntegrationSettings - openai_settings = IntegrationSettings.objects.filter( - integration_type='openai', - account=account, - is_active=True - ).first() - if openai_settings and openai_settings.config: - model_from_settings = openai_settings.config.get('model') - if model_from_settings: - # Validate model is in our supported list - from igny8_core.utils.ai_processor import MODEL_RATES - if model_from_settings in MODEL_RATES: - config['model'] = model_from_settings - except Exception as e: - import logging - logger = logging.getLogger(__name__) - logger.warning(f"Could not load model from IntegrationSettings: {e}", exc_info=True) + config = integration_settings.config or {} - # Merge with defaults - default_config = { - "model": "gpt-4.1", - "max_tokens": 4000, - "temperature": 0.7, - "response_format": None, + # Get model from config + model = config.get('model') + if not model: + raise ValueError( + f"Model not configured in IntegrationSettings for account {account.id}. " + f"Please set 'model' in OpenAI integration settings." + ) + + # 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: + # MODEL_RATES not available - skip validation + pass + + # Get max_tokens and temperature from config (with reasonable defaults for API) + max_tokens = config.get('max_tokens', 4000) # Reasonable default for API limits + temperature = config.get('temperature', 0.7) # Reasonable default + + # 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: + # JSON_MODE_MODELS not available - skip + pass + + return { + 'model': model, + 'max_tokens': max_tokens, + 'temperature': temperature, + 'response_format': response_format, } - - return {**default_config, **config} - - -def get_model(function_name: str) -> str: - """Get model name for function""" - config = get_model_config(function_name) - return config.get("model", "gpt-4.1") - - -def get_max_tokens(function_name: str) -> int: - """Get max tokens for function""" - config = get_model_config(function_name) - return config.get("max_tokens", 4000) - - -def get_temperature(function_name: str) -> float: - """Get temperature for function""" - config = get_model_config(function_name) - return config.get("temperature", 0.7)