Browse Source

Merge branch 'main' of https://github.com/ionite34/StabilityMatrix

pull/135/head v2.4.4
Ionite 1 year ago
parent
commit
4cbd5b62f2
No known key found for this signature in database
  1. 8
      CHANGELOG.md
  2. 9
      StabilityMatrix.Avalonia/Languages/Resources.Designer.cs
  3. 3
      StabilityMatrix.Avalonia/Languages/Resources.resx
  4. 22
      StabilityMatrix.Avalonia/ViewModels/LaunchPageViewModel.cs
  5. 4
      StabilityMatrix.Avalonia/ViewModels/PackageManagerViewModel.cs
  6. 11
      StabilityMatrix.Avalonia/ViewModels/Progress/PackageInstallProgressItemViewModel.cs
  7. 15
      StabilityMatrix.Avalonia/Views/LaunchPageView.axaml
  8. 2
      StabilityMatrix.Core/Models/PackageModification/IPackageModificationRunner.cs
  9. 20
      StabilityMatrix.Core/Models/PackageModification/PackageModificationRunner.cs
  10. 4
      StabilityMatrix.Core/Models/Packages/BaseGitPackage.cs
  11. 100
      StabilityMatrix.Core/Models/Packages/ComfyUI.cs
  12. 8
      StabilityMatrix.Core/Models/Packages/Fooocus.cs
  13. 2
      StabilityMatrix.Core/Models/Settings/Settings.cs

8
CHANGELOG.md

@ -5,6 +5,14 @@ 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.4.4
### Added
- Added button to toggle automatic scrolling of console output
### Fixed
- Fixed [#130](https://github.com/LykosAI/StabilityMatrix/issues/130) ComfyUI extra_model_paths.yaml file being overwritten on each launch
- Fixed some package updates not showing any console output
- Fixed auto-close of update dialog when package update is complete
## v2.4.3
### Added
- Added "--no-download-sd-model" launch argument option for Stable Diffusion Web UI

9
StabilityMatrix.Avalonia/Languages/Resources.Designer.cs generated

@ -464,6 +464,15 @@ namespace StabilityMatrix.Avalonia.Languages {
}
}
/// <summary>
/// Looks up a localized string similar to Automatically scroll to end of console output.
/// </summary>
public static string Label_AutoScrollToEnd {
get {
return ResourceManager.GetString("Label_AutoScrollToEnd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Base Model.
/// </summary>

3
StabilityMatrix.Avalonia/Languages/Resources.resx

@ -639,4 +639,7 @@
<data name="Label_Branch" xml:space="preserve">
<value>Branch</value>
</data>
<data name="Label_AutoScrollToEnd" xml:space="preserve">
<value>Automatically scroll to end of console output</value>
</data>
</root>

22
StabilityMatrix.Avalonia/ViewModels/LaunchPageViewModel.cs

@ -86,6 +86,9 @@ public partial class LaunchPageViewModel : PageViewModelBase, IDisposable, IAsyn
[ObservableProperty]
private BasePackage? runningPackage;
[ObservableProperty]
private bool autoScrollToEnd;
public virtual BasePackage? SelectedBasePackage =>
PackageFactory.FindPackageByName(SelectedPackage?.PackageName);
@ -126,6 +129,12 @@ public partial class LaunchPageViewModel : PageViewModelBase, IDisposable, IAsyn
settings => settings.ActiveInstalledPackage
);
settingsManager.RelayPropertyFor(
this,
vm => vm.AutoScrollToEnd,
settings => settings.AutoScrollLaunchConsoleToEnd
);
EventManager.Instance.PackageLaunchRequested += OnPackageLaunchRequested;
EventManager.Instance.OneClickInstallFinished += OnOneClickInstallFinished;
EventManager.Instance.InstalledPackagesChanged += OnInstalledPackagesChanged;
@ -161,6 +170,14 @@ public partial class LaunchPageViewModel : PageViewModelBase, IDisposable, IAsyn
LaunchAsync().SafeFireAndForget();
}
partial void OnAutoScrollToEndChanged(bool value)
{
if (value)
{
EventManager.Instance.OnScrollToBottomRequested();
}
}
public override void OnLoaded()
{
// Ensure active package either exists or is null
@ -179,6 +196,7 @@ public partial class LaunchPageViewModel : PageViewModelBase, IDisposable, IAsyn
// Load active package
SelectedPackage = settingsManager.Settings.ActiveInstalledPackage;
AutoScrollToEnd = settingsManager.Settings.AutoScrollLaunchConsoleToEnd;
}
[RelayCommand]
@ -487,8 +505,12 @@ public partial class LaunchPageViewModel : PageViewModelBase, IDisposable, IAsyn
private void OnProcessOutputReceived(ProcessOutput output)
{
Console.Post(output);
if (AutoScrollToEnd)
{
EventManager.Instance.OnScrollToBottomRequested();
}
}
private void OnOneClickInstallFinished(object? sender, bool e)
{

4
StabilityMatrix.Avalonia/ViewModels/PackageManagerViewModel.cs

@ -143,6 +143,9 @@ public partial class PackageManagerViewModel : PageViewModelBase
EventManager.Instance.OnPackageInstallProgressAdded(runner);
await runner.ExecuteSteps(steps.ToList());
if (!runner.Failed)
{
EventManager.Instance.OnInstalledPackagesChanged();
notificationService.Show(
"Package Install Complete",
@ -151,6 +154,7 @@ public partial class PackageManagerViewModel : PageViewModelBase
);
}
}
}
private IEnumerable<UnknownInstalledPackage> IndexUnknownPackages()
{

11
StabilityMatrix.Avalonia/ViewModels/Progress/PackageInstallProgressItemViewModel.cs

@ -42,6 +42,7 @@ public class PackageInstallProgressItemViewModel : ProgressItemViewModelBase
Progress.IsIndeterminate = e.IsIndeterminate;
Progress.Text = packageModificationRunner.CurrentStep?.ProgressTitle;
Name = packageModificationRunner.CurrentStep?.ProgressTitle;
Failed = packageModificationRunner.Failed;
if (string.IsNullOrWhiteSpace(e.Message) || e.Message.Contains("Downloading..."))
return;
@ -51,12 +52,20 @@ public class PackageInstallProgressItemViewModel : ProgressItemViewModelBase
if (
e is { Message: not null, Percentage: >= 100 }
&& e.Message.Contains("Package Install Complete")
&& e.Message.Contains(
packageModificationRunner.ModificationCompleteMessage ?? "Package Install Complete"
)
&& Progress.CloseWhenFinished
)
{
Dispatcher.UIThread.Post(() => dialog?.Hide());
}
if (Failed)
{
Progress.Text = "Package Modification Failed";
Name = "Package Modification Failed";
}
}
public async Task ShowProgressDialog()

15
StabilityMatrix.Avalonia/Views/LaunchPageView.axaml

@ -12,6 +12,7 @@
xmlns:vm="clr-namespace:StabilityMatrix.Avalonia.ViewModels"
xmlns:system="clr-namespace:System;assembly=System.Runtime"
xmlns:lang="clr-namespace:StabilityMatrix.Avalonia.Languages"
xmlns:avalonia="clr-namespace:Projektanker.Icons.Avalonia;assembly=Projektanker.Icons.Avalonia"
d:DataContext="{x:Static mocks:DesignData.LaunchPageViewModel}"
d:DesignHeight="450"
d:DesignWidth="700"
@ -25,7 +26,7 @@
</controls:UserControlBase.Resources>
<Grid RowDefinitions="Auto,*,Auto">
<Grid ColumnDefinitions="Auto,*,Auto"
<Grid ColumnDefinitions="Auto,*,Auto,Auto"
Margin="0,8,0, 8">
<Grid ColumnDefinitions="0.8*,0.2*" Margin="16,8,0,0">
<!-- Use split if extra commands, otherwise normal launch button -->
@ -145,6 +146,18 @@
<ToggleButton
Grid.Column="2"
Width="48"
Margin="8,8,0,0"
IsChecked="{Binding AutoScrollToEnd}"
ToolTip.Tip="{x:Static lang:Resources.Label_AutoScrollToEnd}"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
FontSize="16">
<avalonia:Icon Value="fa-solid fa-arrow-down-wide-short" />
</ToggleButton>
<ToggleButton
Grid.Column="3"
Width="48"
Margin="8,8,16,0"
IsChecked="{Binding ShowManualInputPrompt}"
ToolTip.Tip="{x:Static lang:Resources.Action_SendInput}"

2
StabilityMatrix.Core/Models/PackageModification/IPackageModificationRunner.cs

@ -12,4 +12,6 @@ public interface IPackageModificationRunner
List<string> ConsoleOutput { get; }
Guid Id { get; }
bool ShowDialogOnStart { get; init; }
string? ModificationCompleteMessage { get; init; }
bool Failed { get; set; }
}

20
StabilityMatrix.Core/Models/PackageModification/PackageModificationRunner.cs

@ -21,9 +21,27 @@ public class PackageModificationRunner : IPackageModificationRunner
foreach (var step in steps)
{
CurrentStep = step;
try
{
await step.ExecuteAsync(progress).ConfigureAwait(false);
}
catch (Exception e)
{
progress.Report(
new ProgressReport(
1f,
title: "Error modifying package",
message: $"Error: {e}",
isIndeterminate: false
)
);
Failed = true;
break;
}
}
if (!Failed)
{
progress.Report(
new ProgressReport(
1f,
@ -31,6 +49,7 @@ public class PackageModificationRunner : IPackageModificationRunner
isIndeterminate: false
)
);
}
IsRunning = false;
}
@ -39,6 +58,7 @@ public class PackageModificationRunner : IPackageModificationRunner
public bool ShowDialogOnStart { get; init; }
public bool IsRunning { get; set; }
public bool Failed { get; set; }
public ProgressReport CurrentProgress { get; set; }
public IPackageStep? CurrentStep { get; set; }
public List<string> ConsoleOutput { get; } = new();

4
StabilityMatrix.Core/Models/Packages/BaseGitPackage.cs

@ -290,7 +290,7 @@ public abstract class BaseGitPackage : BasePackage
)
.ConfigureAwait(false);
await InstallPackage(installedPackage.FullPath, torchVersion, progress)
await InstallPackage(installedPackage.FullPath, torchVersion, progress, onConsoleOutput)
.ConfigureAwait(false);
return new InstalledPackageVersion { InstalledReleaseVersion = latestRelease.TagName };
@ -312,7 +312,7 @@ public abstract class BaseGitPackage : BasePackage
progress
)
.ConfigureAwait(false);
await InstallPackage(installedPackage.FullPath, torchVersion, progress)
await InstallPackage(installedPackage.FullPath, torchVersion, progress, onConsoleOutput)
.ConfigureAwait(false);
return new InstalledPackageVersion

100
StabilityMatrix.Core/Models/Packages/ComfyUI.cs

@ -9,8 +9,10 @@ using StabilityMatrix.Core.Models.Progress;
using StabilityMatrix.Core.Processes;
using StabilityMatrix.Core.Python;
using StabilityMatrix.Core.Services;
using YamlDotNet.RepresentationModel;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.TypeInspectors;
namespace StabilityMatrix.Core.Models.Packages;
@ -233,11 +235,6 @@ public class ComfyUI : BaseGitPackage
var extraPathsYamlPath = installDirectory + "extra_model_paths.yaml";
var modelsDir = SettingsManager.ModelsDirectory;
var deserializer = new DeserializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.IgnoreUnmatchedProperties()
.Build();
var exists = File.Exists(extraPathsYamlPath);
if (!exists)
{
@ -245,34 +242,87 @@ public class ComfyUI : BaseGitPackage
File.WriteAllText(extraPathsYamlPath, string.Empty);
}
var yaml = File.ReadAllText(extraPathsYamlPath);
var comfyModelPaths =
deserializer.Deserialize<ComfyModelPathsYaml>(yaml)
??
// ReSharper disable once NullCoalescingConditionIsAlwaysNotNullAccordingToAPIContract
// cuz it can actually be null lol
new ComfyModelPathsYaml();
comfyModelPaths.StabilityMatrix ??= new ComfyModelPathsYaml.SmData();
comfyModelPaths.StabilityMatrix.Checkpoints = Path.Combine(modelsDir, "StableDiffusion");
comfyModelPaths.StabilityMatrix.Vae = Path.Combine(modelsDir, "VAE");
comfyModelPaths.StabilityMatrix.Loras =
using var sr = new StringReader(yaml);
var yamlStream = new YamlStream();
yamlStream.Load(sr);
if (!yamlStream.Documents.Any())
{
yamlStream.Documents.Add(new YamlDocument(new YamlMappingNode()));
}
var root = yamlStream.Documents[0].RootNode;
if (root is not YamlMappingNode mappingNode)
{
throw new Exception("Invalid extra_model_paths.yaml");
}
// check if we have a child called "stability_matrix"
var stabilityMatrixNode = mappingNode.Children.FirstOrDefault(
c => c.Key.ToString() == "stability_matrix"
);
if (stabilityMatrixNode.Key != null)
{
if (stabilityMatrixNode.Value is not YamlMappingNode nodeValue)
return Task.CompletedTask;
nodeValue.Children["checkpoints"] = Path.Combine(modelsDir, "StableDiffusion");
nodeValue.Children["vae"] = Path.Combine(modelsDir, "VAE");
nodeValue.Children["loras"] =
$"{Path.Combine(modelsDir, "Lora")}\n" + $"{Path.Combine(modelsDir, "LyCORIS")}";
comfyModelPaths.StabilityMatrix.UpscaleModels =
nodeValue.Children["upscale_models"] =
$"{Path.Combine(modelsDir, "ESRGAN")}\n"
+ $"{Path.Combine(modelsDir, "RealESRGAN")}\n"
+ $"{Path.Combine(modelsDir, "SwinIR")}";
comfyModelPaths.StabilityMatrix.Embeddings = Path.Combine(modelsDir, "TextualInversion");
comfyModelPaths.StabilityMatrix.Hypernetworks = Path.Combine(modelsDir, "Hypernetwork");
comfyModelPaths.StabilityMatrix.Controlnet = Path.Combine(modelsDir, "ControlNet");
comfyModelPaths.StabilityMatrix.Clip = Path.Combine(modelsDir, "CLIP");
comfyModelPaths.StabilityMatrix.Diffusers = Path.Combine(modelsDir, "Diffusers");
comfyModelPaths.StabilityMatrix.Gligen = Path.Combine(modelsDir, "GLIGEN");
comfyModelPaths.StabilityMatrix.VaeApprox = Path.Combine(modelsDir, "ApproxVAE");
nodeValue.Children["embeddings"] = Path.Combine(modelsDir, "TextualInversion");
nodeValue.Children["hypernetworks"] = Path.Combine(modelsDir, "Hypernetwork");
nodeValue.Children["controlnet"] = Path.Combine(modelsDir, "ControlNet");
nodeValue.Children["clip"] = Path.Combine(modelsDir, "CLIP");
nodeValue.Children["diffusers"] = Path.Combine(modelsDir, "Diffusers");
nodeValue.Children["gligen"] = Path.Combine(modelsDir, "GLIGEN");
nodeValue.Children["vae_approx"] = Path.Combine(modelsDir, "ApproxVAE");
}
else
{
stabilityMatrixNode = new KeyValuePair<YamlNode, YamlNode>(
new YamlScalarNode("stability_matrix"),
new YamlMappingNode
{
{ "checkpoints", Path.Combine(modelsDir, "StableDiffusion") },
{ "vae", Path.Combine(modelsDir, "VAE") },
{
"loras",
$"{Path.Combine(modelsDir, "Lora")}\n{Path.Combine(modelsDir, "LyCORIS")}"
},
{
"upscale_models",
$"{Path.Combine(modelsDir, "ESRGAN")}\n{Path.Combine(modelsDir, "RealESRGAN")}\n{Path.Combine(modelsDir, "SwinIR")}"
},
{ "embeddings", Path.Combine(modelsDir, "TextualInversion") },
{ "hypernetworks", Path.Combine(modelsDir, "Hypernetwork") },
{ "controlnet", Path.Combine(modelsDir, "ControlNet") },
{ "clip", Path.Combine(modelsDir, "CLIP") },
{ "diffusers", Path.Combine(modelsDir, "Diffusers") },
{ "gligen", Path.Combine(modelsDir, "GLIGEN") },
{ "vae_approx", Path.Combine(modelsDir, "ApproxVAE") }
}
);
}
var newRootNode = new YamlMappingNode();
foreach (
var child in mappingNode.Children.Where(c => c.Key.ToString() != "stability_matrix")
)
{
newRootNode.Children.Add(child);
}
newRootNode.Children.Add(stabilityMatrixNode);
var serializer = new SerializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.Build();
var yamlData = serializer.Serialize(comfyModelPaths);
var yamlData = serializer.Serialize(newRootNode);
File.WriteAllText(extraPathsYamlPath, yamlData);
return Task.CompletedTask;

8
StabilityMatrix.Core/Models/Packages/Fooocus.cs

@ -85,11 +85,9 @@ public class Fooocus : BaseGitPackage
public override IEnumerable<TorchVersion> AvailableTorchVersions =>
new[] { TorchVersion.Cpu, TorchVersion.Cuda, TorchVersion.Rocm };
public override async Task<string> GetLatestVersion()
{
var release = await GetLatestRelease().ConfigureAwait(false);
return release.TagName!;
}
public override Task<string> GetLatestVersion() => Task.FromResult("main");
public override bool ShouldIgnoreReleases => true;
public override async Task InstallPackage(
string installLocation,

2
StabilityMatrix.Core/Models/Settings/Settings.cs

@ -56,6 +56,8 @@ public class Settings
public float AnimationScale { get; set; } = 1.0f;
public bool AutoScrollLaunchConsoleToEnd { get; set; } = true;
public void RemoveInstalledPackageAndUpdateActive(InstalledPackage package)
{
RemoveInstalledPackageAndUpdateActive(package.Id);

Loading…
Cancel
Save