From 67f7ca974004335883298f1e82fbc19cca89e967 Mon Sep 17 00:00:00 2001 From: markwallace-microsoft <127216156+markwallace-microsoft@users.noreply.github.com> Date: Fri, 22 Nov 2024 14:49:50 +0000 Subject: [PATCH] Improve the DI sample and function naming --- .../GettingStarted/Step1_Create_Kernel.cs | 2 +- .../GettingStarted/Step2_Add_Plugins.cs | 2 +- .../GettingStarted/Step3_Yaml_Prompt.cs | 2 +- .../Step4_Dependency_Injection.cs | 54 ++++++++++++++++++- .../GettingStarted/Step5_Chat_Prompt.cs | 2 +- .../GettingStarted/Step6_Responsible_AI.cs | 2 +- .../GettingStarted/Step8_Pipelining.cs | 2 +- 7 files changed, 59 insertions(+), 7 deletions(-) diff --git a/dotnet/samples/GettingStarted/Step1_Create_Kernel.cs b/dotnet/samples/GettingStarted/Step1_Create_Kernel.cs index faa8811f1c22..e7f2d50462ed 100644 --- a/dotnet/samples/GettingStarted/Step1_Create_Kernel.cs +++ b/dotnet/samples/GettingStarted/Step1_Create_Kernel.cs @@ -14,7 +14,7 @@ public sealed class Step1_Create_Kernel(ITestOutputHelper output) : BaseTest(out /// Show how to create a and use it to execute prompts. /// [Fact] - public async Task RunAsync() + public async Task CreateKernelAsync() { // Create a kernel with OpenAI chat completion Kernel kernel = Kernel.CreateBuilder() diff --git a/dotnet/samples/GettingStarted/Step2_Add_Plugins.cs b/dotnet/samples/GettingStarted/Step2_Add_Plugins.cs index bb2fc387aabe..b3294919607f 100644 --- a/dotnet/samples/GettingStarted/Step2_Add_Plugins.cs +++ b/dotnet/samples/GettingStarted/Step2_Add_Plugins.cs @@ -17,7 +17,7 @@ public sealed class Step2_Add_Plugins(ITestOutputHelper output) : BaseTest(outpu /// Shows different ways to load a instances. /// [Fact] - public async Task RunAsync() + public async Task AddPluginsAsync() { // Create a kernel with OpenAI chat completion IKernelBuilder kernelBuilder = Kernel.CreateBuilder(); diff --git a/dotnet/samples/GettingStarted/Step3_Yaml_Prompt.cs b/dotnet/samples/GettingStarted/Step3_Yaml_Prompt.cs index 3fe837bf098e..29d50f7b6da7 100644 --- a/dotnet/samples/GettingStarted/Step3_Yaml_Prompt.cs +++ b/dotnet/samples/GettingStarted/Step3_Yaml_Prompt.cs @@ -15,7 +15,7 @@ public sealed class Step3_Yaml_Prompt(ITestOutputHelper output) : BaseTest(outpu /// Show how to create a prompt from a YAML resource. /// [Fact] - public async Task RunAsync() + public async Task CreatPromptFromYamlAsync() { // Create a kernel with OpenAI chat completion Kernel kernel = Kernel.CreateBuilder() diff --git a/dotnet/samples/GettingStarted/Step4_Dependency_Injection.cs b/dotnet/samples/GettingStarted/Step4_Dependency_Injection.cs index dd39962d627a..42cab45aa97a 100644 --- a/dotnet/samples/GettingStarted/Step4_Dependency_Injection.cs +++ b/dotnet/samples/GettingStarted/Step4_Dependency_Injection.cs @@ -16,7 +16,7 @@ public sealed class Step4_Dependency_Injection(ITestOutputHelper output) : BaseT /// Show how to create a that participates in Dependency Injection. /// [Fact] - public async Task RunAsync() + public async Task GetKernelUsingDependencyInjectionAsync() { // If an application follows DI guidelines, the following line is unnecessary because DI will inject an instance of the KernelClient class to a class that references it. // DI container guidelines - https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection-guidelines#recommendations @@ -32,6 +32,22 @@ public async Task RunAsync() } } + /// + /// Show how to use a plugin that participates in Dependency Injection. + /// + [Fact] + public async Task PluginUsingDependencyInjectionAsync() + { + // If an application follows DI guidelines, the following line is unnecessary because DI will inject an instance of the KernelClient class to a class that references it. + // DI container guidelines - https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection-guidelines#recommendations + var serviceProvider = BuildServiceProvider(); + var kernel = serviceProvider.GetRequiredService(); + + // Invoke the prompt which relies on invoking a plugin that depends on a service made avaiable using Dependency Injection. + PromptExecutionSettings settings = new() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() }; + Console.WriteLine(await kernel.InvokePromptAsync("Greet the current user by name.", new(settings))); + } + /// /// Build a ServiceProvider that can be used to resolve services. /// @@ -39,10 +55,12 @@ private ServiceProvider BuildServiceProvider() { var collection = new ServiceCollection(); collection.AddSingleton(new XunitLogger(this.Output)); + collection.AddSingleton(new FakeUserService()); var kernelBuilder = collection.AddKernel(); kernelBuilder.Services.AddOpenAIChatCompletion(TestConfiguration.OpenAI.ChatModelId, TestConfiguration.OpenAI.ApiKey); kernelBuilder.Plugins.AddFromType(); + kernelBuilder.Plugins.AddFromType(); return collection.BuildServiceProvider(); } @@ -63,4 +81,38 @@ public string GetCurrentUtcTime() return utcNow; } } + + /// + /// A plugin that returns the current time. + /// + public class UserInformation(IUserService userService) + { + + [KernelFunction] + [Description("Retrieves the current users name.")] + public string GetUsername() + { + return userService.GetCurrentUsername(); + } + } + + /// + /// Interface for a service to get the current user id. + /// + public interface IUserService + { + /// + /// Return the user id for the current user. + /// + string GetCurrentUsername(); + } + + /// + /// Fake implementation of + /// + public class FakeUserService : IUserService + { + /// + public string GetCurrentUsername() => "Bob"; + } } diff --git a/dotnet/samples/GettingStarted/Step5_Chat_Prompt.cs b/dotnet/samples/GettingStarted/Step5_Chat_Prompt.cs index 41e90085a5ec..5541b1f07838 100644 --- a/dotnet/samples/GettingStarted/Step5_Chat_Prompt.cs +++ b/dotnet/samples/GettingStarted/Step5_Chat_Prompt.cs @@ -10,7 +10,7 @@ public sealed class Step5_Chat_Prompt(ITestOutputHelper output) : BaseTest(outpu /// Show how to construct a chat prompt and invoke it. /// [Fact] - public async Task RunAsync() + public async Task InvokeChatPromptAsync() { // Create a kernel with OpenAI chat completion Kernel kernel = Kernel.CreateBuilder() diff --git a/dotnet/samples/GettingStarted/Step6_Responsible_AI.cs b/dotnet/samples/GettingStarted/Step6_Responsible_AI.cs index 30a0d69c5c14..d1f717aa47e0 100644 --- a/dotnet/samples/GettingStarted/Step6_Responsible_AI.cs +++ b/dotnet/samples/GettingStarted/Step6_Responsible_AI.cs @@ -11,7 +11,7 @@ public sealed class Step6_Responsible_AI(ITestOutputHelper output) : BaseTest(ou /// Show how to use prompt filters to ensure that prompts are rendered in a responsible manner. /// [Fact] - public async Task RunAsync() + public async Task AddPromptFilterAsync() { // Create a kernel with OpenAI chat completion var builder = Kernel.CreateBuilder() diff --git a/dotnet/samples/GettingStarted/Step8_Pipelining.cs b/dotnet/samples/GettingStarted/Step8_Pipelining.cs index 135d7d73d616..a7d554f11cd5 100644 --- a/dotnet/samples/GettingStarted/Step8_Pipelining.cs +++ b/dotnet/samples/GettingStarted/Step8_Pipelining.cs @@ -14,7 +14,7 @@ public sealed class Step8_Pipelining(ITestOutputHelper output) : BaseTest(output /// them in a sequence, passing the output from one as input to the next. /// [Fact] - public async Task RunAsync() + public async Task CreateFunctionPipelineAsync() { IKernelBuilder builder = Kernel.CreateBuilder(); builder.AddOpenAIChatCompletion(