diff --git a/StabilityMatrix.Core/Converters/Json/OneOfJsonConverter.cs b/StabilityMatrix.Core/Converters/Json/OneOfJsonConverter.cs new file mode 100644 index 00000000..876db568 --- /dev/null +++ b/StabilityMatrix.Core/Converters/Json/OneOfJsonConverter.cs @@ -0,0 +1,63 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using OneOf; + +namespace StabilityMatrix.Core.Converters.Json; + +public class OneOfJsonConverter : JsonConverter> +{ + /// + public override OneOf Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) + { + // Not sure how else to do this without polymorphic type markers but that would not serialize into T1/T2 + // So just try to deserialize T1, if it fails, try T2 + Exception? t1Exception = null; + Exception? t2Exception = null; + + try + { + if (JsonSerializer.Deserialize(ref reader, options) is { } t1) + { + return t1; + } + } + catch (JsonException e) + { + t1Exception = e; + } + + try + { + if (JsonSerializer.Deserialize(ref reader, options) is { } t2) + { + return t2; + } + } + catch (JsonException e) + { + t2Exception = e; + } + + throw new JsonException( + $"Failed to deserialize OneOf<{typeof(T1)}, {typeof(T2)}> as either {typeof(T1)} or {typeof(T2)}", + new AggregateException([t1Exception, t2Exception]) + ); + } + + /// + public override void Write(Utf8JsonWriter writer, OneOf value, JsonSerializerOptions options) + { + if (value.IsT0) + { + JsonSerializer.Serialize(writer, value.AsT0, options); + } + else + { + JsonSerializer.Serialize(writer, value.AsT1, options); + } + } +} diff --git a/StabilityMatrix.Core/Inference/ComfyClient.cs b/StabilityMatrix.Core/Inference/ComfyClient.cs index 6fa578a3..248396f0 100644 --- a/StabilityMatrix.Core/Inference/ComfyClient.cs +++ b/StabilityMatrix.Core/Inference/ComfyClient.cs @@ -6,11 +6,13 @@ using NLog; using Polly.Contrib.WaitAndRetry; using Refit; using StabilityMatrix.Core.Api; +using StabilityMatrix.Core.Converters.Json; using StabilityMatrix.Core.Exceptions; using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Models; using StabilityMatrix.Core.Models.Api.Comfy; using StabilityMatrix.Core.Models.Api.Comfy.Nodes; +using StabilityMatrix.Core.Models.Api.Comfy.NodeTypes; using StabilityMatrix.Core.Models.Api.Comfy.WebSocketData; using StabilityMatrix.Core.Models.FileInterfaces; using Websocket.Client; @@ -27,8 +29,12 @@ public class ComfyClient : InferenceClientBase private readonly IComfyApi comfyApi; private bool isDisposed; - private JsonSerializerOptions jsonSerializerOptions = - new() { PropertyNamingPolicy = JsonNamingPolicies.SnakeCaseLower, }; + private readonly JsonSerializerOptions jsonSerializerOptions = + new() + { + PropertyNamingPolicy = JsonNamingPolicies.SnakeCaseLower, + Converters = { new OneOfJsonConverter() } + }; // ReSharper disable once MemberCanBePrivate.Global public string ClientId { get; } = Guid.NewGuid().ToString(); @@ -87,7 +93,13 @@ public class ComfyClient : InferenceClientBase public ComfyClient(IApiFactory apiFactory, Uri baseAddress) { - comfyApi = apiFactory.CreateRefitClient(baseAddress); + comfyApi = apiFactory.CreateRefitClient( + baseAddress, + new RefitSettings + { + ContentSerializer = new SystemTextJsonContentSerializer(jsonSerializerOptions), + } + ); BaseAddress = baseAddress; // Setup websocket client