From 8924bdc627d87931ac9261e9212afc9f7d242aa7 Mon Sep 17 00:00:00 2001 From: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com> Date: Mon, 23 Sep 2024 15:37:49 +0100 Subject: [PATCH] .Net: Fix function calling integration tests (#8948) ### Motivation, Context and Description Some of the function-calling integration tests were failing occasionally due to various reasons not related to the function-calling functionality in SK. For example, the AI model could decide to call the same function twice instead of once in one out of ten integration test runs. Additionally, Azure may have activated the content management policy by default, causing a few integration tests to fail with the error: "Error: Exception while invoking function. HTTP 400 (content_filter), Parameter: prompt. The response was filtered due to the prompt triggering Azure OpenAI's content management policy. Please modify your prompt and retry." Lastly, some of the integration tests were disabled to unblock the latest release because the AI model started to call functions that were not related to the prompt but were advertised to the model. This PR fixes the intermittently failing tests and re-enables the disabled ones. --- ...penAIChatCompletionFunctionCallingTests.cs | 91 +++++++++++-------- ...pletion_AutoFunctionChoiceBehaviorTests.cs | 12 +-- ...ion_RequiredFunctionChoiceBehaviorTests.cs | 10 +- ...pletion_AutoFunctionChoiceBehaviorTests.cs | 10 +- ...enAIChatCompletion_FunctionCallingTests.cs | 36 ++++---- ...ion_RequiredFunctionChoiceBehaviorTests.cs | 11 +-- 6 files changed, 80 insertions(+), 90 deletions(-) diff --git a/dotnet/src/IntegrationTests/Connectors/AzureOpenAI/AzureOpenAIChatCompletionFunctionCallingTests.cs b/dotnet/src/IntegrationTests/Connectors/AzureOpenAI/AzureOpenAIChatCompletionFunctionCallingTests.cs index c3616167b2c8..17d55396756f 100644 --- a/dotnet/src/IntegrationTests/Connectors/AzureOpenAI/AzureOpenAIChatCompletionFunctionCallingTests.cs +++ b/dotnet/src/IntegrationTests/Connectors/AzureOpenAI/AzureOpenAIChatCompletionFunctionCallingTests.cs @@ -81,7 +81,20 @@ public async Task CanAutoInvokeKernelFunctionsStreamingAsync() public async Task CanAutoInvokeKernelFunctionsWithComplexTypeParametersAsync() { // Arrange - var kernel = this.CreateAndInitializeKernel(importHelperPlugin: true); + var kernel = this.CreateAndInitializeKernel(); + kernel.ImportPluginFromFunctions("HelperFunctions", + [ + kernel.CreateFunctionFromMethod((WeatherParameters parameters) => + { + if (parameters.City.Name.Equals("Dublin", StringComparison.OrdinalIgnoreCase) && + (parameters.City.Country.Equals("Ireland", StringComparison.OrdinalIgnoreCase) || parameters.City.Country.Equals("IE", StringComparison.OrdinalIgnoreCase))) + { + return Task.FromResult(42.8); // 42.8 Fahrenheit. + } + + throw new NotSupportedException($"Weather in {parameters.City.Name} ({parameters.City.Country}) is not supported."); + }, "Get_Current_Temperature", "Get current temperature."), + ]); AzureOpenAIPromptExecutionSettings settings = new() { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions }; @@ -129,10 +142,19 @@ public async Task CanAutoInvokeKernelFunctionsWithEnumTypeParametersAsync() public async Task CanAutoInvokeKernelFunctionFromPromptAsync() { // Arrange + var invokedFunctions = new List(); + + var filter = new FakeFunctionFilter(async (context, next) => + { + invokedFunctions.Add(context.Function.Name); + await next(context); + }); + var kernel = this.CreateAndInitializeKernel(); + kernel.FunctionInvocationFilters.Add(filter); var promptFunction = KernelFunctionFactory.CreateFromPrompt( - "Your role is always to return this text - 'A Game-Changer for the Transportation Industry'. Don't ask for more details or context.", + "Hey LLM, give me one news title that's hot off the press!", functionName: "FindLatestNews", description: "Searches for the latest news."); @@ -144,21 +166,30 @@ public async Task CanAutoInvokeKernelFunctionFromPromptAsync() AzureOpenAIPromptExecutionSettings settings = new() { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions }; // Act - var result = await kernel.InvokePromptAsync("Show me the latest news as they are.", new(settings)); + var result = await kernel.InvokePromptAsync("Show me the latest news.", new(settings)); // Assert - Assert.NotNull(result); - Assert.Contains("Transportation", result.GetValue(), StringComparison.InvariantCultureIgnoreCase); + Assert.Contains(invokedFunctions, functionName => functionName.Contains("InvokePromptAsync")); + Assert.Contains(invokedFunctions, functionName => functionName.Contains("FindLatestNews")); } [Fact] public async Task CanAutoInvokeKernelFunctionFromPromptStreamingAsync() { // Arrange + var invokedFunctions = new List(); + + var filter = new FakeFunctionFilter(async (context, next) => + { + invokedFunctions.Add(context.Function.Name); + await next(context); + }); + var kernel = this.CreateAndInitializeKernel(); + kernel.FunctionInvocationFilters.Add(filter); var promptFunction = KernelFunctionFactory.CreateFromPrompt( - "Your role is always to return this text - 'A Game-Changer for the Transportation Industry'. Don't ask for more details or context.", + "Hey LLM, give me one news title that's hot off the press!", functionName: "FindLatestNews", description: "Searches for the latest news."); @@ -170,20 +201,14 @@ public async Task CanAutoInvokeKernelFunctionFromPromptStreamingAsync() AzureOpenAIPromptExecutionSettings settings = new() { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions }; // Act - var streamingResult = kernel.InvokePromptStreamingAsync("Show me the latest news as they are.", new(settings)); - - var builder = new StringBuilder(); - + var streamingResult = kernel.InvokePromptStreamingAsync("Show me the latest news.", new(settings)); await foreach (var update in streamingResult) { - builder.Append(update.ToString()); } - var result = builder.ToString(); - // Assert - Assert.NotNull(result); - Assert.Contains("Transportation", result, StringComparison.InvariantCultureIgnoreCase); + Assert.Contains(invokedFunctions, functionName => functionName.Contains("InvokePromptStreamingAsync")); + Assert.Contains(invokedFunctions, functionName => functionName.Contains("FindLatestNews")); } [Fact] @@ -482,7 +507,7 @@ public async Task ConnectorAgnosticFunctionCallingModelClassesCanBeUsedForAutoFu Assert.NotNull(getWeatherForCityFunctionCallResult.Result); } - [Fact(Skip = "Weather in Boston (USA) is not supported.")] + [Fact] public async Task ConnectorAgnosticFunctionCallingModelClassesCanBeUsedForManualFunctionCallingForStreamingAsync() { // Arrange @@ -784,10 +809,13 @@ public async Task ItShouldSupportOldFunctionCallingModelSerializedIntoChatHistor string? emailBody = null, emailRecipient = null; var kernel = this.CreateAndInitializeKernel(importHelperPlugin: true); - kernel.ImportPluginFromFunctions("EmailPlugin", [KernelFunctionFactory.CreateFromMethod((string body, string recipient) => { emailBody = body; emailRecipient = recipient; }, "SendEmail")]); + kernel.ImportPluginFromFunctions("EmailPlugin", [ + KernelFunctionFactory.CreateFromMethod((string body, string recipient) => { emailBody = body; emailRecipient = recipient; }, "SendEmail"), + KernelFunctionFactory.CreateFromMethod(() => "abc@domain.com", "GetMyEmail") + ]); // The deserialized chat history contains a list of function calls and the final answer to the question regarding the color of the sky in Boston. - chatHistory.AddUserMessage("Send the exact answer to my email: abc@domain.com"); + chatHistory.AddUserMessage("Send the exact answer to my email."); var settings = new AzureOpenAIPromptExecutionSettings() { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions }; @@ -820,10 +848,13 @@ public async Task ItShouldSupportNewFunctionCallingModelSerializedIntoChatHistor string? emailBody = null, emailRecipient = null; var kernel = this.CreateAndInitializeKernel(importHelperPlugin: true); - kernel.ImportPluginFromFunctions("EmailPlugin", [KernelFunctionFactory.CreateFromMethod((string body, string recipient) => { emailBody = body; emailRecipient = recipient; }, "SendEmail")]); + kernel.ImportPluginFromFunctions("EmailPlugin", [ + KernelFunctionFactory.CreateFromMethod((string body, string recipient) => { emailBody = body; emailRecipient = recipient; }, "SendEmail"), + KernelFunctionFactory.CreateFromMethod(() => "abc@domain.com", "GetMyEmail") + ]); // The deserialized chat history contains a list of function calls and the final answer to the question regarding the color of the sky in Boston. - chatHistory.AddUserMessage("Send the exact answer to my email: abc@domain.com"); + chatHistory.AddUserMessage("Send the exact answer to my email."); var settings = new AzureOpenAIPromptExecutionSettings() { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions }; @@ -832,7 +863,7 @@ public async Task ItShouldSupportNewFunctionCallingModelSerializedIntoChatHistor // Assert Assert.Equal("abc@domain.com", emailRecipient); - Assert.Contains("61\u00B0F", emailBody); + Assert.Contains("61", emailBody); } /// @@ -867,7 +898,7 @@ public async Task SubsetOfFunctionsCanBeUsedForFunctionCallingAsync() // Arrange var kernel = this.CreateAndInitializeKernel(); - var function = kernel.CreateFunctionFromMethod(() => DayOfWeek.Friday, "GetDayOfWeek", "Retrieves the current day of the week."); + var function = kernel.CreateFunctionFromMethod(() => DayOfWeek.Friday.ToString(), "GetDayOfWeek", "Retrieves the current day of the week."); kernel.ImportPluginFromFunctions("HelperFunctions", [function]); var chatHistory = new ChatHistory(); @@ -891,7 +922,7 @@ public async Task RequiredFunctionShouldBeCalledAsync() // Arrange var kernel = this.CreateAndInitializeKernel(); - var function = kernel.CreateFunctionFromMethod(() => DayOfWeek.Friday, "GetDayOfWeek", "Retrieves the current day of the week."); + var function = kernel.CreateFunctionFromMethod(() => DayOfWeek.Friday.ToString(), "GetDayOfWeek", "Retrieves the current day of the week."); kernel.ImportPluginFromFunctions("HelperFunctions", [function]); var chatHistory = new ChatHistory(); @@ -939,20 +970,6 @@ private Kernel CreateAndInitializeKernel(bool importHelperPlugin = false) _ => "31 and snowing", }; }, "Get_Weather_For_City", "Gets the current weather for the specified city"), - kernel.CreateFunctionFromMethod((WeatherParameters parameters) => - { - if (parameters.City.Name == "Dublin" && (parameters.City.Country == "Ireland" || parameters.City.Country == "IE")) - { - return Task.FromResult(42.8); // 42.8 Fahrenheit. - } - - throw new NotSupportedException($"Weather in {parameters.City.Name} ({parameters.City.Country}) is not supported."); - }, "Get_Current_Temperature", "Get current temperature."), - kernel.CreateFunctionFromMethod((double temperatureInFahrenheit) => - { - double temperatureInCelsius = (temperatureInFahrenheit - 32) * 5 / 9; - return Task.FromResult(temperatureInCelsius); - }, "Convert_Temperature_From_Fahrenheit_To_Celsius", "Convert temperature from Fahrenheit to Celsius.") ]); } diff --git a/dotnet/src/IntegrationTests/Connectors/AzureOpenAI/AzureOpenAIChatCompletion_AutoFunctionChoiceBehaviorTests.cs b/dotnet/src/IntegrationTests/Connectors/AzureOpenAI/AzureOpenAIChatCompletion_AutoFunctionChoiceBehaviorTests.cs index 3e23f3e32cad..6e723aceaccc 100644 --- a/dotnet/src/IntegrationTests/Connectors/AzureOpenAI/AzureOpenAIChatCompletion_AutoFunctionChoiceBehaviorTests.cs +++ b/dotnet/src/IntegrationTests/Connectors/AzureOpenAI/AzureOpenAIChatCompletion_AutoFunctionChoiceBehaviorTests.cs @@ -58,7 +58,6 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeKernelFunctionAutomat // Assert Assert.NotNull(result); - Assert.Single(invokedFunctions); Assert.Contains("GetCurrentDate", invokedFunctions); } @@ -94,7 +93,6 @@ public async Task SpecifiedInPromptInstructsConnectorToInvokeKernelFunctionAutom // Assert Assert.NotNull(result); - Assert.Single(invokedFunctions); Assert.Contains("GetCurrentDate", invokedFunctions); } @@ -127,7 +125,7 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeKernelFunctionManuall var functionCalls = FunctionCallContent.GetFunctionCalls(result); Assert.NotNull(functionCalls); - Assert.Single(functionCalls); + Assert.NotEmpty(functionCalls); var functionCall = functionCalls.First(); Assert.Equal("DateTimeUtils", functionCall.PluginName); @@ -164,7 +162,6 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeKernelFunctionAutomat // Assert Assert.NotNull(result); - Assert.Single(invokedFunctions); Assert.Contains("GetCurrentDate", invokedFunctions); } @@ -205,11 +202,10 @@ public async Task SpecifiedInPromptInstructsConnectorToInvokeKernelFunctionAutom // Assert Assert.NotNull(result); - Assert.Single(invokedFunctions); Assert.Contains("GetCurrentDate", invokedFunctions); } - [Fact(Skip = "Temporarily disabled to unblock PR pipeline.")] + [Fact] public async Task SpecifiedInCodeInstructsConnectorToInvokeKernelFunctionManuallyForStreamingAsync() { // Arrange @@ -240,7 +236,6 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeKernelFunctionManuall } // Assert - Assert.Single(functionsForManualInvocation); Assert.Contains("DateTimeUtils-GetCurrentDate", functionsForManualInvocation); Assert.Empty(invokedFunctions); @@ -275,7 +270,7 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeNonKernelFunctionManu var functionCalls = FunctionCallContent.GetFunctionCalls(result); Assert.NotNull(functionCalls); - Assert.Single(functionCalls); + Assert.NotEmpty(functionCalls); var functionCall = functionCalls.First(); Assert.Equal("DateTimeUtils", functionCall.PluginName); @@ -313,7 +308,6 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeNonKernelFunctionManu } // Assert - Assert.Single(functionsForManualInvocation); Assert.Contains("DateTimeUtils-GetCurrentDate", functionsForManualInvocation); Assert.Empty(invokedFunctions); diff --git a/dotnet/src/IntegrationTests/Connectors/AzureOpenAI/AzureOpenAIChatCompletion_RequiredFunctionChoiceBehaviorTests.cs b/dotnet/src/IntegrationTests/Connectors/AzureOpenAI/AzureOpenAIChatCompletion_RequiredFunctionChoiceBehaviorTests.cs index 87dba474cb62..b155b9204e47 100644 --- a/dotnet/src/IntegrationTests/Connectors/AzureOpenAI/AzureOpenAIChatCompletion_RequiredFunctionChoiceBehaviorTests.cs +++ b/dotnet/src/IntegrationTests/Connectors/AzureOpenAI/AzureOpenAIChatCompletion_RequiredFunctionChoiceBehaviorTests.cs @@ -98,7 +98,6 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeKernelFunctionAutomat // Assert Assert.NotNull(result); - Assert.Single(invokedFunctions); Assert.Contains("GetCurrentDate", invokedFunctions); } @@ -134,7 +133,6 @@ public async Task SpecifiedInPromptInstructsConnectorToInvokeKernelFunctionAutom // Assert Assert.NotNull(result); - Assert.Single(invokedFunctions); Assert.Contains("GetCurrentDate", invokedFunctions); } @@ -167,7 +165,7 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeKernelFunctionManuall var functionCalls = FunctionCallContent.GetFunctionCalls(result); Assert.NotNull(functionCalls); - Assert.Single(functionCalls); + Assert.NotEmpty(functionCalls); var functionCall = functionCalls.First(); Assert.Equal("DateTimeUtils", functionCall.PluginName); @@ -250,7 +248,6 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeKernelFunctionAutomat // Assert Assert.NotNull(result); - Assert.Single(invokedFunctions); Assert.Contains("GetCurrentDate", invokedFunctions); } @@ -291,7 +288,6 @@ public async Task SpecifiedInPromptInstructsConnectorToInvokeKernelFunctionAutom // Assert Assert.NotNull(result); - Assert.Single(invokedFunctions); Assert.Contains("GetCurrentDate", invokedFunctions); } @@ -326,7 +322,6 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeKernelFunctionManuall } // Assert - Assert.Single(functionsForManualInvocation); Assert.Contains("DateTimeUtils-GetCurrentDate", functionsForManualInvocation); Assert.Empty(invokedFunctions); @@ -361,7 +356,7 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeNonKernelFunctionManu var functionCalls = FunctionCallContent.GetFunctionCalls(result); Assert.NotNull(functionCalls); - Assert.Single(functionCalls); + Assert.NotEmpty(functionCalls); var functionCall = functionCalls.First(); Assert.Equal("DateTimeUtils", functionCall.PluginName); @@ -399,7 +394,6 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeNonKernelFunctionManu } // Assert - Assert.Single(functionsForManualInvocation); Assert.Contains("DateTimeUtils-GetCurrentDate", functionsForManualInvocation); Assert.Empty(invokedFunctions); diff --git a/dotnet/src/IntegrationTests/Connectors/OpenAI/OpenAIChatCompletion_AutoFunctionChoiceBehaviorTests.cs b/dotnet/src/IntegrationTests/Connectors/OpenAI/OpenAIChatCompletion_AutoFunctionChoiceBehaviorTests.cs index 905e4edf5159..2a7d1d6f8f63 100644 --- a/dotnet/src/IntegrationTests/Connectors/OpenAI/OpenAIChatCompletion_AutoFunctionChoiceBehaviorTests.cs +++ b/dotnet/src/IntegrationTests/Connectors/OpenAI/OpenAIChatCompletion_AutoFunctionChoiceBehaviorTests.cs @@ -55,7 +55,6 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeKernelFunctionAutomat // Assert Assert.NotNull(result); - Assert.Single(invokedFunctions); Assert.Contains("GetCurrentDate", invokedFunctions); } @@ -91,7 +90,6 @@ public async Task SpecifiedInPromptInstructsConnectorToInvokeKernelFunctionAutom // Assert Assert.NotNull(result); - Assert.Single(invokedFunctions); Assert.Contains("GetCurrentDate", invokedFunctions); } @@ -124,7 +122,7 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeKernelFunctionManuall var functionCalls = FunctionCallContent.GetFunctionCalls(result); Assert.NotNull(functionCalls); - Assert.Single(functionCalls); + Assert.NotEmpty(functionCalls); var functionCall = functionCalls.First(); Assert.Equal("DateTimeUtils", functionCall.PluginName); @@ -161,7 +159,6 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeKernelFunctionAutomat // Assert Assert.NotNull(result); - Assert.Single(invokedFunctions); Assert.Contains("GetCurrentDate", invokedFunctions); } @@ -202,7 +199,6 @@ public async Task SpecifiedInPromptInstructsConnectorToInvokeKernelFunctionAutom // Assert Assert.NotNull(result); - Assert.Single(invokedFunctions); Assert.Contains("GetCurrentDate", invokedFunctions); } @@ -237,7 +233,6 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeKernelFunctionManuall } // Assert - Assert.Single(functionsForManualInvocation); Assert.Contains("DateTimeUtils-GetCurrentDate", functionsForManualInvocation); Assert.Empty(invokedFunctions); @@ -272,7 +267,7 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeNonKernelFunctionManu var functionCalls = FunctionCallContent.GetFunctionCalls(result); Assert.NotNull(functionCalls); - Assert.Single(functionCalls); + Assert.NotEmpty(functionCalls); var functionCall = functionCalls.First(); Assert.Equal("DateTimeUtils", functionCall.PluginName); @@ -310,7 +305,6 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeNonKernelFunctionManu } // Assert - Assert.Single(functionsForManualInvocation); Assert.Contains("DateTimeUtils-GetCurrentDate", functionsForManualInvocation); Assert.Empty(invokedFunctions); diff --git a/dotnet/src/IntegrationTests/Connectors/OpenAI/OpenAIChatCompletion_FunctionCallingTests.cs b/dotnet/src/IntegrationTests/Connectors/OpenAI/OpenAIChatCompletion_FunctionCallingTests.cs index 0423323cfab0..a9659d146899 100644 --- a/dotnet/src/IntegrationTests/Connectors/OpenAI/OpenAIChatCompletion_FunctionCallingTests.cs +++ b/dotnet/src/IntegrationTests/Connectors/OpenAI/OpenAIChatCompletion_FunctionCallingTests.cs @@ -80,7 +80,19 @@ public async Task CanAutoInvokeKernelFunctionsStreamingAsync() public async Task CanAutoInvokeKernelFunctionsWithComplexTypeParametersAsync() { // Arrange - var kernel = this.CreateAndInitializeKernel(importHelperPlugin: true); + var kernel = this.CreateAndInitializeKernel(); + kernel.ImportPluginFromFunctions("HelperFunctions", + [ + kernel.CreateFunctionFromMethod((WeatherParameters parameters) => + { + if (parameters.City.Name == "Dublin" && (parameters.City.Country == "Ireland" || parameters.City.Country == "IE")) + { + return Task.FromResult(42.8); // 42.8 Fahrenheit. + } + + throw new NotSupportedException($"Weather in {parameters.City.Name} ({parameters.City.Country}) is not supported."); + }, "Get_Current_Temperature", "Get current temperature."), + ]); OpenAIPromptExecutionSettings settings = new() { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions }; @@ -185,7 +197,7 @@ public async Task CanAutoInvokeKernelFunctionFromPromptStreamingAsync() Assert.Contains("Transportation", result, StringComparison.InvariantCultureIgnoreCase); } - [Fact(Skip = "Temporarily disabled to unblock PR pipeline.")] + [Fact] public async Task ConnectorSpecificChatMessageContentClassesCanBeUsedForManualFunctionCallingAsync() { // Arrange @@ -482,7 +494,7 @@ public async Task ConnectorAgnosticFunctionCallingModelClassesCanBeUsedForAutoFu Assert.NotNull(getWeatherForCityFunctionCallResult.Result); } - [Fact(Skip = "Weather in Boston (USA) is not supported.")] + [Fact] public async Task ConnectorAgnosticFunctionCallingModelClassesCanBeUsedForManualFunctionCallingForStreamingAsync() { // Arrange @@ -867,7 +879,7 @@ public async Task SubsetOfFunctionsCanBeUsedForFunctionCallingAsync() // Arrange var kernel = this.CreateAndInitializeKernel(); - var function = kernel.CreateFunctionFromMethod(() => DayOfWeek.Friday, "GetDayOfWeek", "Retrieves the current day of the week."); + var function = kernel.CreateFunctionFromMethod(() => DayOfWeek.Friday.ToString(), "GetDayOfWeek", "Retrieves the current day of the week."); kernel.ImportPluginFromFunctions("HelperFunctions", [function]); var chatHistory = new ChatHistory(); @@ -891,7 +903,7 @@ public async Task RequiredFunctionShouldBeCalledAsync() // Arrange var kernel = this.CreateAndInitializeKernel(); - var function = kernel.CreateFunctionFromMethod(() => DayOfWeek.Friday, "GetDayOfWeek", "Retrieves the current day of the week."); + var function = kernel.CreateFunctionFromMethod(() => DayOfWeek.Friday.ToString(), "GetDayOfWeek", "Retrieves the current day of the week."); kernel.ImportPluginFromFunctions("HelperFunctions", [function]); var chatHistory = new ChatHistory(); @@ -937,20 +949,6 @@ private Kernel CreateAndInitializeKernel(bool importHelperPlugin = false) _ => "31 and snowing", }; }, "Get_Weather_For_City", "Gets the current weather for the specified city"), - kernel.CreateFunctionFromMethod((WeatherParameters parameters) => - { - if (parameters.City.Name == "Dublin" && (parameters.City.Country == "Ireland" || parameters.City.Country == "IE")) - { - return Task.FromResult(42.8); // 42.8 Fahrenheit. - } - - throw new NotSupportedException($"Weather in {parameters.City.Name} ({parameters.City.Country}) is not supported."); - }, "Get_Current_Temperature", "Get current temperature."), - kernel.CreateFunctionFromMethod((double temperatureInFahrenheit) => - { - double temperatureInCelsius = (temperatureInFahrenheit - 32) * 5 / 9; - return Task.FromResult(temperatureInCelsius); - }, "Convert_Temperature_From_Fahrenheit_To_Celsius", "Convert temperature from Fahrenheit to Celsius.") ]); } diff --git a/dotnet/src/IntegrationTests/Connectors/OpenAI/OpenAIChatCompletion_RequiredFunctionChoiceBehaviorTests.cs b/dotnet/src/IntegrationTests/Connectors/OpenAI/OpenAIChatCompletion_RequiredFunctionChoiceBehaviorTests.cs index 9ef51074d40a..3bb20904e0c8 100644 --- a/dotnet/src/IntegrationTests/Connectors/OpenAI/OpenAIChatCompletion_RequiredFunctionChoiceBehaviorTests.cs +++ b/dotnet/src/IntegrationTests/Connectors/OpenAI/OpenAIChatCompletion_RequiredFunctionChoiceBehaviorTests.cs @@ -96,7 +96,6 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeRequiredFunctionAutom // Assert Assert.NotNull(result); - Assert.Single(invokedFunctions); Assert.Contains("GetCurrentDate", invokedFunctions); } @@ -132,7 +131,6 @@ public async Task SpecifiedInPromptInstructsConnectorToInvokeKernelFunctionAutom // Assert Assert.NotNull(result); - Assert.Single(invokedFunctions); Assert.Contains("GetCurrentDate", invokedFunctions); } @@ -165,7 +163,7 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeKernelFunctionManuall var functionCalls = FunctionCallContent.GetFunctionCalls(result); Assert.NotNull(functionCalls); - Assert.Single(functionCalls); + Assert.NotEmpty(functionCalls); var functionCall = functionCalls.First(); Assert.Equal("DateTimeUtils", functionCall.PluginName); @@ -238,7 +236,6 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeKernelFunctionAutomat } // Assert - Assert.Single(invokedFunctions); Assert.Contains("GetCurrentDate", invokedFunctions); } @@ -278,8 +275,6 @@ public async Task SpecifiedInPromptInstructsConnectorToInvokeKernelFunctionAutom // Assert Assert.NotNull(result); - - Assert.Single(invokedFunctions); Assert.Contains("GetCurrentDate", invokedFunctions); } @@ -314,7 +309,6 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeKernelFunctionManuall } // Assert - Assert.Single(functionsForManualInvocation); Assert.Contains("DateTimeUtils-GetCurrentDate", functionsForManualInvocation); Assert.Empty(invokedFunctions); @@ -349,7 +343,7 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeNonKernelFunctionManu var functionCalls = FunctionCallContent.GetFunctionCalls(result); Assert.NotNull(functionCalls); - Assert.Single(functionCalls); + Assert.NotEmpty(functionCalls); var functionCall = functionCalls.First(); Assert.Equal("DateTimeUtils", functionCall.PluginName); @@ -387,7 +381,6 @@ public async Task SpecifiedInCodeInstructsConnectorToInvokeNonKernelFunctionManu } // Assert - Assert.Single(functionsForManualInvocation); Assert.Contains("DateTimeUtils-GetCurrentDate", functionsForManualInvocation); Assert.Empty(invokedFunctions);