Fix enum serialization (#61)
* Fix enum serialization * Add tests for enum serialization * Add missing enum serialization configuration. * Ensure enums serialize as expected using defaults --------- Co-authored-by: Eirik Tsarpalis <eirik.tsarpalis@gmail.com>
This commit is contained in:
parent
1a5732b158
commit
96ba2fa076
5 changed files with 58 additions and 28 deletions
|
|
@ -485,7 +485,7 @@ public static class McpClientExtensions
|
||||||
Throw.IfNull(client);
|
Throw.IfNull(client);
|
||||||
|
|
||||||
return client.SendRequestAsync<EmptyResult>(
|
return client.SendRequestAsync<EmptyResult>(
|
||||||
CreateRequest("logging/setLevel", new() { ["level"] = level.ToJsonValue() }),
|
CreateRequest("logging/setLevel", new() { ["level"] = level }),
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -514,22 +514,6 @@ public static class McpClientExtensions
|
||||||
return parameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ToJsonValue(this LoggingLevel level)
|
|
||||||
{
|
|
||||||
return level switch
|
|
||||||
{
|
|
||||||
LoggingLevel.Debug => "debug",
|
|
||||||
LoggingLevel.Info => "info",
|
|
||||||
LoggingLevel.Notice => "notice",
|
|
||||||
LoggingLevel.Warning => "warning",
|
|
||||||
LoggingLevel.Error => "error",
|
|
||||||
LoggingLevel.Critical => "critical",
|
|
||||||
LoggingLevel.Alert => "alert",
|
|
||||||
LoggingLevel.Emergency => "emergency",
|
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(level))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Provides an AI function that calls a tool through <see cref="IMcpClient"/>.</summary>
|
/// <summary>Provides an AI function that calls a tool through <see cref="IMcpClient"/>.</summary>
|
||||||
private sealed class McpAIFunction(IMcpClient client, Tool tool) : AIFunction
|
private sealed class McpAIFunction(IMcpClient client, Tool tool) : AIFunction
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,29 @@
|
||||||
namespace ModelContextProtocol.Protocol.Types;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace ModelContextProtocol.Protocol.Types;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A request to include context from one or more MCP servers (including the caller), to be attached to the prompt.
|
/// A request to include context from one or more MCP servers (including the caller), to be attached to the prompt.
|
||||||
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonConverter(typeof(JsonStringEnumConverter<ContextInclusion>))]
|
||||||
public enum ContextInclusion
|
public enum ContextInclusion
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// No context should be included.
|
/// No context should be included.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonStringEnumMemberName("none")]
|
||||||
None,
|
None,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Include context from the server that sent the request.
|
/// Include context from the server that sent the request.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonStringEnumMemberName("thisServer")]
|
||||||
ThisServer,
|
ThisServer,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Include context from all servers that the client is connected to.
|
/// Include context from all servers that the client is connected to.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonStringEnumMemberName("allServers")]
|
||||||
AllServers
|
AllServers
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,37 +7,38 @@ namespace ModelContextProtocol.Protocol.Types;
|
||||||
/// These map to syslog message severities, as specified in RFC-5424:
|
/// These map to syslog message severities, as specified in RFC-5424:
|
||||||
/// https://datatracker.ietf.org/doc/html/rfc5424#section-6.2.1
|
/// https://datatracker.ietf.org/doc/html/rfc5424#section-6.2.1
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonConverter(typeof(JsonStringEnumConverter<LoggingLevel>))]
|
||||||
public enum LoggingLevel
|
public enum LoggingLevel
|
||||||
{
|
{
|
||||||
/// <summary>Detailed debug information, typically only valuable to developers.</summary>
|
/// <summary>Detailed debug information, typically only valuable to developers.</summary>
|
||||||
[JsonPropertyName("debug")]
|
[JsonStringEnumMemberName("debug")]
|
||||||
Debug,
|
Debug,
|
||||||
|
|
||||||
/// <summary>Normal operational messages that require no action.</summary>
|
/// <summary>Normal operational messages that require no action.</summary>
|
||||||
[JsonPropertyName("info")]
|
[JsonStringEnumMemberName("info")]
|
||||||
Info,
|
Info,
|
||||||
|
|
||||||
/// <summary>Normal but significant events that might deserve attention.</summary>
|
/// <summary>Normal but significant events that might deserve attention.</summary>
|
||||||
[JsonPropertyName("notice")]
|
[JsonStringEnumMemberName("notice")]
|
||||||
Notice,
|
Notice,
|
||||||
|
|
||||||
/// <summary>Warning conditions that don't represent an error but indicate potential issues.</summary>
|
/// <summary>Warning conditions that don't represent an error but indicate potential issues.</summary>
|
||||||
[JsonPropertyName("warning")]
|
[JsonStringEnumMemberName("warning")]
|
||||||
Warning,
|
Warning,
|
||||||
|
|
||||||
/// <summary>Error conditions that should be addressed but don't require immediate action.</summary>
|
/// <summary>Error conditions that should be addressed but don't require immediate action.</summary>
|
||||||
[JsonPropertyName("error")]
|
[JsonStringEnumMemberName("error")]
|
||||||
Error,
|
Error,
|
||||||
|
|
||||||
/// <summary>Critical conditions that require immediate attention.</summary>
|
/// <summary>Critical conditions that require immediate attention.</summary>
|
||||||
[JsonPropertyName("critical")]
|
[JsonStringEnumMemberName("critical")]
|
||||||
Critical,
|
Critical,
|
||||||
|
|
||||||
/// <summary>Action must be taken immediately to address the condition.</summary>
|
/// <summary>Action must be taken immediately to address the condition.</summary>
|
||||||
[JsonPropertyName("alert")]
|
[JsonStringEnumMemberName("alert")]
|
||||||
Alert,
|
Alert,
|
||||||
|
|
||||||
/// <summary>System is unusable and requires immediate attention.</summary>
|
/// <summary>System is unusable and requires immediate attention.</summary>
|
||||||
[JsonPropertyName("emergency")]
|
[JsonStringEnumMemberName("emergency")]
|
||||||
Emergency
|
Emergency
|
||||||
}
|
}
|
||||||
|
|
@ -6,17 +6,18 @@ namespace ModelContextProtocol.Protocol.Types;
|
||||||
/// Represents the type of role in the conversation.
|
/// Represents the type of role in the conversation.
|
||||||
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonConverter(typeof(JsonStringEnumConverter<Role>))]
|
||||||
public enum Role
|
public enum Role
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Corresponds to the user in the conversation.
|
/// Corresponds to the user in the conversation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("user")]
|
[JsonStringEnumMemberName("user")]
|
||||||
User,
|
User,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Corresponds to the AI in the conversation.
|
/// Corresponds to the AI in the conversation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("assistant")]
|
[JsonStringEnumMemberName("assistant")]
|
||||||
Assistant
|
Assistant
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using ModelContextProtocol.Protocol.Types;
|
using ModelContextProtocol.Protocol.Types;
|
||||||
|
using ModelContextProtocol.Utils.Json;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace ModelContextProtocol.Tests.Protocol;
|
namespace ModelContextProtocol.Tests.Protocol;
|
||||||
|
|
@ -51,4 +52,41 @@ public static class ProtocolTypeTests
|
||||||
|
|
||||||
Assert.True(JsonElement.DeepEquals(document.RootElement, tool.InputSchema));
|
Assert.True(JsonElement.DeepEquals(document.RootElement, tool.InputSchema));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(Role.User, "\"user\"")]
|
||||||
|
[InlineData(Role.Assistant, "\"assistant\"")]
|
||||||
|
public static void SerializeRole_ShouldBeCamelCased(Role role, string expectedValue)
|
||||||
|
{
|
||||||
|
var actualValue = JsonSerializer.Serialize(role);
|
||||||
|
|
||||||
|
Assert.Equal(expectedValue, actualValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(LoggingLevel.Debug, "\"debug\"")]
|
||||||
|
[InlineData(LoggingLevel.Info, "\"info\"")]
|
||||||
|
[InlineData(LoggingLevel.Notice, "\"notice\"")]
|
||||||
|
[InlineData(LoggingLevel.Warning, "\"warning\"")]
|
||||||
|
[InlineData(LoggingLevel.Error, "\"error\"")]
|
||||||
|
[InlineData(LoggingLevel.Critical, "\"critical\"")]
|
||||||
|
[InlineData(LoggingLevel.Alert, "\"alert\"")]
|
||||||
|
[InlineData(LoggingLevel.Emergency, "\"emergency\"")]
|
||||||
|
public static void SerializeLoggingLevel_ShouldBeCamelCased(LoggingLevel level, string expectedValue)
|
||||||
|
{
|
||||||
|
var actualValue = JsonSerializer.Serialize(level);
|
||||||
|
|
||||||
|
Assert.Equal(expectedValue, actualValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(ContextInclusion.None, "\"none\"")]
|
||||||
|
[InlineData(ContextInclusion.ThisServer, "\"thisServer\"")]
|
||||||
|
[InlineData(ContextInclusion.AllServers, "\"allServers\"")]
|
||||||
|
public static void ContextInclusion_ShouldBeCamelCased(ContextInclusion level, string expectedValue)
|
||||||
|
{
|
||||||
|
var actualValue = JsonSerializer.Serialize(level);
|
||||||
|
|
||||||
|
Assert.Equal(expectedValue, actualValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue