Skip to content

Commit f979500

Browse files
committed
Avoid duplication of tool JSON settings with MEAI
Integrate more seamlessly with the AIJsonUtilities default JSON settings by just adding our delta on top. This includes honoring its type info resolver chain and default settings,
1 parent 3cd5546 commit f979500

File tree

2 files changed

+11
-14
lines changed

2 files changed

+11
-14
lines changed

src/Extensions/ToolJsonOptions.cs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System.Diagnostics;
22
using System.Text.Json;
3-
using System.Text.Json.Serialization;
4-
using System.Text.Json.Serialization.Metadata;
3+
using Microsoft.Extensions.AI;
54

65
namespace Devlooped.Extensions.AI;
76

@@ -16,19 +15,14 @@ public static class ToolJsonOptions
1615
/// <summary>
1716
/// Default <see cref="JsonSerializerOptions"/> for function calling and tools.
1817
/// </summary>
19-
public static JsonSerializerOptions Default { get; } = new(JsonSerializerDefaults.Web)
18+
public static JsonSerializerOptions Default { get; } = new(AIJsonUtilities.DefaultOptions)
2019
{
2120
Converters =
2221
{
2322
new AdditionalPropertiesDictionaryConverter(),
24-
new JsonStringEnumConverter(),
2523
},
26-
DefaultIgnoreCondition =
27-
JsonIgnoreCondition.WhenWritingDefault |
28-
JsonIgnoreCondition.WhenWritingNull,
29-
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
3024
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
31-
WriteIndented = Debugger.IsAttached,
32-
TypeInfoResolver = new TypeInjectingResolver(new DefaultJsonTypeInfoResolver())
25+
WriteIndented = Debugger.IsAttached || AIJsonUtilities.DefaultOptions.WriteIndented,
26+
TypeInfoResolver = new TypeInjectingResolver(AIJsonUtilities.DefaultOptions.TypeInfoResolverChain)
3327
};
3428
}

src/Extensions/TypeInjectingResolver.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ public static JsonSerializerOptions WithTypeInjection(this JsonSerializerOptions
1818
if (options.IsReadOnly)
1919
options = new(options);
2020

21-
options.TypeInfoResolver = new TypeInjectingResolver(
22-
JsonTypeInfoResolver.Combine([.. options.TypeInfoResolverChain]));
21+
options.TypeInfoResolver = new TypeInjectingResolver(options.TypeInfoResolverChain);
2322

2423
return options;
2524
}
@@ -29,12 +28,15 @@ public static JsonSerializerOptions WithTypeInjection(this JsonSerializerOptions
2928
/// A custom <see cref="IJsonTypeInfoResolver"/> that injects a $type property into object types
3029
/// so they can be automatically distinguished during deserialization or inspection.
3130
/// </summary>
32-
public class TypeInjectingResolver(IJsonTypeInfoResolver inner) : IJsonTypeInfoResolver
31+
public class TypeInjectingResolver(IList<IJsonTypeInfoResolver> chain) : IJsonTypeInfoResolver
3332
{
33+
readonly IJsonTypeInfoResolver resolver = JsonTypeInfoResolver.Combine([.. chain]);
34+
3435
/// <inheritdoc />
3536
public JsonTypeInfo? GetTypeInfo(Type type, JsonSerializerOptions options)
3637
{
37-
var info = inner.GetTypeInfo(type, options);
38+
var info = resolver.GetTypeInfo(type, options);
39+
3840
// The $type would already be present for polymorphic serialization.
3941
if (info?.Kind == JsonTypeInfoKind.Object && !info.Properties.Any(x => x.Name == "$type"))
4042
{
@@ -43,6 +45,7 @@ public class TypeInjectingResolver(IJsonTypeInfoResolver inner) : IJsonTypeInfoR
4345
prop.Order = -1000; // Ensure it is serialized first
4446
info.Properties.Add(prop);
4547
}
48+
4649
return info;
4750
}
4851
}

0 commit comments

Comments
 (0)