From 087f0120931f7276aa005953f36ede10b2c63cdc Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Sun, 30 Jun 2024 12:04:26 -0500 Subject: [PATCH] feat: begin work on creating input schema from function method info --- .../Utils/JsonSchemaGenerator.cs | 58 +++++++++++++++++++ .../Unit/Utils/JsonSchemaGeneratorTests.cs | 45 ++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 src/AnthropicClient/Utils/JsonSchemaGenerator.cs create mode 100644 tests/AnthropicClient.Tests/Unit/Utils/JsonSchemaGeneratorTests.cs diff --git a/src/AnthropicClient/Utils/JsonSchemaGenerator.cs b/src/AnthropicClient/Utils/JsonSchemaGenerator.cs new file mode 100644 index 0000000..4950171 --- /dev/null +++ b/src/AnthropicClient/Utils/JsonSchemaGenerator.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Text.Json.Nodes; + +using AnthropicClient.Models; + +namespace AnthropicClient.Utils; + +static class JsonSchemaGenerator +{ + private const string TypeKey = "type"; + private const string PropertiesKey = "properties"; + private const string RequiredPropertiesKey = "required"; + private const string DescriptionKey = "description"; + private const string Object = "object"; + + public static JsonNode GenerateInputSchema(AnthropicFunction function) + { + var parameters = function.Method.GetParameters(); + var schema = new JsonObject() + { + [TypeKey] = Object + }; + + if (parameters.Length is 0) + { + return schema; + } + + var properties = new JsonObject(); + var requiredProperties = new JsonArray(); + + foreach (var parameter in parameters) + { + if (parameter.ParameterType == typeof(CancellationToken)) + { + continue; + } + + var paramName = parameter.Name; + var paramDescription = string.Empty; + var paramRequired = parameter.HasDefaultValue; + + var paramObject = new JsonObject(); + paramObject[DescriptionKey] = paramDescription; + + properties[paramName] = paramObject; + + if (paramRequired) + { + requiredProperties.Add(paramName); + } + } + + schema[PropertiesKey] = properties; + schema[RequiredPropertiesKey] = requiredProperties; + return schema; + } +} \ No newline at end of file diff --git a/tests/AnthropicClient.Tests/Unit/Utils/JsonSchemaGeneratorTests.cs b/tests/AnthropicClient.Tests/Unit/Utils/JsonSchemaGeneratorTests.cs new file mode 100644 index 0000000..b6b874a --- /dev/null +++ b/tests/AnthropicClient.Tests/Unit/Utils/JsonSchemaGeneratorTests.cs @@ -0,0 +1,45 @@ +using System.Text.Json.Nodes; + +namespace AnthropicClient.Tests.Unit.Models; + +public class JsonSchemaGeneratorTests +{ + [Fact] + public void GenerateInputSchema_GivenFunctionWithNoParameters_ReturnsSchemaWithTypeObject() + { + var expectedSchema = new JsonObject + { + ["type"] = "object" + }; + var testMethod = () => true; + var function = new AnthropicFunction(testMethod.Method); + + var schema = JsonSchemaGenerator.GenerateInputSchema(function); + + JsonAssert.Equal(expectedSchema, schema); + } + + [Fact] + public void GenerateInputSchema_GivenFunctionWithParameter_ItShouldReturnSchemaWithProperty() + { + var expectedSchema = new JsonObject() + { + ["type"] = "object", + ["properties"] = new JsonObject() + { + ["age"] = new JsonObject() + { + ["description"] = string.Empty + } + }, + ["required"] = new JsonArray(), + }; + + var testMethod = (int age) => age; + var function = new AnthropicFunction(testMethod.Method); + + var schema = JsonSchemaGenerator.GenerateInputSchema(function); + + JsonAssert.Equal(expectedSchema, schema); + } +} \ No newline at end of file