Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.Net: Replace SK's IAIServiceProvider with IServiceProvider #3714

Merged
merged 11 commits into from
Nov 28, 2023
Merged
5 changes: 4 additions & 1 deletion dotnet/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.TimeProvider.Testing" Version="8.0.0" />
Expand Down Expand Up @@ -72,7 +74,8 @@
<PackageVersion Include="Milvus.Client" Version="2.2.2-preview.6" />
<!-- Symbols -->
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
<!-- Analyzers -->
<!-- Toolset -->
<PackageVersion Include="Microsoft.Net.Compilers.Toolset" Version="4.8.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0-preview1.23165.1" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers">
<PrivateAssets>all</PrivateAssets>
Expand Down
18 changes: 0 additions & 18 deletions dotnet/SK-dotnet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TelemetryExample", "samples
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Connectors.Memory.Kusto", "src\Connectors\Connectors.Memory.Kusto\Connectors.Memory.Kusto.csproj", "{E07608CC-D710-4655-BB9E-D22CF3CDD193}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Reliability.Polly", "src\Extensions\Reliability.Polly\Reliability.Polly.csproj", "{D4540A0F-98E3-4E70-9093-1948AE5B2AAD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Reliability.Basic", "src\Extensions\Reliability.Basic\Reliability.Basic.csproj", "{3DC4DBD8-20A5-4937-B4F5-BB5E24E7A567}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "plugins", "plugins", "{D6D598DF-C17C-46F4-B2B9-CDE82E2DE132}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Plugins.UnitTests", "src\Plugins\Plugins.UnitTests\Plugins.UnitTests.csproj", "{5CB78CE4-895B-4A14-98AA-716A37DEEBB1}"
Expand Down Expand Up @@ -374,18 +370,6 @@ Global
{E07608CC-D710-4655-BB9E-D22CF3CDD193}.Publish|Any CPU.Build.0 = Publish|Any CPU
{E07608CC-D710-4655-BB9E-D22CF3CDD193}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E07608CC-D710-4655-BB9E-D22CF3CDD193}.Release|Any CPU.Build.0 = Release|Any CPU
{D4540A0F-98E3-4E70-9093-1948AE5B2AAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D4540A0F-98E3-4E70-9093-1948AE5B2AAD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4540A0F-98E3-4E70-9093-1948AE5B2AAD}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
{D4540A0F-98E3-4E70-9093-1948AE5B2AAD}.Publish|Any CPU.Build.0 = Publish|Any CPU
{D4540A0F-98E3-4E70-9093-1948AE5B2AAD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4540A0F-98E3-4E70-9093-1948AE5B2AAD}.Release|Any CPU.Build.0 = Release|Any CPU
{3DC4DBD8-20A5-4937-B4F5-BB5E24E7A567}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3DC4DBD8-20A5-4937-B4F5-BB5E24E7A567}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3DC4DBD8-20A5-4937-B4F5-BB5E24E7A567}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
{3DC4DBD8-20A5-4937-B4F5-BB5E24E7A567}.Publish|Any CPU.Build.0 = Publish|Any CPU
{3DC4DBD8-20A5-4937-B4F5-BB5E24E7A567}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3DC4DBD8-20A5-4937-B4F5-BB5E24E7A567}.Release|Any CPU.Build.0 = Release|Any CPU
{5CB78CE4-895B-4A14-98AA-716A37DEEBB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5CB78CE4-895B-4A14-98AA-716A37DEEBB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5CB78CE4-895B-4A14-98AA-716A37DEEBB1}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -504,8 +488,6 @@ Global
{E6EDAB8F-3406-4DBF-9AAB-DF40DC2CA0FA} = {FA3720F1-C99A-49B2-9577-A940257098BF}
{C754950A-E16C-4F96-9CC7-9328E361B5AF} = {FA3720F1-C99A-49B2-9577-A940257098BF}
{E07608CC-D710-4655-BB9E-D22CF3CDD193} = {0247C2C9-86C3-45BA-8873-28B0948EDC0C}
{D4540A0F-98E3-4E70-9093-1948AE5B2AAD} = {078F96B4-09E1-4E0E-B214-F71A4F4BF633}
{3DC4DBD8-20A5-4937-B4F5-BB5E24E7A567} = {078F96B4-09E1-4E0E-B214-F71A4F4BF633}
{D6D598DF-C17C-46F4-B2B9-CDE82E2DE132} = {831DDCA2-7D2C-4C31-80DB-6BDB3E1F7AE0}
{5CB78CE4-895B-4A14-98AA-716A37DEEBB1} = {D6D598DF-C17C-46F4-B2B9-CDE82E2DE132}
{A21FAC7C-0C09-4EAD-843B-926ACEF73C80} = {831DDCA2-7D2C-4C31-80DB-6BDB3E1F7AE0}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public static async Task RunAsync()

Kernel kernel = new KernelBuilder()
.WithLoggerFactory(ConsoleLogger.LoggerFactory)
.WithOpenAIChatCompletionService(
.WithOpenAIChatCompletion(
modelId: openAIModelId,
apiKey: openAIApiKey)
.Build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public static async Task RunAsync()

Kernel kernel = new KernelBuilder()
.WithLoggerFactory(ConsoleLogger.LoggerFactory)
.WithOpenAIChatCompletionService(
.WithOpenAIChatCompletion(
modelId: openAIModelId,
apiKey: openAIApiKey)
.Build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static async Task RunAsync()

Kernel kernel = new KernelBuilder()
.WithLoggerFactory(ConsoleLogger.LoggerFactory)
.WithOpenAIChatCompletionService(
.WithOpenAIChatCompletion(
modelId: openAIModelId,
apiKey: openAIApiKey)
.Build();
Expand Down
175 changes: 22 additions & 153 deletions dotnet/samples/KernelSyntaxExamples/Example08_RetryHandler.cs
Original file line number Diff line number Diff line change
@@ -1,177 +1,46 @@
// Copyright (c) Microsoft. All rights reserved.

using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Http.Resilience;
using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Http;
using Microsoft.SemanticKernel.Plugins.Core;
using Microsoft.SemanticKernel.Reliability.Basic;
using Polly;
using RepoUtils;

// ReSharper disable once InconsistentNaming
#pragma warning disable CA1031 // Do not catch general exception types
#pragma warning disable CA2000 // Dispose objects before losing scope

public static class Example08_RetryHandler
{
public static async Task RunAsync()
{
await DefaultNoRetryAsync();

await ReliabilityBasicExtensionAsync();

await ReliabilityPollyExtensionAsync();

await CustomHandlerAsync();
}

private static async Task DefaultNoRetryAsync()
{
InfoLogger.Logger.LogInformation("============================== Kernel default behavior: No Retry ==============================");
var kernel = InitializeKernelBuilder()
.Build();

await ImportAndExecutePluginAsync(kernel);
}

private static async Task ReliabilityBasicExtensionAsync()
{
InfoLogger.Logger.LogInformation("============================== Using Reliability.Basic extension ==============================");
var retryConfig = new BasicRetryConfig
// Create a Kernel with the HttpClient
var kernel = new KernelBuilder().ConfigureServices(c =>
{
MaxRetryCount = 3,
UseExponentialBackoff = true,
};
retryConfig.RetryableStatusCodes.Add(HttpStatusCode.Unauthorized);

var kernel = InitializeKernelBuilder()
.WithRetryBasic(retryConfig)
.Build();

await ImportAndExecutePluginAsync(kernel);
}

private static async Task ReliabilityPollyExtensionAsync()
{
InfoLogger.Logger.LogInformation("============================== Using Reliability.Polly extension ==============================");
var kernel = InitializeKernelBuilder()
.WithRetryPolly(GetPollyPolicy(InfoLogger.LoggerFactory))
.Build();

await ImportAndExecutePluginAsync(kernel);
}

private static async Task CustomHandlerAsync()
{
InfoLogger.Logger.LogInformation("============================== Using a Custom Http Handler ==============================");
var kernel = InitializeKernelBuilder()
.WithHttpHandlerFactory(new MyCustomHandlerFactory())
.Build();

await ImportAndExecutePluginAsync(kernel);
}

private static KernelBuilder InitializeKernelBuilder()
{
return new KernelBuilder()
.WithLoggerFactory(InfoLogger.LoggerFactory)
// OpenAI settings - you can set the OpenAI.ApiKey to an invalid value to see the retry policy in play
.WithOpenAIChatCompletionService(TestConfiguration.OpenAI.ChatModelId, "BAD_KEY");
}

private static AsyncPolicy<HttpResponseMessage> GetPollyPolicy(ILoggerFactory? logger)
{
// Handle 429 and 401 errors
// Typically 401 would not be something we retry but for demonstration
// purposes we are doing so as it's easy to trigger when using an invalid key.
const int TooManyRequests = 429;
const int Unauthorized = 401;

return Policy
.HandleResult<HttpResponseMessage>(response =>
(int)response.StatusCode is TooManyRequests or Unauthorized)
.WaitAndRetryAsync(new[]
c.AddLogging(c => c.AddConsole().SetMinimumLevel(LogLevel.Information));
c.ConfigureHttpClientDefaults(c =>
{
// Use a standard resiliency policy, augmented to retry on 401 Unauthorized for this example
c.AddStandardResilienceHandler().Configure(o =>
{
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(4),
TimeSpan.FromSeconds(8)
},
(outcome, timespan, retryCount, _)
=> InfoLogger.Logger.LogWarning("Error executing action [attempt {RetryCount} of 3], pausing {PausingMilliseconds}ms. Outcome: {StatusCode}",
retryCount,
timespan.TotalMilliseconds,
outcome.Result.StatusCode));
}

private static async Task ImportAndExecutePluginAsync(Kernel kernel)
{
// Load semantic plugin defined with prompt templates
string folder = RepoFiles.SamplePluginsPath();

kernel.ImportPluginFromObject<TimePlugin>();

var qaPlugin = kernel.ImportPluginFromPromptDirectory(Path.Combine(folder, "QAPlugin"));
o.Retry.ShouldHandle = args => ValueTask.FromResult(args.Outcome.Result?.StatusCode is HttpStatusCode.Unauthorized);
});
});
c.AddOpenAIChatCompletion("gpt-4", "BAD_KEY"); // OpenAI settings - you can set the OpenAI.ApiKey to an invalid value to see the retry policy in play
}).Build();

var question = "How popular is Polly library?";
var logger = kernel.GetService<ILoggerFactory>().CreateLogger(typeof(Example08_RetryHandler));

InfoLogger.Logger.LogInformation("Question: {0}", question);
// To see the retry policy in play, you can set the OpenAI.ApiKey to an invalid value
#pragma warning disable CA1031 // Do not catch general exception types
const string Question = "How popular is Polly library?";
logger.LogInformation("Question: {Question}", Question);
try
{
var answer = await kernel.InvokeAsync(qaPlugin["Question"], question);
InfoLogger.Logger.LogInformation("Answer: {0}", answer.GetValue<string>());
logger.LogInformation("Answer: {Result}", await kernel.InvokePromptAsync(Question));
}
catch (Exception ex)
{
InfoLogger.Logger.LogInformation("Error: {0}", ex.Message);
}
#pragma warning restore CA1031 // Do not catch general exception types
}

// Basic custom retry handler factory
public sealed class MyCustomHandlerFactory : HttpHandlerFactory<MyCustomHandler>
{
}

// Basic custom empty retry handler
public sealed class MyCustomHandler : DelegatingHandler
{
public MyCustomHandler(ILoggerFactory loggerFactory)
{
}

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// Your custom http handling implementation
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent("My custom bad request override")
});
}
}

private static class InfoLogger
{
internal static ILogger Logger => LoggerFactory.CreateLogger("Example08_RetryHandler");
internal static ILoggerFactory LoggerFactory => s_loggerFactory.Value;
private static readonly Lazy<ILoggerFactory> s_loggerFactory = new(LogBuilder);

private static ILoggerFactory LogBuilder()
{
return Microsoft.Extensions.Logging.LoggerFactory.Create(builder =>
{
builder.SetMinimumLevel(LogLevel.Information);
builder.AddFilter("Microsoft", LogLevel.Information);
builder.AddFilter("Microsoft.SemanticKernel", LogLevel.Critical);
builder.AddFilter("Microsoft.SemanticKernel.Reliability", LogLevel.Information);
builder.AddFilter("System", LogLevel.Information);

builder.AddConsole();
});
logger.LogInformation("Error: {Message}", ex.Message);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static async Task RunAsync()

var kernel = new KernelBuilder()
.WithLoggerFactory(ConsoleLogger.LoggerFactory)
.WithOpenAIChatCompletionService(TestConfiguration.OpenAI.ChatModelId, TestConfiguration.OpenAI.ApiKey)
.WithOpenAIChatCompletion(TestConfiguration.OpenAI.ChatModelId, TestConfiguration.OpenAI.ApiKey)
.Build();

var variables = new ContextVariables();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static Task RunAsync()
Console.WriteLine("======== Describe all plugins and functions ========");

var kernel = new KernelBuilder()
.WithOpenAIChatCompletionService(
.WithOpenAIChatCompletion(
modelId: TestConfiguration.OpenAI.ChatModelId,
apiKey: TestConfiguration.OpenAI.ApiKey)
.Build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ private static async Task PoetrySamplesAsync()
Console.WriteLine("======== Sequential Planner - Create and Execute Poetry Plan ========");
var kernel = new KernelBuilder()
.WithLoggerFactory(ConsoleLogger.LoggerFactory)
.WithAzureOpenAIChatCompletionService(
.WithAzureOpenAIChatCompletion(
TestConfiguration.AzureOpenAI.ChatDeploymentName,
TestConfiguration.AzureOpenAI.Endpoint,
TestConfiguration.AzureOpenAI.ApiKey)
Expand Down Expand Up @@ -257,7 +257,7 @@ private static Kernel InitializeKernelAndPlanner(out SequentialPlanner planner,
{
var kernel = new KernelBuilder()
.WithLoggerFactory(ConsoleLogger.LoggerFactory)
.WithAzureOpenAIChatCompletionService(
.WithAzureOpenAIChatCompletion(
TestConfiguration.AzureOpenAI.ChatDeploymentName,
TestConfiguration.AzureOpenAI.Endpoint,
TestConfiguration.AzureOpenAI.ApiKey)
Expand All @@ -274,11 +274,11 @@ private static Kernel InitializeKernel()
// use these to generate and store embeddings for the function descriptions.
var kernel = new KernelBuilder()
.WithLoggerFactory(ConsoleLogger.LoggerFactory)
.WithAzureOpenAIChatCompletionService(
.WithAzureOpenAIChatCompletion(
TestConfiguration.AzureOpenAI.ChatDeploymentName,
TestConfiguration.AzureOpenAI.Endpoint,
TestConfiguration.AzureOpenAI.ApiKey)
.WithAzureOpenAITextEmbeddingGenerationService(
.WithAzureOpenAITextEmbeddingGeneration(
TestConfiguration.AzureOpenAIEmbeddings.DeploymentName,
TestConfiguration.AzureOpenAIEmbeddings.Endpoint,
TestConfiguration.AzureOpenAIEmbeddings.ApiKey)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ private static Kernel InitializeKernel()
{
Kernel kernel = new KernelBuilder()
.WithLoggerFactory(ConsoleLogger.LoggerFactory)
.WithAzureOpenAIChatCompletionService(
.WithAzureOpenAIChatCompletion(
TestConfiguration.AzureOpenAI.ChatDeploymentName,
TestConfiguration.AzureOpenAI.Endpoint,
TestConfiguration.AzureOpenAI.ApiKey)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public static async Task RunAsync()

var memoryWithACS = new MemoryBuilder()
.WithLoggerFactory(ConsoleLogger.LoggerFactory)
.WithOpenAITextEmbeddingGenerationService("text-embedding-ada-002", TestConfiguration.OpenAI.ApiKey)
.WithOpenAITextEmbeddingGeneration("text-embedding-ada-002", TestConfiguration.OpenAI.ApiKey)
.WithMemoryStore(new AzureCognitiveSearchMemoryStore(TestConfiguration.ACS.Endpoint, TestConfiguration.ACS.ApiKey))
.Build();

Expand All @@ -59,7 +59,7 @@ public static async Task RunAsync()

var memoryWithCustomDb = new MemoryBuilder()
.WithLoggerFactory(ConsoleLogger.LoggerFactory)
.WithOpenAITextEmbeddingGenerationService("text-embedding-ada-002", TestConfiguration.OpenAI.ApiKey)
.WithOpenAITextEmbeddingGeneration("text-embedding-ada-002", TestConfiguration.OpenAI.ApiKey)
.WithMemoryStore(new VolatileMemoryStore())
.Build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ private static async Task RunWithStoreAsync(IMemoryStore memoryStore, Cancellati
{
var kernel = new KernelBuilder()
.WithLoggerFactory(ConsoleLogger.LoggerFactory)
.WithOpenAIChatCompletionService(TestConfiguration.OpenAI.ChatModelId, TestConfiguration.OpenAI.ApiKey)
.WithOpenAITextEmbeddingGenerationService(TestConfiguration.OpenAI.EmbeddingModelId, TestConfiguration.OpenAI.ApiKey)
.WithOpenAIChatCompletion(TestConfiguration.OpenAI.ChatModelId, TestConfiguration.OpenAI.ApiKey)
.WithOpenAITextEmbeddingGeneration(TestConfiguration.OpenAI.EmbeddingModelId, TestConfiguration.OpenAI.ApiKey)
.Build();

// Create an embedding generator to use for semantic memory.
Expand Down
Loading
Loading