diff --git a/src/AnthropicClient/Models/FunctionPropertyAttribute.cs b/src/AnthropicClient/Models/FunctionPropertyAttribute.cs
new file mode 100644
index 0000000..6e8ddb0
--- /dev/null
+++ b/src/AnthropicClient/Models/FunctionPropertyAttribute.cs
@@ -0,0 +1,49 @@
+namespace AnthropicClient.Models;
+
+///
+/// Attribute to describe a property of a type that is used as a function parameter.
+///
+[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
+public class FunctionPropertyAttribute : Attribute
+{
+ ///
+ /// Description of the property.
+ ///
+ public string Description { get; } = string.Empty;
+
+ ///
+ /// Whether the property is required.
+ ///
+ public bool Required { get; } = false;
+
+ ///
+ /// Default value of the property.
+ ///
+ public object? DefaultValue { get; } = null;
+
+ ///
+ /// Possible values of the property.
+ ///
+ public object[]? PossibleValues { get; } = null;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Description of the property.
+ /// Whether the property is required.
+ /// Default value of the property.
+ /// Possible values of the property.
+ /// A new instance of the class.
+ public FunctionPropertyAttribute(
+ string description,
+ bool required = false,
+ object? defaultValue = null,
+ object[]? possibleValues = null
+ )
+ {
+ Description = description;
+ Required = required;
+ DefaultValue = defaultValue;
+ PossibleValues = possibleValues;
+ }
+}
\ No newline at end of file
diff --git a/src/AnthropicClient/Utils/JsonSchemaGenerator.cs b/src/AnthropicClient/Utils/JsonSchemaGenerator.cs
index 59bc565..77d57a0 100644
--- a/src/AnthropicClient/Utils/JsonSchemaGenerator.cs
+++ b/src/AnthropicClient/Utils/JsonSchemaGenerator.cs
@@ -1,7 +1,9 @@
using System.Reflection;
+using System.Text.Json;
using System.Text.Json.Nodes;
using AnthropicClient.Models;
+using AnthropicClient.Json;
namespace AnthropicClient.Utils;
@@ -179,15 +181,11 @@ static class JsonSchemaGenerator
_ => throw new InvalidOperationException("Member is not a property or field")
};
- // TODO: Provide attribute to allow specifying...
- // 1. Name
- // 2. Description
- // 3. Required
- // 4. Default values
- // 5. Possible values
+ var attribute = member.GetCustomAttribute();
+
var memberPropertyName = member.Name;
- var memberDescription = string.Empty;
- var memberRequired = Nullable.GetUnderlyingType(memberType) is null;
+ var memberDescription = attribute?.Description ?? string.Empty;
+ var memberRequired = attribute?.Required ?? Nullable.GetUnderlyingType(memberType) is null;
memberProperty = definitions.AsObject().ContainsKey(memberType.FullName)
? new JsonObject()
@@ -201,6 +199,38 @@ static class JsonSchemaGenerator
memberRequiredProperties.Add(memberPropertyName);
}
+ JsonNode? defaultValue = null;
+
+ if (attribute?.DefaultValue is not null)
+ {
+ defaultValue = JsonNode.Parse(JsonSerializer.Serialize(attribute.DefaultValue, JsonSerializationOptions.DefaultOptions));
+ memberProperty["default"] = defaultValue;
+ }
+
+ if (attribute?.PossibleValues is { Length: > 0 })
+ {
+ var enumValues = new JsonArray();
+
+ foreach (var value in attribute.PossibleValues)
+ {
+ var enumValue = JsonNode.Parse(JsonSerializer.Serialize(value, JsonSerializationOptions.DefaultOptions));
+
+ if (defaultValue is null || JsonNode.DeepEquals(enumValue, defaultValue) is false)
+ {
+ enumValues.Add(enumValue);
+ }
+ }
+
+ var containsDefaultValue = enumValues.Where(value => JsonNode.DeepEquals(value, defaultValue)).Any();
+
+ if (defaultValue is not null && containsDefaultValue is false)
+ {
+ enumValues.Add(JsonNode.Parse(defaultValue.ToJsonString(JsonSerializationOptions.DefaultOptions)));
+ }
+
+ memberProperty[EnumKey] = enumValues;
+ }
+
memberProperty[DescriptionKey] = memberDescription;
memberProperties[memberPropertyName] = memberProperty;
}
diff --git a/tests/AnthropicClient.Tests/Unit/Utils/JsonSchemaGeneratorTestData.cs b/tests/AnthropicClient.Tests/Unit/Utils/JsonSchemaGeneratorTestData.cs
index 791b1a6..906d68c 100644
--- a/tests/AnthropicClient.Tests/Unit/Utils/JsonSchemaGeneratorTestData.cs
+++ b/tests/AnthropicClient.Tests/Unit/Utils/JsonSchemaGeneratorTestData.cs
@@ -585,7 +585,7 @@ public class JsonSchemaGeneratorTestData : IEnumerable