From cb941818e53d3bc7689a3f6211115c665238c654 Mon Sep 17 00:00:00 2001 From: JT Date: Sat, 16 Sep 2023 10:57:24 -0700 Subject: [PATCH 1/6] Fix Comfy yaml overrides to not overwrite non-SM data --- .../Models/Packages/ComfyUI.cs | 108 +++++++++++++----- 1 file changed, 79 insertions(+), 29 deletions(-) diff --git a/StabilityMatrix.Core/Models/Packages/ComfyUI.cs b/StabilityMatrix.Core/Models/Packages/ComfyUI.cs index 1c30940be..520d35586 100644 --- a/StabilityMatrix.Core/Models/Packages/ComfyUI.cs +++ b/StabilityMatrix.Core/Models/Packages/ComfyUI.cs @@ -9,8 +9,10 @@ using StabilityMatrix.Core.Processes; using StabilityMatrix.Core.Python; using StabilityMatrix.Core.Services; +using YamlDotNet.RepresentationModel; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; +using YamlDotNet.Serialization.TypeInspectors; namespace StabilityMatrix.Core.Models.Packages; @@ -233,11 +235,6 @@ SharedFolderMethod sharedFolderMethod var extraPathsYamlPath = installDirectory + "extra_model_paths.yaml"; var modelsDir = SettingsManager.ModelsDirectory; - var deserializer = new DeserializerBuilder() - .WithNamingConvention(UnderscoredNamingConvention.Instance) - .IgnoreUnmatchedProperties() - .Build(); - var exists = File.Exists(extraPathsYamlPath); if (!exists) { @@ -245,34 +242,87 @@ SharedFolderMethod sharedFolderMethod File.WriteAllText(extraPathsYamlPath, string.Empty); } var yaml = File.ReadAllText(extraPathsYamlPath); - var comfyModelPaths = - deserializer.Deserialize(yaml) - ?? - // ReSharper disable once NullCoalescingConditionIsAlwaysNotNullAccordingToAPIContract - // cuz it can actually be null lol - new ComfyModelPathsYaml(); - - comfyModelPaths.StabilityMatrix ??= new ComfyModelPathsYaml.SmData(); - comfyModelPaths.StabilityMatrix.Checkpoints = Path.Combine(modelsDir, "StableDiffusion"); - comfyModelPaths.StabilityMatrix.Vae = Path.Combine(modelsDir, "VAE"); - comfyModelPaths.StabilityMatrix.Loras = - $"{Path.Combine(modelsDir, "Lora")}\n" + $"{Path.Combine(modelsDir, "LyCORIS")}"; - comfyModelPaths.StabilityMatrix.UpscaleModels = - $"{Path.Combine(modelsDir, "ESRGAN")}\n" - + $"{Path.Combine(modelsDir, "RealESRGAN")}\n" - + $"{Path.Combine(modelsDir, "SwinIR")}"; - comfyModelPaths.StabilityMatrix.Embeddings = Path.Combine(modelsDir, "TextualInversion"); - comfyModelPaths.StabilityMatrix.Hypernetworks = Path.Combine(modelsDir, "Hypernetwork"); - comfyModelPaths.StabilityMatrix.Controlnet = Path.Combine(modelsDir, "ControlNet"); - comfyModelPaths.StabilityMatrix.Clip = Path.Combine(modelsDir, "CLIP"); - comfyModelPaths.StabilityMatrix.Diffusers = Path.Combine(modelsDir, "Diffusers"); - comfyModelPaths.StabilityMatrix.Gligen = Path.Combine(modelsDir, "GLIGEN"); - comfyModelPaths.StabilityMatrix.VaeApprox = Path.Combine(modelsDir, "ApproxVAE"); + using var sr = new StringReader(yaml); + var yamlStream = new YamlStream(); + yamlStream.Load(sr); + + if (!yamlStream.Documents.Any()) + { + yamlStream.Documents.Add(new YamlDocument(new YamlMappingNode())); + } + + var root = yamlStream.Documents[0].RootNode; + if (root is not YamlMappingNode mappingNode) + { + throw new Exception("Invalid extra_model_paths.yaml"); + } + // check if we have a child called "stability_matrix" + var stabilityMatrixNode = mappingNode.Children.FirstOrDefault( + c => c.Key.ToString() == "stability_matrix" + ); + + if (stabilityMatrixNode.Key != null) + { + if (stabilityMatrixNode.Value is not YamlMappingNode nodeValue) + return Task.CompletedTask; + + nodeValue.Children["checkpoints"] = Path.Combine(modelsDir, "StableDiffusion"); + nodeValue.Children["vae"] = Path.Combine(modelsDir, "VAE"); + nodeValue.Children["loras"] = + $"{Path.Combine(modelsDir, "Lora")}\n" + $"{Path.Combine(modelsDir, "LyCORIS")}"; + nodeValue.Children["upscale_models"] = + $"{Path.Combine(modelsDir, "ESRGAN")}\n" + + $"{Path.Combine(modelsDir, "RealESRGAN")}\n" + + $"{Path.Combine(modelsDir, "SwinIR")}"; + nodeValue.Children["embeddings"] = Path.Combine(modelsDir, "TextualInversion"); + nodeValue.Children["hypernetworks"] = Path.Combine(modelsDir, "Hypernetwork"); + nodeValue.Children["controlnet"] = Path.Combine(modelsDir, "ControlNet"); + nodeValue.Children["clip"] = Path.Combine(modelsDir, "CLIP"); + nodeValue.Children["diffusers"] = Path.Combine(modelsDir, "Diffusers"); + nodeValue.Children["gligen"] = Path.Combine(modelsDir, "GLIGEN"); + nodeValue.Children["vae_approx"] = Path.Combine(modelsDir, "ApproxVAE"); + } + else + { + stabilityMatrixNode = new KeyValuePair( + new YamlScalarNode("stability_matrix"), + new YamlMappingNode + { + { "checkpoints", Path.Combine(modelsDir, "StableDiffusion") }, + { "vae", Path.Combine(modelsDir, "VAE") }, + { + "loras", + $"{Path.Combine(modelsDir, "Lora")}\n{Path.Combine(modelsDir, "LyCORIS")}" + }, + { + "upscale_models", + $"{Path.Combine(modelsDir, "ESRGAN")}\n{Path.Combine(modelsDir, "RealESRGAN")}\n{Path.Combine(modelsDir, "SwinIR")}" + }, + { "embeddings", Path.Combine(modelsDir, "TextualInversion") }, + { "hypernetworks", Path.Combine(modelsDir, "Hypernetwork") }, + { "controlnet", Path.Combine(modelsDir, "ControlNet") }, + { "clip", Path.Combine(modelsDir, "CLIP") }, + { "diffusers", Path.Combine(modelsDir, "Diffusers") }, + { "gligen", Path.Combine(modelsDir, "GLIGEN") }, + { "vae_approx", Path.Combine(modelsDir, "ApproxVAE") } + } + ); + } + + var newRootNode = new YamlMappingNode(); + foreach ( + var child in mappingNode.Children.Where(c => c.Key.ToString() != "stability_matrix") + ) + { + newRootNode.Children.Add(child); + } + + newRootNode.Children.Add(stabilityMatrixNode); var serializer = new SerializerBuilder() .WithNamingConvention(UnderscoredNamingConvention.Instance) .Build(); - var yamlData = serializer.Serialize(comfyModelPaths); + var yamlData = serializer.Serialize(newRootNode); File.WriteAllText(extraPathsYamlPath, yamlData); return Task.CompletedTask; From 230dd0249722060379dbde2a702c24a84d9af46d Mon Sep 17 00:00:00 2001 From: JT Date: Sat, 16 Sep 2023 11:05:03 -0700 Subject: [PATCH 2/6] chagenlog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6633e0a64..c46436162 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ All notable changes to Stability Matrix will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2.0.0.html). +## v2.4.4 +### Fixed +- Fixed ComfyUI extra_model_paths.yaml file being overwritten on each launch + ## v2.4.3 ### Added - Added "--no-download-sd-model" launch argument option for Stable Diffusion Web UI From 1423562c61325800a106b6dc0519f508be5305c0 Mon Sep 17 00:00:00 2001 From: JT Date: Sat, 16 Sep 2023 11:05:35 -0700 Subject: [PATCH 3/6] add issue # to chagenlog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c46436162..1c1c7359a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2 ## v2.4.4 ### Fixed -- Fixed ComfyUI extra_model_paths.yaml file being overwritten on each launch +- Fixed [#130](https://github.com/LykosAI/StabilityMatrix/issues/130) ComfyUI extra_model_paths.yaml file being overwritten on each launch ## v2.4.3 ### Added From 1273af84ba361cfcf4ec7b926d85e48cc3957499 Mon Sep 17 00:00:00 2001 From: JT Date: Sat, 16 Sep 2023 15:20:55 -0700 Subject: [PATCH 4/6] AutoScroll to end & package fixes - Added button for auto-scroll-to-end for package console output - Fixed auto-close dialog not closing on package updates - Fixed missing onConsoleOutput for package updates - Switched Foooocus to branch-only mode --- .../Languages/Resources.Designer.cs | 9 +++++++ .../Languages/Resources.resx | 3 +++ .../ViewModels/LaunchPageViewModel.cs | 24 ++++++++++++++++++- .../PackageInstallProgressItemViewModel.cs | 4 +++- .../Views/LaunchPageView.axaml | 15 +++++++++++- .../IPackageModificationRunner.cs | 1 + .../Models/Packages/BaseGitPackage.cs | 4 ++-- .../Models/Packages/Fooocus.cs | 8 +++---- .../Models/Settings/Settings.cs | 2 ++ 9 files changed, 60 insertions(+), 10 deletions(-) diff --git a/StabilityMatrix.Avalonia/Languages/Resources.Designer.cs b/StabilityMatrix.Avalonia/Languages/Resources.Designer.cs index 81aa8822e..5cbc24b53 100644 --- a/StabilityMatrix.Avalonia/Languages/Resources.Designer.cs +++ b/StabilityMatrix.Avalonia/Languages/Resources.Designer.cs @@ -464,6 +464,15 @@ public static string Label_Appearance { } } + /// + /// Looks up a localized string similar to Automatically scroll to end of console output. + /// + public static string Label_AutoScrollToEnd { + get { + return ResourceManager.GetString("Label_AutoScrollToEnd", resourceCulture); + } + } + /// /// Looks up a localized string similar to Base Model. /// diff --git a/StabilityMatrix.Avalonia/Languages/Resources.resx b/StabilityMatrix.Avalonia/Languages/Resources.resx index 4b09fa284..88399d11f 100644 --- a/StabilityMatrix.Avalonia/Languages/Resources.resx +++ b/StabilityMatrix.Avalonia/Languages/Resources.resx @@ -639,4 +639,7 @@ Branch + + Automatically scroll to end of console output + \ No newline at end of file diff --git a/StabilityMatrix.Avalonia/ViewModels/LaunchPageViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/LaunchPageViewModel.cs index 3905cfe1e..076ef466e 100644 --- a/StabilityMatrix.Avalonia/ViewModels/LaunchPageViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/LaunchPageViewModel.cs @@ -86,6 +86,9 @@ public partial class LaunchPageViewModel : PageViewModelBase, IDisposable, IAsyn [ObservableProperty] private BasePackage? runningPackage; + [ObservableProperty] + private bool autoScrollToEnd; + public virtual BasePackage? SelectedBasePackage => PackageFactory.FindPackageByName(SelectedPackage?.PackageName); @@ -126,6 +129,12 @@ ServiceManager dialogFactory settings => settings.ActiveInstalledPackage ); + settingsManager.RelayPropertyFor( + this, + vm => vm.AutoScrollToEnd, + settings => settings.AutoScrollLaunchConsoleToEnd + ); + EventManager.Instance.PackageLaunchRequested += OnPackageLaunchRequested; EventManager.Instance.OneClickInstallFinished += OnOneClickInstallFinished; EventManager.Instance.InstalledPackagesChanged += OnInstalledPackagesChanged; @@ -161,6 +170,14 @@ private void OnPackageLaunchRequested(object? sender, Guid e) LaunchAsync().SafeFireAndForget(); } + partial void OnAutoScrollToEndChanged(bool value) + { + if (value) + { + EventManager.Instance.OnScrollToBottomRequested(); + } + } + public override void OnLoaded() { // Ensure active package either exists or is null @@ -179,6 +196,7 @@ public override void OnLoaded() // Load active package SelectedPackage = settingsManager.Settings.ActiveInstalledPackage; + AutoScrollToEnd = settingsManager.Settings.AutoScrollLaunchConsoleToEnd; } [RelayCommand] @@ -487,7 +505,11 @@ private void OnProcessExited(object? sender, int exitCode) private void OnProcessOutputReceived(ProcessOutput output) { Console.Post(output); - EventManager.Instance.OnScrollToBottomRequested(); + + if (AutoScrollToEnd) + { + EventManager.Instance.OnScrollToBottomRequested(); + } } private void OnOneClickInstallFinished(object? sender, bool e) diff --git a/StabilityMatrix.Avalonia/ViewModels/Progress/PackageInstallProgressItemViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Progress/PackageInstallProgressItemViewModel.cs index 70dadda1b..7c01a0c41 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Progress/PackageInstallProgressItemViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Progress/PackageInstallProgressItemViewModel.cs @@ -51,7 +51,9 @@ private void PackageModificationRunnerOnProgressChanged(object? sender, Progress if ( e is { Message: not null, Percentage: >= 100 } - && e.Message.Contains("Package Install Complete") + && e.Message.Contains( + packageModificationRunner.ModificationCompleteMessage ?? "Package Install Complete" + ) && Progress.CloseWhenFinished ) { diff --git a/StabilityMatrix.Avalonia/Views/LaunchPageView.axaml b/StabilityMatrix.Avalonia/Views/LaunchPageView.axaml index a1f2e330b..1d5f4ec6d 100644 --- a/StabilityMatrix.Avalonia/Views/LaunchPageView.axaml +++ b/StabilityMatrix.Avalonia/Views/LaunchPageView.axaml @@ -12,6 +12,7 @@ xmlns:vm="clr-namespace:StabilityMatrix.Avalonia.ViewModels" xmlns:system="clr-namespace:System;assembly=System.Runtime" xmlns:lang="clr-namespace:StabilityMatrix.Avalonia.Languages" + xmlns:avalonia="clr-namespace:Projektanker.Icons.Avalonia;assembly=Projektanker.Icons.Avalonia" d:DataContext="{x:Static mocks:DesignData.LaunchPageViewModel}" d:DesignHeight="450" d:DesignWidth="700" @@ -25,7 +26,7 @@ - @@ -145,6 +146,18 @@ + + + + ConsoleOutput { get; } Guid Id { get; } bool ShowDialogOnStart { get; init; } + string? ModificationCompleteMessage { get; init; } } diff --git a/StabilityMatrix.Core/Models/Packages/BaseGitPackage.cs b/StabilityMatrix.Core/Models/Packages/BaseGitPackage.cs index b6d50e189..e88e2d80d 100644 --- a/StabilityMatrix.Core/Models/Packages/BaseGitPackage.cs +++ b/StabilityMatrix.Core/Models/Packages/BaseGitPackage.cs @@ -290,7 +290,7 @@ await DownloadPackage( ) .ConfigureAwait(false); - await InstallPackage(installedPackage.FullPath, torchVersion, progress) + await InstallPackage(installedPackage.FullPath, torchVersion, progress, onConsoleOutput) .ConfigureAwait(false); return new InstalledPackageVersion { InstalledReleaseVersion = latestRelease.TagName }; @@ -312,7 +312,7 @@ await DownloadPackage( progress ) .ConfigureAwait(false); - await InstallPackage(installedPackage.FullPath, torchVersion, progress) + await InstallPackage(installedPackage.FullPath, torchVersion, progress, onConsoleOutput) .ConfigureAwait(false); return new InstalledPackageVersion diff --git a/StabilityMatrix.Core/Models/Packages/Fooocus.cs b/StabilityMatrix.Core/Models/Packages/Fooocus.cs index f5026ff12..c564d3f8a 100644 --- a/StabilityMatrix.Core/Models/Packages/Fooocus.cs +++ b/StabilityMatrix.Core/Models/Packages/Fooocus.cs @@ -85,11 +85,9 @@ IPrerequisiteHelper prerequisiteHelper public override IEnumerable AvailableTorchVersions => new[] { TorchVersion.Cpu, TorchVersion.Cuda, TorchVersion.Rocm }; - public override async Task GetLatestVersion() - { - var release = await GetLatestRelease().ConfigureAwait(false); - return release.TagName!; - } + public override Task GetLatestVersion() => Task.FromResult("main"); + + public override bool ShouldIgnoreReleases => true; public override async Task InstallPackage( string installLocation, diff --git a/StabilityMatrix.Core/Models/Settings/Settings.cs b/StabilityMatrix.Core/Models/Settings/Settings.cs index 4c6edb9a2..d2e667bca 100644 --- a/StabilityMatrix.Core/Models/Settings/Settings.cs +++ b/StabilityMatrix.Core/Models/Settings/Settings.cs @@ -56,6 +56,8 @@ public InstalledPackage? ActiveInstalledPackage public float AnimationScale { get; set; } = 1.0f; + public bool AutoScrollLaunchConsoleToEnd { get; set; } = true; + public void RemoveInstalledPackageAndUpdateActive(InstalledPackage package) { RemoveInstalledPackageAndUpdateActive(package.Id); From c0305c628fede1e0a321dea92b14de543ac4f8ea Mon Sep 17 00:00:00 2001 From: JT Date: Sat, 16 Sep 2023 15:25:25 -0700 Subject: [PATCH 5/6] chagenlog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c1c7359a..8145f5f53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2.0.0.html). ## v2.4.4 +### Added +- Added button to toggle automatic scrolling of console output ### Fixed - Fixed [#130](https://github.com/LykosAI/StabilityMatrix/issues/130) ComfyUI extra_model_paths.yaml file being overwritten on each launch +- Fixed some package updates not showing any console output +- Fixed auto-close of update dialog when package update is complete ## v2.4.3 ### Added From 1db2ca9083fb272974534309fce875cb85aa56fd Mon Sep 17 00:00:00 2001 From: JT Date: Mon, 18 Sep 2023 10:33:46 -0700 Subject: [PATCH 6/6] Catch & display install errors --- .../ViewModels/PackageManagerViewModel.cs | 16 +++++---- .../PackageInstallProgressItemViewModel.cs | 7 ++++ .../IPackageModificationRunner.cs | 1 + .../PackageModificationRunner.cs | 36 ++++++++++++++----- 4 files changed, 46 insertions(+), 14 deletions(-) diff --git a/StabilityMatrix.Avalonia/ViewModels/PackageManagerViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/PackageManagerViewModel.cs index d0044144c..865e998de 100644 --- a/StabilityMatrix.Avalonia/ViewModels/PackageManagerViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/PackageManagerViewModel.cs @@ -143,12 +143,16 @@ public async Task ShowInstallDialog() EventManager.Instance.OnPackageInstallProgressAdded(runner); await runner.ExecuteSteps(steps.ToList()); - EventManager.Instance.OnInstalledPackagesChanged(); - notificationService.Show( - "Package Install Complete", - $"{viewModel.InstallName} installed successfully", - NotificationType.Success - ); + + if (!runner.Failed) + { + EventManager.Instance.OnInstalledPackagesChanged(); + notificationService.Show( + "Package Install Complete", + $"{viewModel.InstallName} installed successfully", + NotificationType.Success + ); + } } } diff --git a/StabilityMatrix.Avalonia/ViewModels/Progress/PackageInstallProgressItemViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Progress/PackageInstallProgressItemViewModel.cs index 7c01a0c41..dc410872a 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Progress/PackageInstallProgressItemViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Progress/PackageInstallProgressItemViewModel.cs @@ -42,6 +42,7 @@ private void PackageModificationRunnerOnProgressChanged(object? sender, Progress Progress.IsIndeterminate = e.IsIndeterminate; Progress.Text = packageModificationRunner.CurrentStep?.ProgressTitle; Name = packageModificationRunner.CurrentStep?.ProgressTitle; + Failed = packageModificationRunner.Failed; if (string.IsNullOrWhiteSpace(e.Message) || e.Message.Contains("Downloading...")) return; @@ -59,6 +60,12 @@ private void PackageModificationRunnerOnProgressChanged(object? sender, Progress { Dispatcher.UIThread.Post(() => dialog?.Hide()); } + + if (Failed) + { + Progress.Text = "Package Modification Failed"; + Name = "Package Modification Failed"; + } } public async Task ShowProgressDialog() diff --git a/StabilityMatrix.Core/Models/PackageModification/IPackageModificationRunner.cs b/StabilityMatrix.Core/Models/PackageModification/IPackageModificationRunner.cs index 81c89e853..6c6f1e9cc 100644 --- a/StabilityMatrix.Core/Models/PackageModification/IPackageModificationRunner.cs +++ b/StabilityMatrix.Core/Models/PackageModification/IPackageModificationRunner.cs @@ -13,4 +13,5 @@ public interface IPackageModificationRunner Guid Id { get; } bool ShowDialogOnStart { get; init; } string? ModificationCompleteMessage { get; init; } + bool Failed { get; set; } } diff --git a/StabilityMatrix.Core/Models/PackageModification/PackageModificationRunner.cs b/StabilityMatrix.Core/Models/PackageModification/PackageModificationRunner.cs index 034bf1d39..c546671e3 100644 --- a/StabilityMatrix.Core/Models/PackageModification/PackageModificationRunner.cs +++ b/StabilityMatrix.Core/Models/PackageModification/PackageModificationRunner.cs @@ -21,16 +21,35 @@ public async Task ExecuteSteps(IReadOnlyList steps) foreach (var step in steps) { CurrentStep = step; - await step.ExecuteAsync(progress).ConfigureAwait(false); + try + { + await step.ExecuteAsync(progress).ConfigureAwait(false); + } + catch (Exception e) + { + progress.Report( + new ProgressReport( + 1f, + title: "Error modifying package", + message: $"Error: {e}", + isIndeterminate: false + ) + ); + Failed = true; + break; + } } - progress.Report( - new ProgressReport( - 1f, - message: ModificationCompleteMessage ?? "Package Install Complete", - isIndeterminate: false - ) - ); + if (!Failed) + { + progress.Report( + new ProgressReport( + 1f, + message: ModificationCompleteMessage ?? "Package Install Complete", + isIndeterminate: false + ) + ); + } IsRunning = false; } @@ -39,6 +58,7 @@ public async Task ExecuteSteps(IReadOnlyList steps) public bool ShowDialogOnStart { get; init; } public bool IsRunning { get; set; } + public bool Failed { get; set; } public ProgressReport CurrentProgress { get; set; } public IPackageStep? CurrentStep { get; set; } public List ConsoleOutput { get; } = new();