fix(ai) - add ai model preferences fallback (#20704)

**Problem** 
AI_MODEL_PREFERENCES, JSON env var is not supported +
IS_CONFIG_VARIABLES_IN_DB_ENABLED=false in twenty cloud server
-> No option to set AI_MODEL_PREFERENCES

**Solution** 
AI_MODEL_PREFERENCES supports three override sources beyond the
hardcoded code defaults, in priority order:

- DB (IS_CONFIG_VARIABLES_IN_DB_ENABLED=true), the only writable source;
admin-panel mutations persist here
- ENV not usable in Twenty Cloud, which does not handle JSON-format env
vars
- **Introduced in this PR** --> File
(AI_MODEL_PREFERENCES_STORAGE_PATH), a read-only startup fallback, the
only viable override in Cloud/self-managed deployments where DB config
is disabled and JSON env vars are unsupported.
This commit is contained in:
Etienne
2026-05-19 15:19:24 +02:00
committed by GitHub
parent d5ff9eb515
commit 827f24df2b
6 changed files with 88 additions and 23 deletions
@@ -66,6 +66,7 @@ import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.g
import { UserAuthGuard } from 'src/engine/guards/user-auth.guard';
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
import { MODEL_FAMILY_LABELS } from 'src/engine/metadata-modules/ai/ai-models/constants/model-family-labels.const';
import { AiModelPreferencesService } from 'src/engine/metadata-modules/ai/ai-models/services/ai-model-preferences.service';
import { AiModelRegistryService } from 'src/engine/metadata-modules/ai/ai-models/services/ai-model-registry.service';
import { DefaultAiCatalogService } from 'src/engine/metadata-modules/ai/ai-models/services/default-ai-catalog.service';
import { ModelsDevCatalogService } from 'src/engine/metadata-modules/ai/ai-models/services/models-dev-catalog.service';
@@ -108,6 +109,7 @@ export class AdminPanelResolver {
private featureFlagService: FeatureFlagService,
private readonly twentyConfigService: TwentyConfigService,
private readonly aiModelRegistryService: AiModelRegistryService,
private readonly aiModelPreferencesService: AiModelPreferencesService,
private readonly defaultAiCatalogService: DefaultAiCatalogService,
private readonly modelsDevCatalogService: ModelsDevCatalogService,
private readonly usageAnalyticsService: UsageAnalyticsService,
@@ -263,7 +265,7 @@ export class AdminPanelResolver {
}),
);
const prefs = this.twentyConfigService.get('AI_MODEL_PREFERENCES');
const prefs = this.aiModelPreferencesService.getPreferences();
return {
models,
@@ -44,7 +44,7 @@ import {
} from 'src/engine/core-modules/twenty-config/twenty-config.exception';
import { type AiModelPreferences } from 'src/engine/metadata-modules/ai/ai-models/types/ai-model-preferences.type';
import { type AiProvidersConfig } from 'src/engine/metadata-modules/ai/ai-models/types/ai-providers-config.type';
import { loadDefaultModelPreferences } from 'src/engine/metadata-modules/ai/ai-models/utils/load-default-model-preferences.util';
import { DEFAULT_MODEL_PREFERENCES } from 'src/engine/metadata-modules/ai/ai-models/utils/load-default-model-preferences.util';
export class ConfigVariables {
@ConfigVariablesMetadata({
@@ -1429,7 +1429,16 @@ export class ConfigVariables {
type: ConfigVariableType.JSON,
})
@IsOptional()
AI_MODEL_PREFERENCES: AiModelPreferences = loadDefaultModelPreferences();
AI_MODEL_PREFERENCES: AiModelPreferences = DEFAULT_MODEL_PREFERENCES;
@ConfigVariablesMetadata({
group: ConfigVariablesGroup.LLM,
description:
'Storage path for AI model preferences fallback (e.g. config/ai-model-preferences.json). Loaded at startup and used only when no value is set via AI_MODEL_PREFERENCES env var or the database.',
type: ConfigVariableType.STRING,
})
@IsOptional()
AI_MODEL_PREFERENCES_STORAGE_PATH?: string;
@ConfigVariablesMetadata({
group: ConfigVariablesGroup.SERVER_CONFIG,