Skip to content

Commit dfac5ed

Browse files
authored
Merge pull request #1138 from ionite34/fixes-updates-and-mega-chagenlog
Fixed output browser refresh not loading new categories, streamlined …
2 parents 67b5983 + d33a5b7 commit dfac5ed

File tree

21 files changed

+671
-541
lines changed

21 files changed

+671
-541
lines changed

CHANGELOG.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,75 @@ All notable changes to Stability Matrix will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2.0.0.html).
77

8+
## v2.15.0
9+
### Added
10+
- Added new package - [AI Toolkit](https://github.com/ostris/ai-toolkit/)
11+
- Added new package - [FramePack](https://github.com/lllyasviel/FramePack)
12+
- Added new package - [FramePack Studio](https://github.com/colinurbs/FramePack-Studio)
13+
- Added Python Version selector for all new package installs
14+
- Added the ability to rename packages
15+
- Added support for authenticated model downloads in the HuggingFace model browser. Visit Settings → Accounts to add your HuggingFace token.
16+
- Added support for dragging-and-dropping Civitai-generated images into Inference to load metadata
17+
- Added the ability to search by pasting an entire Civitai model URL into the search bar in the Civitai model browser
18+
- Added "Clear Pip Cache" and "Clear uv Cache" commands to the Settings -> Embedded Python section
19+
- Added settings to disable base models from appearing in the Checkpoint Manager and Civitai Model Browser base model selectors
20+
- Added Inference "Favorite Dimensions" quick selector - editable in Settings → Inference, or click the 💾 button inside the dropdown
21+
- Added setting for Inference dimension step change - the value the dimensions increase or decrease by when using the step buttons or scroll wheel in Inference
22+
- Added "Install Nunchaku" option to the ComfyUI Package Commands menu
23+
- Added "Select All" button to the Installed Extensions page
24+
- Added experimental ROCm pytorch install for ComfyUI (non-Zluda) on Windows - requires a compatible AMD GPU
25+
- Added base model type labels (SD1.5, SDXL, Flux, etc.) to Inference model selection boxes
26+
- Added UNET shared folder link for SD.Next
27+
- Added Manual Install button for installing Package extensions that aren't in the indexes
28+
- Added Next and Previous buttons to the Civitai details page to navigate between results
29+
- Added Negative Rejection Steering (NRS) by @reithan to Inference
30+
- Added Wan 2.2 models to the HuggingFace tab of the model browser
31+
- Added Tiled Encode/Decode options to FaceDetailer in Inference
32+
- Added Ukrainian translation thanks to @r0ddty!
33+
- Added Czech translation thanks to @PEKArt!
34+
### Changed
35+
🌟 Civitai Model Details: A Grand Reimagining! 🌟
36+
- No more peering through a tiny window! Introducing a massive overhaul of the Civitai Model Details page, transforming it from a cramped dialog into a spacious, feature-rich hub for all your model exploration needs.
37+
- We've listened to your howls for more, and now you can dive deep into every aspect of your favorite models with unprecedented clarity and control:
38+
- Expansive View: The new full-page layout means all essential information, descriptions, and previews are laid out beautifully, banishing the old, restrictive dialog forever.
39+
- Rich Details at a Glance: Author, base model, last updated, SHA hashes, file name overrides/patterns – everything you need, perfectly organized and always accessible.
40+
- Overhauled Image Viewer: Enjoy a sleek, modern image viewer that includes Civitai metadata and supports zooming, panning, and full-screen viewing. No more squinting at tiny thumbnails!
41+
- Integrated Inference Options: For supported models, adjust sampler, scheduler, steps, CFG Scale, width, and height directly from the details page, streamlining your workflow like never before!
42+
----
43+
- Updated all Python version management, virtual environment creation, and pip installs to use `uv` for improved reliability, compatibility, and speed
44+
- You can now select release versions when installing ComfyUI
45+
- You can no longer select branches when installing InvokeAI
46+
- Updated InvokeAI install to use the intended install method (resolves [#1329](https://github.com/LykosAI/StabilityMatrix/issues/1329))
47+
- Updated ComfyUI installs for AMD users on Linux to use the latest rocm6.3 torch index
48+
- Updated ComfyUI-Zluda installs to use the newer install-n method (fixes [#1347](https://github.com/LykosAI/StabilityMatrix/issues/1347))
49+
- Removed disclaimer from reForge since the author is now active again
50+
- Updated git operations to better avoid conflicts
51+
- Updated Japanese translation
52+
- Civitai model browser image loading now uses dynamic resizing for better performance and a smoother scrolling experience
53+
- Undo ComfyUI process tracking changes for now due to causing more issues than it solved
54+
- Updated GPU parsing fallback on Linux systems to use the method provided by @irql-notlessorequal
55+
- New installs of ComfyUI, SD.Next, and InvokeAI will now use Python 3.12, unless otherwise specified in the Advanced Options during installation
56+
- New installs of all other packages will now use Python 3.10.18, unless otherwise specified in the Advanced Options during installation
57+
- Updated ComfyUI installs for AMD users on Linux to use the latest rocm6.4 torch index
58+
- Updated package delete confirmation dialog
59+
### Fixed
60+
- Fixed an error when packages and other processes exit before process tracking on windows can initialize
61+
- Fixed "none" appearing in wildcard field when using Face Detailer in Inference
62+
- Fixed [#1254](https://github.com/LykosAI/StabilityMatrix/issues/1254) - Unable to scroll samplers in Inference
63+
- Fixed [#1294](https://github.com/LykosAI/StabilityMatrix/issues/1294) - Improper sorting of output folders in Output Browser
64+
- Fixed [#1300](https://github.com/LykosAI/StabilityMatrix/issues/1300) - Git errors when installing Extension Packs
65+
- Fixed [#1317](https://github.com/LykosAI/StabilityMatrix/issues/1317) - Inference missing GGUF text encoders
66+
- Fixed [#1324](https://github.com/LykosAI/StabilityMatrix/issues/1324) - Window height slightly increasing every launch
67+
- Fixed [#1357](https://github.com/LykosAI/StabilityMatrix/issues/1357) - Case insensitivity causing duplicate key exceptions on non-Windows systems
68+
- Fixed [#1360](https://github.com/LykosAI/StabilityMatrix/issues/1360) - A1111 install not using correct torch for 5000-series GPUs
69+
- Fixed [#1361](https://github.com/LykosAI/StabilityMatrix/issues/1361) - numpy and other Forge startup
70+
- Fixed [#1365](https://github.com/LykosAI/StabilityMatrix/issues/1365) - Output folder list not updating when Refresh button clicked
71+
### Supporters
72+
#### 🌟 Visionaries
73+
To our incredible Visionaries, the architects of our ambition: Your profound support is the powerhouse behind this massive v2.15.0 release. You don't just light the path; you fuel the entire journey, allowing us to build bigger, move faster, and turn bold ideas into reality. Our deepest gratitude to: **Waterclouds**, **Corey T**, **bluepopsicle**, **Bob S**, **Ibixat**, **whudunit**, and **TheTekknician**! We are immensely grateful for your trust and partnership in shaping the future of Stability Matrix. Thank you for everything!
74+
#### 🚀 Pioneers
75+
A heartfelt salute to our trailblazing Pioneers! Your consistent support helps us navigate the development landscape, ensuring we stay on the right track and can explore new frontiers. A huge thanks to: **tankfox**, **Mr. Unknown**, **Szir777**, **Tigon**, **Noah M**, **USATechDude**, **Thom**, **SeraphOfSalem**, and a special welcome to our newest Pioneers - **Desert Viber**, **Tundra Everquill**, **Adam**, and **Droolguy**! Thank you for being the vanguard of our community!
76+
877
## v2.15.0-pre.2
978
### Added
1079
- Added new package - [AI Toolkit](https://github.com/ostris/ai-toolkit/)

StabilityMatrix.Avalonia/Models/TreeViewDirectory.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,7 @@ public partial class TreeViewDirectory : ObservableObject
88
public ObservableCollection<TreeViewDirectory> SubDirectories { get; set; } = new();
99
public required string Name { get; set; }
1010
public required string Path { get; set; }
11+
12+
[ObservableProperty]
13+
public partial bool IsExpanded { get; set; }
1114
}

StabilityMatrix.Avalonia/ViewModels/CheckpointBrowser/CivitDetailsPageViewModel.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,9 @@ modelType is CivitModelType.Checkpoint
916916
baseModelType == CivitBaseModelType.Flux1D.GetStringValue()
917917
|| baseModelType == CivitBaseModelType.Flux1S.GetStringValue()
918918
|| baseModelType == CivitBaseModelType.WanVideo.GetStringValue()
919+
|| baseModelType?.StartsWith("Wan", StringComparison.OrdinalIgnoreCase) is true
920+
|| baseModelType?.StartsWith("Flux", StringComparison.OrdinalIgnoreCase) is true
921+
|| baseModelType?.StartsWith("Hunyuan", StringComparison.OrdinalIgnoreCase) is true
919922
)
920923
)
921924
{

StabilityMatrix.Avalonia/ViewModels/OutputsPageViewModel.cs

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,8 @@ private void RefreshCategories()
656656
.Select(packageFactory.GetPackagePair)
657657
.WhereNotNull()
658658
.Where(p =>
659-
p.BasePackage.SharedOutputFolders is { Count: > 0 } && p.InstalledPackage.FullPath != null
659+
p.BasePackage.SharedOutputFolders is { Count: > 0 }
660+
&& p.InstalledPackage is { FullPath: not null }
660661
)
661662
.Select(pair => new TreeViewDirectory
662663
{
@@ -679,9 +680,15 @@ private void RefreshCategories()
679680
}
680681
);
681682

682-
categoriesCache.EditDiff(packageCategories, (a, b) => a.Path == b.Path);
683+
categoriesCache.Edit(updater => updater.Load(packageCategories));
683684

684-
SelectedCategory = previouslySelectedCategory ?? Categories.First();
685+
if (!string.IsNullOrWhiteSpace(previouslySelectedCategory?.Path))
686+
{
687+
FindAndExpandPathToCategory(Categories, previouslySelectedCategory.Path);
688+
}
689+
690+
SelectedCategory =
691+
FindCategoryByPath(Categories, previouslySelectedCategory?.Path) ?? Categories.FirstOrDefault();
685692
}
686693

687694
private ObservableCollection<TreeViewDirectory> GetSubfolders(string strPath)
@@ -713,4 +720,75 @@ private ObservableCollection<TreeViewDirectory> GetSubfolders(string strPath)
713720

714721
return subfolders;
715722
}
723+
724+
private TreeViewDirectory? FindCategoryByPath(IEnumerable<TreeViewDirectory> nodes, string? path)
725+
{
726+
// Can't find a category if the path is null or empty
727+
if (string.IsNullOrEmpty(path))
728+
{
729+
return null;
730+
}
731+
732+
foreach (var node in nodes)
733+
{
734+
// Check if the current node is the one we're looking for
735+
if (node.Path == path)
736+
{
737+
return node;
738+
}
739+
740+
if (node.SubDirectories is not { Count: > 0 })
741+
continue;
742+
743+
// If not, and if this node has children, search within its children
744+
var foundInChildren = FindCategoryByPath(node.SubDirectories, path);
745+
if (foundInChildren != null)
746+
{
747+
// Found it in a sub-directory, so return it up the call stack
748+
return foundInChildren;
749+
}
750+
}
751+
752+
// If we've searched all nodes at this level and their children without success
753+
return null;
754+
}
755+
756+
/// <summary>
757+
/// Recursively searches for a category by its path and expands all parent nodes along the way.
758+
/// </summary>
759+
/// <param name="nodes">The collection of nodes to search within.</param>
760+
/// <param name="targetPath">The path of the node to find.</param>
761+
/// <returns>True if the target node was found in this branch; otherwise, false.</returns>
762+
private bool FindAndExpandPathToCategory(IEnumerable<TreeViewDirectory> nodes, string? targetPath)
763+
{
764+
if (string.IsNullOrEmpty(targetPath))
765+
{
766+
return false;
767+
}
768+
769+
foreach (var node in nodes)
770+
{
771+
// First, check if the target is a direct descendant of this node.
772+
// This is the recursive part.
773+
if (
774+
node.SubDirectories is { Count: > 0 }
775+
&& FindAndExpandPathToCategory(node.SubDirectories, targetPath)
776+
)
777+
{
778+
// If the recursive call returns true, it means the target was found
779+
// in this node's children. Therefore, this node is an ancestor and
780+
// must be expanded.
781+
node.IsExpanded = true;
782+
return true; // Bubble "true" up to the parent.
783+
}
784+
785+
// After checking children, check if the current node itself is the target.
786+
if (node.Path == targetPath)
787+
{
788+
return true; // Found it. Start the "bubble up" of true values.
789+
}
790+
}
791+
792+
return false; // Target was not found in this collection of nodes.
793+
}
716794
}

StabilityMatrix.Avalonia/Views/OutputsPage.axaml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
xmlns:lang="clr-namespace:StabilityMatrix.Avalonia.Languages"
1111
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
1212
xmlns:mocks="clr-namespace:StabilityMatrix.Avalonia.DesignData"
13+
xmlns:models="clr-namespace:StabilityMatrix.Avalonia.Models"
1314
xmlns:outputsPage="clr-namespace:StabilityMatrix.Avalonia.ViewModels.OutputsPage"
1415
xmlns:scroll="clr-namespace:StabilityMatrix.Avalonia.Controls.Scroll"
1516
xmlns:selectableImageCard="clr-namespace:StabilityMatrix.Avalonia.Controls.SelectableImageCard"
@@ -48,7 +49,16 @@
4849
Margin="0,0,12,0"
4950
IsVisible="{Binding ShowFolders}"
5051
ItemsSource="{Binding Categories}"
51-
SelectedItem="{Binding SelectedCategory}">
52+
SelectedItem="{Binding SelectedCategory}"
53+
SelectionMode="AlwaysSelected">
54+
<TreeView.ItemContainerTheme>
55+
<ControlTheme
56+
x:DataType="models:TreeViewDirectory"
57+
BasedOn="{StaticResource {x:Type TreeViewItem}}"
58+
TargetType="TreeViewItem">
59+
<Setter Property="IsExpanded" Value="{Binding IsExpanded}" />
60+
</ControlTheme>
61+
</TreeView.ItemContainerTheme>
5262
<TreeView.ItemTemplate>
5363
<TreeDataTemplate ItemsSource="{Binding SubDirectories}">
5464
<TextBlock

StabilityMatrix.Core/Helper/ProcessTracker.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ public JobObject(string name)
199199

200200
Name = name;
201201

202-
handle = CreateJobObjectA(IntPtr.Zero, name);
202+
handle = CreateJobObject(IntPtr.Zero, name);
203203

204204
var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION
205205
{
@@ -271,10 +271,15 @@ protected override bool ReleaseHandle()
271271
}
272272
}
273273

274-
[LibraryImport("kernel32.dll", StringMarshalling = StringMarshalling.Utf16)]
275-
private static partial IntPtr CreateJobObjectA(IntPtr lpJobAttributes, string name);
274+
[LibraryImport(
275+
"kernel32.dll",
276+
EntryPoint = "CreateJobObjectW",
277+
SetLastError = true,
278+
StringMarshalling = StringMarshalling.Utf16
279+
)]
280+
private static partial IntPtr CreateJobObject(IntPtr lpJobAttributes, string name);
276281

277-
[LibraryImport("kernel32.dll")]
282+
[LibraryImport("kernel32.dll", SetLastError = true)]
278283
[return: MarshalAs(UnmanagedType.Bool)]
279284
private static partial bool SetInformationJobObject(
280285
IntPtr job,

StabilityMatrix.Core/Models/Packages/A3WebUI.cs

Lines changed: 28 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -204,77 +204,51 @@ public override async Task InstallPackage(
204204
)
205205
{
206206
progress?.Report(new ProgressReport(-1f, "Setting up venv", isIndeterminate: true));
207-
208207
await using var venvRunner = await SetupVenvPure(
209208
installLocation,
210209
pythonVersion: options.PythonOptions.PythonVersion
211210
)
212211
.ConfigureAwait(false);
213212

214-
await venvRunner.PipInstall("--upgrade pip wheel", onConsoleOutput).ConfigureAwait(false);
215-
216-
progress?.Report(new ProgressReport(-1f, "Installing requirements...", isIndeterminate: true));
217-
218-
var torchVersion = options.PythonOptions.TorchIndex ?? GetRecommendedTorchVersion();
213+
var torchIndex = options.PythonOptions.TorchIndex ?? GetRecommendedTorchVersion();
219214
var isBlackwell =
220-
torchVersion is TorchIndex.Cuda
215+
torchIndex is TorchIndex.Cuda
221216
&& (SettingsManager.Settings.PreferredGpu?.IsBlackwellGpu() ?? HardwareHelper.HasBlackwellGpu());
222217

223-
var requirements = new FilePath(installLocation, "requirements_versions.txt");
224-
var pipArgs = torchVersion switch
218+
// 1. Configure the entire install process declaratively.
219+
var config = new PipInstallConfig
225220
{
226-
TorchIndex.Mps => new PipInstallArgs().WithTorch("==2.3.1").WithTorchVision("==0.18.1"),
227-
_ => new PipInstallArgs()
228-
.WithTorch(isBlackwell ? string.Empty : "==2.1.2")
229-
.WithTorchVision(isBlackwell ? string.Empty : "==0.16.2")
230-
.WithTorchExtraIndex(
231-
torchVersion switch
232-
{
233-
TorchIndex.Cpu => "cpu",
234-
TorchIndex.Cuda when isBlackwell => "cu128",
235-
TorchIndex.Cuda => "cu121",
236-
TorchIndex.Rocm => "rocm5.6",
237-
TorchIndex.Mps => "cpu",
238-
_ => throw new NotSupportedException($"Unsupported torch version: {torchVersion}"),
239-
}
240-
),
221+
RequirementsFilePaths = ["requirements_versions.txt"],
222+
TorchVersion = torchIndex == TorchIndex.Mps ? "==2.3.1" : (isBlackwell ? "" : "==2.1.2"),
223+
TorchvisionVersion = torchIndex == TorchIndex.Mps ? "==0.18.1" : (isBlackwell ? "" : "==0.16.2"),
224+
XformersVersion = isBlackwell ? " " : "==0.0.23.post1",
225+
CudaIndex = isBlackwell ? "cu128" : "cu121",
226+
RocmIndex = "rocm5.6",
227+
ExtraPipArgs =
228+
[
229+
"https://github.com/openai/CLIP/archive/d50d76daa670286dd6cacf3bcd80b5e4823fc8e1.zip",
230+
],
241231
};
242232

243-
if (torchVersion == TorchIndex.Cuda)
244-
{
245-
pipArgs = pipArgs.WithXFormers("==0.0.23.post1");
246-
}
247-
248-
if (installedPackage.PipOverrides != null)
249-
{
250-
pipArgs = pipArgs.WithUserOverrides(installedPackage.PipOverrides);
251-
}
252-
253-
await venvRunner.PipInstall(pipArgs, onConsoleOutput).ConfigureAwait(false);
254-
255-
pipArgs = new PipInstallArgs(
256-
"https://github.com/openai/CLIP/archive/d50d76daa670286dd6cacf3bcd80b5e4823fc8e1.zip"
257-
).WithParsedFromRequirementsTxt(
258-
await requirements.ReadAllTextAsync(cancellationToken).ConfigureAwait(false),
259-
excludePattern: "torch"
260-
);
261-
262-
if (installedPackage.PipOverrides != null)
263-
{
264-
pipArgs = pipArgs.WithUserOverrides(installedPackage.PipOverrides);
265-
}
266-
267-
await venvRunner.PipInstall(pipArgs, onConsoleOutput).ConfigureAwait(false);
233+
// 2. Execute the standardized installation process.
234+
await StandardPipInstallProcessAsync(
235+
venvRunner,
236+
options,
237+
installedPackage,
238+
config,
239+
onConsoleOutput,
240+
progress,
241+
cancellationToken
242+
)
243+
.ConfigureAwait(false);
268244

245+
// 3. Perform any final, package-specific tasks.
269246
progress?.Report(new ProgressReport(-1f, "Updating configuration", isIndeterminate: true));
270-
271-
// Create and add {"show_progress_type": "TAESD"} to config.json
272-
// Only add if the file doesn't exist
273247
var configPath = Path.Combine(installLocation, "config.json");
274248
if (!File.Exists(configPath))
275249
{
276-
var config = new JsonObject { { "show_progress_type", "TAESD" } };
277-
await File.WriteAllTextAsync(configPath, config.ToString(), cancellationToken)
250+
var configJson = new JsonObject { { "show_progress_type", "TAESD" } };
251+
await File.WriteAllTextAsync(configPath, configJson.ToString(), cancellationToken)
278252
.ConfigureAwait(false);
279253
}
280254

0 commit comments

Comments
 (0)