From c2788c389320c6b89e4d9109273fe082ea4b519c Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Mon, 1 Jul 2024 23:14:08 -0500 Subject: [PATCH] fix: address methods that return void or task in those cases return null --- src/AnthropicClient/Models/ToolCall.cs | 5 ++- src/AnthropicClient/Models/ToolCallResult.cs | 2 +- .../Unit/Models/ToolCallTests.cs | 34 +++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/AnthropicClient/Models/ToolCall.cs b/src/AnthropicClient/Models/ToolCall.cs index c78a1ae..824a317 100644 --- a/src/AnthropicClient/Models/ToolCall.cs +++ b/src/AnthropicClient/Models/ToolCall.cs @@ -1,5 +1,6 @@ using System.Reflection; using System.Text.Json; +using System.Threading.Tasks; using AnthropicClient.Json; @@ -65,7 +66,9 @@ public class ToolCall const string resultPropertyName = "Result"; var resultProperty = task.GetType().GetProperty(resultPropertyName); - result = resultProperty is not null ? (T)resultProperty.GetValue(task) : default; + var isVoidTaskResult = resultProperty.PropertyType.FullName.Contains("VoidTaskResult"); + + result = resultProperty is not null && isVoidTaskResult is false ? (T)resultProperty.GetValue(task) : default; } else { diff --git a/src/AnthropicClient/Models/ToolCallResult.cs b/src/AnthropicClient/Models/ToolCallResult.cs index 441c39a..d0ea5a5 100644 --- a/src/AnthropicClient/Models/ToolCallResult.cs +++ b/src/AnthropicClient/Models/ToolCallResult.cs @@ -6,7 +6,7 @@ namespace AnthropicClient.Models; public class ToolCallResult { /// - /// The value of the tool call result. + /// The value of the tool call result. Can be null if the call failed, the call was successful but the return type is void or Task, or the call was successful but the return value is null /// public T? Value { get; } diff --git a/tests/AnthropicClient.Tests/Unit/Models/ToolCallTests.cs b/tests/AnthropicClient.Tests/Unit/Models/ToolCallTests.cs index a347cbe..4c8400c 100644 --- a/tests/AnthropicClient.Tests/Unit/Models/ToolCallTests.cs +++ b/tests/AnthropicClient.Tests/Unit/Models/ToolCallTests.cs @@ -221,6 +221,40 @@ public class ToolCallTests : SerializationTest result.Value.Should().Be("John"); result.Error.Should().BeNull(); } + + [Fact] + public async Task InvokeAsync_WhenCalledAndToolReturnsVoid_ItShouldReturnSuccessResult() + { + var func = (int i) => { }; + var anthropicFunction = new AnthropicFunction(func.Method, func.Target); + var tool = new Tool("tool", "description", anthropicFunction); + + var input = new Dictionary { { "i", 42 } }; + var toolCall = new ToolCall(tool, new ToolUseContent { Input = input }); + + var result = await toolCall.InvokeAsync(); + + result.IsSuccess.Should().BeTrue(); + result.Value.Should().BeNull(); + result.Error.Should().BeNull(); + } + + [Fact] + public async Task InvokeAsync_WhenCalledAndToolReturnsTask_ItShouldReturnSuccessResult() + { + var func = async (int i) => await Task.CompletedTask; + var anthropicFunction = new AnthropicFunction(func.Method, func.Target); + var tool = new Tool("tool", "description", anthropicFunction); + + var input = new Dictionary { { "i", 42 } }; + var toolCall = new ToolCall(tool, new ToolUseContent { Input = input }); + + var result = await toolCall.InvokeAsync(); + + result.IsSuccess.Should().BeTrue(); + result.Value.Should().BeNull(); + result.Error.Should().BeNull(); + } } class Person