Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,11 @@ public void ItCreatesOpenAIExecutionSettingsWithCorrectDefaults()
Assert.Equal(1, executionSettings.TopP);
Assert.Equal(0, executionSettings.FrequencyPenalty);
Assert.Equal(0, executionSettings.PresencePenalty);
Assert.Equal(1, executionSettings.ResultsPerPrompt);
Assert.Null(executionSettings.StopSequences);
Assert.Null(executionSettings.TokenSelectionBiases);
Assert.Null(executionSettings.TopLogprobs);
Assert.Null(executionSettings.Logprobs);
Assert.Null(executionSettings.AzureChatExtensionsOptions);
Assert.Null(executionSettings.AzureChatDataSource);
Assert.Equal(128, executionSettings.MaxTokens);
}

Expand All @@ -45,7 +44,6 @@ public void ItUsesExistingOpenAIExecutionSettings()
TopP = 0.7,
FrequencyPenalty = 0.7,
PresencePenalty = 0.7,
ResultsPerPrompt = 2,
StopSequences = new string[] { "foo", "bar" },
ChatSystemPrompt = "chat system prompt",
MaxTokens = 128,
Expand Down Expand Up @@ -231,7 +229,6 @@ public void PromptExecutionSettingsFreezeWorksAsExpected()
// Assert
Assert.True(executionSettings.IsFrozen);
Assert.Throws<InvalidOperationException>(() => executionSettings.ModelId = "gpt-4");
Assert.Throws<InvalidOperationException>(() => executionSettings.ResultsPerPrompt = 2);
Assert.Throws<InvalidOperationException>(() => executionSettings.Temperature = 1);
Assert.Throws<InvalidOperationException>(() => executionSettings.TopP = 1);
Assert.Throws<NotSupportedException>(() => executionSettings.StopSequences?.Add("STOP"));
Expand Down Expand Up @@ -262,7 +259,6 @@ private static void AssertExecutionSettings(AzureOpenAIPromptExecutionSettings e
Assert.Equal(0.7, executionSettings.TopP);
Assert.Equal(0.7, executionSettings.FrequencyPenalty);
Assert.Equal(0.7, executionSettings.PresencePenalty);
Assert.Equal(2, executionSettings.ResultsPerPrompt);
Assert.Equal(new string[] { "foo", "bar" }, executionSettings.StopSequences);
Assert.Equal("chat system prompt", executionSettings.ChatSystemPrompt);
Assert.Equal(new Dictionary<int, int>() { { 1, 2 }, { 3, 4 } }, executionSettings.TokenSelectionBiases);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.

using System.IO;
using System.Net.Http;

namespace SemanticKernel.Connectors.AzureOpenAI.UnitTests;

Expand All @@ -17,4 +18,13 @@ internal static string GetTestResponse(string fileName)
{
return File.ReadAllText($"./TestData/{fileName}");
}

/// <summary>
/// Reads test response from file and create <see cref="StreamContent"/>.
/// </summary>
/// <param name="fileName">Name of the file with test response.</param>
internal static StreamContent GetTestResponseAsStream(string fileName)
{
return new StreamContent(File.OpenRead($"./TestData/{fileName}"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@

using System.Collections.Generic;
using System.Linq;
using Azure.AI.OpenAI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.AzureOpenAI;
using static Microsoft.SemanticKernel.Connectors.AzureOpenAI.AzureToolCallBehavior;
using OpenAI.Chat;
using static Microsoft.SemanticKernel.Connectors.AzureOpenAI.AzureOpenAIToolCallBehavior;

namespace SemanticKernel.Connectors.AzureOpenAI.UnitTests;

/// <summary>
/// Unit tests for <see cref="AzureToolCallBehavior"/>
/// Unit tests for <see cref="AzureOpenAIToolCallBehavior"/>
/// </summary>
public sealed class AzureToolCallBehaviorTests
public sealed class AzureOpenAIToolCallBehaviorTests
{
[Fact]
public void EnableKernelFunctionsReturnsCorrectKernelFunctionsInstance()
{
// Arrange & Act
var behavior = AzureToolCallBehavior.EnableKernelFunctions;
var behavior = AzureOpenAIToolCallBehavior.EnableKernelFunctions;

// Assert
Assert.IsType<KernelFunctions>(behavior);
Expand All @@ -30,7 +30,7 @@ public void AutoInvokeKernelFunctionsReturnsCorrectKernelFunctionsInstance()
{
// Arrange & Act
const int DefaultMaximumAutoInvokeAttempts = 128;
var behavior = AzureToolCallBehavior.AutoInvokeKernelFunctions;
var behavior = AzureOpenAIToolCallBehavior.AutoInvokeKernelFunctions;

// Assert
Assert.IsType<KernelFunctions>(behavior);
Expand All @@ -42,7 +42,7 @@ public void EnableFunctionsReturnsEnabledFunctionsInstance()
{
// Arrange & Act
List<AzureOpenAIFunction> functions = [new("Plugin", "Function", "description", [], null)];
var behavior = AzureToolCallBehavior.EnableFunctions(functions);
var behavior = AzureOpenAIToolCallBehavior.EnableFunctions(functions);

// Assert
Assert.IsType<EnabledFunctions>(behavior);
Expand All @@ -52,7 +52,7 @@ public void EnableFunctionsReturnsEnabledFunctionsInstance()
public void RequireFunctionReturnsRequiredFunctionInstance()
{
// Arrange & Act
var behavior = AzureToolCallBehavior.RequireFunction(new("Plugin", "Function", "description", [], null));
var behavior = AzureOpenAIToolCallBehavior.RequireFunction(new("Plugin", "Function", "description", [], null));

// Assert
Assert.IsType<RequiredFunction>(behavior);
Expand All @@ -63,65 +63,62 @@ public void KernelFunctionsConfigureOptionsWithNullKernelDoesNotAddTools()
{
// Arrange
var kernelFunctions = new KernelFunctions(autoInvoke: false);
var chatCompletionsOptions = new ChatCompletionsOptions();

// Act
kernelFunctions.ConfigureOptions(null, chatCompletionsOptions);
var options = kernelFunctions.ConfigureOptions(null);

// Assert
Assert.Empty(chatCompletionsOptions.Tools);
Assert.Null(options.Choice);
Assert.Null(options.Tools);
}

[Fact]
public void KernelFunctionsConfigureOptionsWithoutFunctionsDoesNotAddTools()
{
// Arrange
var kernelFunctions = new KernelFunctions(autoInvoke: false);
var chatCompletionsOptions = new ChatCompletionsOptions();
var kernel = Kernel.CreateBuilder().Build();

// Act
kernelFunctions.ConfigureOptions(kernel, chatCompletionsOptions);
var options = kernelFunctions.ConfigureOptions(kernel);

// Assert
Assert.Null(chatCompletionsOptions.ToolChoice);
Assert.Empty(chatCompletionsOptions.Tools);
Assert.Null(options.Choice);
Assert.Null(options.Tools);
}

[Fact]
public void KernelFunctionsConfigureOptionsWithFunctionsAddsTools()
{
// Arrange
var kernelFunctions = new KernelFunctions(autoInvoke: false);
var chatCompletionsOptions = new ChatCompletionsOptions();
var kernel = Kernel.CreateBuilder().Build();

var plugin = this.GetTestPlugin();

kernel.Plugins.Add(plugin);

// Act
kernelFunctions.ConfigureOptions(kernel, chatCompletionsOptions);
var options = kernelFunctions.ConfigureOptions(kernel);

// Assert
Assert.Equal(ChatCompletionsToolChoice.Auto, chatCompletionsOptions.ToolChoice);
Assert.Equal(ChatToolChoice.Auto, options.Choice);

this.AssertTools(chatCompletionsOptions);
this.AssertTools(options.Tools);
}

[Fact]
public void EnabledFunctionsConfigureOptionsWithoutFunctionsDoesNotAddTools()
{
// Arrange
var enabledFunctions = new EnabledFunctions([], autoInvoke: false);
var chatCompletionsOptions = new ChatCompletionsOptions();

// Act
enabledFunctions.ConfigureOptions(null, chatCompletionsOptions);
var options = enabledFunctions.ConfigureOptions(null);

// Assert
Assert.Null(chatCompletionsOptions.ToolChoice);
Assert.Empty(chatCompletionsOptions.Tools);
Assert.Null(options.Choice);
Assert.Null(options.Tools);
}

[Fact]
Expand All @@ -130,10 +127,9 @@ public void EnabledFunctionsConfigureOptionsWithAutoInvokeAndNullKernelThrowsExc
// Arrange
var functions = this.GetTestPlugin().GetFunctionsMetadata().Select(function => function.ToAzureOpenAIFunction());
var enabledFunctions = new EnabledFunctions(functions, autoInvoke: true);
var chatCompletionsOptions = new ChatCompletionsOptions();

// Act & Assert
var exception = Assert.Throws<KernelException>(() => enabledFunctions.ConfigureOptions(null, chatCompletionsOptions));
var exception = Assert.Throws<KernelException>(() => enabledFunctions.ConfigureOptions(null));
Assert.Equal($"Auto-invocation with {nameof(EnabledFunctions)} is not supported when no kernel is provided.", exception.Message);
}

Expand All @@ -143,11 +139,10 @@ public void EnabledFunctionsConfigureOptionsWithAutoInvokeAndEmptyKernelThrowsEx
// Arrange
var functions = this.GetTestPlugin().GetFunctionsMetadata().Select(function => function.ToAzureOpenAIFunction());
var enabledFunctions = new EnabledFunctions(functions, autoInvoke: true);
var chatCompletionsOptions = new ChatCompletionsOptions();
var kernel = Kernel.CreateBuilder().Build();

// Act & Assert
var exception = Assert.Throws<KernelException>(() => enabledFunctions.ConfigureOptions(kernel, chatCompletionsOptions));
var exception = Assert.Throws<KernelException>(() => enabledFunctions.ConfigureOptions(kernel));
Assert.Equal($"The specified {nameof(EnabledFunctions)} function MyPlugin-MyFunction is not available in the kernel.", exception.Message);
}

Expand All @@ -160,18 +155,17 @@ public void EnabledFunctionsConfigureOptionsWithKernelAndPluginsAddsTools(bool a
var plugin = this.GetTestPlugin();
var functions = plugin.GetFunctionsMetadata().Select(function => function.ToAzureOpenAIFunction());
var enabledFunctions = new EnabledFunctions(functions, autoInvoke);
var chatCompletionsOptions = new ChatCompletionsOptions();
var kernel = Kernel.CreateBuilder().Build();

kernel.Plugins.Add(plugin);

// Act
enabledFunctions.ConfigureOptions(kernel, chatCompletionsOptions);
var options = enabledFunctions.ConfigureOptions(kernel);

// Assert
Assert.Equal(ChatCompletionsToolChoice.Auto, chatCompletionsOptions.ToolChoice);
Assert.Equal(ChatToolChoice.Auto, options.Choice);

this.AssertTools(chatCompletionsOptions);
this.AssertTools(options.Tools);
}

[Fact]
Expand All @@ -180,10 +174,9 @@ public void RequiredFunctionsConfigureOptionsWithAutoInvokeAndNullKernelThrowsEx
// Arrange
var function = this.GetTestPlugin().GetFunctionsMetadata().Select(function => function.ToAzureOpenAIFunction()).First();
var requiredFunction = new RequiredFunction(function, autoInvoke: true);
var chatCompletionsOptions = new ChatCompletionsOptions();

// Act & Assert
var exception = Assert.Throws<KernelException>(() => requiredFunction.ConfigureOptions(null, chatCompletionsOptions));
var exception = Assert.Throws<KernelException>(() => requiredFunction.ConfigureOptions(null));
Assert.Equal($"Auto-invocation with {nameof(RequiredFunction)} is not supported when no kernel is provided.", exception.Message);
}

Expand All @@ -193,11 +186,10 @@ public void RequiredFunctionsConfigureOptionsWithAutoInvokeAndEmptyKernelThrowsE
// Arrange
var function = this.GetTestPlugin().GetFunctionsMetadata().Select(function => function.ToAzureOpenAIFunction()).First();
var requiredFunction = new RequiredFunction(function, autoInvoke: true);
var chatCompletionsOptions = new ChatCompletionsOptions();
var kernel = Kernel.CreateBuilder().Build();

// Act & Assert
var exception = Assert.Throws<KernelException>(() => requiredFunction.ConfigureOptions(kernel, chatCompletionsOptions));
var exception = Assert.Throws<KernelException>(() => requiredFunction.ConfigureOptions(kernel));
Assert.Equal($"The specified {nameof(RequiredFunction)} function MyPlugin-MyFunction is not available in the kernel.", exception.Message);
}

Expand All @@ -207,18 +199,17 @@ public void RequiredFunctionConfigureOptionsAddsTools()
// Arrange
var plugin = this.GetTestPlugin();
var function = plugin.GetFunctionsMetadata()[0].ToAzureOpenAIFunction();
var chatCompletionsOptions = new ChatCompletionsOptions();
var requiredFunction = new RequiredFunction(function, autoInvoke: true);
var kernel = new Kernel();
kernel.Plugins.Add(plugin);

// Act
requiredFunction.ConfigureOptions(kernel, chatCompletionsOptions);
var options = requiredFunction.ConfigureOptions(kernel);

// Assert
Assert.NotNull(chatCompletionsOptions.ToolChoice);
Assert.NotNull(options.Choice);

this.AssertTools(chatCompletionsOptions);
this.AssertTools(options.Tools);
}

private KernelPlugin GetTestPlugin()
Expand All @@ -233,16 +224,15 @@ private KernelPlugin GetTestPlugin()
return KernelPluginFactory.CreateFromFunctions("MyPlugin", [function]);
}

private void AssertTools(ChatCompletionsOptions chatCompletionsOptions)
private void AssertTools(IList<ChatTool>? tools)
{
Assert.Single(chatCompletionsOptions.Tools);

var tool = chatCompletionsOptions.Tools[0] as ChatCompletionsFunctionToolDefinition;
Assert.NotNull(tools);
var tool = Assert.Single(tools);

Assert.NotNull(tool);

Assert.Equal("MyPlugin-MyFunction", tool.Name);
Assert.Equal("Test Function", tool.Description);
Assert.Equal("{\"type\":\"object\",\"required\":[],\"properties\":{\"parameter1\":{\"type\":\"string\"},\"parameter2\":{\"type\":\"string\"}}}", tool.Parameters.ToString());
Assert.Equal("MyPlugin-MyFunction", tool.FunctionName);
Assert.Equal("Test Function", tool.FunctionDescription);
Assert.Equal("{\"type\":\"object\",\"required\":[],\"properties\":{\"parameter1\":{\"type\":\"string\"},\"parameter2\":{\"type\":\"string\"}}}", tool.FunctionParameters.ToString());
}
}
Loading