Skip to content
Merged

v2.16.2 #1700

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
2265802
Merge pull request #1279 from ionite34/inference-auto-generate-after-…
mohnjiles Jun 16, 2026
b791c9f
Merge pull request #1280 from ionite34/optimize-image-grid-performance
mohnjiles Jun 21, 2026
67025fa
Merge pull request #1281 from ionite34/fix-appimage-desktop-file
mohnjiles Jun 18, 2026
262bb12
Merge pull request #1285 from ionite34/backport/main/pr-1279
mohnjiles Jun 21, 2026
6ae7305
fix chagenlog merge
mohnjiles Jun 21, 2026
9c44d54
Merge branch 'main' into backport/main/pr-1281
mohnjiles Jun 21, 2026
22a3aed
Merge branch 'main' into backport/main/pr-1280
mohnjiles Jun 21, 2026
208d1d4
Merge pull request #1287 from ionite34/backport/main/pr-1281
mohnjiles Jun 21, 2026
111bb10
Merge branch 'main' into backport/main/pr-1280
mohnjiles Jun 21, 2026
c8ea3b1
Merge pull request #1286 from ionite34/backport/main/pr-1280
mohnjiles Jun 21, 2026
6d56722
Merge pull request #1288 from ionite34/generate-after-launch-chagenlog
mohnjiles Jun 22, 2026
fba8487
Update CHANGELOG.md
mohnjiles Jun 22, 2026
6cf5644
Merge pull request #1289 from ionite34/backport/main/pr-1288
mohnjiles Jun 22, 2026
ed3bec0
Support new Civitai file types (Diffusion Model, Text Encoder, ...)
mohnjiles Jul 6, 2026
a3c88d5
Apply Gemini review: centralize shared-folder routing for Civit files
mohnjiles Jul 6, 2026
78833d7
Route Krea 2 checkpoints to DiffusionModels in UNet-only fallback
mohnjiles Jul 6, 2026
22e9365
Add 2.16.2 changelog entries for CivitAI file type support
mohnjiles Jul 6, 2026
6b15866
Apply Gemini review: restore null-safety in Civit file selection
mohnjiles Jul 7, 2026
89f6216
Merge pull request #1297 from ionite34/civit-new-file-types
mohnjiles Jul 7, 2026
ed6aedf
Merge pull request #1295 from ionite34/paint-canvas-perf-and-crash-ha…
mohnjiles Jul 8, 2026
1075d82
fix chagenlog merge
mohnjiles Jul 15, 2026
ab0c043
Merge pull request #1301 from ionite34/backport/main/pr-1295
mohnjiles Jul 15, 2026
0279efa
Merge pull request #1303 from ionite34/claude/bug-bash-2-16-2-5ac12b
mohnjiles Jul 17, 2026
852b377
fix merg
mohnjiles Jul 18, 2026
8206c79
fix merg
mohnjiles Jul 18, 2026
72c769e
fix chagenlog merge
mohnjiles Jul 18, 2026
b621e7a
Remove dangling dialog fragment left by extension-check conflict reso…
mohnjiles Jul 18, 2026
e4f8f1a
Merge pull request #1304 from ionite34/backport/main/pr-1303
mohnjiles Jul 18, 2026
a670ffb
Merge branch 'main' of https://github.com/LykosAI/StabilityMatrix-Dev…
mohnjiles Jul 18, 2026
86a91ea
Add changelog entries for the docs site, FUSE3 AppImage, and bnb wheel
mohnjiles Jul 18, 2026
aaac9c1
Apply Gemini review: fix Jenkins pupnet command version var and -y flag
mohnjiles Jul 18, 2026
77c1166
Merge pull request #1305 from ionite34/downmerg-from-public
mohnjiles Jul 18, 2026
3a92927
Merge branch 'main' of https://github.com/LykosAI/StabilityMatrix-Dev…
mohnjiles Jul 18, 2026
fe482fb
Add OneTrainer Windows ROCm changelog entries; tighten 2.16.2 wording
mohnjiles Jul 18, 2026
650144a
docs: add v2.16.2 technical release notes page
mohnjiles Jul 18, 2026
b62d81b
Merge pull request #1307 from ionite34/downmerg-from-public
mohnjiles Jul 19, 2026
2c964b1
Merge pull request #1311 from ionite34/docs-fluid-width-toggle
mohnjiles Jul 19, 2026
71c3f08
Merge pull request #1312 from ionite34/backport/main/pr-1311
mohnjiles Jul 19, 2026
5df0927
Merge branch 'main' of https://github.com/LykosAI/StabilityMatrix-Dev…
mohnjiles Jul 26, 2026
c454096
Merge pull request #1314 from ionite34/downmerg-from-public
mohnjiles Jul 26, 2026
4761d7e
Merge pull request #1318 from ionite34/civit-null-stats-deleted-pages
mohnjiles Aug 2, 2026
295bddd
fix chagenlog
mohnjiles Aug 2, 2026
c8133e3
Merge pull request #1319 from ionite34/backport/main/pr-1318
mohnjiles Aug 2, 2026
59b2054
Merge pull request #1320 from ionite34/changelog/v2.16.2-shoutouts
mohnjiles Aug 2, 2026
ff6b5ba
fix chagenlog
mohnjiles Aug 2, 2026
3581283
Merge pull request #1321 from ionite34/backport/main/pr-1320
mohnjiles Aug 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,57 @@ All notable changes to Stability Matrix will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2.0.0.html).

## v2.16.2
> Full technical notes for this release: [docs.lykos.ai/stability-matrix/release-notes/2.16.2](https://docs.lykos.ai/stability-matrix/release-notes/2.16.2)
### Added
- πŸ“š **New documentation site** at [docs.lykos.ai](https://docs.lykos.ai/stability-matrix/) β€” getting started and installation guides, package manager and Inference walkthroughs, environment variable and advanced configuration references, a terminology glossary, and troubleshooting for common issues. Written by @NeuralFault!
- Added **OneTrainer** to the native **Windows ROCm (AMD GPU)** helper β€” new OneTrainer installs on supported AMD hardware get the ROCm PyTorch build, ROCm-aware bitsandbytes and triton dependencies, and the right launch environment applied automatically. New OneTrainer installs also default to Python 3.12 on all platforms - thanks to @NeuralFault!
### Changed
- **Generate now auto-resumes after launching ComfyUI.** If you press Generate in Inference while ComfyUI isn't connected and choose to launch it from the connection prompt, the queued generation now waits for startup and runs on its own once connected - no need to press Generate a second time
- Updated the **Windows ROCm helper**'s bundled bitsandbytes wheel to a build compatible with ROCm 7.13–7.15, so it keeps working as AMD's ROCm Technical Preview builds update - thanks to @NeuralFault!
- CivitAI downloads now pick their destination folder from the file's declared type (**Diffusion Model**/**UNet** β†’ DiffusionModels, **Text Encoder** β†’ TextEncoders, **CLIP Vision** β†’ ClipVision, **ControlNet** β†’ ControlNet, **Upscaler** β†’ upscalers) instead of guessing from the model's name. Name-based guessing remains only for files typed plain "Model", and now recognizes **Krea 2** checkpoints as UNet-only
### Fixed
- Fixed a class of random crashes in the Inference **mask editor** and **image annotation editor** β€” undo/redo, layer operations, exporting, or closing the editor could free graphics resources that were still being drawn with, occasionally crashing mid-stroke or while saving. Canvas rendering has been restructured so this can't happen
- Fixed **pen pressure** re-widening the whole stroke instead of following the pen while drawing, and mouse-drawn strokes coming back ~25% thicker after saving and reopening a project. Existing project files load exactly as before
- Fixed the mask editor and image annotation editor leaking graphics memory β€” the paint canvas wasn't released on close, and paint-bucket fills were never freed
- Fixed fast brush strokes occasionally failing with a "collection was modified" error while the stroke was still being drawn
- Fixed opening older projects whose masks contained stroke points outside the canvas failing with an overflow error
- Fixed a potential crash when the paint canvas rendered before its size was set
- Fixed CivitAI models showing an empty Files section with no download links when their files use CivitAI's newer type labels (e.g. **Krea 2 Turbo** and **Z-Image**, typed **Diffusion Model** or **Text Encoder**). All current CivitAI file types are now recognized across the browser, details page, version dialog, bulk download, and installed/update detection
- Fixed CivitAI "Download with Stability Matrix" links saving UNet-only checkpoints (Flux, Wan Video, Hunyuan, Krea 2) into the **StableDiffusion** folder β€” external links now use the same destination logic as the in-app browser
- Fixed [#1666](https://github.com/LykosAI/StabilityMatrix/issues/1666) - AppImage builds creating a broken `.desktop` entry that never appeared in the application launcher and reverted manual edits on the next launch. AppImage runs now install a proper launcher entry with the app icon, and the running window shows the correct icon in the dock/taskbar (deb/rpm/flatpak installs keep their package-managed entries)
- Fixed `stabilitymatrix://` deep links (e.g. CivitAI "Download with Stability Matrix" buttons) being ignored on Linux AppImage builds
- Fixed [#1668](https://github.com/LykosAI/StabilityMatrix/issues/1668) - the **Output Browser** crashing on open when an output folder contained a broken junction or symlink (a folder whose target no longer exists); those entries are now skipped instead of taking the page down
- Fixed [#1681](https://github.com/LykosAI/StabilityMatrix/issues/1681) - Inference generation with **FaceDetailer** failing instantly with "An item with the same key has already been added" when two installed custom node folders share the same git remote
- Fixed [#1679](https://github.com/LykosAI/StabilityMatrix/issues/1679) - model details pages never showing the **Installed** label, delete button, or version checkmark for files whose type displays as "Unknown". Installed detection now goes by file hash, so it works no matter what type CivitAI reports
- Fixed [#1667](https://github.com/LykosAI/StabilityMatrix/issues/1667) - importing an existing package folder silently pre-selecting **Forge** as the package type, misclassifying re-imported packages. The type is now auto-detected from the folder's git remote
- Fixed [#1669](https://github.com/LykosAI/StabilityMatrix/issues/1669) - **Stable Diffusion WebUI reForge** installing the CUDA build of PyTorch on Linux AMD systems even with ROCm selected
- Fixed [#1672](https://github.com/LykosAI/StabilityMatrix/issues/1672) - **Image Lab** failing with a generic "ComfyUI rejected the workflow" error when generating with a GGUF model while the **ComfyUI-GGUF** extension isn't installed β€” it now offers the same one-click **install and restart** prompt as Inference
- Fixed GGUF-quantized **text encoders** failing with a ComfyUI error when selected β€” they now load through the ComfyUI-GGUF CLIP loaders in all Inference workflows and Image Lab (mixed GGUF + safetensors selections work too), with the install prompt appearing if the extension is missing
- Fixed **Chroma** and other single-encoder models being impossible to configure in Inference UNet workflows β€” the encoder **Type** dropdown was missing `chroma` and other single-encoder types, and the closest option (`flux`) demanded a second encoder these models don't use. The missing types are now listed, and single-encoder types get a single encoder slot
- Fixed GGUF text encoders in the shared **TextEncoders** folder not appearing in the Inference Text Encoder dropdowns while connected to ComfyUI
- Fixed [#1682](https://github.com/LykosAI/StabilityMatrix/issues/1682) - the Linux **AppImage** failing to start on modern distros (Ubuntu 24.04+, Fedora 40+) that no longer ship `libfuse2`. The AppImage now uses a FUSE3-based runtime, and falls back to extract-and-run when FUSE isn't available at all - thanks to @NeuralFault!
- Fixed the Model Browser failing with "CivitAI can't be reached right now (OK: OK)" β€” CivitAI recently started returning `null` for some model statistics (download counts, ratings), which broke loading the whole page of results. Missing stats are now read as 0
- Fixed [#1695](https://github.com/LykosAI/StabilityMatrix/issues/1695) - models whose CivitAI page has since been deleted showing an error dialog on every click, with no way to break the link:
- The model details page now shows locally cached info instead of a dead page when the CivitAI page is gone
- **Next/Previous** on the details page skip over deleted models instead of getting stuck on an error
- New right-click **Disconnect from Source** action on Checkpoint Manager cards severs the link to the deleted page while keeping the local metadata (name, description, thumbnail, trigger words) β€” after disconnecting, clicking the card selects it like any other local model
- Fixed **OneTrainer** failing to launch with current upstream versions after its UI script was renamed (`train_ui.py` β†’ `train_ui_ctk.py`) - thanks to @NeuralFault!
### Performance
- Dragging an image layer with the **Move** tool in the layered mask editor now re-renders only the dragged layer instead of re-compositing every layer on each pointer move, so dragging stays smooth in multi-layer projects
- Faster color-mask extraction for regional prompting β€” a 1024Γ—1024 canvas with six regions previously did over six million dictionary lookups per extraction
- Fixed a small native memory leak while drawing with the mouse (a path object per frame was never freed), and removed a redundant full-canvas scan after every paint-bucket fill
- The **Checkpoints** and **Outputs** galleries now load thumbnails at display size instead of full resolution, using far less memory and scrolling much more smoothly with large libraries
- The **CivitAI** and **OpenModelDB** browsers now keep card images in memory, so scrolling back over models you've already seen no longer re-loads them from disk
- Lightened the CivitAI model cards so they render faster while scrolling
### Security
- Bundled **ADetailer** model downloads now point at a fixed Hugging Face revision instead of the repository's moving `main` branch, so an upstream re-upload can't change what you get - thanks to @ungrav!
### Supporters
#### 🌟 Visionaries
There's not much glamour in a release like this one: crashes hunted down in the mask editor, downloads finally landing in the folders they belong in, Linux installs that just start. Our Visionaries are the reason we can hand a whole cycle to that kind of work, and to writing the documentation that now lives inside the app. Thank you **Waterclouds**, **MrMxyzptlk12836**, **Psilocyfer18731**, **bluepopsicle**, **Ibixat**, **Droolguy**, **KalAbaddon**, **LG**, **snotty**, **whudunit**, **cusalapapen1481**, and **moon_milky2843** for backing the unglamorous parts as generously as the exciting ones. And a warm welcome to **tarekk071223**, **CC**, and **SnooSnooEternal**, the newest names on this list; it's genuinely good to have you here. πŸ’›
#### πŸš€ Pioneers
Our Pioneers hold up the other half of this, and what a steady crew you are: **Szir777**, **[USA]TechDude**, **SinthCore**, **Jisuren**, **Tigon**, **jweg79**, **rwx14662**, **Hurbie53**, **ahnhj.al**, **drew.lukas**, **Tuskaruho**, **Cjloha**, **Alligator1907**, **Bitti**, **Ghislain G**, **CommissarGiygas16050**, **qob97515211**, **bastardofbethlehem**, and **Zombop**, thank you for sticking around release after release. A big hello as well to **Silerae**, **joshsciascia72**, and **rad64741317**, who join the Pioneers this time; we're really happy you're with us. Every fix in this changelog has a bit of all of you behind it. πŸ’›

## v2.16.1
### Added
- Added **automatic text encoder and VAE selection** to the Inference Model card. Selecting a model now fills any empty encoder slots and the default VAE with the matching local files for the detected workflow, so you don't need to know which files pair with which architecture (e.g. `qwen_3_4b` or `qwen_3_8b` + Flux.2 VAE for Flux.2 Klein, `clip_l` + `t5xxl` for Flux, `qwen_3_06b` + `qwen_image_vae` for Anima). Anything you pick manually is never overridden
Expand Down
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ node("Diligence") {
// - pupnet 1.9.1 globally installed
sh "rm -rf StabilityMatrix.Avalonia/bin/*"
sh "rm -rf StabilityMatrix.Avalonia/obj/*"
sh "/home/jenkins/.dotnet/tools/pupnet -r linux-x64 -c Release --kind appimage --app-version $RELEASE_VERSION --clean"
sh "/home/jenkins/.dotnet/tools/pupnet -r linux-x64 -c Release --kind appimage --app-version ${version} --clean -y"
}
}
} finally {
Expand Down
6 changes: 6 additions & 0 deletions StabilityMatrix.Avalonia/App.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,12 @@ private void Setup()
// Setup uri handler for `stabilitymatrix://` protocol
Program.UriHandler.RegisterUriScheme();

// Write a correct .desktop entry for AppImage runs so the app appears in the launcher
if (Compat.IsLinux)
{
LinuxDesktopIntegration.CreateDesktopFile();
}

// Setup activation protocol handlers (uri handler on macOS)
if (Compat.IsMacOS && this.TryGetFeature<IActivatableLifetime>() is { } activatableLifetime)
{
Expand Down
12 changes: 6 additions & 6 deletions StabilityMatrix.Avalonia/Assets/sitecustomize.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ def is_terminal(self) -> bool:
except ImportError:
pass
except Exception as e:
print("[sitecustomize error]:", e)
print("[sitecustomize error]:", e, file=sys.stderr)

try:
from pip._vendor.rich import console

Expand All @@ -79,19 +79,19 @@ def is_terminal(self) -> bool:
except ImportError:
pass
except Exception as e:
print("[sitecustomize error]:", e)
print("[sitecustomize error]:", e, file=sys.stderr)

# Patch tqdm to use stdout instead of stderr
def _patch_tqdm():
try:
import sys
from tqdm import std

sys.stderr = sys.stdout
except ImportError:
pass
except Exception as e:
print("[sitecustomize error]:", e)
print("[sitecustomize error]:", e, file=sys.stderr)

# Run startup customizations. Each is isolated so that a failure in one (or an
# unusual host environment, e.g. an interpreter probe with no real stdio) can
Expand All @@ -101,7 +101,7 @@ def _run_safely(func):
func()
except Exception as e:
try:
print("[sitecustomize error]:", e)
print("[sitecustomize error]:", e, file=sys.stderr)
except Exception:
pass

Expand Down
48 changes: 24 additions & 24 deletions StabilityMatrix.Avalonia/Controls/ImageLoaders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,35 @@ internal static class ImageLoaders
{
private static string BaseFileCachePath => Path.Combine(Path.GetTempPath(), "StabilityMatrix", "Cache");

private static readonly Lazy<MemoryImageCache> OutputsPageImageCacheLazy =
new(
() => new MemoryImageCache { MaxMemoryCacheCount = 64 },
LazyThreadSafetyMode.ExecutionAndPublication
);
private static readonly Lazy<MemoryImageCache> OutputsPageImageCacheLazy = new(
() => new MemoryImageCache { MaxMemoryCacheCount = 64 },
LazyThreadSafetyMode.ExecutionAndPublication
);

public static IImageCache OutputsPageImageCache => OutputsPageImageCacheLazy.Value;

private static readonly Lazy<ImageCache> OpenModelDbImageCacheLazy =
new(
() =>
new ImageCache(
new CacheOptions
private static readonly Lazy<ImageCache> OpenModelDbImageCacheLazy = new(
() =>
new ImageCache(
new CacheOptions
{
BaseCachePath = BaseFileCachePath,
CacheFolderName = "OpenModelDbImageCache",
CacheDuration = TimeSpan.FromDays(1),
// Keep decoded bitmaps in memory so scrolling doesn't re-decode from disk each time.
MaxMemoryCacheCount = 96,
HttpClient = new HttpClient(NetCache.Background)
{
BaseCachePath = BaseFileCachePath,
CacheFolderName = "OpenModelDbImageCache",
CacheDuration = TimeSpan.FromDays(1),
HttpClient = new HttpClient(NetCache.Background)
DefaultRequestHeaders =
{
DefaultRequestHeaders =
{
UserAgent = { new ProductInfoHeaderValue("StabilityMatrix", "2.0") },
Referrer = new Uri("https://openmodelsdb.info/"),
}
}
}
),
LazyThreadSafetyMode.ExecutionAndPublication
);
UserAgent = { new ProductInfoHeaderValue("StabilityMatrix", "2.0") },
Referrer = new Uri("https://openmodelsdb.info/"),
},
},
}
),
LazyThreadSafetyMode.ExecutionAndPublication
);

public static IImageCache OpenModelDbImageCache => OpenModelDbImageCacheLazy.Value;
}
70 changes: 70 additions & 0 deletions StabilityMatrix.Avalonia/Controls/Models/LiveStroke.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace StabilityMatrix.Avalonia.Controls.Models;

/// <summary>
/// An in-progress stroke being drawn by the user. Unlike a finalized <see cref="PenPath"/>,
/// a live stroke is written by the UI thread (pointer events appending points) while the
/// compositor render thread concurrently reads it every frame.
/// </summary>
/// <remarks>
/// Thread safety comes from copy-on-append publication rather than locks: points live in an
/// array that is never mutated after it becomes visible to readers. Appending copies the
/// current array into a larger one and publishes it with a single
/// <see cref="Volatile.Write{T}(ref T, T)"/>, so a reader always observes a fully written,
/// stable snapshot β€” there is no window where a resize or in-place write can tear a read.
/// Writes must come from a single thread (the UI thread); reads may come from any thread.
/// </remarks>
public sealed class LiveStroke
{
private PenPoint[] points = [];

/// <summary>
/// Immutable stroke metadata (color, radius, feathering, shape bounds, etc.).
/// The template's own <see cref="PenPath.Points"/> list is unused and stays empty;
/// live points are tracked by this class instead.
/// </summary>
public required PenPath Template { get; init; }

/// <summary>
/// Returns a stable snapshot of the points recorded so far. The returned array is
/// never mutated β€” callers may iterate it freely on any thread.
/// </summary>
public PenPoint[] GetPointsSnapshot() => Volatile.Read(ref points);

/// <summary>
/// Appends points to the stroke. Must only be called from the single writer (UI) thread.
/// </summary>
public void AddPoints(ReadOnlySpan<PenPoint> newPoints)
{
if (newPoints.IsEmpty)
return;

// Single-writer: no other thread mutates `points`, so a plain read is sufficient here.
var current = points;
var next = new PenPoint[current.Length + newPoints.Length];
current.AsSpan().CopyTo(next);
newPoints.CopyTo(next.AsSpan(current.Length));

// Release-publish: the array contents above are guaranteed visible to any thread
// that observes the new reference.
Volatile.Write(ref points, next);
}

/// <summary>
/// Snapshots this live stroke into a finalized, fully independent <see cref="PenPath"/>.
/// </summary>
public PenPath ToPenPath() => Template with { Points = [.. GetPointsSnapshot()] };

/// <summary>
/// Creates a live stroke from a previously serialized <see cref="PenPath"/>.
/// </summary>
public static LiveStroke FromPenPath(PenPath path)
{
var stroke = new LiveStroke { Template = path with { Points = [] } };
stroke.AddPoints(CollectionsMarshal.AsSpan(path.Points));
return stroke;
}
}
Loading
Loading