diff --git a/Anthropic.SDK.Tests/Anthropic.SDK.Tests.csproj b/Anthropic.SDK.Tests/Anthropic.SDK.Tests.csproj index 8990cbd..c397e73 100644 --- a/Anthropic.SDK.Tests/Anthropic.SDK.Tests.csproj +++ b/Anthropic.SDK.Tests/Anthropic.SDK.Tests.csproj @@ -40,8 +40,8 @@ - - + + diff --git a/Anthropic.SDK.Tests/SemanticKernelInitializationTests.cs b/Anthropic.SDK.Tests/SemanticKernelInitializationTests.cs index d9e9ad7..eb48590 100644 --- a/Anthropic.SDK.Tests/SemanticKernelInitializationTests.cs +++ b/Anthropic.SDK.Tests/SemanticKernelInitializationTests.cs @@ -103,6 +103,76 @@ public async Task TestSKPDF() } + [TestMethod] + public async Task TestSKLuckyNumber() + { + var skChatService = + new ChatClientBuilder(new AnthropicClient().Messages) + .UseFunctionInvocation() + .Build() + .AsChatCompletionService(); + var sk = Kernel.CreateBuilder(); + sk.Plugins.AddFromType("LuckyNumber"); + sk.Services.AddSingleton(skChatService); + var kernel = sk.Build(); + var chatCompletionService = kernel.Services.GetRequiredService(); + // Create chat history + var history = new ChatHistory(); + history.AddUserMessage("What is today's lucky number?"); + OpenAIPromptExecutionSettings promptExecutionSettings = new() + { + FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(), + ModelId = AnthropicModels.Claude35Haiku, + MaxTokens = 512 + }; + // Get the response from the AI + var result = await chatCompletionService.GetChatMessageContentAsync( + history, + executionSettings: promptExecutionSettings, + kernel: kernel + ); + Assert.IsTrue(result.Content.Contains("895-122")); + } + + [TestMethod] + public async Task TestSKLuckyNumberStreaming() + { + var skChatService = + new ChatClientBuilder(new AnthropicClient().Messages) + .UseFunctionInvocation() + .Build() + .AsChatCompletionService(); + var sk = Kernel.CreateBuilder(); + sk.Plugins.AddFromType("LuckyNumber"); + sk.Services.AddSingleton(skChatService); + var kernel = sk.Build(); + var chatCompletionService = kernel.Services.GetRequiredService(); + // Create chat history + var history = new ChatHistory(); + history.AddUserMessage("What is today's lucky number?"); + OpenAIPromptExecutionSettings promptExecutionSettings = new() + { + FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(), + ModelId = AnthropicModels.Claude35Haiku, + MaxTokens = 512 + }; + // Get the response from the AI + var sbResponse = new StringBuilder(); + await foreach (var streamingContent in chatCompletionService.GetStreamingChatMessageContentsAsync( + history, promptExecutionSettings, kernel)) + + { + if (streamingContent.Content is not null) + { + sbResponse.Append(streamingContent.Content); + } + } + + var result = sbResponse.ToString(); + + Assert.Contains("895-122", result); + } + } @@ -120,5 +190,12 @@ public async Task GetWeather(string location) { return "It is 72 degrees and sunny in " + location; } + + [KernelFunction("LuckyNumber")] + [Description("Gets today's lucky number.")] + public string GetLuckyNumber() + { + return "Today's lucky number is 895-122"; + } } } diff --git a/Anthropic.SDK/Anthropic.SDK.csproj b/Anthropic.SDK/Anthropic.SDK.csproj index a598c2c..d51a115 100644 --- a/Anthropic.SDK/Anthropic.SDK.csproj +++ b/Anthropic.SDK/Anthropic.SDK.csproj @@ -14,12 +14,12 @@ Claude, AI, ML, API, Anthropic Claude API - Web Search, MCP Servers, and Claude 4 Models + Web Search, MCP Servers, and Claude 4 Models, Minor Bug Fixes Anthropic.SDK - 5.4.0 - 5.4.0.0 - 5.4.0.0 + 5.4.1 + 5.4.1.0 + 5.4.1.0 True README.md icon.png diff --git a/Anthropic.SDK/Messaging/MessagesEndpoint.ChatClient.cs b/Anthropic.SDK/Messaging/MessagesEndpoint.ChatClient.cs index 7ebcf4d..9becd3e 100644 --- a/Anthropic.SDK/Messaging/MessagesEndpoint.ChatClient.cs +++ b/Anthropic.SDK/Messaging/MessagesEndpoint.ChatClient.cs @@ -155,7 +155,10 @@ async IAsyncEnumerable IChatClient.GetStreamingResponseAsync { foreach (var f in response.ToolCalls) { - update.Contents.Add(new FunctionCallContent(f.Id, f.Name, JsonSerializer.Deserialize>(f.Arguments.ToString()))); + update.Contents.Add(new FunctionCallContent(f.Id, f.Name, + !string.IsNullOrEmpty(f.Arguments.ToString()) + ? JsonSerializer.Deserialize>(f.Arguments.ToString()) + : new Dictionary())); } } diff --git a/Anthropic.SDK/Messaging/VertexAIMessagesEndpoint.ChatClient.cs b/Anthropic.SDK/Messaging/VertexAIMessagesEndpoint.ChatClient.cs index c7459f4..7073298 100644 --- a/Anthropic.SDK/Messaging/VertexAIMessagesEndpoint.ChatClient.cs +++ b/Anthropic.SDK/Messaging/VertexAIMessagesEndpoint.ChatClient.cs @@ -107,7 +107,10 @@ async IAsyncEnumerable IChatClient.GetStreamingResponseAsync { foreach (var f in response.ToolCalls) { - update.Contents.Add(new FunctionCallContent(f.Id, f.Name, JsonSerializer.Deserialize>(f.Arguments.ToString()))); + update.Contents.Add(new FunctionCallContent(f.Id, f.Name, + !string.IsNullOrEmpty(f.Arguments.ToString()) + ? JsonSerializer.Deserialize>(f.Arguments.ToString()) + : new Dictionary())); } }