From 0515afb1e004e8c798968c4bfd591b564f84c42e Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Sun, 30 Jun 2024 12:01:58 -0500 Subject: [PATCH] fix: modify tool class to have static methods and create input schema from function --- src/AnthropicClient/Models/Tool.cs | 102 ++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 17 deletions(-) diff --git a/src/AnthropicClient/Models/Tool.cs b/src/AnthropicClient/Models/Tool.cs index ea4be30..85273f2 100644 --- a/src/AnthropicClient/Models/Tool.cs +++ b/src/AnthropicClient/Models/Tool.cs @@ -1,3 +1,5 @@ +using System.Reflection; +using System.Text.Json.Nodes; using System.Text.Json.Serialization; using AnthropicClient.Utils; @@ -12,40 +14,106 @@ public class Tool /// /// Gets the name of the tool. /// - public string Name { get; init; } = string.Empty; + public string Name { get; } /// /// Gets the description of the tool. /// - public string Description { get; init; } = string.Empty; + public string Description { get; } /// /// Gets the input schema of the tool. /// [JsonPropertyName("input_schema")] - public InputSchema InputSchema { get; init; } = new(); - - [JsonConstructor] - internal Tool() - { - } + public JsonNode InputSchema { get; } /// - /// Initializes a new instance of the class. + /// Gets the function of the tool. /// - /// The name of the tool. - /// The description of the tool. - /// The input schema of the tool. - /// Thrown when the name, description, or input schema is null. - /// A new instance of the class. - public Tool(string name, string description, InputSchema inputSchema) + [JsonIgnore] + public AnthropicFunction Function { get; } + + internal Tool(string name, string description, AnthropicFunction function) { ArgumentValidator.ThrowIfNull(name, nameof(name)); ArgumentValidator.ThrowIfNull(description, nameof(description)); - ArgumentValidator.ThrowIfNull(inputSchema, nameof(inputSchema)); + ArgumentValidator.ThrowIfNull(function, nameof(function)); Name = name; Description = description; - InputSchema = inputSchema; + Function = function; + InputSchema = JsonSchemaGenerator.GenerateInputSchema(function); + } + + /// + /// Creates a tool from a static method. + /// + /// The name of the tool. + /// The description of the tool. + /// The type that contains the method. + /// The name of the method. + /// Thrown when , , , or is null. + /// Thrown when the method is not found in the type. + /// The created tool as instance of . + public static Tool CreateFromStaticMethod(string name, string description, Type type, string methodName) + { + ArgumentValidator.ThrowIfNull(name, nameof(name)); + ArgumentValidator.ThrowIfNull(description, nameof(description)); + ArgumentValidator.ThrowIfNull(type, nameof(type)); + ArgumentValidator.ThrowIfNull(methodName, nameof(methodName)); + + var method = type.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static); + + if (method is null) + { + throw new ArgumentException($"Method '{methodName}' not found in type '{type.FullName}'.", nameof(methodName)); + } + + return new Tool(name, description, new AnthropicFunction(method)); + } + + /// + /// Creates a tool from an instance method. + /// + /// The name of the tool. + /// The description of the tool. + /// The instance that contains the method. + /// The name of the method. + /// Thrown when , , , or is null. + /// Thrown when the method is not found in the type. + /// The created tool as instance of . + public static Tool CreateFromInstanceMethod(string name, string description, object instance, string methodName) + { + ArgumentValidator.ThrowIfNull(name, nameof(name)); + ArgumentValidator.ThrowIfNull(description, nameof(description)); + ArgumentValidator.ThrowIfNull(instance, nameof(instance)); + ArgumentValidator.ThrowIfNull(methodName, nameof(methodName)); + + var method = instance.GetType().GetMethod(methodName, BindingFlags.Public | BindingFlags.Instance); + + if (method is null) + { + throw new ArgumentException($"Method '{methodName}' not found in type '{instance.GetType().FullName}'.", nameof(methodName)); + } + + return new Tool(name, description, new AnthropicFunction(method, instance)); + } + + /// + /// Creates a tool from a function. + /// + /// The type of the result. + /// The name of the tool. + /// The description of the tool. + /// The function. + /// Thrown when , , or is null. + /// The created tool as instance of . + public static Tool CreateFromFunction(string name, string description, Func func) + { + ArgumentValidator.ThrowIfNull(name, nameof(name)); + ArgumentValidator.ThrowIfNull(description, nameof(description)); + ArgumentValidator.ThrowIfNull(func, nameof(func)); + + return new Tool(name, description, new AnthropicFunction(func.Method, func.Target)); } } \ No newline at end of file