From 2af1ef92923de276d7b546bbe06e0fda4eb0d1d2 Mon Sep 17 00:00:00 2001 From: Leonid Pershin Date: Sun, 26 Oct 2025 18:33:33 +0300 Subject: [PATCH] Enhance AIImages mod by adding scheduler support and updating UI for improved model and sampler selection. Localized strings in English and Russian have been updated for clarity. Update AIImages.dll to reflect changes in functionality. --- Assemblies/AIImages.dll | Bin 62464 -> 70144 bytes Languages/English/Keyed/AIImages.xml | 7 + Languages/Russian/Keyed/AIImages.xml | 7 + Source/AIImages/Models/GenerationRequest.cs | 1 + .../Models/StableDiffusionSettings.cs | 2 + .../Services/IStableDiffusionApiService.cs | 5 + .../Services/StableDiffusionApiService.cs | 51 +++ .../AIImages/Settings/AIImagesModSettings.cs | 14 + Source/AIImages/UI/AIImagesSettingsUI.cs | 349 +++++++++++++++--- Source/AIImages/Window_AIImage.cs | 1 + 10 files changed, 376 insertions(+), 61 deletions(-) diff --git a/Assemblies/AIImages.dll b/Assemblies/AIImages.dll index 1045dbbdfb349d94008bf83ad9598f4c118f621d..8b8bc0f28965e82e5a7a7892b2a19fe6228d64fe 100644 GIT binary patch literal 70144 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 literal 62464 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 diff --git a/Languages/English/Keyed/AIImages.xml b/Languages/English/Keyed/AIImages.xml index 28a0bce..3e9adf6 100644 --- a/Languages/English/Keyed/AIImages.xml +++ b/Languages/English/Keyed/AIImages.xml @@ -45,10 +45,16 @@ API Endpoint Test Connection Load Available Models + Model + No model selected + Load models first + Load Samplers & Schedulers Successfully connected to API! Failed to connect to API. Check endpoint and ensure Stable Diffusion WebUI is running. Loaded {0} models from API No models found. Check API connection. + Loaded {0} samplers and {1} schedulers from API + No samplers or schedulers found. Check API connection. Generation Settings Configure image generation parameters Art Style @@ -58,6 +64,7 @@ Width Height Sampler + Schedule Type Prompts Base prompts that will be added to all generations Base Positive Prompt diff --git a/Languages/Russian/Keyed/AIImages.xml b/Languages/Russian/Keyed/AIImages.xml index fcdd1d7..33070b5 100644 --- a/Languages/Russian/Keyed/AIImages.xml +++ b/Languages/Russian/Keyed/AIImages.xml @@ -45,10 +45,16 @@ Адрес API Проверить соединение Загрузить доступные модели + Модель + Модель не выбрана + Сначала загрузите модели + Загрузить сэмплеры и планировщики Успешное подключение к API! Не удалось подключиться к API. Проверьте адрес и убедитесь, что Stable Diffusion WebUI запущен. Загружено {0} моделей из API Модели не найдены. Проверьте подключение к API. + Загружено {0} сэмплеров и {1} планировщиков из API + Сэмплеры и планировщики не найдены. Проверьте подключение к API. Настройки генерации Настройка параметров генерации изображений Художественный стиль @@ -58,6 +64,7 @@ Ширина Высота Сэмплер + Тип планировщика Промпты Базовые промпты, которые будут добавлены ко всем генерациям Базовый позитивный промпт diff --git a/Source/AIImages/Models/GenerationRequest.cs b/Source/AIImages/Models/GenerationRequest.cs index 3843729..057949d 100644 --- a/Source/AIImages/Models/GenerationRequest.cs +++ b/Source/AIImages/Models/GenerationRequest.cs @@ -12,6 +12,7 @@ namespace AIImages.Models public int Width { get; set; } public int Height { get; set; } public string Sampler { get; set; } + public string Scheduler { get; set; } public int Seed { get; set; } public string Model { get; set; } } diff --git a/Source/AIImages/Models/StableDiffusionSettings.cs b/Source/AIImages/Models/StableDiffusionSettings.cs index 634d918..90ffef8 100644 --- a/Source/AIImages/Models/StableDiffusionSettings.cs +++ b/Source/AIImages/Models/StableDiffusionSettings.cs @@ -12,6 +12,7 @@ namespace AIImages.Models public int Width { get; set; } public int Height { get; set; } public string Sampler { get; set; } + public string Scheduler { get; set; } public int Seed { get; set; } public string Model { get; set; } public ArtStyle ArtStyle { get; set; } @@ -24,6 +25,7 @@ namespace AIImages.Models Width = 512; Height = 768; Sampler = "Euler a"; + Scheduler = "Automatic"; Seed = -1; // Случайный seed ArtStyle = ArtStyle.Realistic; PositivePrompt = ""; diff --git a/Source/AIImages/Services/IStableDiffusionApiService.cs b/Source/AIImages/Services/IStableDiffusionApiService.cs index 247175c..3e6617a 100644 --- a/Source/AIImages/Services/IStableDiffusionApiService.cs +++ b/Source/AIImages/Services/IStableDiffusionApiService.cs @@ -28,5 +28,10 @@ namespace AIImages.Services /// Получает список доступных сэмплеров /// Task> GetAvailableSamplers(string apiEndpoint); + + /// + /// Получает список доступных schedulers + /// + Task> GetAvailableSchedulers(string apiEndpoint); } } diff --git a/Source/AIImages/Services/StableDiffusionApiService.cs b/Source/AIImages/Services/StableDiffusionApiService.cs index 34a409a..3bb9373 100644 --- a/Source/AIImages/Services/StableDiffusionApiService.cs +++ b/Source/AIImages/Services/StableDiffusionApiService.cs @@ -50,6 +50,7 @@ namespace AIImages.Services width = request.Width, height = request.Height, sampler_name = request.Sampler, + scheduler = request.Scheduler, seed = request.Seed, save_images = false, send_images = true, @@ -186,6 +187,38 @@ namespace AIImages.Services } } + public async Task> GetAvailableSchedulers(string apiEndpoint) + { + try + { + string endpoint = $"{apiEndpoint}/sdapi/v1/schedulers"; + HttpResponseMessage response = await httpClient.GetAsync(endpoint); + + if (!response.IsSuccessStatusCode) + return GetDefaultSchedulers(); + + string jsonResponse = await response.Content.ReadAsStringAsync(); + var schedulers = JsonConvert.DeserializeObject>(jsonResponse); + + var schedulerNames = new List(); + if (schedulers != null) + { + foreach (var scheduler in schedulers) + { + schedulerNames.Add(scheduler.name); + } + } + + Log.Message($"[AI Images] Found {schedulerNames.Count} schedulers"); + return schedulerNames; + } + catch (Exception ex) + { + Log.Warning($"[AI Images] Failed to load schedulers: {ex.Message}"); + return GetDefaultSchedulers(); + } + } + private List GetDefaultSamplers() { return new List @@ -212,6 +245,19 @@ namespace AIImages.Services }; } + private List GetDefaultSchedulers() + { + return new List + { + "Automatic", + "Uniform", + "Karras", + "Exponential", + "Polyexponential", + "SGM Uniform", + }; + } + // Вспомогательные классы для десериализации JSON ответов #pragma warning disable S3459, S1144 // Properties set by JSON deserializer private sealed class Txt2ImgResponse @@ -229,6 +275,11 @@ namespace AIImages.Services { public string name { get; set; } } + + private sealed class SdScheduler + { + public string name { get; set; } + } #pragma warning restore S3459, S1144 } } diff --git a/Source/AIImages/Settings/AIImagesModSettings.cs b/Source/AIImages/Settings/AIImagesModSettings.cs index 388b62f..e081f14 100644 --- a/Source/AIImages/Settings/AIImagesModSettings.cs +++ b/Source/AIImages/Settings/AIImagesModSettings.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using AIImages.Models; using Verse; @@ -13,6 +14,17 @@ namespace AIImages.Settings public string apiEndpoint = "http://127.0.0.1:7860"; public string selectedModel = ""; public string selectedSampler = "Euler a"; + public string selectedScheduler = "Automatic"; + + // Кэшированные списки из API (не сохраняются) + [Unsaved] + public List availableModels = new List(); + + [Unsaved] + public List availableSamplers = new List(); + + [Unsaved] + public List availableSchedulers = new List(); // Настройки генерации public int steps = 30; @@ -42,6 +54,7 @@ namespace AIImages.Settings Scribe_Values.Look(ref apiEndpoint, "apiEndpoint", "http://127.0.0.1:7860"); Scribe_Values.Look(ref selectedModel, "selectedModel", ""); Scribe_Values.Look(ref selectedSampler, "selectedSampler", "Euler a"); + Scribe_Values.Look(ref selectedScheduler, "selectedScheduler", "Automatic"); Scribe_Values.Look(ref steps, "steps", 30); Scribe_Values.Look(ref cfgScale, "cfgScale", 7.5f); @@ -79,6 +92,7 @@ namespace AIImages.Settings Width = width, Height = height, Sampler = selectedSampler, + Scheduler = selectedScheduler, Seed = seed, Model = selectedModel, ArtStyle = artStyle, diff --git a/Source/AIImages/UI/AIImagesSettingsUI.cs b/Source/AIImages/UI/AIImagesSettingsUI.cs index 6c7cd7f..3efd7c5 100644 --- a/Source/AIImages/UI/AIImagesSettingsUI.cs +++ b/Source/AIImages/UI/AIImagesSettingsUI.cs @@ -21,13 +21,7 @@ namespace AIImages public static void DoSettingsWindowContents(Rect inRect, AIImagesModSettings settings) { - // Инициализируем буферы при первом вызове - if (string.IsNullOrEmpty(stepsBuffer)) - { - stepsBuffer = settings.steps.ToString(); - widthBuffer = settings.width.ToString(); - heightBuffer = settings.height.ToString(); - } + InitializeBuffers(settings); Listing_Standard listingStandard = new Listing_Standard(); Rect viewRect = new Rect(0f, 0f, inRect.width - 20f, 1200f); @@ -35,7 +29,31 @@ namespace AIImages Widgets.BeginScrollView(inRect, ref scrollPosition, viewRect); listingStandard.Begin(viewRect); - // === API Settings === + DrawApiSettings(listingStandard, settings); + DrawGenerationSettings(listingStandard, settings); + DrawSamplerSchedulerSettings(listingStandard, settings); + DrawPromptsSettings(listingStandard, settings); + DrawOptionsSettings(listingStandard, settings); + + listingStandard.End(); + Widgets.EndScrollView(); + } + + private static void InitializeBuffers(AIImagesModSettings settings) + { + if (string.IsNullOrEmpty(stepsBuffer)) + { + stepsBuffer = settings.steps.ToString(); + widthBuffer = settings.width.ToString(); + heightBuffer = settings.height.ToString(); + } + } + + private static void DrawApiSettings( + Listing_Standard listingStandard, + AIImagesModSettings settings + ) + { listingStandard.Label( "AIImages.Settings.ApiSection".Translate(), -1f, @@ -47,21 +65,66 @@ namespace AIImages settings.apiEndpoint = listingStandard.TextEntry(settings.apiEndpoint); listingStandard.Gap(8f); - // Кнопка проверки подключения if (listingStandard.ButtonText("AIImages.Settings.TestConnection".Translate())) { _ = TestApiConnection(settings.apiEndpoint); } - // Кнопка загрузки моделей if (listingStandard.ButtonText("AIImages.Settings.LoadModels".Translate())) { _ = LoadModelsFromApi(settings); } - listingStandard.Gap(12f); + DrawModelDropdown(listingStandard, settings); - // === Generation Settings === + if (listingStandard.ButtonText("AIImages.Settings.LoadSamplersSchedulers".Translate())) + { + _ = LoadSamplersAndSchedulers(settings); + } + + listingStandard.Gap(12f); + } + + private static void DrawModelDropdown( + Listing_Standard listingStandard, + AIImagesModSettings settings + ) + { + if ( + listingStandard.ButtonTextLabeled( + "AIImages.Settings.Model".Translate(), + string.IsNullOrEmpty(settings.selectedModel) + ? "AIImages.Settings.NoModelSelected".Translate() + : settings.selectedModel + ) + ) + { + List modelOptions = new List(); + if (!settings.availableModels.Any()) + { + modelOptions.Add( + new FloatMenuOption("AIImages.Settings.LoadModelsFirst".Translate(), null) + ); + } + else + { + foreach (string model in settings.availableModels) + { + string localModel = model; + modelOptions.Add( + new FloatMenuOption(model, () => settings.selectedModel = localModel) + ); + } + } + Find.WindowStack.Add(new FloatMenu(modelOptions)); + } + } + + private static void DrawGenerationSettings( + Listing_Standard listingStandard, + AIImagesModSettings settings + ) + { listingStandard.Label( "AIImages.Settings.GenerationSection".Translate(), -1f, @@ -69,7 +132,28 @@ namespace AIImages ); listingStandard.GapLine(); - // Art Style + DrawArtStyleDropdown(listingStandard, settings); + listingStandard.Gap(8f); + + listingStandard.Label("AIImages.Settings.Steps".Translate() + $": {settings.steps}"); + settings.steps = (int)listingStandard.Slider(settings.steps, 1, 150); + listingStandard.Gap(8f); + + listingStandard.Label( + "AIImages.Settings.CfgScale".Translate() + $": {settings.cfgScale:F1}" + ); + settings.cfgScale = listingStandard.Slider(settings.cfgScale, 1f, 30f); + listingStandard.Gap(8f); + + DrawSizeSettings(listingStandard, settings); + listingStandard.Gap(12f); + } + + private static void DrawArtStyleDropdown( + Listing_Standard listingStandard, + AIImagesModSettings settings + ) + { if ( listingStandard.ButtonTextLabeled( "AIImages.Settings.ArtStyle".Translate(), @@ -87,22 +171,13 @@ namespace AIImages } Find.WindowStack.Add(new FloatMenu(styleOptions)); } + } - listingStandard.Gap(8f); - - // Steps - listingStandard.Label("AIImages.Settings.Steps".Translate() + $": {settings.steps}"); - settings.steps = (int)listingStandard.Slider(settings.steps, 1, 150); - listingStandard.Gap(8f); - - // CFG Scale - listingStandard.Label( - "AIImages.Settings.CfgScale".Translate() + $": {settings.cfgScale:F1}" - ); - settings.cfgScale = listingStandard.Slider(settings.cfgScale, 1f, 30f); - listingStandard.Gap(8f); - - // Width + private static void DrawSizeSettings( + Listing_Standard listingStandard, + AIImagesModSettings settings + ) + { listingStandard.Label("AIImages.Settings.Width".Translate() + ":"); widthBuffer = listingStandard.TextEntry(widthBuffer); if (int.TryParse(widthBuffer, out int width)) @@ -110,7 +185,6 @@ namespace AIImages settings.width = Mathf.Clamp(width, 64, 2048); } - // Height listingStandard.Label("AIImages.Settings.Height".Translate() + ":"); heightBuffer = listingStandard.TextEntry(heightBuffer); if (int.TryParse(heightBuffer, out int height)) @@ -118,41 +192,119 @@ namespace AIImages settings.height = Mathf.Clamp(height, 64, 2048); } - // Common size presets + DrawSizePresets(listingStandard, settings); + } + + private static void DrawSizePresets( + Listing_Standard listingStandard, + AIImagesModSettings settings + ) + { listingStandard.Gap(4f); - Rect presetRect = listingStandard.GetRect(30f); - if (Widgets.ButtonText(new Rect(presetRect.x, presetRect.y, 80f, 30f), "512x512")) + Rect presetRect1 = listingStandard.GetRect(30f); + DrawPresetButton(presetRect1, 0f, "512x512", 512, 512, settings); + DrawPresetButton(presetRect1, 85f, "512x768", 512, 768, settings); + DrawPresetButton(presetRect1, 170f, "768x768", 768, 768, settings); + + listingStandard.Gap(4f); + Rect presetRect2 = listingStandard.GetRect(30f); + DrawPresetButton(presetRect2, 0f, "896x1152", 896, 1152, settings, 90f); + DrawPresetButton(presetRect2, 95f, "1024x1024", 1024, 1024, settings, 90f); + } + + private static void DrawPresetButton( + Rect rect, + float xOffset, + string label, + int width, + int height, + AIImagesModSettings settings, + float buttonWidth = 80f + ) + { + if (Widgets.ButtonText(new Rect(rect.x + xOffset, rect.y, buttonWidth, 30f), label)) { - settings.width = 512; - settings.height = 512; - widthBuffer = "512"; - heightBuffer = "512"; - } - if (Widgets.ButtonText(new Rect(presetRect.x + 85f, presetRect.y, 80f, 30f), "512x768")) - { - settings.width = 512; - settings.height = 768; - widthBuffer = "512"; - heightBuffer = "768"; + settings.width = width; + settings.height = height; + widthBuffer = width.ToString(); + heightBuffer = height.ToString(); } + } + + private static void DrawSamplerSchedulerSettings( + Listing_Standard listingStandard, + AIImagesModSettings settings + ) + { + DrawSamplerDropdown(listingStandard, settings); + DrawSchedulerDropdown(listingStandard, settings); + listingStandard.Gap(12f); + } + + private static void DrawSamplerDropdown( + Listing_Standard listingStandard, + AIImagesModSettings settings + ) + { if ( - Widgets.ButtonText(new Rect(presetRect.x + 170f, presetRect.y, 80f, 30f), "768x768") + listingStandard.ButtonTextLabeled( + "AIImages.Settings.Sampler".Translate(), + settings.selectedSampler + ) ) { - settings.width = 768; - settings.height = 768; - widthBuffer = "768"; - heightBuffer = "768"; + List samplerOptions = new List(); + var availableSamplers = settings.availableSamplers.Any() + ? settings.availableSamplers + : new List { settings.selectedSampler }; + + foreach (string sampler in availableSamplers) + { + string localSampler = sampler; + samplerOptions.Add( + new FloatMenuOption(sampler, () => settings.selectedSampler = localSampler) + ); + } + Find.WindowStack.Add(new FloatMenu(samplerOptions)); } + } - listingStandard.Gap(12f); + private static void DrawSchedulerDropdown( + Listing_Standard listingStandard, + AIImagesModSettings settings + ) + { + if ( + listingStandard.ButtonTextLabeled( + "AIImages.Settings.Scheduler".Translate(), + settings.selectedScheduler + ) + ) + { + List schedulerOptions = new List(); + var availableSchedulers = settings.availableSchedulers.Any() + ? settings.availableSchedulers + : new List { settings.selectedScheduler }; - // Sampler - listingStandard.Label("AIImages.Settings.Sampler".Translate() + ":"); - settings.selectedSampler = listingStandard.TextEntry(settings.selectedSampler); - listingStandard.Gap(12f); + foreach (string scheduler in availableSchedulers) + { + string localScheduler = scheduler; + schedulerOptions.Add( + new FloatMenuOption( + scheduler, + () => settings.selectedScheduler = localScheduler + ) + ); + } + Find.WindowStack.Add(new FloatMenu(schedulerOptions)); + } + } - // === Prompts === + private static void DrawPromptsSettings( + Listing_Standard listingStandard, + AIImagesModSettings settings + ) + { listingStandard.Label( "AIImages.Settings.PromptsSection".Translate(), -1f, @@ -167,8 +319,13 @@ namespace AIImages listingStandard.Label("AIImages.Settings.BaseNegativePrompt".Translate() + ":"); settings.baseNegativePrompt = listingStandard.TextEntry(settings.baseNegativePrompt, 3); listingStandard.Gap(12f); + } - // === Options === + private static void DrawOptionsSettings( + Listing_Standard listingStandard, + AIImagesModSettings settings + ) + { listingStandard.Label("AIImages.Settings.OptionsSection".Translate()); listingStandard.GapLine(); @@ -187,12 +344,8 @@ namespace AIImages listingStandard.Gap(12f); - // Save path listingStandard.Label("AIImages.Settings.SavePath".Translate() + ":"); settings.savePath = listingStandard.TextEntry(settings.savePath); - - listingStandard.End(); - Widgets.EndScrollView(); } private static async System.Threading.Tasks.Task TestApiConnection(string endpoint) @@ -231,6 +384,7 @@ namespace AIImages { Log.Message("[AI Images] Loading models from API..."); var models = await AIImagesMod.ApiService.GetAvailableModels(settings.apiEndpoint); + settings.availableModels = models; if (models.Count > 0) { @@ -239,8 +393,13 @@ namespace AIImages MessageTypeDefOf.PositiveEvent ); - // Если модель не выбрана, выбираем первую - if (string.IsNullOrEmpty(settings.selectedModel) && models.Count > 0) + if ( + ( + string.IsNullOrEmpty(settings.selectedModel) + || !models.Contains(settings.selectedModel) + ) + && models.Count > 0 + ) { settings.selectedModel = models[0]; } @@ -261,5 +420,73 @@ namespace AIImages ); } } + + private static async System.Threading.Tasks.Task LoadSamplersAndSchedulers( + AIImagesModSettings settings + ) + { + try + { + Log.Message("[AI Images] Loading samplers and schedulers from API..."); + + var samplers = await AIImagesMod.ApiService.GetAvailableSamplers( + settings.apiEndpoint + ); + settings.availableSamplers = samplers; + + var schedulers = await AIImagesMod.ApiService.GetAvailableSchedulers( + settings.apiEndpoint + ); + settings.availableSchedulers = schedulers; + + int totalCount = samplers.Count + schedulers.Count; + if (totalCount > 0) + { + Messages.Message( + "AIImages.Settings.SamplersSchedulersLoaded".Translate( + samplers.Count, + schedulers.Count + ), + MessageTypeDefOf.PositiveEvent + ); + + if ( + ( + string.IsNullOrEmpty(settings.selectedSampler) + || !samplers.Contains(settings.selectedSampler) + ) + && samplers.Count > 0 + ) + { + settings.selectedSampler = samplers[0]; + } + + if ( + ( + string.IsNullOrEmpty(settings.selectedScheduler) + || !schedulers.Contains(settings.selectedScheduler) + ) + && schedulers.Count > 0 + ) + { + settings.selectedScheduler = schedulers[0]; + } + } + else + { + Messages.Message( + "AIImages.Settings.NoSamplersSchedulersFound".Translate(), + MessageTypeDefOf.RejectInput + ); + } + } + catch (Exception ex) + { + Messages.Message( + $"Error loading samplers/schedulers: {ex.Message}", + MessageTypeDefOf.RejectInput + ); + } + } } } diff --git a/Source/AIImages/Window_AIImage.cs b/Source/AIImages/Window_AIImage.cs index 8476fdd..0719248 100644 --- a/Source/AIImages/Window_AIImage.cs +++ b/Source/AIImages/Window_AIImage.cs @@ -131,6 +131,7 @@ namespace AIImages Width = generationSettings.Width, Height = generationSettings.Height, Sampler = generationSettings.Sampler, + Scheduler = generationSettings.Scheduler, Seed = generationSettings.Seed, Model = AIImagesMod.Settings.apiEndpoint, };