Skip to content

Commit 89dc5f6

Browse files
committed
Added RemoteModels for downloadable encoder models
1 parent 852f6d6 commit 89dc5f6

5 files changed

Lines changed: 125 additions & 11 deletions

File tree

StabilityMatrix.Avalonia/Controls/Inference/UnetModelCard.axaml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,15 @@
6767
Text="{x:Static lang:Resources.Label_VAE}"
6868
TextAlignment="Left" />
6969

70-
<ui:FAComboBox
70+
<controls:BetterComboBox
7171
Grid.Row="2"
7272
Grid.Column="1"
7373
Margin="4"
7474
HorizontalAlignment="Stretch"
75-
DisplayMemberBinding="{Binding ShortDisplayName}"
7675
IsTextSearchEnabled="True"
7776
ItemsSource="{Binding ClientManager.VaeModels}"
78-
SelectedItem="{Binding SelectedVae}" />
77+
SelectedItem="{Binding SelectedVae}"
78+
Theme="{StaticResource BetterComboBoxHybridModelTheme}"/>
7979

8080
<!-- CLIP Selection 1 -->
8181
<TextBlock
@@ -86,15 +86,16 @@
8686
Text="CLIP 1"
8787
TextAlignment="Left" />
8888

89-
<ui:FAComboBox
89+
<controls:BetterComboBox
9090
Grid.Row="3"
9191
Grid.Column="1"
92+
Name="Clip1ComboBox"
9293
Margin="4"
9394
HorizontalAlignment="Stretch"
94-
DisplayMemberBinding="{Binding ShortDisplayName}"
9595
IsTextSearchEnabled="True"
9696
ItemsSource="{Binding ClientManager.ClipModels}"
97-
SelectedItem="{Binding SelectedClip1}" />
97+
SelectedItem="{Binding SelectedClip1}"
98+
Theme="{StaticResource BetterComboBoxHybridModelTheme}"/>
9899

99100
<!-- CLIP Selection 2 -->
100101
<TextBlock
@@ -105,15 +106,16 @@
105106
Text="CLIP 2"
106107
TextAlignment="Left" />
107108

108-
<ui:FAComboBox
109+
<controls:BetterComboBox
109110
Grid.Row="4"
110111
Grid.Column="1"
112+
Name="Clip2ComboBox"
111113
Margin="4"
112114
HorizontalAlignment="Stretch"
113-
DisplayMemberBinding="{Binding ShortDisplayName}"
114115
IsTextSearchEnabled="True"
115116
ItemsSource="{Binding ClientManager.ClipModels}"
116-
SelectedItem="{Binding SelectedClip2}" />
117+
SelectedItem="{Binding SelectedClip2}"
118+
Theme="{StaticResource BetterComboBoxHybridModelTheme}"/>
117119
</Grid>
118120
</controls:Card>
119121
</ControlTemplate>
Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,53 @@
1-
using Avalonia.Controls.Primitives;
1+
using AsyncAwaitBestPractices;
2+
using Avalonia.Controls;
3+
using Avalonia.Controls.Primitives;
4+
using StabilityMatrix.Avalonia.ViewModels.Inference;
25
using StabilityMatrix.Core.Attributes;
6+
using StabilityMatrix.Core.Models;
37

48
namespace StabilityMatrix.Avalonia.Controls;
59

610
[Transient]
7-
public class UnetModelCard : TemplatedControl;
11+
public class UnetModelCard : TemplatedControl
12+
{
13+
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
14+
{
15+
base.OnApplyTemplate(e);
16+
17+
var clip1ComboBox = e.NameScope.Find("Clip1ComboBox") as BetterComboBox;
18+
clip1ComboBox!.SelectionChanged += UpscalerComboBox_OnSelectionChanged;
19+
20+
var clip2ComboBox = e.NameScope.Find("Clip2ComboBox") as BetterComboBox;
21+
clip2ComboBox!.SelectionChanged += UpscalerComboBox_OnSelectionChanged;
22+
}
23+
24+
private void UpscalerComboBox_OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
25+
{
26+
if (e.AddedItems.Count == 0)
27+
return;
28+
29+
var item = e.AddedItems[0];
30+
if (item is HybridModelFile { IsDownloadable: true })
31+
{
32+
// Reset the selection
33+
e.Handled = true;
34+
35+
if (
36+
e.RemovedItems.Count > 0
37+
&& e.RemovedItems[0] is HybridModelFile { IsDownloadable: false } removedItem
38+
)
39+
{
40+
(sender as BetterComboBox)!.SelectedItem = removedItem;
41+
}
42+
else
43+
{
44+
(sender as BetterComboBox)!.SelectedItem = null;
45+
}
46+
47+
// Show dialog to download the model
48+
(DataContext as UnetModelCardViewModel)!
49+
.RemoteDownloadCommand.ExecuteAsync(item)
50+
.SafeFireAndForget();
51+
}
52+
}
53+
}

StabilityMatrix.Avalonia/Services/InferenceClientManager.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ public partial class InferenceClientManager : ObservableObject, IInferenceClient
136136
new ObservableCollectionExtended<HybridModelFile>();
137137

138138
private readonly SourceCache<HybridModelFile, string> clipModelsSource = new(p => p.GetId());
139+
private readonly SourceCache<HybridModelFile, string> downloadableClipModelsSource = new(p => p.GetId());
139140

140141
public IObservableCollection<HybridModelFile> ClipModels { get; } =
141142
new ObservableCollectionExtended<HybridModelFile>();
@@ -237,6 +238,7 @@ ICompletionProvider completionProvider
237238

238239
clipModelsSource
239240
.Connect()
241+
.Or(downloadableClipModelsSource.Connect())
240242
.SortBy(
241243
f => f.ShortDisplayName,
242244
SortDirection.Ascending,
@@ -526,6 +528,11 @@ private void ResetSharedProperties()
526528
HybridModelFile.Comparer
527529
);
528530

531+
var downloadableClipModels = RemoteModels.ClipModelFiles.Where(
532+
u => !clipModelsSource.Lookup(u.GetId()).HasValue
533+
);
534+
downloadableClipModelsSource.EditDiff(downloadableClipModels, HybridModelFile.Comparer);
535+
529536
samplersSource.EditDiff(ComfySampler.Defaults, ComfySampler.Comparer);
530537

531538
latentUpscalersSource.EditDiff(ComfyUpscaler.Defaults, ComfyUpscaler.Comparer);

StabilityMatrix.Avalonia/ViewModels/Inference/UnetModelCardViewModel.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
using System.Text.Json.Nodes;
66
using System.Threading.Tasks;
77
using CommunityToolkit.Mvvm.ComponentModel;
8+
using CommunityToolkit.Mvvm.Input;
9+
using FluentAvalonia.UI.Controls;
810
using StabilityMatrix.Avalonia.Controls;
911
using StabilityMatrix.Avalonia.Models;
1012
using StabilityMatrix.Avalonia.Models.Inference;
1113
using StabilityMatrix.Avalonia.Services;
1214
using StabilityMatrix.Avalonia.ViewModels.Base;
15+
using StabilityMatrix.Avalonia.ViewModels.Dialogs;
1316
using StabilityMatrix.Core.Attributes;
1417
using StabilityMatrix.Core.Models;
1518
using StabilityMatrix.Core.Models.Api.Comfy.Nodes;
@@ -44,6 +47,22 @@ ServiceManager<ViewModelBase> vmFactory
4447

4548
public IInferenceClientManager ClientManager { get; } = clientManager;
4649

50+
[RelayCommand]
51+
private async Task RemoteDownload(HybridModelFile? modelFile)
52+
{
53+
if (modelFile?.DownloadableResource is not { } resource)
54+
return;
55+
56+
var confirmDialog = vmFactory.Get<DownloadResourceViewModel>();
57+
confirmDialog.Resource = resource;
58+
confirmDialog.FileName = modelFile.FileName;
59+
60+
if (await confirmDialog.GetDialog().ShowAsync() == ContentDialogResult.Primary)
61+
{
62+
confirmDialog.StartDownload();
63+
}
64+
}
65+
4766
public async Task<bool> ValidateModel()
4867
{
4968
if (SelectedModel != null)

StabilityMatrix.Core/Helper/RemoteModels.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,4 +293,44 @@ private static RemoteResource ControlNetCommon(string path, string sha256)
293293

294294
public static IEnumerable<HybridModelFile> SamModelFiles =>
295295
SamModels.Select(HybridModelFile.FromDownloadable);
296+
297+
private static IEnumerable<RemoteResource> ClipModels =>
298+
[
299+
new RemoteResource
300+
{
301+
Url = new Uri(
302+
"https://huggingface.co/comfyanonymous/flux_text_encoders/resolve/main/clip_l.safetensors"
303+
),
304+
InfoUrl = new Uri("https://huggingface.co/comfyanonymous/flux_text_encoders"),
305+
HashSha256 = "660c6f5b1abae9dc498ac2d21e1347d2abdb0cf6c0c0c8576cd796491d9a6cdd",
306+
Author = "OpenAI",
307+
LicenseType = "MIT",
308+
ContextType = SharedFolderType.CLIP,
309+
},
310+
new RemoteResource
311+
{
312+
Url = new Uri(
313+
"https://huggingface.co/comfyanonymous/flux_text_encoders/resolve/main/t5xxl_fp16.safetensors"
314+
),
315+
InfoUrl = new Uri("https://huggingface.co/comfyanonymous/flux_text_encoders"),
316+
HashSha256 = "6e480b09fae049a72d2a8c5fbccb8d3e92febeb233bbe9dfe7256958a9167635",
317+
Author = "Google",
318+
LicenseType = "Apache 2.0",
319+
ContextType = SharedFolderType.CLIP,
320+
},
321+
new RemoteResource
322+
{
323+
Url = new Uri(
324+
"https://huggingface.co/comfyanonymous/flux_text_encoders/resolve/main/t5xxl_fp8_e4m3fn.safetensors"
325+
),
326+
InfoUrl = new Uri("https://huggingface.co/comfyanonymous/flux_text_encoders"),
327+
HashSha256 = "7d330da4816157540d6bb7838bf63a0f02f573fc48ca4d8de34bb0cbfd514f09",
328+
Author = "Google",
329+
LicenseType = "Apache 2.0",
330+
ContextType = SharedFolderType.CLIP,
331+
}
332+
];
333+
334+
public static IEnumerable<HybridModelFile> ClipModelFiles =>
335+
ClipModels.Select(HybridModelFile.FromDownloadable);
296336
}

0 commit comments

Comments
 (0)