From 7c72905f3880574c77e4a2b8b8d2f7469889272c Mon Sep 17 00:00:00 2001 From: Ionite Date: Tue, 14 Oct 2025 13:38:59 -0700 Subject: [PATCH 1/2] Merge pull request #1162 from ionite34/fix-civit (cherry picked from commit 2b6773a08161299068444289de646348fe615140) --- CHANGELOG.md | 4 ++ .../Services/AccountsService.cs | 55 +++++++++++++++---- .../StabilityMatrix.Avalonia.csproj | 2 +- StabilityMatrix.Core/Api/ICivitTRPCApi.cs | 16 +++++- .../Api/CivitTRPC/CivitUserAccountResponse.cs | 25 +++++++++ 5 files changed, 88 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6422762af..e5b84d8b8 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.15.3 +### Fixed +- Fixed [#1424](https://github.com/LykosAI/StabilityMatrix/issues/1424) - Civitai account 401 error when connecting accounts, updated for new API changes + ## v2.15.2 ### Changed - Updated Avalonia to 11.3.7 diff --git a/StabilityMatrix.Avalonia/Services/AccountsService.cs b/StabilityMatrix.Avalonia/Services/AccountsService.cs index 4bd4a61e3..7e38cb517 100644 --- a/StabilityMatrix.Avalonia/Services/AccountsService.cs +++ b/StabilityMatrix.Avalonia/Services/AccountsService.cs @@ -172,8 +172,10 @@ public async Task CivitLoginAsync(string apiToken) var secrets = await secretsManager.SafeLoadAsync(); // Get id first using the api token - var userAccount = await civitTRPCApi.GetUserAccountDefault(apiToken); - var id = userAccount.Result.Data.Json.Id; + var userAccount = await civitTRPCApi.GetUserAccount(bearerToken: apiToken); + var id = + userAccount.InnerJson?.Id + ?? throw new InvalidOperationException("GetUserAccount did not contain an id"); // Then get the username using the id var account = await civitTRPCApi.GetUserById(new CivitGetUserByIdRequest { Id = id }, apiToken); @@ -241,7 +243,7 @@ secrets.LykosAccountV2 is not null { IsConnected = true, Principal = principal, - User = user + User = user, } ); @@ -282,27 +284,55 @@ private async Task RefreshHuggingFaceAsync(Secrets secrets) if (response.IsSuccessStatusCode && response.Content != null) { // Token is valid, user info fetched - logger.LogInformation("Hugging Face token is valid. User: {Username}", response.Content.Name); - OnHuggingFaceAccountStatusUpdate(new HuggingFaceAccountStatusUpdateEventArgs(true, response.Content.Name)); + logger.LogInformation( + "Hugging Face token is valid. User: {Username}", + response.Content.Name + ); + OnHuggingFaceAccountStatusUpdate( + new HuggingFaceAccountStatusUpdateEventArgs(true, response.Content.Name) + ); } else { // Token is likely invalid or other API error - logger.LogWarning("Hugging Face token validation failed. Status: {StatusCode}, Error: {Error}, Content: {Content}", response.StatusCode, response.Error?.ToString(), await response.Error?.GetContentAsAsync() ?? "N/A"); - OnHuggingFaceAccountStatusUpdate(new HuggingFaceAccountStatusUpdateEventArgs(false, null, $"Token validation failed: {response.StatusCode}")); + logger.LogWarning( + "Hugging Face token validation failed. Status: {StatusCode}, Error: {Error}, Content: {Content}", + response.StatusCode, + response.Error?.ToString(), + await response.Error?.GetContentAsAsync() ?? "N/A" + ); + OnHuggingFaceAccountStatusUpdate( + new HuggingFaceAccountStatusUpdateEventArgs( + false, + null, + $"Token validation failed: {response.StatusCode}" + ) + ); } } catch (ApiException apiEx) { // Handle Refit's ApiException (network issues, non-success status codes not caught by IsSuccessStatusCode if IApiResponse isn't used directly) - logger.LogError(apiEx, "Hugging Face API request failed during token validation. Content: {Content}", await apiEx.GetContentAsAsync() ?? "N/A"); - OnHuggingFaceAccountStatusUpdate(new HuggingFaceAccountStatusUpdateEventArgs(false, null, "API request failed during token validation.")); + logger.LogError( + apiEx, + "Hugging Face API request failed during token validation. Content: {Content}", + await apiEx.GetContentAsAsync() ?? "N/A" + ); + OnHuggingFaceAccountStatusUpdate( + new HuggingFaceAccountStatusUpdateEventArgs( + false, + null, + "API request failed during token validation." + ) + ); } catch (Exception ex) { // Handle other unexpected errors logger.LogError(ex, "An unexpected error occurred during Hugging Face token validation."); - OnHuggingFaceAccountStatusUpdate(new HuggingFaceAccountStatusUpdateEventArgs(false, null, "An unexpected error occurred.")); + OnHuggingFaceAccountStatusUpdate( + new HuggingFaceAccountStatusUpdateEventArgs(false, null, "An unexpected error occurred.") + ); } } else @@ -390,7 +420,10 @@ private void OnHuggingFaceAccountStatusUpdate(HuggingFaceAccountStatusUpdateEven else if (e.IsConnected && HuggingFaceStatus?.IsConnected == false) { // Assuming Username might be null for now as we are not fetching it. - logger.LogInformation("Hugging Face account connected" + (string.IsNullOrWhiteSpace(e.Username) ? "" : $" (User: {e.Username})")); + logger.LogInformation( + "Hugging Face account connected" + + (string.IsNullOrWhiteSpace(e.Username) ? "" : $" (User: {e.Username})") + ); } else if (!e.IsConnected && !string.IsNullOrWhiteSpace(e.ErrorMessage)) { diff --git a/StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj b/StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj index dda31a288..b07d45eed 100644 --- a/StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj +++ b/StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj @@ -7,7 +7,7 @@ true true ./Assets/Icon.ico - 2.15.0-dev.999 + 2.16.0-dev.999 $(Version) true true diff --git a/StabilityMatrix.Core/Api/ICivitTRPCApi.cs b/StabilityMatrix.Core/Api/ICivitTRPCApi.cs index 8d51f6f1a..548d47364 100644 --- a/StabilityMatrix.Core/Api/ICivitTRPCApi.cs +++ b/StabilityMatrix.Core/Api/ICivitTRPCApi.cs @@ -20,13 +20,25 @@ Task GetUserProfile( [QueryUriFormat(UriFormat.UriEscaped)] [Get("/api/trpc/buzz.getUserAccount")] - Task> GetUserAccount( + Task> GetUserAccount( [Query] string input, [Authorize] string bearerToken, CancellationToken cancellationToken = default ); - Task> GetUserAccountDefault( + [QueryUriFormat(UriFormat.UriEscaped)] + [Get("/api/trpc/buzz.getUserAccount")] + Task> GetUserAccount( + [Authorize] string bearerToken, + CancellationToken cancellationToken = default + ); + + /// + /// Calls with default JSON input. + /// Not required and returns 401 since Oct 2025 since civit changes. + /// Mainly just use instead. + /// + Task> GetUserAccountDefault( string bearerToken, CancellationToken cancellationToken = default ) diff --git a/StabilityMatrix.Core/Models/Api/CivitTRPC/CivitUserAccountResponse.cs b/StabilityMatrix.Core/Models/Api/CivitTRPC/CivitUserAccountResponse.cs index 3fffd4dca..6a9410d78 100644 --- a/StabilityMatrix.Core/Models/Api/CivitTRPC/CivitUserAccountResponse.cs +++ b/StabilityMatrix.Core/Models/Api/CivitTRPC/CivitUserAccountResponse.cs @@ -21,3 +21,28 @@ public record CivitTrpcResponseDataJson public required TJson Json { get; set; } } } + +/// +/// Like CivitTrpcResponse, but wrapped as the first item of an array. +/// +/// +public record CivitTrpcArrayResponse +{ + [JsonPropertyName("result")] + public required CivitTrpcResponseData Result { get; set; } + + [JsonIgnore] + public T? InnerJson => Result.Data.Json.FirstOrDefault(); + + public record CivitTrpcResponseData + { + [JsonPropertyName("data")] + public required CivitTrpcResponseDataJson Data { get; set; } + } + + public record CivitTrpcResponseDataJson + { + [JsonPropertyName("Json")] + public required List Json { get; set; } + } +} From dd2eef687fb181af82bb26b8b6e0e69702b2f3d0 Mon Sep 17 00:00:00 2001 From: JT Date: Sun, 19 Oct 2025 19:54:52 -0700 Subject: [PATCH 2/2] Merge pull request #1164 from ionite34/moar-fixes Comfy-zluda fixes, use launch scripts for swarm, possibly fix some threading issues in a couple components, and fix wrong destination file name when moving duplicates for model sharing (cherry picked from commit 03d526b416eaa72cee30938ac5c5aaad0f79f626) --- CHANGELOG.md | 13 ++++ .../Helpers/UnixPrerequisiteHelper.cs | 64 +++++++++++++++++++ .../Helpers/WindowsPrerequisiteHelper.cs | 63 ++++++++++++++++++ .../Dialogs/PythonPackagesViewModel.cs | 14 ++-- .../Inference/IImageGalleryComponent.cs | 20 ++++-- StabilityMatrix.Core/Helper/FileTransfers.cs | 15 +++-- .../Helper/IPrerequisiteHelper.cs | 1 + .../InstallSageAttentionStep.cs | 5 ++ .../Models/Packages/ComfyZluda.cs | 9 ++- .../Models/Packages/InvokeAI.cs | 2 +- .../Models/Packages/StableSwarm.cs | 28 ++++---- 11 files changed, 201 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5b84d8b8..964c766d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,21 @@ 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.15.3 +### Changed +- Updated fallback rocm index for InvokeAI to rocm6.3 +- Updated SwarmUI to launch via the launch script for better compatibility ### Fixed +- Fixed cuDNN frontend error on ComfyUI-Zluda startup (thanks @neural_fault!) +- Maybe finally actually fixed threading issue with the Python Packages dialog search box for real this time? (may fix [#1392](https://github.com/LykosAI/StabilityMatrix/issues/1392)) +- Fixed potential install failures when moving duplicate files into shared model folders (may fix [#1393](https://github.com/LykosAI/StabilityMatrix/issues/1393)) +- Fixed potential threading issues with the Inference image gallery (may fix [#1408](https://github.com/LykosAI/StabilityMatrix/issues/1408)) - Fixed [#1424](https://github.com/LykosAI/StabilityMatrix/issues/1424) - Civitai account 401 error when connecting accounts, updated for new API changes +### Supporters +#### 🌟 Visionaries +Our deepest gratitude to our Visionaries for their foundational support: **Waterclouds**, **JungleDragon**, **bluepopsicle**, **Bob S**, and **whudunit**! Your commitment allows us to focus on the essential work of squashing bugs and improving stability, ensuring a rock-solid experience for everyone. +#### 🚀 Pioneers +A huge thank you to our incredible Pioneers for keeping the project on track! Your support is vital for these important refinement updates. Thank you to **Szir777**, **Noah M**, **USATechDude**, **Thom**, **SeraphOfSalem**, **Desert Viber**, **Tundra Everquill**, **Adam**, **Droolguy**, **Philip R.**, **ACTUALLY_the_Real_Willem_Dafoe**, **takyamtom**, and a warm welcome to our newest Pioneer, **robek**! + ## v2.15.2 ### Changed diff --git a/StabilityMatrix.Avalonia/Helpers/UnixPrerequisiteHelper.cs b/StabilityMatrix.Avalonia/Helpers/UnixPrerequisiteHelper.cs index d3369988a..b70175ee2 100644 --- a/StabilityMatrix.Avalonia/Helpers/UnixPrerequisiteHelper.cs +++ b/StabilityMatrix.Avalonia/Helpers/UnixPrerequisiteHelper.cs @@ -12,6 +12,7 @@ using StabilityMatrix.Avalonia.Languages; using StabilityMatrix.Core.Exceptions; using StabilityMatrix.Core.Helper; +using StabilityMatrix.Core.Helper.HardwareInfo; using StabilityMatrix.Core.Models; using StabilityMatrix.Core.Models.FileInterfaces; using StabilityMatrix.Core.Models.Packages; @@ -696,6 +697,69 @@ public async Task InstallUvIfNecessary(IProgress? progress = nul File.Delete(UvDownloadPath); } + public string? GetGfxArchFromAmdGpuName() + { + var gpu = + settingsManager.Settings.PreferredGpu + ?? HardwareHelper.IterGpuInfo().FirstOrDefault(x => x is { Name: not null, IsAmd: true }); + + if (gpu?.Name is null || !gpu.IsAmd) + return null; + + // Normalize for safer substring checks (handles RX7800 vs RX 7800, etc.) + var name = gpu.Name; + var nameNoSpaces = name.Replace(" ", "", StringComparison.Ordinal); + + return name switch + { + // RDNA4 + _ when Has("9060") || Has("9070") => "gfx1201", + + // RDNA3.5 APUs + _ when Has("860M") => "gfx1152", + _ when Has("890M") => "gfx1150", + _ when Has("8040S") || Has("8050S") || Has("8060S") || Has("880M") || Has("Z2 Extreme") => + "gfx1151", + + // RDNA3 APUs (Phoenix) + _ when Has("740M") || Has("760M") || Has("780M") || Has("Z1") || Has("Z2") => "gfx1103", + + // RDNA3 dGPU Navi33 + _ when Has("7400") || Has("7500") || Has("7600") || Has("7650") || Has("7700S") => "gfx1102", + + // RDNA3 dGPU Navi32 + _ when Has("7700") || Has("RX 7800") || HasNoSpace("RX7800") => "gfx1101", + + // RDNA3 dGPU Navi31 (incl. Pro) + _ when Has("W7800") || Has("7900") || Has("7950") || Has("7990") => "gfx1100", + + // RDNA2 APUs (Rembrandt) + _ when Has("660M") || Has("680M") => "gfx1035", + + // RDNA2 Navi24 low-end (incl. some mobiles) + _ when Has("6300") || Has("6400") || Has("6450") || Has("6500") || Has("6550") || Has("6500M") => + "gfx1034", + + // RDNA2 Navi23 + _ when Has("6600") || Has("6650") || Has("6700S") || Has("6800S") || Has("6600M") => "gfx1032", + + // RDNA2 Navi22 (note: desktop 6800 is NOT here; that’s Navi21/gfx1030) + _ when Has("6700") || Has("6750") || Has("6800M") || Has("6850M") => "gfx1031", + + // RDNA2 Navi21 (big die) + _ when Has("6800") || Has("6900") || Has("6950") => "gfx1030", + + _ => null, + }; + + bool HasNoSpace(string s) => + nameNoSpaces.Contains( + s.Replace(" ", "", StringComparison.Ordinal), + StringComparison.OrdinalIgnoreCase + ); + bool Has(string s) => name.Contains(s, StringComparison.OrdinalIgnoreCase); + } + private async Task DownloadAndExtractPrerequisite( IProgress? progress, string downloadUrl, diff --git a/StabilityMatrix.Avalonia/Helpers/WindowsPrerequisiteHelper.cs b/StabilityMatrix.Avalonia/Helpers/WindowsPrerequisiteHelper.cs index ed16218c1..db647119f 100644 --- a/StabilityMatrix.Avalonia/Helpers/WindowsPrerequisiteHelper.cs +++ b/StabilityMatrix.Avalonia/Helpers/WindowsPrerequisiteHelper.cs @@ -921,6 +921,69 @@ public async Task AddMissingLibsToVenv( // await downloadPath.DeleteAsync(); } + public string? GetGfxArchFromAmdGpuName() + { + var gpu = + settingsManager.Settings.PreferredGpu + ?? HardwareHelper.IterGpuInfo().FirstOrDefault(x => x is { Name: not null, IsAmd: true }); + + if (gpu?.Name is null || !gpu.IsAmd) + return null; + + // Normalize for safer substring checks (handles RX7800 vs RX 7800, etc.) + var name = gpu.Name; + var nameNoSpaces = name.Replace(" ", "", StringComparison.Ordinal); + + return name switch + { + // RDNA4 + _ when Has("9060") || Has("9070") => "gfx1201", + + // RDNA3.5 APUs + _ when Has("860M") => "gfx1152", + _ when Has("890M") => "gfx1150", + _ when Has("8040S") || Has("8050S") || Has("8060S") || Has("880M") || Has("Z2 Extreme") => + "gfx1151", + + // RDNA3 APUs (Phoenix) + _ when Has("740M") || Has("760M") || Has("780M") || Has("Z1") || Has("Z2") => "gfx1103", + + // RDNA3 dGPU Navi33 + _ when Has("7400") || Has("7500") || Has("7600") || Has("7650") || Has("7700S") => "gfx1102", + + // RDNA3 dGPU Navi32 + _ when Has("7700") || Has("RX 7800") || HasNoSpace("RX7800") => "gfx1101", + + // RDNA3 dGPU Navi31 (incl. Pro) + _ when Has("W7800") || Has("7900") || Has("7950") || Has("7990") => "gfx1100", + + // RDNA2 APUs (Rembrandt) + _ when Has("660M") || Has("680M") => "gfx1035", + + // RDNA2 Navi24 low-end (incl. some mobiles) + _ when Has("6300") || Has("6400") || Has("6450") || Has("6500") || Has("6550") || Has("6500M") => + "gfx1034", + + // RDNA2 Navi23 + _ when Has("6600") || Has("6650") || Has("6700S") || Has("6800S") || Has("6600M") => "gfx1032", + + // RDNA2 Navi22 (note: desktop 6800 is NOT here; that’s Navi21/gfx1030) + _ when Has("6700") || Has("6750") || Has("6800M") || Has("6850M") => "gfx1031", + + // RDNA2 Navi21 (big die) + _ when Has("6800") || Has("6900") || Has("6950") => "gfx1030", + + _ => null, + }; + + bool HasNoSpace(string s) => + nameNoSpaces.Contains( + s.Replace(" ", "", StringComparison.Ordinal), + StringComparison.OrdinalIgnoreCase + ); + bool Has(string s) => name.Contains(s, StringComparison.OrdinalIgnoreCase); + } + private async Task DownloadAndExtractPrerequisite( IProgress? progress, string downloadUrl, diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/PythonPackagesViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/PythonPackagesViewModel.cs index 81bf8e256..3d19f6a2a 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/PythonPackagesViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/PythonPackagesViewModel.cs @@ -68,6 +68,7 @@ private void PostConstruct() var searchPredicate = this.WhenPropertyChanged(vm => vm.SearchQuery) .Throttle(TimeSpan.FromMilliseconds(100)) .DistinctUntilChanged() + .ObserveOn(SynchronizationContext.Current!) .Select(value => { if (string.IsNullOrWhiteSpace(value.Value)) @@ -86,8 +87,8 @@ private void PostConstruct() .Filter(searchPredicate) .Transform(p => new PythonPackagesItemViewModel(settingsManager) { Package = p }) .SortBy(vm => vm.Package.Name) - .Bind(Packages) .ObserveOn(SynchronizationContext.Current!) + .Bind(Packages) .Subscribe(); } @@ -120,10 +121,14 @@ await pyInstallationManager.GetInstallationAsync( var packages = await venvRunner.PipList(); - packageSource.EditDiff(packages); + Dispatcher.UIThread.Post(() => + { + var currentName = SelectedPackage?.Package.Name; + SelectedPackage = null; - // Delay a bit to prevent thread issues with UI list - await Task.Delay(100); + packageSource.EditDiff(packages); + SelectedPackage = Packages.FirstOrDefault(p => p.Package.Name == currentName); + }); } } finally @@ -155,6 +160,7 @@ await pyInstallationManager.GetInstallationAsync( { // Backup selected package var currentPackageName = SelectedPackage?.Package.Name; + SelectedPackage = null; packageSource.EditDiff(packages); diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/IImageGalleryComponent.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/IImageGalleryComponent.cs index 65f9fa0a8..7aefa10b3 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/IImageGalleryComponent.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/IImageGalleryComponent.cs @@ -1,4 +1,5 @@ using System.Linq; +using Avalonia.Threading; using StabilityMatrix.Avalonia.Models; namespace StabilityMatrix.Avalonia.ViewModels.Inference; @@ -12,13 +13,20 @@ public interface IImageGalleryComponent /// public void LoadImagesToGallery(params ImageSource[] imageSources) { - ImageGalleryCardViewModel.ImageSources.Clear(); - - foreach (var imageSource in imageSources) + Dispatcher.UIThread.Post(() => { - ImageGalleryCardViewModel.ImageSources.Add(imageSource); - } + ImageGalleryCardViewModel.SelectedImage = null; + ImageGalleryCardViewModel.SelectedImageIndex = -1; + + ImageGalleryCardViewModel.ImageSources.Clear(); + + foreach (var imageSource in imageSources) + { + ImageGalleryCardViewModel.ImageSources.Add(imageSource); + } - ImageGalleryCardViewModel.SelectedImage = imageSources.FirstOrDefault(); + ImageGalleryCardViewModel.SelectedImageIndex = imageSources.Length > 0 ? 0 : -1; + ImageGalleryCardViewModel.SelectedImage = imageSources.FirstOrDefault(); + }); } } diff --git a/StabilityMatrix.Core/Helper/FileTransfers.cs b/StabilityMatrix.Core/Helper/FileTransfers.cs index 1f254e4d5..737260b87 100644 --- a/StabilityMatrix.Core/Helper/FileTransfers.cs +++ b/StabilityMatrix.Core/Helper/FileTransfers.cs @@ -24,7 +24,7 @@ public static ulong GetBufferSize(ulong totalBytes) => < 100 * Size.MiB => 16 * Size.KiB, < 500 * Size.MiB => Size.MiB, < Size.GiB => 16 * Size.MiB, - _ => 32 * Size.MiB + _ => 32 * Size.MiB, }; /// @@ -234,12 +234,15 @@ public static async Task MoveFileAsync( // append a number to the file name until it doesn't exist for (var i = 0; i < 100; i++) { - if (!destinationFile.Exists) + var destDir = destinationFile.Directory; + var baseName = destinationFile.NameWithoutExtension; + var ext = destinationFile.Extension; + var candidate = destDir?.JoinFile($"{baseName} ({i}){ext}"); + if (candidate?.Exists is false) + { + destinationFile = candidate; break; - - destinationFile = new FilePath( - destinationFile.NameWithoutExtension + $" ({i})" + destinationFile.Extension - ); + } } } else if (!overwrite) diff --git a/StabilityMatrix.Core/Helper/IPrerequisiteHelper.cs b/StabilityMatrix.Core/Helper/IPrerequisiteHelper.cs index a99a525a2..27f15f7fd 100644 --- a/StabilityMatrix.Core/Helper/IPrerequisiteHelper.cs +++ b/StabilityMatrix.Core/Helper/IPrerequisiteHelper.cs @@ -297,4 +297,5 @@ Task AddMissingLibsToVenv( Task InstallPythonIfNecessary(PyVersion version, IProgress? progress = null); Task InstallVirtualenvIfNecessary(PyVersion version, IProgress? progress = null); Task InstallTkinterIfNecessary(PyVersion version, IProgress? progress = null); + string? GetGfxArchFromAmdGpuName(); } diff --git a/StabilityMatrix.Core/Models/PackageModification/InstallSageAttentionStep.cs b/StabilityMatrix.Core/Models/PackageModification/InstallSageAttentionStep.cs index 723f1afba..6577d2208 100644 --- a/StabilityMatrix.Core/Models/PackageModification/InstallSageAttentionStep.cs +++ b/StabilityMatrix.Core/Models/PackageModification/InstallSageAttentionStep.cs @@ -94,6 +94,11 @@ await pyInstallationManager.GetInstallationAsync(pyVersion).ConfigureAwait(false sageWheelUrl = "https://github.com/woct0rdho/SageAttention/releases/download/v2.2.0-windows.post3/sageattention-2.2.0+cu128torch2.9.0.post3-cp39-abi3-win_amd64.whl"; } + else if (torchInfo.Version.Contains("2.9.0") && torchInfo.Version.Contains("cu130")) + { + sageWheelUrl = + "https://github.com/woct0rdho/SageAttention/releases/download/v2.2.0-windows.post3/sageattention-2.2.0+cu130torch2.9.0.post3-cp39-abi3-win_amd64.whl"; + } var pipArgs = new PipInstallArgs("triton-windows"); diff --git a/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs b/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs index 9fbe88721..72911e1d7 100644 --- a/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs +++ b/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs @@ -201,7 +201,6 @@ private Dictionary GetEnvVars(bool isInstall) ["HIP_PATH_64"] = hipPath, ["GIT"] = portableGitBin.JoinFile("git.exe"), }; - envVars.Update(settingsManager.Settings.EnvironmentVariables); if (envVars.TryGetValue("PATH", out var pathValue)) { @@ -219,6 +218,14 @@ private Dictionary GetEnvVars(bool isInstall) envVars["MIOPEN_FIND_MODE"] = "2"; envVars["MIOPEN_LOG_LEVEL"] = "3"; + var gfxArch = PrerequisiteHelper.GetGfxArchFromAmdGpuName(); + if (!string.IsNullOrWhiteSpace(gfxArch)) + { + envVars["TRITON_OVERRIDE_ARCH"] = gfxArch; + } + + envVars.Update(settingsManager.Settings.EnvironmentVariables); + return envVars; } } diff --git a/StabilityMatrix.Core/Models/Packages/InvokeAI.cs b/StabilityMatrix.Core/Models/Packages/InvokeAI.cs index d61b15c37..ed7ac4846 100644 --- a/StabilityMatrix.Core/Models/Packages/InvokeAI.cs +++ b/StabilityMatrix.Core/Models/Packages/InvokeAI.cs @@ -215,7 +215,7 @@ public override async Task InstallPackage( TorchIndex.Cpu when Compat.IsLinux => "https://download.pytorch.org/whl/cpu", TorchIndex.Cuda when isLegacyNvidiaGpu => "https://download.pytorch.org/whl/cu126", TorchIndex.Cuda => "https://download.pytorch.org/whl/cu128", - TorchIndex.Rocm => "https://download.pytorch.org/whl/rocm6.2.4", + TorchIndex.Rocm => "https://download.pytorch.org/whl/rocm6.3", _ => string.Empty, }; diff --git a/StabilityMatrix.Core/Models/Packages/StableSwarm.cs b/StabilityMatrix.Core/Models/Packages/StableSwarm.cs index 5ccdc21f7..4ba902a7a 100644 --- a/StabilityMatrix.Core/Models/Packages/StableSwarm.cs +++ b/StabilityMatrix.Core/Models/Packages/StableSwarm.cs @@ -432,22 +432,20 @@ await Helper ); } - var releaseFolder = Path.Combine(installLocation, "src", "bin", "live_release"); - var dllName = "StableSwarmUI.dll"; - if (File.Exists(Path.Combine(releaseFolder, "SwarmUI.dll"))) - { - dllName = "SwarmUI.dll"; - } + var launchScriptPath = Path.Combine( + installLocation, + Compat.IsWindows ? "launch-windows.bat" + : Compat.IsMacOS ? "launch-macos.sh" + : "launch-linux.sh" + ); - dotnetProcess = await prerequisiteHelper - .RunDotnet( - args: [Path.Combine(releaseFolder, dllName), .. options.Arguments], - workingDirectory: installLocation, - envVars: aspEnvVars, - onProcessOutput: HandleConsoleOutput, - waitForExit: false - ) - .ConfigureAwait(false); + dotnetProcess = ProcessRunner.StartAnsiProcess( + launchScriptPath, + options.Arguments, + installLocation, + HandleConsoleOutput, + aspEnvVars + ); } public override async Task CheckForUpdates(InstalledPackage package)