|
|
@ -56,7 +56,8 @@ public partial class InferenceClientManager : ObservableObject, IInferenceClient |
|
|
|
|
|
|
|
|
|
|
|
private readonly SourceCache<HybridModelFile, string> modelsSource = new(p => p.GetId()); |
|
|
|
private readonly SourceCache<HybridModelFile, string> modelsSource = new(p => p.GetId()); |
|
|
|
|
|
|
|
|
|
|
|
public IObservableCollection<HybridModelFile> Models { get; } = new ObservableCollectionExtended<HybridModelFile>(); |
|
|
|
public IObservableCollection<HybridModelFile> Models { get; } = |
|
|
|
|
|
|
|
new ObservableCollectionExtended<HybridModelFile>(); |
|
|
|
|
|
|
|
|
|
|
|
private readonly SourceCache<HybridModelFile, string> vaeModelsSource = new(p => p.GetId()); |
|
|
|
private readonly SourceCache<HybridModelFile, string> vaeModelsSource = new(p => p.GetId()); |
|
|
|
|
|
|
|
|
|
|
@ -67,14 +68,16 @@ public partial class InferenceClientManager : ObservableObject, IInferenceClient |
|
|
|
|
|
|
|
|
|
|
|
private readonly SourceCache<HybridModelFile, string> controlNetModelsSource = new(p => p.GetId()); |
|
|
|
private readonly SourceCache<HybridModelFile, string> controlNetModelsSource = new(p => p.GetId()); |
|
|
|
|
|
|
|
|
|
|
|
private readonly SourceCache<HybridModelFile, string> downloadableControlNetModelsSource = new(p => p.GetId()); |
|
|
|
private readonly SourceCache<HybridModelFile, string> downloadableControlNetModelsSource = |
|
|
|
|
|
|
|
new(p => p.GetId()); |
|
|
|
|
|
|
|
|
|
|
|
public IObservableCollection<HybridModelFile> ControlNetModels { get; } = |
|
|
|
public IObservableCollection<HybridModelFile> ControlNetModels { get; } = |
|
|
|
new ObservableCollectionExtended<HybridModelFile>(); |
|
|
|
new ObservableCollectionExtended<HybridModelFile>(); |
|
|
|
|
|
|
|
|
|
|
|
private readonly SourceCache<ComfySampler, string> samplersSource = new(p => p.Name); |
|
|
|
private readonly SourceCache<ComfySampler, string> samplersSource = new(p => p.Name); |
|
|
|
|
|
|
|
|
|
|
|
public IObservableCollection<ComfySampler> Samplers { get; } = new ObservableCollectionExtended<ComfySampler>(); |
|
|
|
public IObservableCollection<ComfySampler> Samplers { get; } = |
|
|
|
|
|
|
|
new ObservableCollectionExtended<ComfySampler>(); |
|
|
|
|
|
|
|
|
|
|
|
private readonly SourceCache<ComfyUpscaler, string> modelUpscalersSource = new(p => p.Name); |
|
|
|
private readonly SourceCache<ComfyUpscaler, string> modelUpscalersSource = new(p => p.Name); |
|
|
|
|
|
|
|
|
|
|
@ -82,7 +85,8 @@ public partial class InferenceClientManager : ObservableObject, IInferenceClient |
|
|
|
|
|
|
|
|
|
|
|
private readonly SourceCache<ComfyUpscaler, string> downloadableUpscalersSource = new(p => p.Name); |
|
|
|
private readonly SourceCache<ComfyUpscaler, string> downloadableUpscalersSource = new(p => p.Name); |
|
|
|
|
|
|
|
|
|
|
|
public IObservableCollection<ComfyUpscaler> Upscalers { get; } = new ObservableCollectionExtended<ComfyUpscaler>(); |
|
|
|
public IObservableCollection<ComfyUpscaler> Upscalers { get; } = |
|
|
|
|
|
|
|
new ObservableCollectionExtended<ComfyUpscaler>(); |
|
|
|
|
|
|
|
|
|
|
|
private readonly SourceCache<ComfyScheduler, string> schedulersSource = new(p => p.Name); |
|
|
|
private readonly SourceCache<ComfyScheduler, string> schedulersSource = new(p => p.Name); |
|
|
|
|
|
|
|
|
|
|
@ -105,7 +109,11 @@ public partial class InferenceClientManager : ObservableObject, IInferenceClient |
|
|
|
|
|
|
|
|
|
|
|
modelsSource |
|
|
|
modelsSource |
|
|
|
.Connect() |
|
|
|
.Connect() |
|
|
|
.SortBy(f => f.ShortDisplayName, SortDirection.Ascending, SortOptimisations.ComparesImmutableValuesOnly) |
|
|
|
.SortBy( |
|
|
|
|
|
|
|
f => f.ShortDisplayName, |
|
|
|
|
|
|
|
SortDirection.Ascending, |
|
|
|
|
|
|
|
SortOptimisations.ComparesImmutableValuesOnly |
|
|
|
|
|
|
|
) |
|
|
|
.DeferUntilLoaded() |
|
|
|
.DeferUntilLoaded() |
|
|
|
.Bind(Models) |
|
|
|
.Bind(Models) |
|
|
|
.Subscribe(); |
|
|
|
.Subscribe(); |
|
|
@ -114,7 +122,9 @@ public partial class InferenceClientManager : ObservableObject, IInferenceClient |
|
|
|
.Connect() |
|
|
|
.Connect() |
|
|
|
.Or(downloadableControlNetModelsSource.Connect()) |
|
|
|
.Or(downloadableControlNetModelsSource.Connect()) |
|
|
|
.Sort( |
|
|
|
.Sort( |
|
|
|
SortExpressionComparer<HybridModelFile>.Ascending(f => f.Type).ThenByAscending(f => f.ShortDisplayName) |
|
|
|
SortExpressionComparer<HybridModelFile> |
|
|
|
|
|
|
|
.Ascending(f => f.Type) |
|
|
|
|
|
|
|
.ThenByAscending(f => f.ShortDisplayName) |
|
|
|
) |
|
|
|
) |
|
|
|
.DeferUntilLoaded() |
|
|
|
.DeferUntilLoaded() |
|
|
|
.Bind(ControlNetModels) |
|
|
|
.Bind(ControlNetModels) |
|
|
@ -153,7 +163,9 @@ public partial class InferenceClientManager : ObservableObject, IInferenceClient |
|
|
|
if (IsConnected) |
|
|
|
if (IsConnected) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LoadSharedPropertiesAsync() |
|
|
|
LoadSharedPropertiesAsync() |
|
|
|
.SafeFireAndForget(onException: ex => logger.LogError(ex, "Error loading shared properties")); |
|
|
|
.SafeFireAndForget( |
|
|
|
|
|
|
|
onException: ex => logger.LogError(ex, "Error loading shared properties") |
|
|
|
|
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
@ -176,7 +188,10 @@ public partial class InferenceClientManager : ObservableObject, IInferenceClient |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Get control net model names |
|
|
|
// Get control net model names |
|
|
|
if (await Client.GetNodeOptionNamesAsync("ControlNetLoader", "control_net_name") is { } controlNetModelNames) |
|
|
|
if ( |
|
|
|
|
|
|
|
await Client.GetNodeOptionNamesAsync("ControlNetLoader", "control_net_name") is |
|
|
|
|
|
|
|
{ } controlNetModelNames |
|
|
|
|
|
|
|
) |
|
|
|
{ |
|
|
|
{ |
|
|
|
controlNetModelsSource.EditDiff( |
|
|
|
controlNetModelsSource.EditDiff( |
|
|
|
controlNetModelNames.Select(HybridModelFile.FromRemote), |
|
|
|
controlNetModelNames.Select(HybridModelFile.FromRemote), |
|
|
@ -187,13 +202,18 @@ public partial class InferenceClientManager : ObservableObject, IInferenceClient |
|
|
|
// Fetch sampler names from KSampler node |
|
|
|
// Fetch sampler names from KSampler node |
|
|
|
if (await Client.GetSamplerNamesAsync() is { } samplerNames) |
|
|
|
if (await Client.GetSamplerNamesAsync() is { } samplerNames) |
|
|
|
{ |
|
|
|
{ |
|
|
|
samplersSource.EditDiff(samplerNames.Select(name => new ComfySampler(name)), ComfySampler.Comparer); |
|
|
|
samplersSource.EditDiff( |
|
|
|
|
|
|
|
samplerNames.Select(name => new ComfySampler(name)), |
|
|
|
|
|
|
|
ComfySampler.Comparer |
|
|
|
|
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Upscalers is latent and esrgan combined |
|
|
|
// Upscalers is latent and esrgan combined |
|
|
|
|
|
|
|
|
|
|
|
// Add latent upscale methods from LatentUpscale node |
|
|
|
// Add latent upscale methods from LatentUpscale node |
|
|
|
if (await Client.GetNodeOptionNamesAsync("LatentUpscale", "upscale_method") is { } latentUpscalerNames) |
|
|
|
if ( |
|
|
|
|
|
|
|
await Client.GetNodeOptionNamesAsync("LatentUpscale", "upscale_method") is { } latentUpscalerNames |
|
|
|
|
|
|
|
) |
|
|
|
{ |
|
|
|
{ |
|
|
|
latentUpscalersSource.EditDiff( |
|
|
|
latentUpscalersSource.EditDiff( |
|
|
|
latentUpscalerNames.Select(s => new ComfyUpscaler(s, ComfyUpscalerType.Latent)), |
|
|
|
latentUpscalerNames.Select(s => new ComfyUpscaler(s, ComfyUpscalerType.Latent)), |
|
|
@ -204,7 +224,9 @@ public partial class InferenceClientManager : ObservableObject, IInferenceClient |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Add Model upscale methods |
|
|
|
// Add Model upscale methods |
|
|
|
if (await Client.GetNodeOptionNamesAsync("UpscaleModelLoader", "model_name") is { } modelUpscalerNames) |
|
|
|
if ( |
|
|
|
|
|
|
|
await Client.GetNodeOptionNamesAsync("UpscaleModelLoader", "model_name") is { } modelUpscalerNames |
|
|
|
|
|
|
|
) |
|
|
|
{ |
|
|
|
{ |
|
|
|
modelUpscalersSource.EditDiff( |
|
|
|
modelUpscalersSource.EditDiff( |
|
|
|
modelUpscalerNames.Select(s => new ComfyUpscaler(s, ComfyUpscalerType.ESRGAN)), |
|
|
|
modelUpscalerNames.Select(s => new ComfyUpscaler(s, ComfyUpscalerType.ESRGAN)), |
|
|
@ -219,7 +241,9 @@ public partial class InferenceClientManager : ObservableObject, IInferenceClient |
|
|
|
schedulersSource.Edit(updater => |
|
|
|
schedulersSource.Edit(updater => |
|
|
|
{ |
|
|
|
{ |
|
|
|
updater.AddOrUpdate( |
|
|
|
updater.AddOrUpdate( |
|
|
|
schedulerNames.Where(n => !schedulersSource.Keys.Contains(n)).Select(s => new ComfyScheduler(s)) |
|
|
|
schedulerNames |
|
|
|
|
|
|
|
.Where(n => !schedulersSource.Keys.Contains(n)) |
|
|
|
|
|
|
|
.Select(s => new ComfyScheduler(s)) |
|
|
|
); |
|
|
|
); |
|
|
|
}); |
|
|
|
}); |
|
|
|
logger.LogTrace("Loaded scheduler methods: {@Schedulers}", schedulerNames); |
|
|
|
logger.LogTrace("Loaded scheduler methods: {@Schedulers}", schedulerNames); |
|
|
@ -233,20 +257,24 @@ public partial class InferenceClientManager : ObservableObject, IInferenceClient |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Load local models |
|
|
|
// Load local models |
|
|
|
modelsSource.EditDiff( |
|
|
|
modelsSource.EditDiff( |
|
|
|
modelIndexService.GetFromModelIndex(SharedFolderType.StableDiffusion).Select(HybridModelFile.FromLocal), |
|
|
|
modelIndexService |
|
|
|
|
|
|
|
.GetFromModelIndex(SharedFolderType.StableDiffusion) |
|
|
|
|
|
|
|
.Select(HybridModelFile.FromLocal), |
|
|
|
HybridModelFile.Comparer |
|
|
|
HybridModelFile.Comparer |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
// Load local control net models |
|
|
|
// Load local control net models |
|
|
|
controlNetModelsSource.EditDiff( |
|
|
|
controlNetModelsSource.EditDiff( |
|
|
|
modelIndexService.GetFromModelIndex(SharedFolderType.ControlNet).Select(HybridModelFile.FromLocal), |
|
|
|
modelIndexService |
|
|
|
|
|
|
|
.GetFromModelIndex(SharedFolderType.ControlNet) |
|
|
|
|
|
|
|
.Select(HybridModelFile.FromLocal), |
|
|
|
HybridModelFile.Comparer |
|
|
|
HybridModelFile.Comparer |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
// Downloadable ControlNet models |
|
|
|
// Downloadable ControlNet models |
|
|
|
var downloadableControlNets = RemoteModels |
|
|
|
var downloadableControlNets = RemoteModels.ControlNetModels.Where( |
|
|
|
.ControlNetModels |
|
|
|
u => !controlNetModelsSource.Lookup(u.GetId()).HasValue |
|
|
|
.Where(u => !modelUpscalersSource.Lookup(u.GetId()).HasValue); |
|
|
|
); |
|
|
|
downloadableControlNetModelsSource.EditDiff(downloadableControlNets, HybridModelFile.Comparer); |
|
|
|
downloadableControlNetModelsSource.EditDiff(downloadableControlNets, HybridModelFile.Comparer); |
|
|
|
|
|
|
|
|
|
|
|
// Load local VAE models |
|
|
|
// Load local VAE models |
|
|
@ -264,15 +292,17 @@ public partial class InferenceClientManager : ObservableObject, IInferenceClient |
|
|
|
// Load Upscalers |
|
|
|
// Load Upscalers |
|
|
|
modelUpscalersSource.EditDiff( |
|
|
|
modelUpscalersSource.EditDiff( |
|
|
|
modelIndexService |
|
|
|
modelIndexService |
|
|
|
.GetFromModelIndex(SharedFolderType.ESRGAN | SharedFolderType.RealESRGAN | SharedFolderType.SwinIR) |
|
|
|
.GetFromModelIndex( |
|
|
|
|
|
|
|
SharedFolderType.ESRGAN | SharedFolderType.RealESRGAN | SharedFolderType.SwinIR |
|
|
|
|
|
|
|
) |
|
|
|
.Select(m => new ComfyUpscaler(m.FileName, ComfyUpscalerType.ESRGAN)), |
|
|
|
.Select(m => new ComfyUpscaler(m.FileName, ComfyUpscalerType.ESRGAN)), |
|
|
|
ComfyUpscaler.Comparer |
|
|
|
ComfyUpscaler.Comparer |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
// Remote upscalers |
|
|
|
// Remote upscalers |
|
|
|
var remoteUpscalers = ComfyUpscaler |
|
|
|
var remoteUpscalers = ComfyUpscaler.DefaultDownloadableModels.Where( |
|
|
|
.DefaultDownloadableModels |
|
|
|
u => !modelUpscalersSource.Lookup(u.Name).HasValue |
|
|
|
.Where(u => !modelUpscalersSource.Lookup(u.Name).HasValue); |
|
|
|
); |
|
|
|
downloadableUpscalersSource.EditDiff(remoteUpscalers, ComfyUpscaler.Comparer); |
|
|
|
downloadableUpscalersSource.EditDiff(remoteUpscalers, ComfyUpscaler.Comparer); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -322,7 +352,10 @@ public partial class InferenceClientManager : ObservableObject, IInferenceClient |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc /> |
|
|
|
/// <inheritdoc /> |
|
|
|
public async Task WriteImageToInputAsync(ImageSource imageSource, CancellationToken cancellationToken = default) |
|
|
|
public async Task WriteImageToInputAsync( |
|
|
|
|
|
|
|
ImageSource imageSource, |
|
|
|
|
|
|
|
CancellationToken cancellationToken = default |
|
|
|
|
|
|
|
) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!IsConnected) |
|
|
|
if (!IsConnected) |
|
|
|
return; |
|
|
|
return; |
|
|
|