Add SwarmUI settings management and portrait generation enhancements
- Introduced new API endpoints for managing SwarmUI settings, including fetching and saving presets and age rules. - Updated the portrait generation logic to utilize the new settings structure, allowing for dynamic preset selection based on age. - Enhanced UI components to support SwarmUI settings, including localization for new strings and improved styling for settings sections. - Added tests to verify the functionality of new settings endpoints and portrait generation behavior. This commit lays the groundwork for more flexible and user-friendly portrait generation options.
This commit is contained in:
@@ -55,11 +55,39 @@ internal sealed class SwarmUiClient
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<SwarmUiDiscovery> FetchDiscoveryAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (!IsConfigured)
|
||||
{
|
||||
return SwarmUiDiscovery.Offline;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return await RunWithSessionAsync(async () =>
|
||||
{
|
||||
using var content = new StringContent(
|
||||
JsonSerializer.Serialize(new { session_id = _sessionId }),
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
using var response = await _http.PostAsync("/API/ListT2IParams", content, cancellationToken);
|
||||
response.EnsureSuccessStatusCode();
|
||||
var json = await response.Content.ReadAsStringAsync(cancellationToken);
|
||||
using var document = JsonDocument.Parse(json);
|
||||
return SwarmUiDiscoveryParser.Parse(document.RootElement);
|
||||
}, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogDebug(ex, "SwarmUI discovery failed.");
|
||||
return SwarmUiDiscovery.Offline;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<byte[]> GenerateAsync(
|
||||
string prompt,
|
||||
string negativePrompt,
|
||||
SwarmUiSettings settings,
|
||||
PortraitKind kind,
|
||||
SwarmUiResolvedProfile profile,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (!IsConfigured)
|
||||
@@ -69,7 +97,7 @@ internal sealed class SwarmUiClient
|
||||
|
||||
return await RunWithSessionAsync(async () =>
|
||||
{
|
||||
var preset = settings.PresetFor(kind);
|
||||
var kind = profile.KindPreset;
|
||||
var body = new Dictionary<string, object?>
|
||||
{
|
||||
["session_id"] = _sessionId,
|
||||
@@ -77,28 +105,33 @@ internal sealed class SwarmUiClient
|
||||
["donotsave"] = true,
|
||||
["prompt"] = prompt,
|
||||
["negativeprompt"] = negativePrompt,
|
||||
["model"] = settings.Model,
|
||||
["steps"] = settings.Steps,
|
||||
["cfgscale"] = settings.CfgScale,
|
||||
["width"] = preset.Width,
|
||||
["height"] = preset.Height,
|
||||
["seed"] = settings.Seed,
|
||||
["model"] = profile.Model,
|
||||
["steps"] = profile.Steps,
|
||||
["cfgscale"] = profile.CfgScale,
|
||||
["width"] = kind.Width,
|
||||
["height"] = kind.Height,
|
||||
["seed"] = profile.Seed,
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(settings.Sampler))
|
||||
if (!string.IsNullOrWhiteSpace(profile.Sampler))
|
||||
{
|
||||
body["sampler"] = settings.Sampler;
|
||||
body["sampler"] = profile.Sampler;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(settings.Scheduler))
|
||||
if (!string.IsNullOrWhiteSpace(profile.Scheduler))
|
||||
{
|
||||
body["scheduler"] = settings.Scheduler;
|
||||
body["scheduler"] = profile.Scheduler;
|
||||
}
|
||||
|
||||
if (settings.ClipSkip > 0)
|
||||
if (profile.ClipSkip > 0)
|
||||
{
|
||||
// SwarmUI "CLIP Stop At Layer" — clip skip N is layer -N from the end.
|
||||
body["clipstopatlayer"] = -settings.ClipSkip;
|
||||
body["clipstopatlayer"] = -profile.ClipSkip;
|
||||
}
|
||||
|
||||
var loras = SwarmUiLoraFormatter.FormatForApi(profile.PositiveLoras);
|
||||
if (loras is not null)
|
||||
{
|
||||
body["loras"] = loras;
|
||||
}
|
||||
|
||||
using var content = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json");
|
||||
|
||||
Reference in New Issue
Block a user