Hardcode the source generator in one remaining location and simplify McpJsonUtilities. (#204)
This commit is contained in:
parent
a04cf6a2f5
commit
1c145a5d52
3 changed files with 32 additions and 34 deletions
|
|
@ -53,7 +53,7 @@ public sealed class SseResponseStreamTransport(Stream sseResponseStream, string
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonSerializer.Serialize(GetUtf8JsonWriter(writer), item.Data, McpJsonUtilities.DefaultOptions.GetTypeInfo<IJsonRpcMessage?>());
|
JsonSerializer.Serialize(GetUtf8JsonWriter(writer), item.Data, McpJsonUtilities.JsonContext.Default.IJsonRpcMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ using ModelContextProtocol.Protocol.Messages;
|
||||||
using ModelContextProtocol.Protocol.Types;
|
using ModelContextProtocol.Protocol.Types;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Nodes;
|
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using System.Text.Json.Serialization.Metadata;
|
using System.Text.Json.Serialization.Metadata;
|
||||||
|
|
||||||
|
|
@ -35,36 +34,12 @@ public static partial class McpJsonUtilities
|
||||||
/// Creates default options to use for MCP-related serialization.
|
/// Creates default options to use for MCP-related serialization.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The configured options.</returns>
|
/// <returns>The configured options.</returns>
|
||||||
[UnconditionalSuppressMessage("AotAnalysis", "IL3050", Justification = "DefaultJsonTypeInfoResolver is only used when reflection-based serialization is enabled")]
|
|
||||||
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026", Justification = "DefaultJsonTypeInfoResolver is only used when reflection-based serialization is enabled")]
|
|
||||||
private static JsonSerializerOptions CreateDefaultOptions()
|
private static JsonSerializerOptions CreateDefaultOptions()
|
||||||
{
|
{
|
||||||
// If reflection-based serialization is enabled by default, use it, as it's the most permissive in terms of what it can serialize,
|
// Copy the configuration from the source generated context.
|
||||||
// and we want to be flexible in terms of what can be put into the various collections in the object model.
|
JsonSerializerOptions options = new(JsonContext.Default.Options);
|
||||||
// Otherwise, use the source-generated options to enable trimming and Native AOT.
|
|
||||||
JsonSerializerOptions options;
|
|
||||||
|
|
||||||
if (JsonSerializer.IsReflectionEnabledByDefault)
|
// Chain with all supported types from MEAI
|
||||||
{
|
|
||||||
// Keep in sync with the JsonSourceGenerationOptions attribute on JsonContext below.
|
|
||||||
options = new(JsonSerializerDefaults.Web)
|
|
||||||
{
|
|
||||||
TypeInfoResolver = new DefaultJsonTypeInfoResolver(),
|
|
||||||
Converters = { new JsonStringEnumConverter() },
|
|
||||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
|
||||||
NumberHandling = JsonNumberHandling.AllowReadingFromString,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Keep in sync with any additional settings above beyond what's in JsonContext below.
|
|
||||||
options = new(JsonContext.Default.Options)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Include all types from AIJsonUtilities, so that anything default usable as part of an AIFunction
|
|
||||||
// is also usable as part of an McpServerTool.
|
|
||||||
options.TypeInfoResolverChain.Add(AIJsonUtilities.DefaultOptions.TypeInfoResolver!);
|
options.TypeInfoResolverChain.Add(AIJsonUtilities.DefaultOptions.TypeInfoResolver!);
|
||||||
|
|
||||||
options.MakeReadOnly();
|
options.MakeReadOnly();
|
||||||
|
|
@ -107,11 +82,6 @@ public static partial class McpJsonUtilities
|
||||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
||||||
NumberHandling = JsonNumberHandling.AllowReadingFromString)]
|
NumberHandling = JsonNumberHandling.AllowReadingFromString)]
|
||||||
|
|
||||||
// JSON
|
|
||||||
[JsonSerializable(typeof(JsonDocument))]
|
|
||||||
[JsonSerializable(typeof(JsonElement))]
|
|
||||||
[JsonSerializable(typeof(JsonNode))]
|
|
||||||
|
|
||||||
// JSON-RPC
|
// JSON-RPC
|
||||||
[JsonSerializable(typeof(IJsonRpcMessage))]
|
[JsonSerializable(typeof(IJsonRpcMessage))]
|
||||||
[JsonSerializable(typeof(JsonRpcRequest))]
|
[JsonSerializable(typeof(JsonRpcRequest))]
|
||||||
|
|
|
||||||
28
tests/ModelContextProtocol.Tests/McpJsonUtilitiesTests.cs
Normal file
28
tests/ModelContextProtocol.Tests/McpJsonUtilitiesTests.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
using ModelContextProtocol.Utils.Json;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace ModelContextProtocol.Tests;
|
||||||
|
|
||||||
|
public static class McpJsonUtilitiesTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public static void DefaultOptions_IsSingleton()
|
||||||
|
{
|
||||||
|
var options = McpJsonUtilities.DefaultOptions;
|
||||||
|
|
||||||
|
Assert.NotNull(options);
|
||||||
|
Assert.True(options.IsReadOnly);
|
||||||
|
Assert.Same(options, McpJsonUtilities.DefaultOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public static void DefaultOptions_UseReflectionWhenEnabled()
|
||||||
|
{
|
||||||
|
var options = McpJsonUtilities.DefaultOptions;
|
||||||
|
bool isReflectionEnabled = JsonSerializer.IsReflectionEnabledByDefault;
|
||||||
|
Type anonType = new { Id = 42 }.GetType();
|
||||||
|
|
||||||
|
Assert.True(isReflectionEnabled); // To be disabled once https://github.com/dotnet/extensions/pull/6241 is incorporated
|
||||||
|
Assert.Equal(isReflectionEnabled, options.TryGetTypeInfo(anonType, out _));
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue