diff --git a/static/js/managers/SettingsManager.js b/static/js/managers/SettingsManager.js
index 23f53bc9..5a196bed 100644
--- a/static/js/managers/SettingsManager.js
+++ b/static/js/managers/SettingsManager.js
@@ -904,6 +904,9 @@ export class SettingsManager {
// Helper to update model Combobox presets from catalog / Ollama API
const llmModelInput = document.getElementById('llmModel');
this._llmModelCombobox = null;
+ if (llmModelInput) {
+ llmModelInput.value = state.global.settings.llm_model || '';
+ }
if (llmModelInput && typeof Combobox !== 'undefined') {
const currentProvider = llmProviderSelect ? llmProviderSelect.value : 'openai';
const fallbackModels = currentProvider === 'ollama' ? [] : (this._providerModels[currentProvider] || []);
diff --git a/templates/components/modals/settings/_macros.html b/templates/components/modals/settings/_macros.html
new file mode 100644
index 00000000..a2a5ffa4
--- /dev/null
+++ b/templates/components/modals/settings/_macros.html
@@ -0,0 +1,69 @@
+{# Shared building blocks for the settings modal sections. #}
+{# Usage: {% import 'components/modals/settings/_macros.html' as sm with context %} #}
+{# `with context` is required so macros can call the `t()` translation function. #}
+
+{% macro setting_toggle(id, key, label, help='') %}
+
+
+
+
+
+
+ {{ t('common.language.select') }}
+
+
+
+
+
+ {{ t('common.language.english') }}
+ {{ t('common.language.chinese_simplified') }}
+ {{ t('common.language.chinese_traditional') }}
+ {{ t('common.language.russian') }}
+ {{ t('common.language.german') }}
+ {{ t('common.language.japanese') }}
+ {{ t('common.language.korean') }}
+ {{ t('common.language.french') }}
+ {{ t('common.language.spanish') }}
+ {{ t('common.language.Hebrew') }}
+
+
+
+
+
+
+ {{ sm.setting_toggle('usePortableSettings', 'use_portable_settings', 'settings.storage.locationLabel', 'settings.storage.locationHelp') }}
+
+
+
+
+
+ {{ t('settings.civitaiApiKey') }}
+
+
+
+
+
+
+
+ {{ t('settings.civitaiApiKeyNotConfigured') }}
+
+
+ {{ t('settings.civitaiApiKeySet') }}
+
+
+
+
+
+
+
+
+
+
+
{{ t('common.actions.save') }}
+
{{ t('common.actions.cancel') }}
+
+
+
+
+
+ {{ sm.setting_select('civitaiHost', 'civitai_host', 'settings.civitaiHost.label', [
+ ('civitai.com', 'settings.civitaiHost.options.com'),
+ ('civitai.red', 'settings.civitaiHost.options.red'),
+ ], 'settings.civitaiHost.help') }}
+
+
+ {{ sm.subsection_header('settings.sections.downloads') }}
+
+
+
+
{{ t('settings.downloadBackend.label') }}
+
+
+
+
+
+
+
+ {{ t('settings.downloadBackend.options.python') }}
+ {{ t('settings.downloadBackend.options.aria2') }}
+
+
+
+
+
+
+
+ {{ t('settings.aria2cPath.label') }}
+
+
+
+
+
+
+
+
+
+ {{ sm.subsection_header('settings.aiProvider.title') }}
+ {{ sm.setting_select('llmProvider', 'llm_provider', 'settings.aiProvider.provider', [
+ ('openai', 'settings.aiProvider.providerOptions.openai'),
+ ('ollama', 'settings.aiProvider.providerOptions.ollama'),
+ ('deepseek', 'settings.aiProvider.providerOptions.deepseek'),
+ ('groq', 'settings.aiProvider.providerOptions.groq'),
+ ('openrouter', 'settings.aiProvider.providerOptions.openrouter'),
+ ('google', 'settings.aiProvider.providerOptions.google'),
+ ('opencode-go', 'settings.aiProvider.providerOptions.opencode-go'),
+ ('custom', 'settings.aiProvider.providerOptions.custom'),
+ ], 'settings.aiProvider.providerHelp') }}
+
+
+
+ {{ t('settings.aiProvider.apiBase') }}
+
+
+
+
+
+
+
+
+ {{ t('settings.aiProvider.apiKey') }}
+
+
+
+
+
+
+ {{ t('settings.aiProvider.apiKeyNotSet') }}
+
+
+ {{ t('settings.aiProvider.apiKeySet') }}
+
+
+
+
+
+
+
+
+
+
{{ t('common.actions.save') }}
+
{{ t('common.actions.cancel') }}
+
+
+
+
+
+
+
+ {{ t('settings.aiProvider.model') }}
+
+
+
+
+
+
+
+
+
+ {{ sm.subsection_header('settings.sections.backup') }}
+
+ {{ t('settings.backup.scopeHelp') }}
+
+ {{ sm.setting_toggle('backupAutoEnabled', 'backup_auto_enabled', 'settings.backup.autoEnabled', 'settings.backup.autoEnabledHelp') }}
+
+
+
+
+ {{ t('settings.backup.retention') }}
+
+
+
+
+
+
+
+
+
+
+ {{ t('settings.backup.management') }}
+
+
+
+
+
+ {{ t('settings.backup.exportButton') }}
+
+
+ {{ t('settings.backup.importButton') }}
+
+
+
+
+
+
+
+ {{ t('settings.backup.locationSummary') }}
+
+
+
+ {{ t('settings.backup.openFolderButton') }}
+
+
+
+
+
+
+
+
+
+ {{ sm.subsection_header('settings.sections.proxySettings') }}
+ {{ sm.setting_toggle('proxyEnabled', 'proxy_enabled', 'settings.proxySettings.enableProxy', 'settings.proxySettings.enableProxyHelp') }}
+
+
+
+
+
+
+ {{ t('settings.proxySettings.proxyType') }}
+
+
+
+
+
+ HTTP
+ HTTPS
+ SOCKS4
+ SOCKS5
+
+
+
+
+
+ {{ sm.setting_input('proxyHost', 'proxy_host', 'settings.proxySettings.proxyHost', 'settings.proxySettings.proxyHostPlaceholder', 'settings.proxySettings.proxyHostHelp') }}
+
+ {{ sm.setting_input('proxyPort', 'proxy_port', 'settings.proxySettings.proxyPort', 'settings.proxySettings.proxyPortPlaceholder', 'settings.proxySettings.proxyPortHelp') }}
+
+ {{ sm.setting_input('proxyUsername', 'proxy_username', 'settings.proxySettings.proxyUsername', 'settings.proxySettings.proxyUsernamePlaceholder', 'settings.proxySettings.proxyUsernameHelp') }}
+
+
+
+
+
+ {{ t('settings.proxySettings.proxyPassword') }}
+
+
+
+
+
+
+
+
+
diff --git a/templates/components/modals/settings/interface.html b/templates/components/modals/settings/interface.html
new file mode 100644
index 00000000..a8477576
--- /dev/null
+++ b/templates/components/modals/settings/interface.html
@@ -0,0 +1,127 @@
+{% import 'components/modals/settings/_macros.html' as sm with context %}
+
+
+
+
+ {{ sm.subsection_header('settings.sections.contentFiltering') }}
+ {{ sm.setting_toggle('blurMatureContent', 'blur_mature_content', 'settings.contentFiltering.blurNsfwContent', 'settings.contentFiltering.blurNsfwContentHelp') }}
+ {{ sm.setting_toggle('showOnlySFW', 'show_only_sfw', 'settings.contentFiltering.showOnlySfw', 'settings.contentFiltering.showOnlySfwHelp') }}
+ {{ sm.setting_select('matureBlurLevel', 'mature_blur_level', 'settings.contentFiltering.matureBlurThreshold', [
+ ('PG13', 'settings.contentFiltering.matureBlurThresholdOptions.pg13'),
+ ('R', 'settings.contentFiltering.matureBlurThresholdOptions.r'),
+ ('X', 'settings.contentFiltering.matureBlurThresholdOptions.x'),
+ ('XXX', 'settings.contentFiltering.matureBlurThresholdOptions.xxx'),
+ ], 'settings.contentFiltering.matureBlurThresholdHelp') }}
+
+
+
+
+ {{ sm.subsection_header('settings.sections.videoSettings') }}
+ {{ sm.setting_toggle('autoplayOnHover', 'autoplay_on_hover', 'settings.videoSettings.autoplayOnHover', 'settings.videoSettings.autoplayOnHoverHelp') }}
+
+
+
+
+ {{ sm.subsection_header('settings.sections.layoutSettings') }}
+
+
+
+
+ {{ t('settings.layoutSettings.displayDensity') }}
+
+
+
+
+
+ {{ t('settings.layoutSettings.displayDensityOptions.default') }}
+ {{ t('settings.layoutSettings.displayDensityOptions.medium') }}
+ {{ t('settings.layoutSettings.displayDensityOptions.compact') }}
+
+
+
+
+
+
+
+
+
+
+ {{ t('settings.layoutSettings.recipesLayout') }}
+
+
+
+
+
+
+
+ {{ t('settings.layoutSettings.recipesLayoutOptions.grid') }}
+
+
+
+ {{ t('settings.layoutSettings.recipesLayoutOptions.masonry') }}
+
+
+
+
+
+
+ {{ sm.setting_select('modelNameDisplay', 'model_name_display', 'settings.layoutSettings.modelNameDisplay', [
+ ('model_name', 'settings.layoutSettings.modelNameDisplayOptions.modelName'),
+ ('file_name', 'settings.layoutSettings.modelNameDisplayOptions.fileName'),
+ ], 'settings.layoutSettings.modelNameDisplayHelp') }}
+
+
+ {{ sm.setting_toggle('groupByModel', 'group_by_model', 'settings.layoutSettings.groupByModel', 'settings.layoutSettings.groupByModelHelp') }}
+
+ {{ sm.setting_select('cardInfoDisplay', 'card_info_display', 'settings.layoutSettings.cardInfoDisplay', [
+ ('always', 'settings.layoutSettings.cardInfoDisplayOptions.always'),
+ ('hover', 'settings.layoutSettings.cardInfoDisplayOptions.hover'),
+ ], 'settings.layoutSettings.cardInfoDisplayHelp') }}
+
+
+
+
+
+ {{ t('settings.layoutSettings.cardBlurAmount') }}
+
+
+
+
+
+ 8px
+
+
+
+
+ {{ sm.setting_toggle('showVersionOnCard', 'show_version_on_card', 'settings.layoutSettings.showVersionOnCard', 'settings.layoutSettings.showVersionOnCardHelp') }}
+
+ {{ sm.setting_select('modelCardFooterAction', 'model_card_footer_action', 'settings.layoutSettings.modelCardFooterAction', [
+ ('example_images', 'settings.layoutSettings.modelCardFooterActionOptions.exampleImages'),
+ ('replace_preview', 'settings.layoutSettings.modelCardFooterActionOptions.replacePreview'),
+ ], 'settings.layoutSettings.modelCardFooterActionHelp') }}
+
+
+
+
+ {{ sm.subsection_header('settings.sections.licenseIcons') }}
+ {{ sm.setting_toggle('useNewLicenseIcons', 'use_new_license_icons', 'settings.licenseIcons.useNewStyle', 'settings.licenseIcons.useNewStyleHelp') }}
+
+
+
+
+ {{ sm.subsection_header('settings.sections.misc') }}
+ {{ sm.setting_select('loraSyntaxFormat', 'lora_syntax_format', 'settings.misc.loraSyntaxFormat', [
+ ('full', 'settings.misc.loraSyntaxFormatOptions.full'),
+ ('legacy', 'settings.misc.loraSyntaxFormatOptions.legacy'),
+ ], 'settings.misc.loraSyntaxFormatHelp') }}
+ {{ sm.setting_toggle('includeTriggerWords', 'include_trigger_words', 'settings.misc.includeTriggerWords', 'settings.misc.includeTriggerWordsHelp') }}
+
+
diff --git a/templates/components/modals/settings/library.html b/templates/components/modals/settings/library.html
new file mode 100644
index 00000000..a1522790
--- /dev/null
+++ b/templates/components/modals/settings/library.html
@@ -0,0 +1,482 @@
+{% import 'components/modals/settings/_macros.html' as sm with context %}
+{% set template_preset_options = [
+ ('', 'settings.downloadPathTemplates.templateOptions.flatStructure'),
+ ('{base_model}', 'settings.downloadPathTemplates.templateOptions.byBaseModel'),
+ ('{author}', 'settings.downloadPathTemplates.templateOptions.byAuthor'),
+ ('{first_tag}', 'settings.downloadPathTemplates.templateOptions.byFirstTag'),
+ ('{base_model}/{first_tag}', 'settings.downloadPathTemplates.templateOptions.baseModelFirstTag'),
+ ('{base_model}/{author}', 'settings.downloadPathTemplates.templateOptions.baseModelAuthor'),
+ ('{author}/{first_tag}', 'settings.downloadPathTemplates.templateOptions.authorFirstTag'),
+ ('{base_model}/{author}/{first_tag}', 'settings.downloadPathTemplates.templateOptions.baseModelAuthorFirstTag'),
+ ('custom', 'settings.downloadPathTemplates.templateOptions.customTemplate'),
+] %}
+
+
+
+
+ {{ sm.subsection_header('settings.sections.folderSettings') }}
+
+
+
+
+ {{ t('settings.folderSettings.activeLibrary') }}
+
+
+
+
+
+ {{ t('settings.folderSettings.loadingLibraries') }}
+
+
+
+
+
+ {{ sm.setting_select('defaultLoraRoot', 'default_lora_root', 'settings.folderSettings.defaultLoraRoot', [], 'settings.folderSettings.defaultLoraRootHelp') }}
+
+ {{ sm.setting_select('defaultCheckpointRoot', 'default_checkpoint_root', 'settings.folderSettings.defaultCheckpointRoot', [], 'settings.folderSettings.defaultCheckpointRootHelp') }}
+
+ {{ sm.setting_select('defaultUnetRoot', 'default_unet_root', 'settings.folderSettings.defaultUnetRoot', [], 'settings.folderSettings.defaultUnetRootHelp') }}
+
+ {{ sm.setting_select('defaultEmbeddingRoot', 'default_embedding_root', 'settings.folderSettings.defaultEmbeddingRoot', [], 'settings.folderSettings.defaultEmbeddingRootHelp') }}
+
+
+
+
+ {{ sm.subsection_header('settings.sections.recipeSettings') }}
+ {{ sm.setting_input('recipesPath', 'recipes_path', 'settings.folderSettings.recipesPath', 'settings.folderSettings.recipesPathPlaceholder', 'settings.folderSettings.recipesPathHelp') }}
+
+
+
+
+
+
+
+ {{ t('settings.extraFolderPaths.description') }}
+
+
+
+
+
+
+
+ {{ t('settings.extraFolderPaths.modelTypes.lora') }}
+
+
+
+
+ {{ t('common.actions.add') }}
+
+
+
+
+
+
+
+
+
+
+ {{ t('settings.extraFolderPaths.modelTypes.checkpoint') }}
+
+
+
+
+ {{ t('common.actions.add') }}
+
+
+
+
+
+
+
+
+
+
+ {{ t('settings.extraFolderPaths.modelTypes.unet') }}
+
+
+
+
+ {{ t('common.actions.add') }}
+
+
+
+
+
+
+
+
+
+
+ {{ t('settings.extraFolderPaths.modelTypes.embedding') }}
+
+
+
+
+ {{ t('common.actions.add') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('settings.downloadPathTemplates.modelTypes.lora') }}
+
+
+
+ {% for value, option_label in template_preset_options %}
+ {{ t(option_label) }}
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+
+ {{ t('settings.downloadPathTemplates.modelTypes.checkpoint') }}
+
+
+
+ {% for value, option_label in template_preset_options %}
+ {{ t(option_label) }}
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+
+ {{ t('settings.downloadPathTemplates.modelTypes.embedding') }}
+
+
+
+ {% for value, option_label in template_preset_options %}
+ {{ t(option_label) }}
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('settings.downloadPathTemplates.baseModelPathMappings') }}
+
+
+
+
+
+
+ {{ t('settings.downloadPathTemplates.addMapping') }}
+
+
+
+
+
+
+ {{ sm.setting_toggle('skipPreviouslyDownloadedModelVersions', 'skip_previously_downloaded_model_versions', 'settings.skipPreviouslyDownloadedModelVersions.label', 'settings.skipPreviouslyDownloadedModelVersions.help') }}
+
+
+
+
+
+ {{ t('settings.downloadSkipBaseModels.label') }}
+
+
+
+
+
+ {{ t('settings.downloadSkipBaseModels.summary.none') }}
+ {{ t('settings.downloadSkipBaseModels.actions.edit') }}
+
+
+
+
+
+
+
+ {{ t('settings.downloadSkipBaseModels.actions.clear') }}
+
+
+
+
+ {{ t('settings.downloadSkipBaseModels.empty') }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ sm.subsection_header('settings.sections.versionScope') }}
+ {{ sm.setting_select('versionGrouping', 'version_grouping', 'settings.versionGrouping.label', [
+ ('same_base', 'settings.versionGrouping.options.sameBase'),
+ ('any', 'settings.versionGrouping.options.any'),
+ ], 'settings.versionGrouping.help') }}
+ {{ sm.setting_toggle('hideEarlyAccessUpdates', 'hide_early_access_updates', 'settings.hideEarlyAccessUpdates.label', 'settings.hideEarlyAccessUpdates.help') }}
+ {{ sm.setting_toggle('hidePaidUpdates', 'hide_paid_updates', 'settings.hidePaidUpdates.label', 'settings.hidePaidUpdates.help') }}
+
+
+
+
+ {{ sm.subsection_header('settings.sections.exampleImages') }}
+
+
+
+ {{ t('settings.exampleImages.downloadLocation') }}
+
+
+
+
+ {{ t('settings.exampleImages.download') }}
+
+
+
+
+
+ {{ sm.setting_toggle('autoDownloadExampleImages', 'auto_download_example_images', 'settings.exampleImages.autoDownload', 'settings.exampleImages.autoDownloadHelp') }}
+
+ {{ sm.setting_toggle('optimizeExampleImages', 'optimize_example_images', 'settings.exampleImages.optimizeImages', 'settings.exampleImages.optimizeImagesHelp') }}
+
+
+
+
+
+ {{ t('settings.exampleImages.openMode') }}
+
+
+
+
+
+
+
+
+ {{ t('settings.exampleImages.openModeOptions.system') }}
+ {{ t('settings.exampleImages.openModeOptions.clipboard') }}
+ {{ t('settings.exampleImages.openModeOptions.uriTemplate') }}
+
+
+
+
+
+
+
+
+
+ {{ t('settings.exampleImages.localRoot') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('settings.exampleImages.uriTemplate') }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ sm.subsection_header('settings.sections.autoOrganize') }}
+
+
+
+
+
+
+ {{ t('settings.autoOrganizeExclusions.label') }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ sm.subsection_header('settings.sections.metadata') }}
+
+
+
+
+
+
+ {{ t('settings.metadataRefreshSkipPaths.label') }}
+
+
+
+
+
+
+
+
+
+ {{ sm.setting_toggle('enableCivarchiveApi', 'enable_civarchive_api', 'settings.metadataArchive.enableCivarchiveApi', 'settings.metadataArchive.enableCivarchiveApiHelp') }}
+
+
+ {{ sm.setting_toggle('enableMetadataArchive', 'enable_metadata_archive_db', 'settings.metadataArchive.enableArchiveDb', 'settings.metadataArchive.enableArchiveDbHelp') }}
+
+
+
+
+
+
+
+ {{ t('settings.metadataArchive.management') }}
+
+
+
+
+
+ {{ t('settings.metadataArchive.downloadButton') }}
+
+
+ {{ t('settings.metadataArchive.removeButton') }}
+
+
+
+
+
+
+ {{ sm.setting_select('metadataProviderOrder', 'metadata_provider_order', 'settings.metadataArchive.providerOrder', [
+ ('civitai_archive_sqlite', 'settings.metadataArchive.providerOrderCivitaiArchiveSqlite'),
+ ('civitai_sqlite_archive', 'settings.metadataArchive.providerOrderCivitaiSqliteArchive'),
+ ], 'settings.metadataArchive.providerOrderHelp') }}
+
+
diff --git a/templates/components/modals/settings_modal.html b/templates/components/modals/settings_modal.html
index 17a2c6a1..0cbab3df 100644
--- a/templates/components/modals/settings_modal.html
+++ b/templates/components/modals/settings_modal.html
@@ -39,1494 +39,23 @@
-
+
+
+
+
+