diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c5ead4c7..9a54cb91c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,24 @@ 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.13.3 +### Added +- Added Safetensor Metadata viewer to the Checkpoint Manager context menu - thanks to @genteure! +### Changed +- "Remove symbolic links on shutdown" option now also removes links from Output Sharing +### Fixed +- Fixed [#1083](https://github.com/LykosAI/StabilityMatrix/issues/1083) - "Show Nested Models" incorrectly displaying models from some non-nested folders +- Fixed [#1120](https://github.com/LykosAI/StabilityMatrix/issues/1120) - crash when right clicking in the console after restarting a package +- Fixed issue with InvokeAI model sharing when the host address is set to 0.0.0.0 +- Fixed issue when parsing index URLs in Python Dependencies Override menu +- Fixed issue where models were filtered incorrectly in the Checkpoint Manager +- Fixed ComfyUI-Zluda not using the user-defined pip overrides +### Supporters +#### Visionaries +- A heartfelt thank you to our incredible Visionary-tier Patrons, **Waterclouds**, **TheTekknician**, and **Corey**! Your unwavering support means the world to us! +#### Pioneers +- A big shoutout to our outstanding Pioneer-tier Patrons, **tankfox**, **Mr. Unknown**, **Szir777**, and **NowFallenAngel**! We deeply appreciate your ongoing support and dedication! + ## v2.13.2 ### Changed - Removed SimpleSDXL due to security concerns - thanks to @iwr-redmond for the detailed report. For more information please visit https://github.com/LykosAI/StabilityMatrix/security/advisories. diff --git a/StabilityMatrix.Avalonia/App.axaml b/StabilityMatrix.Avalonia/App.axaml index c33e54b55..bbe5bbd2c 100644 --- a/StabilityMatrix.Avalonia/App.axaml +++ b/StabilityMatrix.Avalonia/App.axaml @@ -41,8 +41,6 @@ avares://StabilityMatrix.Avalonia/Assets/Fonts/NotoSansJP#Noto Sans JP - - diff --git a/StabilityMatrix.Avalonia/Assets/openai-white-logomark.png b/StabilityMatrix.Avalonia/Assets/openai-white-logomark.png new file mode 100644 index 000000000..7bb20eb12 Binary files /dev/null and b/StabilityMatrix.Avalonia/Assets/openai-white-logomark.png differ diff --git a/StabilityMatrix.Avalonia/Languages/Resources.Designer.cs b/StabilityMatrix.Avalonia/Languages/Resources.Designer.cs index 4b1fcef91..06f8c8036 100644 --- a/StabilityMatrix.Avalonia/Languages/Resources.Designer.cs +++ b/StabilityMatrix.Avalonia/Languages/Resources.Designer.cs @@ -2640,7 +2640,7 @@ public static string Label_ReleasesUnavailableForThisPackage { } /// - /// Looks up a localized string similar to Remove shared checkpoints directory symbolic links on shutdown. + /// Looks up a localized string similar to Remove shared folder symbolic links on shutdown. /// public static string Label_RemoveSymlinksOnShutdown { get { @@ -2649,7 +2649,7 @@ public static string Label_RemoveSymlinksOnShutdown { } /// - /// Looks up a localized string similar to Select this option if you're having problems moving Stability Matrix to another drive. + /// Looks up a localized string similar to Removes both model and output folder symbolic links when closing Stability Matrix. Select this option if you're having problems moving Stability Matrix to another drive. /// public static string Label_RemoveSymlinksOnShutdown_Details { get { diff --git a/StabilityMatrix.Avalonia/Languages/Resources.resx b/StabilityMatrix.Avalonia/Languages/Resources.resx index 12ccc82fc..9a17d0c9a 100644 --- a/StabilityMatrix.Avalonia/Languages/Resources.resx +++ b/StabilityMatrix.Avalonia/Languages/Resources.resx @@ -418,10 +418,10 @@ Checkpoint Manager - Remove shared checkpoints directory symbolic links on shutdown + Remove shared folder symbolic links on shutdown - Select this option if you're having problems moving Stability Matrix to another drive + Removes both model and output folder symbolic links when closing Stability Matrix. Select this option if you're having problems moving Stability Matrix to another drive Reset Checkpoints Cache diff --git a/StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj b/StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj index 133b2d5fd..280a138de 100644 --- a/StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj +++ b/StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj @@ -150,6 +150,7 @@ + diff --git a/StabilityMatrix.Avalonia/ViewModels/CheckpointsPageViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/CheckpointsPageViewModel.cs index 057d5ba83..af0e59cd8 100644 --- a/StabilityMatrix.Avalonia/ViewModels/CheckpointsPageViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/CheckpointsPageViewModel.cs @@ -1041,8 +1041,9 @@ private bool FilterModels(LocalModelFile file) { if (SelectedCategory?.Path is null || SelectedCategory?.Path == settingsManager.ModelsDirectory) return file.HasConnectedModel - ? SelectedBaseModels.Contains(file.ConnectedModelInfo.BaseModel ?? "Other") - : SelectedBaseModels.Contains("Other"); + ? SelectedBaseModels.Count == 0 + || SelectedBaseModels.Contains(file.ConnectedModelInfo.BaseModel ?? "Other") + : SelectedBaseModels.Count == 0 || SelectedBaseModels.Contains("Other"); var folderPath = Path.GetDirectoryName(file.RelativePath); var categoryRelativePath = SelectedCategory @@ -1056,16 +1057,30 @@ private bool FilterModels(LocalModelFile file) if ( ( file.HasConnectedModel - ? SelectedBaseModels.Contains(file.ConnectedModelInfo?.BaseModel ?? "Other") - : SelectedBaseModels.Contains("Other") + ? SelectedBaseModels.Count == 0 + || SelectedBaseModels.Contains(file.ConnectedModelInfo?.BaseModel ?? "Other") + : SelectedBaseModels.Count == 0 || SelectedBaseModels.Contains("Other") ) is false ) return false; - return ShowModelsInSubfolders - ? folderPath.StartsWith(categoryRelativePath) - : categoryRelativePath.Equals(folderPath); + // If not showing nested models, just check if the file is directly in this folder + if (!ShowModelsInSubfolders) + return categoryRelativePath.Equals(folderPath, StringComparison.OrdinalIgnoreCase); + + // Split paths into segments + var categorySegments = categoryRelativePath.Split(Path.DirectorySeparatorChar); + var folderSegments = folderPath.Split(Path.DirectorySeparatorChar); + + // Check if folder is a subfolder of category by comparing path segments + if (folderSegments.Length < categorySegments.Length) + return false; + + // Compare each segment of the category path with the folder path + return !categorySegments + .Where((t, i) => !t.Equals(folderSegments[i], StringComparison.OrdinalIgnoreCase)) + .Any(); } private bool FilterCategories(CheckpointCategory category) diff --git a/StabilityMatrix.Avalonia/Views/ConsoleOutputPage.axaml b/StabilityMatrix.Avalonia/Views/ConsoleOutputPage.axaml index 9bfd2f760..a834de737 100644 --- a/StabilityMatrix.Avalonia/Views/ConsoleOutputPage.axaml +++ b/StabilityMatrix.Avalonia/Views/ConsoleOutputPage.axaml @@ -115,8 +115,11 @@ + Header="Search with ChatGPT"> + + + + diff --git a/StabilityMatrix.Core/Helper/SharedFolders.cs b/StabilityMatrix.Core/Helper/SharedFolders.cs index 72826285e..d0c5e0679 100644 --- a/StabilityMatrix.Core/Helper/SharedFolders.cs +++ b/StabilityMatrix.Core/Helper/SharedFolders.cs @@ -195,6 +195,12 @@ public void RemoveLinksForAllPackages() .RemoveModelFolderLinks(package.FullPath, sharedFolderMethod) .GetAwaiter() .GetResult(); + + // Remove output folder links if enabled + if (package.UseSharedOutputFolder) + { + basePackage.RemoveOutputFolderLinks(package.FullPath).GetAwaiter().GetResult(); + } } catch (Exception e) { diff --git a/StabilityMatrix.Core/Models/Packages/A3WebUI.cs b/StabilityMatrix.Core/Models/Packages/A3WebUI.cs index f971fe0dc..a6a302e86 100644 --- a/StabilityMatrix.Core/Models/Packages/A3WebUI.cs +++ b/StabilityMatrix.Core/Models/Packages/A3WebUI.cs @@ -39,7 +39,7 @@ IPrerequisiteHelper prerequisiteHelper new("https://github.com/AUTOMATIC1111/stable-diffusion-webui/raw/master/screenshot.png"); public string RelativeArgsDefinitionScriptPath => "modules.cmd_args"; - public override PackageDifficulty InstallerSortOrder => PackageDifficulty.Recommended; + public override PackageDifficulty InstallerSortOrder => PackageDifficulty.Simple; public override SharedFolderMethod RecommendedSharedFolderMethod => SharedFolderMethod.Symlink; diff --git a/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs b/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs index da22c6106..4f3955660 100644 --- a/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs +++ b/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs @@ -71,6 +71,11 @@ await requirements.ReadAllTextAsync(cancellationToken).ConfigureAwait(false), pipArgs = pipArgs.AddArg("numpy==1.26.0"); + if (installedPackage.PipOverrides != null) + { + pipArgs = pipArgs.WithUserOverrides(installedPackage.PipOverrides); + } + progress?.Report( new ProgressReport(-1f, "Installing Package Requirements...", isIndeterminate: true) ); diff --git a/StabilityMatrix.Core/Models/Packages/InvokeAI.cs b/StabilityMatrix.Core/Models/Packages/InvokeAI.cs index 90cd66374..51ca659e5 100644 --- a/StabilityMatrix.Core/Models/Packages/InvokeAI.cs +++ b/StabilityMatrix.Core/Models/Packages/InvokeAI.cs @@ -22,7 +22,7 @@ public class InvokeAI : BaseGitPackage { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private const string RelativeRootPath = "invokeai-root"; - private string RelativeFrontendBuildPath = Path.Combine("invokeai", "frontend", "web", "dist"); + private readonly string relativeFrontendBuildPath = Path.Combine("invokeai", "frontend", "web", "dist"); public override string Name => "InvokeAI"; public override string DisplayName { get; set; } = "InvokeAI"; @@ -35,7 +35,7 @@ public class InvokeAI : BaseGitPackage public override PackageDifficulty InstallerSortOrder => PackageDifficulty.Nightmare; public override IReadOnlyList ExtraLaunchCommands => - new[] { "invokeai-db-maintenance", "invokeai-import-images", }; + ["invokeai-db-maintenance", "invokeai-import-images"]; public override Uri PreviewImageUri => new("https://raw.githubusercontent.com/invoke-ai/InvokeAI/main/docs/assets/canvas_preview.png"); @@ -57,80 +57,50 @@ IPrerequisiteHelper prerequisiteHelper public override Dictionary> SharedFolders => new() { - [SharedFolderType.StableDiffusion] = new[] - { - Path.Combine(RelativeRootPath, "autoimport", "main") - }, - [SharedFolderType.Lora] = new[] { Path.Combine(RelativeRootPath, "autoimport", "lora") }, - [SharedFolderType.TextualInversion] = new[] - { - Path.Combine(RelativeRootPath, "autoimport", "embedding") - }, - [SharedFolderType.ControlNet] = new[] - { - Path.Combine(RelativeRootPath, "autoimport", "controlnet") - }, - [SharedFolderType.InvokeIpAdapters15] = new[] - { + [SharedFolderType.StableDiffusion] = [Path.Combine(RelativeRootPath, "autoimport", "main")], + [SharedFolderType.Lora] = [Path.Combine(RelativeRootPath, "autoimport", "lora")], + [SharedFolderType.TextualInversion] = [Path.Combine(RelativeRootPath, "autoimport", "embedding")], + [SharedFolderType.ControlNet] = [Path.Combine(RelativeRootPath, "autoimport", "controlnet")], + [SharedFolderType.InvokeIpAdapters15] = + [ Path.Combine(RelativeRootPath, "models", "sd-1", "ip_adapter") - }, - [SharedFolderType.InvokeIpAdaptersXl] = new[] - { + ], + [SharedFolderType.InvokeIpAdaptersXl] = + [ Path.Combine(RelativeRootPath, "models", "sdxl", "ip_adapter") - }, - [SharedFolderType.InvokeClipVision] = new[] - { + ], + [SharedFolderType.InvokeClipVision] = + [ Path.Combine(RelativeRootPath, "models", "any", "clip_vision") - }, - [SharedFolderType.T2IAdapter] = new[] - { - Path.Combine(RelativeRootPath, "autoimport", "t2i_adapter") - } + ], + [SharedFolderType.T2IAdapter] = [Path.Combine(RelativeRootPath, "autoimport", "t2i_adapter")] }; public override Dictionary>? SharedOutputFolders => - new() { [SharedOutputType.Text2Img] = new[] { Path.Combine("invokeai-root", "outputs", "images") } }; + new() { [SharedOutputType.Text2Img] = [Path.Combine("invokeai-root", "outputs", "images")] }; public override string OutputFolderName => Path.Combine("invokeai-root", "outputs", "images"); // https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/CONFIGURATION.md public override List LaunchOptions => [ - new LaunchOptionDefinition - { - Name = "Host", - Type = LaunchOptionType.String, - DefaultValue = "localhost", - Options = ["--host"] - }, - new LaunchOptionDefinition + new() { - Name = "Port", + Name = "Root Directory", Type = LaunchOptionType.String, - DefaultValue = "9090", - Options = ["--port"] + Options = ["--root"] }, - new LaunchOptionDefinition + new() { - Name = "Allow Origins", - Description = - "List of host names or IP addresses that are allowed to connect to the " - + "InvokeAI API in the format ['host1','host2',...]", + Name = "Config File", Type = LaunchOptionType.String, - DefaultValue = "[]", - Options = ["--allow-origins"] - }, - new LaunchOptionDefinition - { - Name = "Precision", - Type = LaunchOptionType.Bool, - Options = ["--precision auto", "--precision float16", "--precision float32"] + Options = ["--config"] }, LaunchOptionDefinition.Extras ]; public override IEnumerable AvailableTorchIndices => - new[] { TorchIndex.Cpu, TorchIndex.Cuda, TorchIndex.Rocm, TorchIndex.Mps }; + [TorchIndex.Cpu, TorchIndex.Cuda, TorchIndex.Rocm, TorchIndex.Mps]; public override TorchIndex GetRecommendedTorchVersion() { @@ -325,7 +295,7 @@ private async Task RunInvokeCommand( VenvRunner.UpdateEnvironmentVariables(env => GetEnvVars(env, installedPackagePath)); // fix frontend build missing for people who updated to v3.6 before the fix - var frontendExistsPath = Path.Combine(installedPackagePath, RelativeFrontendBuildPath); + var frontendExistsPath = Path.Combine(installedPackagePath, relativeFrontendBuildPath); if (!Directory.Exists(frontendExistsPath)) { await SetupAndBuildInvokeFrontend( @@ -422,6 +392,11 @@ ProcessOutput s ) { var invokeAiUrl = match.Value; + if (invokeAiUrl.Contains("0.0.0.0")) + { + invokeAiUrl = invokeAiUrl.Replace("0.0.0.0", "127.0.0.1"); + } + var invokeAiApi = RestService.For( invokeAiUrl, new RefitSettings diff --git a/StabilityMatrix.Core/Models/Packages/StableDiffusionDirectMl.cs b/StabilityMatrix.Core/Models/Packages/StableDiffusionDirectMl.cs index 81f3717b5..9428dd284 100644 --- a/StabilityMatrix.Core/Models/Packages/StableDiffusionDirectMl.cs +++ b/StabilityMatrix.Core/Models/Packages/StableDiffusionDirectMl.cs @@ -36,7 +36,7 @@ IPrerequisiteHelper prerequisiteHelper public override TorchIndex GetRecommendedTorchVersion() => HardwareHelper.PreferDirectMLOrZluda() ? TorchIndex.DirectMl : base.GetRecommendedTorchVersion(); - public override PackageDifficulty InstallerSortOrder => PackageDifficulty.Recommended; + public override PackageDifficulty InstallerSortOrder => PackageDifficulty.Simple; public override List LaunchOptions { diff --git a/StabilityMatrix.Core/Python/PipInstallArgs.cs b/StabilityMatrix.Core/Python/PipInstallArgs.cs index bd161efae..915d7ede4 100644 --- a/StabilityMatrix.Core/Python/PipInstallArgs.cs +++ b/StabilityMatrix.Core/Python/PipInstallArgs.cs @@ -65,6 +65,11 @@ public PipInstallArgs WithUserOverrides(List overri if (string.IsNullOrWhiteSpace(pipOverride.Name)) continue; + if (pipOverride.Name is "--extra-index-url" or "--index-url") + { + pipOverride.Constraint = "="; + } + var pipOverrideArg = pipOverride.ToArgument(); if (pipOverride.Action is PipPackageSpecifierOverrideAction.Update)