Change type of Tool.InputSchema to be JsonElement (#4)
* Change type of Tool.InputSchema to be JsonElement * Add schema validation in the InputSchema property setter. * Simplify AIFunction tool adapter. --------- Co-authored-by: Eirik Tsarpalis <eirik.tsarpalis@gmail.com>
This commit is contained in:
parent
d23e065945
commit
3de19d38e4
3 changed files with 175 additions and 128 deletions
|
|
@ -48,16 +48,10 @@ public class McpServerBuilderExtensionsToolsTests
|
|||
var tool = result.Tools[0];
|
||||
Assert.Equal("Echo", tool.Name);
|
||||
Assert.Equal("Echoes the input back to the client.", tool.Description);
|
||||
Assert.NotNull(tool.InputSchema);
|
||||
Assert.Equal("object", tool.InputSchema.Type);
|
||||
Assert.NotNull(tool.InputSchema.Properties);
|
||||
Assert.NotEmpty(tool.InputSchema.Properties);
|
||||
Assert.Contains("message", tool.InputSchema.Properties);
|
||||
Assert.Equal("string", tool.InputSchema.Properties["message"].Type);
|
||||
Assert.Equal("the echoes message", tool.InputSchema.Properties["message"].Description);
|
||||
Assert.NotNull(tool.InputSchema.Required);
|
||||
Assert.NotEmpty(tool.InputSchema.Required);
|
||||
Assert.Contains("message", tool.InputSchema.Required);
|
||||
Assert.Equal("object", tool.InputSchema.GetProperty("type").GetString());
|
||||
Assert.Equal(JsonValueKind.Object, tool.InputSchema.GetProperty("properties").GetProperty("message").ValueKind);
|
||||
Assert.Equal("the echoes message", tool.InputSchema.GetProperty("properties").GetProperty("message").GetProperty("description").GetString());
|
||||
Assert.Equal(1, tool.InputSchema.GetProperty("required").GetArrayLength());
|
||||
|
||||
tool = result.Tools[1];
|
||||
Assert.Equal("double_echo", tool.Name);
|
||||
|
|
@ -288,31 +282,15 @@ public class McpServerBuilderExtensionsToolsTests
|
|||
var tool = result.Tools.First(t => t.Name == "TestTool");
|
||||
Assert.Equal("TestTool", tool.Name);
|
||||
Assert.Empty(tool.Description!);
|
||||
Assert.NotNull(tool.InputSchema);
|
||||
Assert.Equal("object", tool.InputSchema.Type);
|
||||
Assert.NotNull(tool.InputSchema.Properties);
|
||||
Assert.NotEmpty(tool.InputSchema.Properties);
|
||||
Assert.Equal("object", tool.InputSchema.GetProperty("type").GetString());
|
||||
|
||||
Assert.Contains("number", tool.InputSchema.Properties);
|
||||
Assert.Equal("integer", tool.InputSchema.Properties["number"].Type);
|
||||
|
||||
Assert.Contains("otherNumber", tool.InputSchema.Properties);
|
||||
Assert.Equal("number", tool.InputSchema.Properties["otherNumber"].Type);
|
||||
|
||||
Assert.Contains("someCheck", tool.InputSchema.Properties);
|
||||
Assert.Equal("boolean", tool.InputSchema.Properties["someCheck"].Type);
|
||||
|
||||
Assert.Contains("someDate", tool.InputSchema.Properties);
|
||||
Assert.Equal("string", tool.InputSchema.Properties["someDate"].Type);
|
||||
|
||||
Assert.Contains("someOtherDate", tool.InputSchema.Properties);
|
||||
Assert.Equal("string", tool.InputSchema.Properties["someOtherDate"].Type);
|
||||
|
||||
Assert.Contains("data", tool.InputSchema.Properties);
|
||||
Assert.Equal("array", tool.InputSchema.Properties["data"].Type);
|
||||
|
||||
Assert.Contains("complexObject", tool.InputSchema.Properties);
|
||||
Assert.Equal("object", tool.InputSchema.Properties["complexObject"].Type);
|
||||
Assert.Contains("integer", tool.InputSchema.GetProperty("properties").GetProperty("number").GetProperty("type").GetString());
|
||||
Assert.Contains("number", tool.InputSchema.GetProperty("properties").GetProperty("otherNumber").GetProperty("type").GetString());
|
||||
Assert.Contains("boolean", tool.InputSchema.GetProperty("properties").GetProperty("someCheck").GetProperty("type").GetString());
|
||||
Assert.Contains("string", tool.InputSchema.GetProperty("properties").GetProperty("someDate").GetProperty("type").GetString());
|
||||
Assert.Contains("string", tool.InputSchema.GetProperty("properties").GetProperty("someOtherDate").GetProperty("type").GetString());
|
||||
Assert.Contains("array", tool.InputSchema.GetProperty("properties").GetProperty("data").GetProperty("type").GetString());
|
||||
Assert.Contains("object", tool.InputSchema.GetProperty("properties").GetProperty("complexObject").GetProperty("type").GetString());
|
||||
}
|
||||
|
||||
[McpToolType]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
using ModelContextProtocol.Protocol.Types;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ModelContextProtocol.Tests.Protocol;
|
||||
|
||||
public static class ProtocolTypeTests
|
||||
{
|
||||
[Fact]
|
||||
public static void ToolInputSchema_HasValidDefaultSchema()
|
||||
{
|
||||
var tool = new Tool();
|
||||
JsonElement jsonElement = tool.InputSchema;
|
||||
|
||||
Assert.Equal(JsonValueKind.Object, jsonElement.ValueKind);
|
||||
Assert.Single(jsonElement.EnumerateObject());
|
||||
Assert.True(jsonElement.TryGetProperty("type", out JsonElement typeElement));
|
||||
Assert.Equal(JsonValueKind.String, typeElement.ValueKind);
|
||||
Assert.Equal("object", typeElement.GetString());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("null")]
|
||||
[InlineData("false")]
|
||||
[InlineData("true")]
|
||||
[InlineData("3.5e3")]
|
||||
[InlineData("[]")]
|
||||
[InlineData("{}")]
|
||||
[InlineData("""{"properties":{}}""")]
|
||||
[InlineData("""{"type":"number"}""")]
|
||||
[InlineData("""{"type":"array"}""")]
|
||||
[InlineData("""{"type":["object"]}""")]
|
||||
public static void ToolInputSchema_RejectsInvalidSchemaDocuments(string invalidSchema)
|
||||
{
|
||||
using var document = JsonDocument.Parse(invalidSchema);
|
||||
var tool = new Tool();
|
||||
|
||||
Assert.Throws<ArgumentException>(() => tool.InputSchema = document.RootElement);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("""{"type":"object"}""")]
|
||||
[InlineData("""{"type":"object", "properties": {}, "required" : [] }""")]
|
||||
[InlineData("""{"type":"object", "title": "MyAwesomeTool", "description": "It's awesome!", "properties": {}, "required" : ["NotAParam"] }""")]
|
||||
public static void ToolInputSchema_AcceptsValidSchemaDocuments(string validSchema)
|
||||
{
|
||||
using var document = JsonDocument.Parse(validSchema);
|
||||
var tool = new Tool();
|
||||
|
||||
tool.InputSchema = document.RootElement;
|
||||
Assert.True(JsonElement.DeepEquals(document.RootElement, tool.InputSchema));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
using System.Threading.Channels;
|
||||
using ModelContextProtocol.Protocol.Messages;
|
||||
using ModelContextProtocol.Protocol.Transport;
|
||||
using ModelContextProtocol.Protocol.Types;
|
||||
|
||||
namespace ModelContextProtocol.Tests.Utils;
|
||||
|
||||
|
|
@ -71,7 +72,7 @@ public class TestServerTransport : IServerTransport
|
|||
await WriteMessageAsync(new JsonRpcResponse
|
||||
{
|
||||
Id = request.Id,
|
||||
Result = new Protocol.Types.CreateMessageResult { Content = new(), Model = "model", Role = "role" }
|
||||
Result = new CreateMessageResult { Content = new(), Model = "model", Role = "role" }
|
||||
}, cancellationToken);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue