From 22c0aa07eef4e4e5cb58818c5794e52bbb6ac569 Mon Sep 17 00:00:00 2001 From: NeuralFault Date: Tue, 30 Dec 2025 19:56:34 -0500 Subject: [PATCH 01/29] Fix updating appimage on Linux via self-created bash script --- .../ViewModels/Dialogs/UpdateViewModel.cs | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs index 40131ee01..31820bfd9 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs @@ -162,6 +162,51 @@ await updateHelper.DownloadUpdate( ); } + // Handle Linux AppImage update + if (Compat.IsLinux && Environment.GetEnvironmentVariable("APPIMAGE") is { } appImage) + { + var updateScriptPath = UpdateHelper.UpdateFolder.JoinFile("update_script.sh").FullPath; + var newAppImage = UpdateHelper.ExecutablePath.FullPath; + + var scriptContent = $""" +#!/bin/bash +PID={Environment.ProcessId} +NEW_APPIMAGE="{newAppImage.Replace("\"", "\\\"")}" +OLD_APPIMAGE="{appImage.Replace("\"", "\\\"")}" + +# Wait for the process to exit +while kill -0 "$PID" 2>/dev/null; do + sleep 0.5 +done + +# Move the new AppImage over the old one +mv -f "$NEW_APPIMAGE" "$OLD_APPIMAGE" +chmod +x "$OLD_APPIMAGE" + +# Launch the new AppImage +"$OLD_APPIMAGE" & +"""; + await File.WriteAllTextAsync(updateScriptPath, scriptContent); + + File.SetUnixFileMode( + updateScriptPath, + UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute + ); + + System.Diagnostics.Process.Start( + new System.Diagnostics.ProcessStartInfo + { + FileName = "/bin/bash", + Arguments = updateScriptPath, + UseShellExecute = false, + CreateNoWindow = true, + } + ); + + App.Shutdown(); + return; + } + // Set current version for update messages settingsManager.Transaction( s => s.UpdatingFromVersion = Compat.AppVersion, From 4c4a10fe4ccf6daaea9262ee16af4befbee3bdf4 Mon Sep 17 00:00:00 2001 From: NeuralFault Date: Tue, 30 Dec 2025 22:23:30 -0500 Subject: [PATCH 02/29] Enhance Linux AppImage update process with error handling and user feedback --- .../ViewModels/Dialogs/UpdateViewModel.cs | 59 ++++++++++++------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs index 31820bfd9..f798e14de 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs @@ -165,10 +165,12 @@ await updateHelper.DownloadUpdate( // Handle Linux AppImage update if (Compat.IsLinux && Environment.GetEnvironmentVariable("APPIMAGE") is { } appImage) { - var updateScriptPath = UpdateHelper.UpdateFolder.JoinFile("update_script.sh").FullPath; - var newAppImage = UpdateHelper.ExecutablePath.FullPath; + try + { + var updateScriptPath = UpdateHelper.UpdateFolder.JoinFile("update_script.sh").FullPath; + var newAppImage = UpdateHelper.ExecutablePath.FullPath; - var scriptContent = $""" + var scriptContent = $""" #!/bin/bash PID={Environment.ProcessId} NEW_APPIMAGE="{newAppImage.Replace("\"", "\\\"")}" @@ -183,28 +185,41 @@ sleep 0.5 mv -f "$NEW_APPIMAGE" "$OLD_APPIMAGE" chmod +x "$OLD_APPIMAGE" -# Launch the new AppImage -"$OLD_APPIMAGE" & +# Launch the new AppImage detached +"$OLD_APPIMAGE" > /dev/null 2>&1 & +disown """; - await File.WriteAllTextAsync(updateScriptPath, scriptContent); + await File.WriteAllTextAsync(updateScriptPath, scriptContent); + + File.SetUnixFileMode( + updateScriptPath, + UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute + ); + + System.Diagnostics.Process.Start( + new System.Diagnostics.ProcessStartInfo + { + FileName = "/usr/bin/env", + Arguments = $"bash \"{updateScriptPath}\"", + UseShellExecute = false, + CreateNoWindow = true, + } + ); + + App.Shutdown(); + return; + } + catch (Exception ex) + { + logger.LogError(ex, "Failed to execute AppImage update script"); - File.SetUnixFileMode( - updateScriptPath, - UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute - ); + var dialog = DialogHelper.CreateMarkdownDialog( + "AppImage update script failed. \nCould not replace old AppImage with new version. Please check directory permissions. \nFalling back to standard update process. User intervention required: After program closes, \nplease move the new AppImage extracted in the '.StabilityMatrixUpdate' hidden directory to the old AppImage overwriting it. \n\nClose this dialog to continue with standard update process.", + Resources.Label_UnexpectedErrorOccurred + ); - System.Diagnostics.Process.Start( - new System.Diagnostics.ProcessStartInfo - { - FileName = "/bin/bash", - Arguments = updateScriptPath, - UseShellExecute = false, - CreateNoWindow = true, - } - ); - - App.Shutdown(); - return; + await dialog.ShowAsync(); + } } // Set current version for update messages From 84f508578675d64d16e20e32484b08bc727e48a4 Mon Sep 17 00:00:00 2001 From: NeuralFault Date: Tue, 30 Dec 2025 22:49:19 -0500 Subject: [PATCH 03/29] Refactor AppImage update script execution to improve environment variable handling and error messaging --- .../ViewModels/Dialogs/UpdateViewModel.cs | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs index f798e14de..5635e75e3 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs @@ -170,11 +170,9 @@ await updateHelper.DownloadUpdate( var updateScriptPath = UpdateHelper.UpdateFolder.JoinFile("update_script.sh").FullPath; var newAppImage = UpdateHelper.ExecutablePath.FullPath; - var scriptContent = $""" + var scriptContent = """ #!/bin/bash -PID={Environment.ProcessId} -NEW_APPIMAGE="{newAppImage.Replace("\"", "\\\"")}" -OLD_APPIMAGE="{appImage.Replace("\"", "\\\"")}" +set -e # Wait for the process to exit while kill -0 "$PID" 2>/dev/null; do @@ -196,15 +194,19 @@ sleep 0.5 UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute ); - System.Diagnostics.Process.Start( - new System.Diagnostics.ProcessStartInfo - { - FileName = "/usr/bin/env", - Arguments = $"bash \"{updateScriptPath}\"", - UseShellExecute = false, - CreateNoWindow = true, - } - ); + var startInfo = new System.Diagnostics.ProcessStartInfo + { + FileName = "/usr/bin/env", + Arguments = $"bash \"{updateScriptPath}\"", + UseShellExecute = false, + CreateNoWindow = true, + }; + + startInfo.EnvironmentVariables["PID"] = Environment.ProcessId.ToString(); + startInfo.EnvironmentVariables["NEW_APPIMAGE"] = newAppImage; + startInfo.EnvironmentVariables["OLD_APPIMAGE"] = appImage; + + System.Diagnostics.Process.Start(startInfo); App.Shutdown(); return; @@ -214,7 +216,7 @@ sleep 0.5 logger.LogError(ex, "Failed to execute AppImage update script"); var dialog = DialogHelper.CreateMarkdownDialog( - "AppImage update script failed. \nCould not replace old AppImage with new version. Please check directory permissions. \nFalling back to standard update process. User intervention required: After program closes, \nplease move the new AppImage extracted in the '.StabilityMatrixUpdate' hidden directory to the old AppImage overwriting it. \n\nClose this dialog to continue with standard update process.", + "AppImage update script failed. \nCould not replace old AppImage with new version. Please check directory permissions. \nFalling back to standard update process. User intervention required: \nAfter program closes, \nplease move the new AppImage extracted in the '.StabilityMatrixUpdate' hidden directory to the old AppImage overwriting it. \n\nClose this dialog to continue with standard update process.", Resources.Label_UnexpectedErrorOccurred ); From c421649be4cfde66886fc625b1a9d2e0398e04aa Mon Sep 17 00:00:00 2001 From: NeuralFault Date: Fri, 9 Jan 2026 12:09:21 -0500 Subject: [PATCH 04/29] Add default launch options for ZLUDA stability and update default cross attention method --- .../Models/Packages/ComfyZluda.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs b/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs index 16565208a..a0c381eeb 100644 --- a/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs +++ b/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs @@ -6,6 +6,7 @@ using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Cache; using StabilityMatrix.Core.Helper.HardwareInfo; +using StabilityMatrix.Core.Models; using StabilityMatrix.Core.Models.FileInterfaces; using StabilityMatrix.Core.Models.Progress; using StabilityMatrix.Core.Processes; @@ -42,6 +43,49 @@ IPyInstallationManager pyInstallationManager + "Visual Studio Build Tools for C++ Desktop Development will be installed automatically. " + "AMD GPUs under the RX 6800 may require additional manual setup."; public override string LaunchCommand => Path.Combine("zluda", "zluda.exe"); + + public override List LaunchOptions + { + get + { + var options = base.LaunchOptions; + + // Update Cross Attention Method default + var crossAttentionIndex = options.FindIndex(o => o.Name == "Cross Attention Method"); + if (crossAttentionIndex != -1) + { + options[crossAttentionIndex] = options[crossAttentionIndex] with + { + InitialValue = "--use-quad-cross-attention" + }; + } + + // Add new options before Extras (which is usually last) + var extrasIndex = options.FindIndex(o => o.Name == "Extra Launch Arguments"); + var insertIndex = extrasIndex != -1 ? extrasIndex : options.Count; + + options.Insert(insertIndex, new LaunchOptionDefinition + { + Name = "Disable Async Offload", + Type = LaunchOptionType.Bool, + InitialValue = true, + Options = ["--disable-async-offload"], + Description = "Disable async weight offloading. Recommended for ZLUDA stability.", + }); + + options.Insert(insertIndex + 1, new LaunchOptionDefinition + { + Name = "Disable Pinned Memory", + Type = LaunchOptionType.Bool, + InitialValue = true, + Options = ["--disable-pinned-memory"], + Description = "Disable pinned memory. Recommended for ZLUDA stability.", + }); + + return options; + } + } + public override IEnumerable AvailableTorchIndices => [TorchIndex.Zluda]; public override TorchIndex GetRecommendedTorchVersion() => TorchIndex.Zluda; From 1c447e3a82a68927dfd9187d4a7701673e0a3e37 Mon Sep 17 00:00:00 2001 From: NeuralFault Date: Fri, 16 Jan 2026 16:52:46 -0500 Subject: [PATCH 05/29] Refactor ComfyZluda class to streamline launch options and improve stability settings --- .../Models/Packages/ComfyZluda.cs | 68 ++++++++++++------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs b/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs index a0c381eeb..1470735cb 100644 --- a/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs +++ b/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs @@ -1,12 +1,8 @@ -using System.Diagnostics; -using System.Text.RegularExpressions; -using Injectio.Attributes; -using StabilityMatrix.Core.Exceptions; +using StabilityMatrix.Core.Exceptions; using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Cache; using StabilityMatrix.Core.Helper.HardwareInfo; -using StabilityMatrix.Core.Models; using StabilityMatrix.Core.Models.FileInterfaces; using StabilityMatrix.Core.Models.Progress; using StabilityMatrix.Core.Processes; @@ -41,7 +37,7 @@ IPyInstallationManager pyInstallationManager public override string Disclaimer => "Prerequisite install may require admin privileges and a reboot. " + "Visual Studio Build Tools for C++ Desktop Development will be installed automatically. " - + "AMD GPUs under the RX 6800 may require additional manual setup."; + + "AMD GPUs under the RX 6800 may require additional manual setup. "; public override string LaunchCommand => Path.Combine("zluda", "zluda.exe"); public override List LaunchOptions @@ -56,7 +52,7 @@ public override List LaunchOptions { options[crossAttentionIndex] = options[crossAttentionIndex] with { - InitialValue = "--use-quad-cross-attention" + InitialValue = "--use-quad-cross-attention", }; } @@ -64,23 +60,47 @@ public override List LaunchOptions var extrasIndex = options.FindIndex(o => o.Name == "Extra Launch Arguments"); var insertIndex = extrasIndex != -1 ? extrasIndex : options.Count; - options.Insert(insertIndex, new LaunchOptionDefinition - { - Name = "Disable Async Offload", - Type = LaunchOptionType.Bool, - InitialValue = true, - Options = ["--disable-async-offload"], - Description = "Disable async weight offloading. Recommended for ZLUDA stability.", - }); - - options.Insert(insertIndex + 1, new LaunchOptionDefinition - { - Name = "Disable Pinned Memory", - Type = LaunchOptionType.Bool, - InitialValue = true, - Options = ["--disable-pinned-memory"], - Description = "Disable pinned memory. Recommended for ZLUDA stability.", - }); + options.Insert( + insertIndex, + new LaunchOptionDefinition + { + Name = "Disable Async Offload", + Type = LaunchOptionType.Bool, + InitialValue = true, + Options = ["--disable-async-offload"], + } + ); + + options.Insert( + insertIndex + 1, + new LaunchOptionDefinition + { + Name = "Disable Pinned Memory", + Type = LaunchOptionType.Bool, + InitialValue = true, + Options = ["--disable-pinned-memory"], + } + ); + options.Insert( + insertIndex + 2, + new LaunchOptionDefinition + { + Name = "Disable Smart Memory", + Type = LaunchOptionType.Bool, + InitialValue = false, + Options = ["--disable-smart-memory"], + } + ); + options.Insert( + insertIndex + 3, + new LaunchOptionDefinition + { + Name = "Disable Model/Node Caching", + Type = LaunchOptionType.Bool, + InitialValue = false, + Options = ["--cache-none"], + } + ); return options; } From 69858c35c11a27d9bdf3abe54e1beedbba5c05f8 Mon Sep 17 00:00:00 2001 From: NeuralFault Date: Fri, 16 Jan 2026 17:05:02 -0500 Subject: [PATCH 06/29] Restored directives that got removed accidentally during build debugging. --- StabilityMatrix.Core/Models/Packages/ComfyZluda.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs b/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs index 1470735cb..206f89967 100644 --- a/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs +++ b/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs @@ -1,4 +1,7 @@ -using StabilityMatrix.Core.Exceptions; +using System.Diagnostics; +using System.Text.RegularExpressions; +using Injectio.Attributes; +using StabilityMatrix.Core.Exceptions; using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Cache; From 52acb7d30b563dcdc5580c18061cf6738d26ed67 Mon Sep 17 00:00:00 2001 From: NeuralFault Date: Fri, 16 Jan 2026 17:58:43 -0500 Subject: [PATCH 07/29] Refactored launch option logic and positioning. --- .../Models/Packages/ComfyZluda.cs | 62 +++++++++---------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs b/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs index 206f89967..dd3d84c5c 100644 --- a/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs +++ b/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs @@ -1,11 +1,15 @@ using System.Diagnostics; +using System.Diagnostics; using System.Text.RegularExpressions; +using System.Text.RegularExpressions; +using Injectio.Attributes; using Injectio.Attributes; using StabilityMatrix.Core.Exceptions; using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Cache; using StabilityMatrix.Core.Helper.HardwareInfo; +using StabilityMatrix.Core.Models; using StabilityMatrix.Core.Models.FileInterfaces; using StabilityMatrix.Core.Models.Progress; using StabilityMatrix.Core.Processes; @@ -47,64 +51,54 @@ public override List LaunchOptions { get { - var options = base.LaunchOptions; - - // Update Cross Attention Method default - var crossAttentionIndex = options.FindIndex(o => o.Name == "Cross Attention Method"); - if (crossAttentionIndex != -1) + var options = new List { - options[crossAttentionIndex] = options[crossAttentionIndex] with + new() { + Name = "Cross Attention Method", + Type = LaunchOptionType.Bool, InitialValue = "--use-quad-cross-attention", - }; - } - - // Add new options before Extras (which is usually last) - var extrasIndex = options.FindIndex(o => o.Name == "Extra Launch Arguments"); - var insertIndex = extrasIndex != -1 ? extrasIndex : options.Count; - - options.Insert( - insertIndex, - new LaunchOptionDefinition + Options = + [ + "--use-split-cross-attention", + "--use-quad-cross-attention", + "--use-pytorch-cross-attention", + "--use-sage-attention", + ], + }, + new() { Name = "Disable Async Offload", Type = LaunchOptionType.Bool, InitialValue = true, Options = ["--disable-async-offload"], - } - ); - - options.Insert( - insertIndex + 1, - new LaunchOptionDefinition + }, + new() { Name = "Disable Pinned Memory", Type = LaunchOptionType.Bool, InitialValue = true, Options = ["--disable-pinned-memory"], - } - ); - options.Insert( - insertIndex + 2, - new LaunchOptionDefinition + }, + new() { Name = "Disable Smart Memory", Type = LaunchOptionType.Bool, InitialValue = false, Options = ["--disable-smart-memory"], - } - ); - options.Insert( - insertIndex + 3, - new LaunchOptionDefinition + }, + new() { Name = "Disable Model/Node Caching", Type = LaunchOptionType.Bool, InitialValue = false, Options = ["--cache-none"], - } - ); + }, + }; + options.AddRange( + base.LaunchOptions.Except(base.LaunchOptions.Where(x => x.Name == "Cross Attention Method")) + ); return options; } } From 0e3c7a3b0c9e7f6fb55f0016b3510c11c7138d3f Mon Sep 17 00:00:00 2001 From: NeuralFault <65365345+NeuralFault@users.noreply.github.com> Date: Fri, 16 Jan 2026 18:06:30 -0500 Subject: [PATCH 08/29] Remove duplicate using directives in ComfyZluda.cs --- StabilityMatrix.Core/Models/Packages/ComfyZluda.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs b/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs index dd3d84c5c..8964f5c3b 100644 --- a/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs +++ b/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs @@ -1,11 +1,7 @@ using System.Diagnostics; -using System.Diagnostics; using System.Text.RegularExpressions; -using System.Text.RegularExpressions; -using Injectio.Attributes; using Injectio.Attributes; using StabilityMatrix.Core.Exceptions; -using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Cache; using StabilityMatrix.Core.Helper.HardwareInfo; @@ -97,7 +93,7 @@ public override List LaunchOptions }; options.AddRange( - base.LaunchOptions.Except(base.LaunchOptions.Where(x => x.Name == "Cross Attention Method")) + base.LaunchOptions.Where(x => x.Name != "Cross Attention Method") ); return options; } From a6e052de1afaad4486b0a297dabeef0ec1b6a2dc Mon Sep 17 00:00:00 2001 From: NeuralFault <65365345+NeuralFault@users.noreply.github.com> Date: Fri, 16 Jan 2026 18:17:16 -0500 Subject: [PATCH 09/29] Restored using directive for StabilityMatrix.Core.Extensions thought it said Exceptions, whoops. --- StabilityMatrix.Core/Models/Packages/ComfyZluda.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs b/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs index 8964f5c3b..723db36ba 100644 --- a/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs +++ b/StabilityMatrix.Core/Models/Packages/ComfyZluda.cs @@ -2,6 +2,7 @@ using System.Text.RegularExpressions; using Injectio.Attributes; using StabilityMatrix.Core.Exceptions; +using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Cache; using StabilityMatrix.Core.Helper.HardwareInfo; From 1bcbc0ee9fa58ee18cb6686e46ede3c10607377c Mon Sep 17 00:00:00 2001 From: NeuralFault Date: Fri, 16 Jan 2026 18:17:53 -0500 Subject: [PATCH 10/29] Update PreviewImageUri to use new CDN link for AiToolkit --- StabilityMatrix.Core/Models/Packages/AiToolkit.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/StabilityMatrix.Core/Models/Packages/AiToolkit.cs b/StabilityMatrix.Core/Models/Packages/AiToolkit.cs index 24009cef2..fc1e388e7 100644 --- a/StabilityMatrix.Core/Models/Packages/AiToolkit.cs +++ b/StabilityMatrix.Core/Models/Packages/AiToolkit.cs @@ -35,10 +35,7 @@ IPyInstallationManager pyInstallationManager public override string LicenseUrl => "https://github.com/ostris/ai-toolkit/blob/main/LICENSE"; public override string LaunchCommand => string.Empty; - public override Uri PreviewImageUri => - new( - "https://camo.githubusercontent.com/ea35b399e0d659f9f2ee09cbedb58e1a3ec7a0eab763e8ae8d11d076aad5be40/68747470733a2f2f6f73747269732e636f6d2f77702d636f6e74656e742f75706c6f6164732f323032352f30322f746f6f6c6b69742d75692e6a7067" - ); + public override Uri PreviewImageUri => new("https://cdn.lykos.ai/sm/packages/aitoolkit/preview.webp"); public override string OutputFolderName => "output"; public override IEnumerable AvailableTorchIndices => [TorchIndex.Cuda]; From 965ad7a4857f272629f69d1c68146f86cbdb4d0a Mon Sep 17 00:00:00 2001 From: NeuralFault <65365345+NeuralFault@users.noreply.github.com> Date: Sun, 18 Jan 2026 19:54:56 -0500 Subject: [PATCH 11/29] Corrected gfx110X Windows ROCm nightly index. Added Win-ROCm EnVars Changed index from 110X-dgpu to 110X-all as former stopped getting builds and was merged with other 110X archs in the latter index. Added new environment variables to enhance GPU stability and performance, including settings to prevent out-of-memory errors and re-enable CUDNN in ComfyUI to allow proper MiOpen support. --- StabilityMatrix.Core/Models/Packages/ComfyUI.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/StabilityMatrix.Core/Models/Packages/ComfyUI.cs b/StabilityMatrix.Core/Models/Packages/ComfyUI.cs index 6af2b047f..e0fe67e6a 100644 --- a/StabilityMatrix.Core/Models/Packages/ComfyUI.cs +++ b/StabilityMatrix.Core/Models/Packages/ComfyUI.cs @@ -382,7 +382,7 @@ await StandardPipInstallProcessAsync( var indexUrl = gfxArch switch { "gfx1151" => "https://rocm.nightlies.amd.com/v2/gfx1151", - _ when gfxArch.StartsWith("gfx110") => "https://rocm.nightlies.amd.com/v2/gfx110X-dgpu", + _ when gfxArch.StartsWith("gfx110") => "https://rocm.nightlies.amd.com/v2/gfx110X-all", _ when gfxArch.StartsWith("gfx120") => "https://rocm.nightlies.amd.com/v2/gfx120X-all", _ => throw new ArgumentOutOfRangeException( nameof(gfxArch), @@ -870,6 +870,8 @@ private ImmutableDictionary GetEnvVars(ImmutableDictionary Date: Mon, 19 Jan 2026 16:06:50 +0100 Subject: [PATCH 12/29] Add TiledVAEDecode backend integration (ComfyNodeBuilder + ComfyClient) --- .../Controls/Inference/TiledVAECard.axaml | 64 +++++++++++-------- .../InferenceWanTextToVideoViewModel.cs | 9 ++- .../Inference/Modules/TiledVAEModule.cs | 10 ++- .../Inference/TiledVAECardViewModel.cs | 11 ++++ .../Settings/InferenceSettingsViewModel.cs | 8 +++ .../Comfy/Nodes/TiledVAEDecodeVideoNode.cs | 20 ++++++ .../Models/Settings/Settings.cs | 3 + .../Settings/Inference/WanSettings.cs | 6 ++ 8 files changed, 103 insertions(+), 28 deletions(-) create mode 100644 StabilityMatrix.Core/Models/Api/Comfy/Nodes/TiledVAEDecodeVideoNode.cs create mode 100644 StabilityMatrix.Core/Settings/Inference/WanSettings.cs diff --git a/StabilityMatrix.Avalonia/Controls/Inference/TiledVAECard.axaml b/StabilityMatrix.Avalonia/Controls/Inference/TiledVAECard.axaml index 9c47cbb3c..77ceb2454 100644 --- a/StabilityMatrix.Avalonia/Controls/Inference/TiledVAECard.axaml +++ b/StabilityMatrix.Avalonia/Controls/Inference/TiledVAECard.axaml @@ -5,15 +5,16 @@ xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:vmInference="clr-namespace:StabilityMatrix.Avalonia.ViewModels.Inference" x:DataType="vmInference:TiledVAECardViewModel"> + + - + + - + - - - - - + + + + + + + + + + + + + + + + + + + - - - - - diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceWanTextToVideoViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceWanTextToVideoViewModel.cs index 4b2ac1815..2968ee291 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceWanTextToVideoViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceWanTextToVideoViewModel.cs @@ -10,6 +10,7 @@ using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Models; using StabilityMatrix.Core.Services; +git status namespace StabilityMatrix.Avalonia.ViewModels.Inference; @@ -115,8 +116,14 @@ protected override void BuildPrompt(BuildPromptEventArgs args) SamplerCardViewModel.ApplyStep(args); - // Animated webp output + // ADD THIS - Apply TiledVAE module + TiledVAEModule.ApplyStep(args); + + // ADD THIS LINE - Invoke pre-output actions BEFORE video output! + args.Builder.InvokeAllPreOutputActions(); + VideoOutputSettingsCardViewModel.ApplyStep(args); + } /// diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs index 3199a53fa..84a73258a 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs @@ -34,8 +34,14 @@ protected override void OnApplyStep(ModuleApplyStepEventArgs e) var latent = builder.Connections.Primary.AsT0; var vae = builder.Connections.GetDefaultVAE(); - // Use tiled VAE decode instead of standard decode - var tiledDecode = builder.Nodes.AddTypedNode( + logger.LogWarning("TiledVAE: Injecting TiledVAEDecode"); + logger.LogWarning("UseCustomTemporalTiling value at runtime: {Value}", card.UseCustomTemporalTiling); + + // Always valid values (Wan requires temporal tiling) + int temporalSize = card.UseCustomTemporalTiling ? card.TemporalSize : 64; + int temporalOverlap = card.UseCustomTemporalTiling ? card.TemporalOverlap : 8; + + var node = builder.Nodes.AddTypedNode( new ComfyNodeBuilder.TiledVAEDecode { Name = builder.Nodes.GetUniqueName("TiledVAEDecode"), diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/TiledVAECardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/TiledVAECardViewModel.cs index ae2920778..081901497 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/TiledVAECardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/TiledVAECardViewModel.cs @@ -14,24 +14,35 @@ public partial class TiledVAECardViewModel : LoadableViewModelBase { public const string ModuleKey = "TiledVAE"; + // Spatial tile size (valid for Wan) [ObservableProperty] [NotifyDataErrorInfo] [Required] [Range(64, 4096)] private int tileSize = 512; + // Spatial overlap [ObservableProperty] [NotifyDataErrorInfo] [Required] [Range(0, 4096)] private int overlap = 64; + // NEW: Toggle now means "Use custom temporal tiling settings" + [ObservableProperty] + private bool useCustomTemporalTiling = false; + + // Temporal tile size (must be >= 8) + [ObservableProperty] + private bool useTemporalTiling = true; + [ObservableProperty] [NotifyDataErrorInfo] [Required] [Range(8, 4096)] private int temporalSize = 64; + // Temporal overlap (must be >= 4) [ObservableProperty] [NotifyDataErrorInfo] [Required] diff --git a/StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs index 8cc7e19a4..2de846ae1 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs @@ -69,6 +69,8 @@ public partial class InferenceSettingsViewModel : PageViewModelBase [ObservableProperty] private bool filterExtraNetworksByBaseModel; + [ObservableProperty] private bool enableTiledVae; + private List ignoredFileNameFormatVars = [ "author", @@ -191,6 +193,12 @@ ISettingsManager settingsManager settings => settings.InferenceDimensionStepChange, true ); + settingsManager.RelayPropertyFor( + this, + vm => vm.EnableTiledVae, + settings => settings.EnableTiledVae, + true + ); FavoriteDimensions .ToObservableChangeSet() diff --git a/StabilityMatrix.Core/Models/Api/Comfy/Nodes/TiledVAEDecodeVideoNode.cs b/StabilityMatrix.Core/Models/Api/Comfy/Nodes/TiledVAEDecodeVideoNode.cs new file mode 100644 index 000000000..77c9a0a80 --- /dev/null +++ b/StabilityMatrix.Core/Models/Api/Comfy/Nodes/TiledVAEDecodeVideoNode.cs @@ -0,0 +1,20 @@ +namespace StabilityMatrix.Core.Models.Api.Comfy.Nodes; + +public record TiledVAEDecodeVideoNode : ComfyNode +{ + public override string ClassType => "TiledVAEDecodeVideo"; + + public record Inputs( + ComfyNodeConnection Vae, + ComfyNodeConnection VideoLatent, + int TileSize, + int Overlap + ); + + public Inputs Input { get; init; } = new( + Vae: new(), + VideoLatent: new(), + TileSize: 256, + Overlap: 32 + ); +} diff --git a/StabilityMatrix.Core/Models/Settings/Settings.cs b/StabilityMatrix.Core/Models/Settings/Settings.cs index 1558037ff..ce966e8ea 100644 --- a/StabilityMatrix.Core/Models/Settings/Settings.cs +++ b/StabilityMatrix.Core/Models/Settings/Settings.cs @@ -100,6 +100,9 @@ public InstalledPackage? PreferredWorkflowPackage /// public bool IsCompletionRemoveUnderscoresEnabled { get; set; } = true; + /// COPILOT + public bool EnableTiledVae { get; set; } = false; + /// /// Format for Inference output image file names /// diff --git a/StabilityMatrix.Core/Settings/Inference/WanSettings.cs b/StabilityMatrix.Core/Settings/Inference/WanSettings.cs new file mode 100644 index 000000000..bc5aae40a --- /dev/null +++ b/StabilityMatrix.Core/Settings/Inference/WanSettings.cs @@ -0,0 +1,6 @@ +namespace StabilityMatrix.Core.Settings.Inference; + +public class WanSettings +{ + public bool EnableTiledVae { get; set; } = false; +} From e7c56f44e39100e46009213419d7c675b2bb5175 Mon Sep 17 00:00:00 2001 From: Domica Date: Sat, 17 Jan 2026 18:42:25 +0100 Subject: [PATCH 13/29] Add TiledVAEDecode backend integration (ComfyNodeBuilder + ComfyClient) --- StabilityMatrix.Core/Inference/ComfyClient.cs | 49 ++++++++++++++---- .../Api/Comfy/Nodes/ComfyNodeBuilder.cs | 51 +++++++++++++++++-- .../Comfy/Nodes/TiledVAEDecodeVideoNode.cs | 20 -------- .../Settings/Inference/WanSettings.cs | 6 --- 4 files changed, 86 insertions(+), 40 deletions(-) delete mode 100644 StabilityMatrix.Core/Models/Api/Comfy/Nodes/TiledVAEDecodeVideoNode.cs delete mode 100644 StabilityMatrix.Core/Settings/Inference/WanSettings.cs diff --git a/StabilityMatrix.Core/Inference/ComfyClient.cs b/StabilityMatrix.Core/Inference/ComfyClient.cs index 197adde6e..4b417e5d3 100644 --- a/StabilityMatrix.Core/Inference/ComfyClient.cs +++ b/StabilityMatrix.Core/Inference/ComfyClient.cs @@ -326,22 +326,49 @@ public override async Task CloseAsync(CancellationToken cancellationToken = defa await webSocketClient.Stop(WebSocketCloseStatus.NormalClosure, string.Empty).ConfigureAwait(false); } - public async Task QueuePromptAsync( - Dictionary nodes, - CancellationToken cancellationToken = default - ) +public async Task QueuePromptAsync( + Dictionary nodes, + CancellationToken cancellationToken = default +) +{ + var request = new ComfyPromptRequest { ClientId = ClientId, Prompt = nodes }; + + // DEBUG: dump final workflow JSON + try { - var request = new ComfyPromptRequest { ClientId = ClientId, Prompt = nodes }; - var result = await comfyApi.PostPrompt(request, cancellationToken).ConfigureAwait(false); + var json = JsonSerializer.Serialize(request, jsonSerializerOptions); - // Add task to dictionary and set it as the current task - var task = new ComfyTask(result.PromptId); - PromptTasks.TryAdd(result.PromptId, task); - currentPromptTask = task; + var debugDir = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), + "StabilityMatrix", + "Debug" + ); + + Directory.CreateDirectory(debugDir); + + var path = Path.Combine( + debugDir, + $"wan_workflow_debug_request.json" + ); - return task; + File.WriteAllText(path, json); + + Logger.Warn("WAN DEBUG: Dumped final request JSON to {0}", path); + } + catch (Exception ex) + { + Logger.Error(ex, "WAN DEBUG: Failed to dump final request JSON"); } + var result = await comfyApi.PostPrompt(request, cancellationToken).ConfigureAwait(false); + + var task = new ComfyTask(result.PromptId); + PromptTasks.TryAdd(result.PromptId, task); + currentPromptTask = task; + + return task; +} + public async Task InterruptPromptAsync(CancellationToken cancellationToken = default) { await comfyApi.PostInterrupt(cancellationToken).ConfigureAwait(false); diff --git a/StabilityMatrix.Core/Models/Api/Comfy/Nodes/ComfyNodeBuilder.cs b/StabilityMatrix.Core/Models/Api/Comfy/Nodes/ComfyNodeBuilder.cs index c164a6324..fa2c7e273 100644 --- a/StabilityMatrix.Core/Models/Api/Comfy/Nodes/ComfyNodeBuilder.cs +++ b/StabilityMatrix.Core/Models/Api/Comfy/Nodes/ComfyNodeBuilder.cs @@ -1,4 +1,4 @@ -using System.ComponentModel; +using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Diagnostics.CodeAnalysis; using System.Drawing; @@ -1097,7 +1097,34 @@ public record NRS : ComfyTypedNodeBase public required double Squash { get; set; } } - public ImageNodeConnection Lambda_LatentToImage(LatentNodeConnection latent, VAENodeConnection vae) + public ImageNodeConnection Lambda_LatentToImage( + LatentNodeConnection latent, + VAENodeConnection vae, + bool useTiledVAE = false, + int tileSize = 512, + int overlap = 64, + int temporalSize = 64, + int temporalOverlap = 8) +{ + if (useTiledVAE) + { + var name = GetUniqueName("VAEDecodeTiled"); + return Nodes + .AddTypedNode( + new TiledVAEDecode + { + Name = name, + Samples = latent, + Vae = vae, + TileSize = tileSize, + Overlap = overlap, + TemporalSize = temporalSize, + TemporalOverlap = temporalOverlap + } + ) + .Output; + } + else { var name = GetUniqueName("VAEDecode"); return Nodes @@ -1111,6 +1138,7 @@ public ImageNodeConnection Lambda_LatentToImage(LatentNodeConnection latent, VAE ) .Output; } +} public LatentNodeConnection Lambda_ImageToLatent(ImageNodeConnection pixels, VAENodeConnection vae) { @@ -1519,11 +1547,28 @@ public ImageNodeConnection GetPrimaryAsImage() /// /// Get or convert latest primary connection to image /// +<<<<<<< HEAD public ImageNodeConnection GetPrimaryAsImage(PrimaryNodeConnection primary, VAENodeConnection vae) { return primary.Match(latent => Lambda_LatentToImage(latent, vae), image => image); } +======= + public ImageNodeConnection GetPrimaryAsImage( + PrimaryNodeConnection primary, + VAENodeConnection vae, + bool useTiledVAE = false, + int tileSize = 512, + int overlap = 64, + int temporalSize = 64, + int temporalOverlap = 8) +{ + return primary.Match( + latent => Lambda_LatentToImage(latent, vae, useTiledVAE, tileSize, overlap, temporalSize, temporalOverlap), + image => image + ); + } +>>>>>>> 27accf16 (Update ComfyNodeBuilder.cs) /// /// Get or convert latest primary connection to image /// @@ -1640,4 +1685,4 @@ public VAENodeConnection GetDefaultVAE() } public NodeBuilderConnections Connections { get; } = new(); -} +} \ No newline at end of file diff --git a/StabilityMatrix.Core/Models/Api/Comfy/Nodes/TiledVAEDecodeVideoNode.cs b/StabilityMatrix.Core/Models/Api/Comfy/Nodes/TiledVAEDecodeVideoNode.cs deleted file mode 100644 index 77c9a0a80..000000000 --- a/StabilityMatrix.Core/Models/Api/Comfy/Nodes/TiledVAEDecodeVideoNode.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace StabilityMatrix.Core.Models.Api.Comfy.Nodes; - -public record TiledVAEDecodeVideoNode : ComfyNode -{ - public override string ClassType => "TiledVAEDecodeVideo"; - - public record Inputs( - ComfyNodeConnection Vae, - ComfyNodeConnection VideoLatent, - int TileSize, - int Overlap - ); - - public Inputs Input { get; init; } = new( - Vae: new(), - VideoLatent: new(), - TileSize: 256, - Overlap: 32 - ); -} diff --git a/StabilityMatrix.Core/Settings/Inference/WanSettings.cs b/StabilityMatrix.Core/Settings/Inference/WanSettings.cs deleted file mode 100644 index bc5aae40a..000000000 --- a/StabilityMatrix.Core/Settings/Inference/WanSettings.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace StabilityMatrix.Core.Settings.Inference; - -public class WanSettings -{ - public bool EnableTiledVae { get; set; } = false; -} From 0161e3e2c938624b129544138b9ab56646aca4b0 Mon Sep 17 00:00:00 2001 From: Domica Date: Sat, 17 Jan 2026 23:28:46 +0100 Subject: [PATCH 14/29] Add WAN workflow integration for TiledVAE --- .../Workflows/Wan/wan_base_workflow.json | 9 +++++++++ .../Inference/Profiles/WanInferenceProfile.cs | 10 ++++++++++ .../Models/Packages/PackageLinkTests.cs | 19 +++++++++++++------ 3 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 StabilityMatrix.Core/Inference/Workflows/Wan/wan_base_workflow.json create mode 100644 StabilityMatrix.Core/Settings/Inference/Profiles/WanInferenceProfile.cs diff --git a/StabilityMatrix.Core/Inference/Workflows/Wan/wan_base_workflow.json b/StabilityMatrix.Core/Inference/Workflows/Wan/wan_base_workflow.json new file mode 100644 index 000000000..862dc74ab --- /dev/null +++ b/StabilityMatrix.Core/Inference/Workflows/Wan/wan_base_workflow.json @@ -0,0 +1,9 @@ +"tiled_decode_video": { + "class_type": "TiledVAEDecodeVideo", + "inputs": { + "vae": ["vae_loader", 0], + "video_latent": ["video_latent", 0], + "tile_size": 256, + "overlap": 32 + } +} diff --git a/StabilityMatrix.Core/Settings/Inference/Profiles/WanInferenceProfile.cs b/StabilityMatrix.Core/Settings/Inference/Profiles/WanInferenceProfile.cs new file mode 100644 index 000000000..bf21f48a0 --- /dev/null +++ b/StabilityMatrix.Core/Settings/Inference/Profiles/WanInferenceProfile.cs @@ -0,0 +1,10 @@ +namespace StabilityMatrix.Core.Inference.Profiles +{ + public class WanInferenceProfile : InferenceProfileBase + { + public override string Name => "WAN"; + public override Type SettingsType => typeof(WanSettings); + + // Existing logic like BuildWorkflow(), BuildAddons(), etc. + } +} diff --git a/StabilityMatrix.Tests/Models/Packages/PackageLinkTests.cs b/StabilityMatrix.Tests/Models/Packages/PackageLinkTests.cs index c0b3113e4..6d964c7a4 100644 --- a/StabilityMatrix.Tests/Models/Packages/PackageLinkTests.cs +++ b/StabilityMatrix.Tests/Models/Packages/PackageLinkTests.cs @@ -44,12 +44,19 @@ public async Task TestPreviewImageUri(BasePackage package) await HttpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, imageUri)) ); - Assert.IsTrue( - response.IsSuccessStatusCode, - "Failed to get PreviewImageUri at {0}: {1}", - imageUri, - response - ); + if (response.StatusCode == System.Net.HttpStatusCode.Forbidden) +{ + Assert.Inconclusive( + $"PreviewImageUri blocked by host (403): {imageUri}" + ); +} + +Assert.IsTrue( + response.IsSuccessStatusCode, + "Failed to get PreviewImageUri at {0}: {1}", + imageUri, + response +); } [TestMethod] From c5482d4ff40e2bbaab1f478af77d61a9871f0c85 Mon Sep 17 00:00:00 2001 From: Domica Date: Sat, 17 Jan 2026 18:21:47 +0100 Subject: [PATCH 15/29] Cleanup: remove unused files, debug code, and workflow noise --- .../InferenceWanTextToVideoViewModel.cs | 1 - StabilityMatrix.Core/Inference/ComfyClient.cs | 28 ------------------- 2 files changed, 29 deletions(-) diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceWanTextToVideoViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceWanTextToVideoViewModel.cs index 2968ee291..54a69561e 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceWanTextToVideoViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceWanTextToVideoViewModel.cs @@ -10,7 +10,6 @@ using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Models; using StabilityMatrix.Core.Services; -git status namespace StabilityMatrix.Avalonia.ViewModels.Inference; diff --git a/StabilityMatrix.Core/Inference/ComfyClient.cs b/StabilityMatrix.Core/Inference/ComfyClient.cs index 4b417e5d3..efa08c312 100644 --- a/StabilityMatrix.Core/Inference/ComfyClient.cs +++ b/StabilityMatrix.Core/Inference/ComfyClient.cs @@ -333,33 +333,6 @@ public async Task QueuePromptAsync( { var request = new ComfyPromptRequest { ClientId = ClientId, Prompt = nodes }; - // DEBUG: dump final workflow JSON - try - { - var json = JsonSerializer.Serialize(request, jsonSerializerOptions); - - var debugDir = Path.Combine( - Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), - "StabilityMatrix", - "Debug" - ); - - Directory.CreateDirectory(debugDir); - - var path = Path.Combine( - debugDir, - $"wan_workflow_debug_request.json" - ); - - File.WriteAllText(path, json); - - Logger.Warn("WAN DEBUG: Dumped final request JSON to {0}", path); - } - catch (Exception ex) - { - Logger.Error(ex, "WAN DEBUG: Failed to dump final request JSON"); - } - var result = await comfyApi.PostPrompt(request, cancellationToken).ConfigureAwait(false); var task = new ComfyTask(result.PromptId); @@ -368,7 +341,6 @@ public async Task QueuePromptAsync( return task; } - public async Task InterruptPromptAsync(CancellationToken cancellationToken = default) { await comfyApi.PostInterrupt(cancellationToken).ConfigureAwait(false); From 1cbb0ba9f37a5bf3f15a3e23052abb5b079057f2 Mon Sep 17 00:00:00 2001 From: Domica Date: Tue, 20 Jan 2026 07:21:32 +0000 Subject: [PATCH 16/29] Format ComfyNodeBuilder with csharpier --- .../Api/Comfy/Nodes/ComfyNodeBuilder.cs | 136 +++++++++--------- 1 file changed, 71 insertions(+), 65 deletions(-) diff --git a/StabilityMatrix.Core/Models/Api/Comfy/Nodes/ComfyNodeBuilder.cs b/StabilityMatrix.Core/Models/Api/Comfy/Nodes/ComfyNodeBuilder.cs index fa2c7e273..baf394808 100644 --- a/StabilityMatrix.Core/Models/Api/Comfy/Nodes/ComfyNodeBuilder.cs +++ b/StabilityMatrix.Core/Models/Api/Comfy/Nodes/ComfyNodeBuilder.cs @@ -1,4 +1,4 @@ -using System.ComponentModel; +using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Diagnostics.CodeAnalysis; using System.Drawing; @@ -67,16 +67,16 @@ public record TiledVAEDecode : ComfyTypedNodeBase { public required LatentNodeConnection Samples { get; init; } public required VAENodeConnection Vae { get; init; } - + [Range(64, 4096)] public int TileSize { get; init; } = 512; - + [Range(0, 4096)] public int Overlap { get; init; } = 64; - + [Range(8, 4096)] public int TemporalSize { get; init; } = 64; - + [Range(4, 4096)] public int TemporalOverlap { get; init; } = 8; } @@ -1097,48 +1097,49 @@ public record NRS : ComfyTypedNodeBase public required double Squash { get; set; } } - public ImageNodeConnection Lambda_LatentToImage( - LatentNodeConnection latent, - VAENodeConnection vae, - bool useTiledVAE = false, - int tileSize = 512, - int overlap = 64, - int temporalSize = 64, - int temporalOverlap = 8) -{ - if (useTiledVAE) - { - var name = GetUniqueName("VAEDecodeTiled"); - return Nodes - .AddTypedNode( - new TiledVAEDecode - { - Name = name, - Samples = latent, - Vae = vae, - TileSize = tileSize, - Overlap = overlap, - TemporalSize = temporalSize, - TemporalOverlap = temporalOverlap - } - ) - .Output; - } - else + public ImageNodeConnection Lambda_LatentToImage( + LatentNodeConnection latent, + VAENodeConnection vae, + bool useTiledVAE = false, + int tileSize = 512, + int overlap = 64, + int temporalSize = 64, + int temporalOverlap = 8 + ) { - var name = GetUniqueName("VAEDecode"); - return Nodes - .AddTypedNode( - new VAEDecode - { - Name = name, - Samples = latent, - Vae = vae, - } - ) - .Output; + if (useTiledVAE) + { + var name = GetUniqueName("VAEDecodeTiled"); + return Nodes + .AddTypedNode( + new TiledVAEDecode + { + Name = name, + Samples = latent, + Vae = vae, + TileSize = tileSize, + Overlap = overlap, + TemporalSize = temporalSize, + TemporalOverlap = temporalOverlap, + } + ) + .Output; + } + else + { + var name = GetUniqueName("VAEDecode"); + return Nodes + .AddTypedNode( + new VAEDecode + { + Name = name, + Samples = latent, + Vae = vae, + } + ) + .Output; + } } -} public LatentNodeConnection Lambda_ImageToLatent(ImageNodeConnection pixels, VAENodeConnection vae) { @@ -1547,28 +1548,33 @@ public ImageNodeConnection GetPrimaryAsImage() /// /// Get or convert latest primary connection to image /// -<<<<<<< HEAD - public ImageNodeConnection GetPrimaryAsImage(PrimaryNodeConnection primary, VAENodeConnection vae) + public ImageNodeConnection GetPrimaryAsImage( + PrimaryNodeConnection primary, + VAENodeConnection vae, + bool useTiledVAE = false, + int tileSize = 512, + int overlap = 64, + int temporalSize = 64, + int temporalOverlap = 8 + ) { - return primary.Match(latent => Lambda_LatentToImage(latent, vae), image => image); + return primary.Match( + latent => + Lambda_LatentToImage( + latent, + vae, + useTiledVAE, + tileSize, + overlap, + temporalSize, + temporalOverlap + ), + image => image + ); } -======= - public ImageNodeConnection GetPrimaryAsImage( - PrimaryNodeConnection primary, - VAENodeConnection vae, - bool useTiledVAE = false, - int tileSize = 512, - int overlap = 64, - int temporalSize = 64, - int temporalOverlap = 8) -{ - return primary.Match( - latent => Lambda_LatentToImage(latent, vae, useTiledVAE, tileSize, overlap, temporalSize, temporalOverlap), - image => image - ); - } ->>>>>>> 27accf16 (Update ComfyNodeBuilder.cs) + + /// /// Get or convert latest primary connection to image /// @@ -1685,4 +1691,4 @@ public VAENodeConnection GetDefaultVAE() } public NodeBuilderConnections Connections { get; } = new(); -} \ No newline at end of file +} From baa0c37c0ea5a5689ba662aabb54325543410924 Mon Sep 17 00:00:00 2001 From: Domica Date: Tue, 20 Jan 2026 08:40:59 +0000 Subject: [PATCH 17/29] Fix: unify temporal tiling toggle and align UI with backend - Removed redundant UseTemporalTiling property from TiledVAECardViewModel - Consolidated temporal tiling logic into UseCustomTemporalTiling - Updated TiledVAECard.axaml bindings to use UseCustomTemporalTiling - Ensured temporal controls visibility and backend behavior remain consistent --- .../Controls/Inference/TiledVAECard.axaml | 4 ++-- .../ViewModels/Inference/TiledVAECardViewModel.cs | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/StabilityMatrix.Avalonia/Controls/Inference/TiledVAECard.axaml b/StabilityMatrix.Avalonia/Controls/Inference/TiledVAECard.axaml index 77ceb2454..79414e564 100644 --- a/StabilityMatrix.Avalonia/Controls/Inference/TiledVAECard.axaml +++ b/StabilityMatrix.Avalonia/Controls/Inference/TiledVAECard.axaml @@ -54,10 +54,10 @@ + IsChecked="{Binding UseCustomTemporalTiling}" /> - + diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/TiledVAECardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/TiledVAECardViewModel.cs index 081901497..a89ba141f 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/TiledVAECardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/TiledVAECardViewModel.cs @@ -28,14 +28,11 @@ public partial class TiledVAECardViewModel : LoadableViewModelBase [Range(0, 4096)] private int overlap = 64; - // NEW: Toggle now means "Use custom temporal tiling settings" + // Toggle: Use custom temporal tiling settings [ObservableProperty] private bool useCustomTemporalTiling = false; // Temporal tile size (must be >= 8) - [ObservableProperty] - private bool useTemporalTiling = true; - [ObservableProperty] [NotifyDataErrorInfo] [Required] From 47642bd537a6e99af637a9eb336fa153d7cd56d9 Mon Sep 17 00:00:00 2001 From: Domica Date: Tue, 20 Jan 2026 08:46:48 +0000 Subject: [PATCH 18/29] chore: update TiledVAE settings and adjust logging level - Added/updated TiledVAE-related settings in Settings.cs - Replaced LogWarning with LogDebug in TiledVAEModule for non-critical tracing - Ensures cleaner production logs and consistent configuration handling --- .../ViewModels/Inference/Modules/TiledVAEModule.cs | 9 ++++++--- StabilityMatrix.Core/Models/Settings/Settings.cs | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs index 84a73258a..195ed512e 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs @@ -34,8 +34,11 @@ protected override void OnApplyStep(ModuleApplyStepEventArgs e) var latent = builder.Connections.Primary.AsT0; var vae = builder.Connections.GetDefaultVAE(); - logger.LogWarning("TiledVAE: Injecting TiledVAEDecode"); - logger.LogWarning("UseCustomTemporalTiling value at runtime: {Value}", card.UseCustomTemporalTiling); + logger.LogDebug("TiledVAE: Injecting TiledVAEDecode"); + logger.LogDebug( + "UseCustomTemporalTiling value at runtime: {value}", + card.UseCustomTemporalTiling + ); // Always valid values (Wan requires temporal tiling) int temporalSize = card.UseCustomTemporalTiling ? card.TemporalSize : 64; @@ -50,7 +53,7 @@ protected override void OnApplyStep(ModuleApplyStepEventArgs e) TileSize = card.TileSize, Overlap = card.Overlap, TemporalSize = card.TemporalSize, - TemporalOverlap = card.TemporalOverlap + TemporalOverlap = card.TemporalOverlap, } ); diff --git a/StabilityMatrix.Core/Models/Settings/Settings.cs b/StabilityMatrix.Core/Models/Settings/Settings.cs index ce966e8ea..3669be144 100644 --- a/StabilityMatrix.Core/Models/Settings/Settings.cs +++ b/StabilityMatrix.Core/Models/Settings/Settings.cs @@ -100,9 +100,9 @@ public InstalledPackage? PreferredWorkflowPackage /// public bool IsCompletionRemoveUnderscoresEnabled { get; set; } = true; - /// COPILOT + /// NEW public bool EnableTiledVae { get; set; } = false; - + /// /// Format for Inference output image file names /// From a567d9940e707f537a3bdbfe959fedb0fa409325 Mon Sep 17 00:00:00 2001 From: Domica Date: Tue, 20 Jan 2026 10:30:58 +0100 Subject: [PATCH 19/29] Apply suggestion from @ionite34 Confirmed. Co-authored-by: Ionite --- .../ViewModels/Settings/InferenceSettingsViewModel.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs index 2de846ae1..8e76bbc13 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs @@ -69,7 +69,9 @@ public partial class InferenceSettingsViewModel : PageViewModelBase [ObservableProperty] private bool filterExtraNetworksByBaseModel; - [ObservableProperty] private bool enableTiledVae; + [ObservableProperty] + private bool enableTiledVae; + private List ignoredFileNameFormatVars = [ From 2600b4ecda9f045d7aa885dd04d17bb100b3f700 Mon Sep 17 00:00:00 2001 From: Domica Date: Tue, 20 Jan 2026 09:42:26 +0000 Subject: [PATCH 20/29] chore: remove leftover WAN workflow json (unused and out of scope) --- .../Inference/Modules/TiledVAEModule.cs | 13 ++--- .../Workflows/Wan/wan_base_workflow.json | 9 --- .../Inference/Profiles/WanInferenceProfile.cs | 10 ---- .../Models/Packages/PackageLinkTests.cs | 58 +++++++++---------- 4 files changed, 31 insertions(+), 59 deletions(-) delete mode 100644 StabilityMatrix.Core/Inference/Workflows/Wan/wan_base_workflow.json delete mode 100644 StabilityMatrix.Core/Settings/Inference/Profiles/WanInferenceProfile.cs diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs index 195ed512e..516751ff1 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs @@ -22,7 +22,6 @@ protected override void OnApplyStep(ModuleApplyStepEventArgs e) { var card = GetCard(); - // Register a pre-output action that replaces standard VAE decode with tiled decode e.PreOutputActions.Add(args => { var builder = args.Builder; @@ -40,10 +39,6 @@ protected override void OnApplyStep(ModuleApplyStepEventArgs e) card.UseCustomTemporalTiling ); - // Always valid values (Wan requires temporal tiling) - int temporalSize = card.UseCustomTemporalTiling ? card.TemporalSize : 64; - int temporalOverlap = card.UseCustomTemporalTiling ? card.TemporalOverlap : 8; - var node = builder.Nodes.AddTypedNode( new ComfyNodeBuilder.TiledVAEDecode { @@ -52,13 +47,15 @@ protected override void OnApplyStep(ModuleApplyStepEventArgs e) Vae = vae, TileSize = card.TileSize, Overlap = card.Overlap, - TemporalSize = card.TemporalSize, - TemporalOverlap = card.TemporalOverlap, + + // Temporal tiling (WAN requires temporal tiling) + TemporalSize = card.UseCustomTemporalTiling ? card.TemporalSize : 64, + TemporalOverlap = card.UseCustomTemporalTiling ? card.TemporalOverlap : 8, } ); // Update primary connection to the decoded image - builder.Connections.Primary = tiledDecode.Output; + builder.Connections.Primary = node.Output; }); } } diff --git a/StabilityMatrix.Core/Inference/Workflows/Wan/wan_base_workflow.json b/StabilityMatrix.Core/Inference/Workflows/Wan/wan_base_workflow.json deleted file mode 100644 index 862dc74ab..000000000 --- a/StabilityMatrix.Core/Inference/Workflows/Wan/wan_base_workflow.json +++ /dev/null @@ -1,9 +0,0 @@ -"tiled_decode_video": { - "class_type": "TiledVAEDecodeVideo", - "inputs": { - "vae": ["vae_loader", 0], - "video_latent": ["video_latent", 0], - "tile_size": 256, - "overlap": 32 - } -} diff --git a/StabilityMatrix.Core/Settings/Inference/Profiles/WanInferenceProfile.cs b/StabilityMatrix.Core/Settings/Inference/Profiles/WanInferenceProfile.cs deleted file mode 100644 index bf21f48a0..000000000 --- a/StabilityMatrix.Core/Settings/Inference/Profiles/WanInferenceProfile.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace StabilityMatrix.Core.Inference.Profiles -{ - public class WanInferenceProfile : InferenceProfileBase - { - public override string Name => "WAN"; - public override Type SettingsType => typeof(WanSettings); - - // Existing logic like BuildWorkflow(), BuildAddons(), etc. - } -} diff --git a/StabilityMatrix.Tests/Models/Packages/PackageLinkTests.cs b/StabilityMatrix.Tests/Models/Packages/PackageLinkTests.cs index 6d964c7a4..6c21c92d2 100644 --- a/StabilityMatrix.Tests/Models/Packages/PackageLinkTests.cs +++ b/StabilityMatrix.Tests/Models/Packages/PackageLinkTests.cs @@ -25,7 +25,6 @@ public sealed class PackageLinkTests Backoff.DecorrelatedJitterBackoffV2(TimeSpan.FromMilliseconds(200), 3), onRetry: (outcome, timespan, retryAttempt, context) => { - // Log retry attempt if needed Console.WriteLine($"Retry attempt {retryAttempt}, waiting {timespan.TotalSeconds} seconds"); } ); @@ -36,27 +35,24 @@ public async Task TestPreviewImageUri(BasePackage package) { var imageUri = package.PreviewImageUri; - // If is GitHub Uri, use jsdelivr instead due to rate limiting + // If GitHub URL, use jsDelivr to avoid rate limiting imageUri = GitHubToJsDelivr(imageUri); - // Test http head is successful with retry policy var response = await RetryPolicy.ExecuteAsync(async () => await HttpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, imageUri)) ); - if (response.StatusCode == System.Net.HttpStatusCode.Forbidden) -{ - Assert.Inconclusive( - $"PreviewImageUri blocked by host (403): {imageUri}" - ); -} + // 403 should fail — URL is invalid or blocked + Assert.AreNotEqual( + System.Net.HttpStatusCode.Forbidden, + response.StatusCode, + $"PreviewImageUri returned 403 Forbidden: {imageUri}" + ); -Assert.IsTrue( - response.IsSuccessStatusCode, - "Failed to get PreviewImageUri at {0}: {1}", - imageUri, - response -); + Assert.IsTrue( + response.IsSuccessStatusCode, + $"Failed to get PreviewImageUri at {imageUri}: {response}" + ); } [TestMethod] @@ -70,34 +66,32 @@ public async Task TestLicenseUrl(BasePackage package) var licenseUri = new Uri(package.LicenseUrl); - // If is GitHub Uri, use jsdelivr instead due to rate limiting + // If GitHub URL, use jsDelivr to avoid rate limiting licenseUri = GitHubToJsDelivr(licenseUri); - // Test http head is successful with retry policy var response = await RetryPolicy.ExecuteAsync(async () => await HttpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, licenseUri)) ); - Assert.IsTrue( - response.IsSuccessStatusCode, - "Failed to get LicenseUrl at {0}: {1}", - licenseUri, - response - ); + Assert.IsTrue(response.IsSuccessStatusCode, $"Failed to get LicenseUrl at {licenseUri}: {response}"); } private static Uri GitHubToJsDelivr(Uri uri) { - // Like https://github.com/user/Repo/blob/main/LICENSE - // becomes: https://cdn.jsdelivr.net/gh/user/Repo@main/LICENSE - if (uri.Host.Equals("github.com", StringComparison.OrdinalIgnoreCase)) + // Example: + // https://github.com/user/Repo/blob/main/LICENSE + // becomes: + // https://cdn.jsdelivr.net/gh/user/Repo@main/LICENSE + + if (!uri.Host.Equals("github.com", StringComparison.OrdinalIgnoreCase)) + return uri; + + var segments = uri.AbsolutePath.Split('/', StringSplitOptions.RemoveEmptyEntries); + + if (segments is [var user, var repo, "blob", var branch, ..]) { - var segments = uri.AbsolutePath.Split('/', StringSplitOptions.RemoveEmptyEntries); - if (segments is [var user, var repo, "blob", var branch, ..]) - { - var path = string.Join("/", segments.Skip(4)); - return new Uri($"https://cdn.jsdelivr.net/gh/{user}/{repo}@{branch}/{path}"); - } + var path = string.Join("/", segments.Skip(4)); + return new Uri($"https://cdn.jsdelivr.net/gh/{user}/{repo}@{branch}/{path}"); } return uri; From ce0861cc9873eebf89f2491ae1f06632ef99d4a6 Mon Sep 17 00:00:00 2001 From: Domica Date: Tue, 20 Jan 2026 10:12:01 +0000 Subject: [PATCH 21/29] fix: sync WAN viewmodel and ComfyClient after cleanup --- .../InferenceWanTextToVideoViewModel.cs | 15 +++-- StabilityMatrix.Core/Inference/ComfyClient.cs | 57 ++++++++++--------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceWanTextToVideoViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceWanTextToVideoViewModel.cs index 54a69561e..3eae3478f 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceWanTextToVideoViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceWanTextToVideoViewModel.cs @@ -70,8 +70,8 @@ RunningPackageService runningPackageService BatchSizeCardViewModel = vmFactory.Get(); - VideoOutputSettingsCardViewModel = vmFactory.Get( - vm => vm.Fps = 16.0d + VideoOutputSettingsCardViewModel = vmFactory.Get(vm => + vm.Fps = 16.0d ); StackCardViewModel = vmFactory.Get(); @@ -94,7 +94,7 @@ protected override void BuildPrompt(BuildPromptEventArgs args) builder.Connections.Seed = args.SeedOverride switch { { } seed => Convert.ToUInt64(seed), - _ => Convert.ToUInt64(SeedCardViewModel.Seed) + _ => Convert.ToUInt64(SeedCardViewModel.Seed), }; // Load models @@ -115,14 +115,13 @@ protected override void BuildPrompt(BuildPromptEventArgs args) SamplerCardViewModel.ApplyStep(args); - // ADD THIS - Apply TiledVAE module + // Apply TiledVAE module TiledVAEModule.ApplyStep(args); - // ADD THIS LINE - Invoke pre-output actions BEFORE video output! + // Invoke pre-output actions BEFORE video output! args.Builder.InvokeAllPreOutputActions(); VideoOutputSettingsCardViewModel.ApplyStep(args); - } /// @@ -171,13 +170,13 @@ CancellationToken cancellationToken OutputNodeNames = buildPromptArgs.Builder.Connections.OutputNodeNames.ToArray(), Parameters = SaveStateToParameters(new GenerationParameters()) with { - Seed = Convert.ToUInt64(seed) + Seed = Convert.ToUInt64(seed), }, Project = inferenceProject, FilesToTransfer = buildPromptArgs.FilesToTransfer, BatchIndex = i, // Only clear output images on the first batch - ClearOutputImages = i == 0 + ClearOutputImages = i == 0, }; batchArgs.Add(generationArgs); diff --git a/StabilityMatrix.Core/Inference/ComfyClient.cs b/StabilityMatrix.Core/Inference/ComfyClient.cs index efa08c312..dbca6a66f 100644 --- a/StabilityMatrix.Core/Inference/ComfyClient.cs +++ b/StabilityMatrix.Core/Inference/ComfyClient.cs @@ -29,16 +29,15 @@ public class ComfyClient : InferenceClientBase private readonly IComfyApi comfyApi; private bool isDisposed; - private readonly JsonSerializerOptions jsonSerializerOptions = - new() + private readonly JsonSerializerOptions jsonSerializerOptions = new() + { + PropertyNamingPolicy = JsonNamingPolicies.SnakeCaseLower, + Converters = { - PropertyNamingPolicy = JsonNamingPolicies.SnakeCaseLower, - Converters = - { - new NodeConnectionBaseJsonConverter(), - new OneOfJsonConverter() - } - }; + new NodeConnectionBaseJsonConverter(), + new OneOfJsonConverter(), + }, + }; // ReSharper disable once MemberCanBePrivate.Global public string ClientId { get; } = Guid.NewGuid().ToString(); @@ -111,20 +110,20 @@ public ComfyClient(IApiFactory apiFactory, Uri baseAddress) { Scheme = "ws", Path = "/ws", - Query = $"clientId={ClientId}" + Query = $"clientId={ClientId}", }.Uri; webSocketClient = new WebsocketClient(wsUri) { Name = nameof(ComfyClient), - ReconnectTimeout = TimeSpan.FromSeconds(30) + ReconnectTimeout = TimeSpan.FromSeconds(30), }; - webSocketClient.DisconnectionHappened.Subscribe( - info => Logger.Info("Websocket Disconnected, ({Type})", info.Type) + webSocketClient.DisconnectionHappened.Subscribe(info => + Logger.Info("Websocket Disconnected, ({Type})", info.Type) ); - webSocketClient.ReconnectionHappened.Subscribe( - info => Logger.Info("Websocket Reconnected, ({Type})", info.Type) + webSocketClient.ReconnectionHappened.Subscribe(info => + Logger.Info("Websocket Reconnected, ({Type})", info.Type) ); webSocketClient.MessageReceived.Subscribe(OnMessageReceived); @@ -287,7 +286,7 @@ private void HandleBinaryMessage(byte[] data) Array.Reverse(typeBytes); }*/ - PreviewImageReceived?.Invoke(this, new ComfyWebSocketImageData { ImageBytes = data[8..], }); + PreviewImageReceived?.Invoke(this, new ComfyWebSocketImageData { ImageBytes = data[8..] }); } public override async Task ConnectAsync(CancellationToken cancellationToken = default) @@ -326,21 +325,23 @@ public override async Task CloseAsync(CancellationToken cancellationToken = defa await webSocketClient.Stop(WebSocketCloseStatus.NormalClosure, string.Empty).ConfigureAwait(false); } -public async Task QueuePromptAsync( - Dictionary nodes, - CancellationToken cancellationToken = default -) -{ - var request = new ComfyPromptRequest { ClientId = ClientId, Prompt = nodes }; + public async Task QueuePromptAsync( + Dictionary nodes, + CancellationToken cancellationToken = default + ) + { + var request = new ComfyPromptRequest { ClientId = ClientId, Prompt = nodes }; - var result = await comfyApi.PostPrompt(request, cancellationToken).ConfigureAwait(false); + var result = await comfyApi.PostPrompt(request, cancellationToken).ConfigureAwait(false); - var task = new ComfyTask(result.PromptId); - PromptTasks.TryAdd(result.PromptId, task); - currentPromptTask = task; + // Add task to dictionary and set it as the current task + var task = new ComfyTask(result.PromptId); + PromptTasks.TryAdd(result.PromptId, task); + currentPromptTask = task; + + return task; + } - return task; -} public async Task InterruptPromptAsync(CancellationToken cancellationToken = default) { await comfyApi.PostInterrupt(cancellationToken).ConfigureAwait(false); From 4bd67c93ff69e25a4a06500188d6c159d67037bc Mon Sep 17 00:00:00 2001 From: Domica Date: Wed, 21 Jan 2026 15:33:20 +0100 Subject: [PATCH 22/29] Update TiledVAEModule.cs Log --- .../ViewModels/Inference/Modules/TiledVAEModule.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs index 516751ff1..93864a1f4 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs @@ -4,6 +4,8 @@ using StabilityMatrix.Avalonia.ViewModels.Base; using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Models.Api.Comfy.Nodes; +using NLog; + namespace StabilityMatrix.Avalonia.ViewModels.Inference.Modules; From 989db8fb595e28c10bd58ad88b290471385a1855 Mon Sep 17 00:00:00 2001 From: Domica Date: Wed, 21 Jan 2026 15:41:51 +0100 Subject: [PATCH 23/29] Update InferenceWanTextToVideoViewModel.cs Correction --- .../Inference/InferenceWanTextToVideoViewModel.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceWanTextToVideoViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceWanTextToVideoViewModel.cs index 3eae3478f..e5ef2da79 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceWanTextToVideoViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceWanTextToVideoViewModel.cs @@ -115,12 +115,6 @@ protected override void BuildPrompt(BuildPromptEventArgs args) SamplerCardViewModel.ApplyStep(args); - // Apply TiledVAE module - TiledVAEModule.ApplyStep(args); - - // Invoke pre-output actions BEFORE video output! - args.Builder.InvokeAllPreOutputActions(); - VideoOutputSettingsCardViewModel.ApplyStep(args); } From ec8f8b514759be5fa0360fdf1881ecad56a0e0ef Mon Sep 17 00:00:00 2001 From: Domica Date: Wed, 21 Jan 2026 19:16:35 +0100 Subject: [PATCH 24/29] Update TiledVAEModule.cs Correction --- .../ViewModels/Inference/Modules/TiledVAEModule.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs index 93864a1f4..082cccd9b 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs @@ -16,6 +16,7 @@ public class TiledVAEModule : ModuleBase public TiledVAEModule(IServiceManager vmFactory) : base(vmFactory) { + this.logger = logger; Title = "Tiled VAE Decode"; AddCards(vmFactory.Get()); } From e25a344659794264972a4f14d566dca3a135fd81 Mon Sep 17 00:00:00 2001 From: Domica Date: Wed, 21 Jan 2026 19:46:49 +0100 Subject: [PATCH 25/29] Create buildexe.yml --- .github/workflows/buildexe.yml | 47 ++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .github/workflows/buildexe.yml diff --git a/.github/workflows/buildexe.yml b/.github/workflows/buildexe.yml new file mode 100644 index 000000000..819c3a283 --- /dev/null +++ b/.github/workflows/buildexe.yml @@ -0,0 +1,47 @@ +name: Build Stability Matrix (Windows) + +on: + push: + branches: [ "clean-main" ] + pull_request: + branches: [ "clean-main" ] + workflow_dispatch: + +jobs: + build-windows: + runs-on: windows-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup .NET SDK 9.x + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '9.0.x' + + - name: Restore Avalonia project + run: dotnet restore StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj + + - name: Restore Tests project + run: dotnet restore StabilityMatrix.Tests/StabilityMatrix.Tests.csproj + + - name: Build Avalonia project + run: dotnet build StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj -c Release --no-restore --no-cache + + - name: Build Tests project + run: dotnet build StabilityMatrix.Tests/StabilityMatrix.Tests.csproj -c Release --no-restore + + - name: Run Tests + run: dotnet test StabilityMatrix.Tests/StabilityMatrix.Tests.csproj -c Release --no-build + + - name: Publish Avalonia app (win10-x64) + run: dotnet publish StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -o ./publish/win10-x64 + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: StabilityMatrix-win10-x64 + path: ./publish/win10-x64/* + compression-level: 6 + retention-days: 14 From 4d0de2d2ef3e2e410f4ec464d014fd0170bdd8e6 Mon Sep 17 00:00:00 2001 From: Domica Date: Wed, 21 Jan 2026 19:52:09 +0100 Subject: [PATCH 26/29] Update TiledVAEModule.cs Logger correction --- .../ViewModels/Inference/Modules/TiledVAEModule.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs index 082cccd9b..36db2f0f1 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/Modules/TiledVAEModule.cs @@ -6,17 +6,17 @@ using StabilityMatrix.Core.Models.Api.Comfy.Nodes; using NLog; - namespace StabilityMatrix.Avalonia.ViewModels.Inference.Modules; [ManagedService] [RegisterTransient] public class TiledVAEModule : ModuleBase { + private static readonly Logger logger = LogManager.GetCurrentClassLogger(); + public TiledVAEModule(IServiceManager vmFactory) : base(vmFactory) { - this.logger = logger; Title = "Tiled VAE Decode"; AddCards(vmFactory.Get()); } @@ -36,11 +36,8 @@ protected override void OnApplyStep(ModuleApplyStepEventArgs e) var latent = builder.Connections.Primary.AsT0; var vae = builder.Connections.GetDefaultVAE(); - logger.LogDebug("TiledVAE: Injecting TiledVAEDecode"); - logger.LogDebug( - "UseCustomTemporalTiling value at runtime: {value}", - card.UseCustomTemporalTiling - ); + logger.Debug("TiledVAE: Injecting TiledVAEDecode"); + logger.Debug("UseCustomTemporalTiling value at runtime: {value}", card.UseCustomTemporalTiling); var node = builder.Nodes.AddTypedNode( new ComfyNodeBuilder.TiledVAEDecode From 53465f8e82f5fc301201383334ad9acd079bc6cc Mon Sep 17 00:00:00 2001 From: Domica Date: Wed, 21 Jan 2026 19:57:10 +0100 Subject: [PATCH 27/29] Update InferenceSettingsViewModel.cs Del --- .../Settings/InferenceSettingsViewModel.cs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs index 8e76bbc13..e54d1bace 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Settings/InferenceSettingsViewModel.cs @@ -69,10 +69,6 @@ public partial class InferenceSettingsViewModel : PageViewModelBase [ObservableProperty] private bool filterExtraNetworksByBaseModel; - [ObservableProperty] - private bool enableTiledVae; - - private List ignoredFileNameFormatVars = [ "author", @@ -195,13 +191,7 @@ ISettingsManager settingsManager settings => settings.InferenceDimensionStepChange, true ); - settingsManager.RelayPropertyFor( - this, - vm => vm.EnableTiledVae, - settings => settings.EnableTiledVae, - true - ); - + FavoriteDimensions .ToObservableChangeSet() .Throttle(TimeSpan.FromMilliseconds(50)) From b9fbcf1744dd6286ab7fd8f85c3bfbb4a47d5e76 Mon Sep 17 00:00:00 2001 From: Domica Date: Wed, 21 Jan 2026 19:57:50 +0100 Subject: [PATCH 28/29] Update Settings.cs --- StabilityMatrix.Core/Models/Settings/Settings.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/StabilityMatrix.Core/Models/Settings/Settings.cs b/StabilityMatrix.Core/Models/Settings/Settings.cs index 3669be144..1558037ff 100644 --- a/StabilityMatrix.Core/Models/Settings/Settings.cs +++ b/StabilityMatrix.Core/Models/Settings/Settings.cs @@ -100,9 +100,6 @@ public InstalledPackage? PreferredWorkflowPackage /// public bool IsCompletionRemoveUnderscoresEnabled { get; set; } = true; - /// NEW - public bool EnableTiledVae { get; set; } = false; - /// /// Format for Inference output image file names /// From 94d72996fcea58bf561f56361428e361917e580f Mon Sep 17 00:00:00 2001 From: Domica Date: Wed, 21 Jan 2026 20:03:46 +0100 Subject: [PATCH 29/29] Update TiledVAECard.axaml --- .../Controls/Inference/TiledVAECard.axaml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/StabilityMatrix.Avalonia/Controls/Inference/TiledVAECard.axaml b/StabilityMatrix.Avalonia/Controls/Inference/TiledVAECard.axaml index 79414e564..f5bc44cf8 100644 --- a/StabilityMatrix.Avalonia/Controls/Inference/TiledVAECard.axaml +++ b/StabilityMatrix.Avalonia/Controls/Inference/TiledVAECard.axaml @@ -52,9 +52,16 @@ - + + + + +