Skip to content

Commit

Permalink
.Net: Replace SK's IAIServiceProvider with IServiceProvider (#3714)
Browse files Browse the repository at this point in the history
Closes #3694
Closes #3693
Closes #3659
Closes #3571
Closes #3191
Closes #2463

(This replaces #3676,
including that as a first commit. That resiliency functionality is no
longer necessary after this change, as developers can simply use
libraries like Microsoft.Extensions.Http.Resilience to achieve the
desired support.)

SK has had a custom IAIServiceProvider interface that's represented a
provider of AI related services. Kernel has then wrapped one of these,
but also wrapped other individual non-AI services, like ILoggerFactory
and HttpClient. This leads to a variety of problems, such as it being
more complicated to construct a Kernel instance, it not integrating as
nicely with a broader dependency injection system, and not being as
future proof because there isn't a good way to flow additional
non-AI-related services through the Kernel to anywhere that might want
access. On the DI front, it's also more difficult to integrate because
all of the KernelBuilder extension methods are specific to
KernelBuilder, and even though they're creating services, the helpers
aren't usable with IServiceCollection and thus with the rest of the DI
system; a developer needs to go directly to the underlying types and
register those directly.

There are also a handful of features that are of little value and in
some cases exposed but not actually implemented, such as setAsDefault
and alsoAsTextCompletion. And other cases where there's something
valuable but missing, such as the ability to create certain kinds of
Azure-related service instances with an existing OpenAIClient.

This PR attempts to address all of these issues and set up SK to evolve
more easily:
- Kernel now wraps an IServiceProvider, and all services (AI and non-AI)
are retrieved from it. This has a variety of benefits, including
future-proofing for wanting to flow more state around, better
integration with other systems (e.g.
Microsoft.Extensions.DependencyInjection), simpler construction, etc.
- KernelBuilder still has dedicated WithXx methods for first-class
features, but they're all layered on top of a new ConfigureServices
method, which lets you add anything to an IServiceCollection. Because
everything is based on IServiceCollection/IServiceProvider, dependencies
are automatically satisfied from the container. For example, for
services that accept an optional HttpClient, if one isn't specified to
the WithXx method, the system will pull one out of the DI container if
it can, which means all existing support for adding configured
HttpClient instances to an IServiceCollection immediately apply to
Kernel{Builder} as well.
- KernelBuilder also exposes a ConfigurePlugins method, largely for
parity with ConfigureServices, as fundmantally a Kernel is just the
combination of a collection of services and a collection of plugins
(plus some additional transient data, event handlers, etc.) This also
integrates with IServiceProvider, with one passed into the callback, so
that if the plugin itself needs access to something like logging, it can
simply get it from the container. These ConfigureServices and
ConfigurePlugins methods can be called any number of times.
- KernelBuilder is now just a simplified, opinionated way to achieve
something you can achieve in two other ways: construct the Kernel
directly, or construct the Kernel via DI. For the latter, you can simply
add Kernel as a DI resource, and it'll automatically be composed out of
what's available. For example, if in ASP.NET you
AddAzureOpenChatCompletion, AddLogging, AddHttp, etc., and then ask for
a Kernel to be injected, that Kernel will be constructed from the
IServiceProvider that contains all of those other resources, and thus
anyone using the Kernel will get that logger, will get that HttpClient,
etc.; the HttpClient will also be used by the Azure OpenAI chat
completion.

@matthewbolanos, @markwallace-microsoft, @SergeyMenshykh, please review
from an SK perspective to let me know if you agree with the direction,
whether there are specific things you'd like to see changed, etc. There
are some straggling things we should still do after this (like add a few
more extension methods for adding plugins to a plugin collection, adding
more tests, revamping XML comments, cleaning up more code, etc.), but
this is a sweeping change and I wanted to get it in.

@eerhardt, @halter73, I'd appreciate it if you could review this from a
DI perspective, e.g. are there variations in the patterns I should be
following, any best-practices I'm violating, whether I'm using singleton
when I should be using transient, etc. etc.

Note that I ran into one issue as part of this: the
Microsoft.Extensions.DependencyInjection support for keyed services
doesn't let you enumerate all services for a particular T, regardless of
key. That's something SK depends on. To workaround that, KernelBuilder
tracks all of the type/keys and injects a dictionary as a service with
that information; then places the Kernel needs it, it can query for that
dictionary and use it. This means that a Kernel constructed with
KernelBuilder will fully support keys, whereas a Kernel constructed with
DI or directly won't work as nicely with named services. My hope is that
M.E.DI can fix this asap (offline conversation) in a way that will allow
SK to upgrade to a patched version, delete its hack, and have those
broader scenarios "just work". In the meantime, though, KernelBuilder
behaves as desired.

I also stopped short of adding Add{Azure}OpenAIXx methods that resolve
the OpenAIClient from the service provider. That'll be an important
thing to do once there's an Aspire component for Azure.AI.OpenAI, but in
the meantime, I didn't want there to be an attractive Add{Azure}OpenAIXx
method that looked like you didn't need to supply the necessary
information even though you do.

---------

Co-authored-by: SergeyMenshykh <sergemenshikh@gmail.com>
  • Loading branch information
stephentoub and SergeyMenshykh authored Nov 28, 2023
1 parent b7f9b1d commit 73afd47
Show file tree
Hide file tree
Showing 190 changed files with 2,214 additions and 5,303 deletions.
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

0 comments on commit 73afd47

Please sign in to comment.