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 @@ -9,6 +9,7 @@
using Microsoft.SemanticKernel.Connectors.AzureOpenAI;
using Microsoft.SemanticKernel.Embeddings;
using Microsoft.SemanticKernel.TextGeneration;
using Microsoft.SemanticKernel.TextToImage;

namespace SemanticKernel.Connectors.AzureOpenAI.UnitTests.Extensions;

Expand Down Expand Up @@ -88,6 +89,40 @@ public void ServiceCollectionAddAzureOpenAITextEmbeddingGenerationAddsValidServi

#endregion

#region Text to image

[Theory]
[InlineData(InitializationType.ApiKey)]
[InlineData(InitializationType.TokenCredential)]
[InlineData(InitializationType.ClientInline)]
[InlineData(InitializationType.ClientInServiceProvider)]
public void ServiceCollectionExtensionsAddAzureOpenAITextToImageService(InitializationType type)
{
// Arrange
var credentials = DelegatedTokenCredential.Create((_, _) => new AccessToken());
var client = new AzureOpenAIClient(new Uri("http://localhost"), "key");
var builder = Kernel.CreateBuilder();

builder.Services.AddSingleton<AzureOpenAIClient>(client);

// Act
IServiceCollection collection = type switch
{
InitializationType.ApiKey => builder.Services.AddAzureOpenAITextToImage("deployment-name", "https://endpoint", "api-key"),
InitializationType.TokenCredential => builder.Services.AddAzureOpenAITextToImage("deployment-name", "https://endpoint", credentials),
InitializationType.ClientInline => builder.Services.AddAzureOpenAITextToImage("deployment-name", client),
InitializationType.ClientInServiceProvider => builder.Services.AddAzureOpenAITextToImage("deployment-name"),
_ => builder.Services
};

// Assert
var service = builder.Build().GetRequiredService<ITextToImageService>();

Assert.True(service is AzureOpenAITextToImageService);
}

#endregion

public enum InitializationType
{
ApiKey,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Microsoft.SemanticKernel.Connectors.AzureOpenAI;
using Microsoft.SemanticKernel.Embeddings;
using Microsoft.SemanticKernel.TextGeneration;
using Microsoft.SemanticKernel.TextToImage;

namespace SemanticKernel.Connectors.AzureOpenAI.UnitTests.Extensions;

Expand All @@ -22,8 +23,8 @@ public sealed class AzureOpenAIServiceKernelBuilderExtensionsTests
[Theory]
[InlineData(InitializationType.ApiKey)]
[InlineData(InitializationType.TokenCredential)]
[InlineData(InitializationType.OpenAIClientInline)]
[InlineData(InitializationType.OpenAIClientInServiceProvider)]
[InlineData(InitializationType.ClientInline)]
[InlineData(InitializationType.ClientInServiceProvider)]
public void KernelBuilderAddAzureOpenAIChatCompletionAddsValidService(InitializationType type)
{
// Arrange
Expand All @@ -38,8 +39,8 @@ public void KernelBuilderAddAzureOpenAIChatCompletionAddsValidService(Initializa
{
InitializationType.ApiKey => builder.AddAzureOpenAIChatCompletion("deployment-name", "https://endpoint", "api-key"),
InitializationType.TokenCredential => builder.AddAzureOpenAIChatCompletion("deployment-name", "https://endpoint", credentials),
InitializationType.OpenAIClientInline => builder.AddAzureOpenAIChatCompletion("deployment-name", client),
InitializationType.OpenAIClientInServiceProvider => builder.AddAzureOpenAIChatCompletion("deployment-name"),
InitializationType.ClientInline => builder.AddAzureOpenAIChatCompletion("deployment-name", client),
InitializationType.ClientInServiceProvider => builder.AddAzureOpenAIChatCompletion("deployment-name"),
_ => builder
};

Expand All @@ -58,8 +59,8 @@ public void KernelBuilderAddAzureOpenAIChatCompletionAddsValidService(Initializa
[Theory]
[InlineData(InitializationType.ApiKey)]
[InlineData(InitializationType.TokenCredential)]
[InlineData(InitializationType.OpenAIClientInline)]
[InlineData(InitializationType.OpenAIClientInServiceProvider)]
[InlineData(InitializationType.ClientInline)]
[InlineData(InitializationType.ClientInServiceProvider)]
public void KernelBuilderAddAzureOpenAITextEmbeddingGenerationAddsValidService(InitializationType type)
{
// Arrange
Expand All @@ -74,8 +75,8 @@ public void KernelBuilderAddAzureOpenAITextEmbeddingGenerationAddsValidService(I
{
InitializationType.ApiKey => builder.AddAzureOpenAITextEmbeddingGeneration("deployment-name", "https://endpoint", "api-key"),
InitializationType.TokenCredential => builder.AddAzureOpenAITextEmbeddingGeneration("deployment-name", "https://endpoint", credentials),
InitializationType.OpenAIClientInline => builder.AddAzureOpenAITextEmbeddingGeneration("deployment-name", client),
InitializationType.OpenAIClientInServiceProvider => builder.AddAzureOpenAITextEmbeddingGeneration("deployment-name"),
InitializationType.ClientInline => builder.AddAzureOpenAITextEmbeddingGeneration("deployment-name", client),
InitializationType.ClientInServiceProvider => builder.AddAzureOpenAITextEmbeddingGeneration("deployment-name"),
_ => builder
};

Expand All @@ -88,12 +89,46 @@ public void KernelBuilderAddAzureOpenAITextEmbeddingGenerationAddsValidService(I

#endregion

#region Text to image

[Theory]
[InlineData(InitializationType.ApiKey)]
[InlineData(InitializationType.TokenCredential)]
[InlineData(InitializationType.ClientInline)]
[InlineData(InitializationType.ClientInServiceProvider)]
public void KernelBuilderExtensionsAddAzureOpenAITextToImageService(InitializationType type)
{
// Arrange
var credentials = DelegatedTokenCredential.Create((_, _) => new AccessToken());
var client = new AzureOpenAIClient(new Uri("http://localhost"), "key");
var builder = Kernel.CreateBuilder();

builder.Services.AddSingleton<AzureOpenAIClient>(client);

// Act
builder = type switch
{
InitializationType.ApiKey => builder.AddAzureOpenAITextToImage("deployment-name", "https://endpoint", "api-key"),
InitializationType.TokenCredential => builder.AddAzureOpenAITextToImage("deployment-name", "https://endpoint", credentials),
InitializationType.ClientInline => builder.AddAzureOpenAITextToImage("deployment-name", client),
InitializationType.ClientInServiceProvider => builder.AddAzureOpenAITextToImage("deployment-name"),
_ => builder
};

// Assert
var service = builder.Build().GetRequiredService<ITextToImageService>();

Assert.True(service is AzureOpenAITextToImageService);
}

#endregion

public enum InitializationType
{
ApiKey,
TokenCredential,
OpenAIClientInline,
OpenAIClientInServiceProvider,
OpenAIClientEndpoint,
ClientInline,
ClientInServiceProvider,
ClientEndpoint,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Microsoft.SemanticKernel.Embeddings;
using Microsoft.SemanticKernel.Http;
using Microsoft.SemanticKernel.TextGeneration;
using Microsoft.SemanticKernel.TextToImage;

#pragma warning disable IDE0039 // Use local function

Expand Down Expand Up @@ -248,6 +249,118 @@ public static IKernelBuilder AddAzureOpenAITextEmbeddingGeneration(

#endregion

#region Images

/// <summary>
/// Add the Azure OpenAI text-to-image service to the list.
/// </summary>
/// <param name="builder">The <see cref="IKernelBuilder"/> instance to augment.</param>
/// <param name="deploymentName">Azure OpenAI deployment name, see https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource</param>
/// <param name="endpoint">Azure OpenAI deployment URL, see https://learn.microsoft.com/azure/cognitive-services/openai/quickstart</param>
/// <param name="credentials">Token credentials, e.g. DefaultAzureCredential, ManagedIdentityCredential, EnvironmentCredential, etc.</param>
/// <param name="modelId">Model identifier, see https://learn.microsoft.com/azure/cognitive-services/openai/quickstart</param>
/// <param name="serviceId">A local identifier for the given AI service</param>
/// <param name="apiVersion">Azure OpenAI API version</param>
/// <returns>The same instance as <paramref name="builder"/>.</returns>
[Experimental("SKEXP0010")]
public static IKernelBuilder AddAzureOpenAITextToImage(
this IKernelBuilder builder,
string deploymentName,
string endpoint,
TokenCredential credentials,
string? modelId = null,
string? serviceId = null,
string? apiVersion = null)
{
Verify.NotNull(builder);
Verify.NotNullOrWhiteSpace(endpoint);
Verify.NotNull(credentials);

builder.Services.AddKeyedSingleton<ITextToImageService>(serviceId, (serviceProvider, _) =>
new AzureOpenAITextToImageService(
deploymentName,
endpoint,
credentials,
modelId,
HttpClientProvider.GetHttpClient(serviceProvider),
serviceProvider.GetService<ILoggerFactory>(),
apiVersion));

return builder;
}

/// <summary>
/// Add the Azure OpenAI text-to-image service to the list.
/// </summary>
/// <param name="builder">The <see cref="IKernelBuilder"/> instance to augment.</param>
/// <param name="deploymentName">Azure OpenAI deployment name, see https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource</param>
/// <param name="endpoint">Azure OpenAI deployment URL, see https://learn.microsoft.com/azure/cognitive-services/openai/quickstart</param>
/// <param name="apiKey">Azure OpenAI API key</param>
/// <param name="modelId">Model identifier, see https://learn.microsoft.com/azure/cognitive-services/openai/quickstart</param>
/// <param name="serviceId">A local identifier for the given AI service</param>
/// <param name="apiVersion">Azure OpenAI API version</param>
/// <param name="httpClient">The HttpClient to use with this service.</param>
/// <returns>The same instance as <paramref name="builder"/>.</returns>
[Experimental("SKEXP0010")]
public static IKernelBuilder AddAzureOpenAITextToImage(
this IKernelBuilder builder,
string deploymentName,
string endpoint,
string apiKey,
string? modelId = null,
string? serviceId = null,
string? apiVersion = null,
HttpClient? httpClient = null)
{
Verify.NotNull(builder);
Verify.NotNullOrWhiteSpace(endpoint);
Verify.NotNullOrWhiteSpace(apiKey);

builder.Services.AddKeyedSingleton<ITextToImageService>(serviceId, (serviceProvider, _) =>
new AzureOpenAITextToImageService(
deploymentName,
endpoint,
apiKey,
modelId,
HttpClientProvider.GetHttpClient(httpClient, serviceProvider),
serviceProvider.GetService<ILoggerFactory>(),
apiVersion));

return builder;
}

/// <summary>
/// Add the Azure OpenAI text-to-image service to the list.
/// </summary>
/// <param name="builder">The <see cref="IKernelBuilder"/> instance to augment.</param>
/// <param name="deploymentName">Azure OpenAI deployment name, see https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource</param>
/// <param name="azureOpenAIClient"><see cref="AzureOpenAIClient"/> to use for the service. If null, one must be available in the service provider when this service is resolved.</param>
/// <param name="modelId">Model identifier, see https://learn.microsoft.com/azure/cognitive-services/openai/quickstart</param>
/// <param name="serviceId">A local identifier for the given AI service</param>
/// <returns>The same instance as <paramref name="builder"/>.</returns>
[Experimental("SKEXP0010")]
public static IKernelBuilder AddAzureOpenAITextToImage(
this IKernelBuilder builder,
string deploymentName,
AzureOpenAIClient? azureOpenAIClient = null,
string? modelId = null,
string? serviceId = null)
{
Verify.NotNull(builder);
Verify.NotNullOrWhiteSpace(deploymentName);

builder.Services.AddKeyedSingleton<ITextToImageService>(serviceId, (serviceProvider, _) =>
new AzureOpenAITextToImageService(
deploymentName,
azureOpenAIClient ?? serviceProvider.GetRequiredService<AzureOpenAIClient>(),
modelId,
serviceProvider.GetService<ILoggerFactory>()));

return builder;
}

#endregion

private static AzureOpenAIClient CreateAzureOpenAIClient(string endpoint, AzureKeyCredential credentials, HttpClient? httpClient) =>
new(new Uri(endpoint), credentials, ClientCore.GetAzureOpenAIClientOptions(httpClient));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Microsoft.SemanticKernel.Embeddings;
using Microsoft.SemanticKernel.Http;
using Microsoft.SemanticKernel.TextGeneration;
using Microsoft.SemanticKernel.TextToImage;

#pragma warning disable IDE0039 // Use local function

Expand Down Expand Up @@ -234,6 +235,109 @@ public static IServiceCollection AddAzureOpenAITextEmbeddingGeneration(

#endregion

#region Images

/// <summary>
/// Add the Azure OpenAI text-to-image service to the list.
Comment thread
SergeyMenshykh marked this conversation as resolved.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> instance to augment.</param>
/// <param name="deploymentName">Azure OpenAI deployment name, see https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource</param>
/// <param name="endpoint">Azure OpenAI deployment URL, see https://learn.microsoft.com/azure/cognitive-services/openai/quickstart</param>
/// <param name="credentials">Token credentials, e.g. DefaultAzureCredential, ManagedIdentityCredential, EnvironmentCredential, etc.</param>
/// <param name="modelId">Model identifier, see https://learn.microsoft.com/azure/cognitive-services/openai/quickstart</param>
/// <param name="serviceId">A local identifier for the given AI service</param>
/// <param name="apiVersion">Azure OpenAI API version</param>
/// <returns>The same instance as <paramref name="services"/>.</returns>
[Experimental("SKEXP0010")]
public static IServiceCollection AddAzureOpenAITextToImage(
this IServiceCollection services,
string deploymentName,
string endpoint,
TokenCredential credentials,
string? modelId = null,
string? serviceId = null,
string? apiVersion = null)
{
Verify.NotNull(services);
Verify.NotNullOrWhiteSpace(endpoint);
Verify.NotNull(credentials);

return services.AddKeyedSingleton<ITextToImageService>(serviceId, (serviceProvider, _) =>
new AzureOpenAITextToImageService(
deploymentName,
endpoint,
credentials,
modelId,
HttpClientProvider.GetHttpClient(serviceProvider),
serviceProvider.GetService<ILoggerFactory>(),
apiVersion));
}

/// <summary>
/// Add the Azure OpenAI text-to-image service to the list.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> instance to augment.</param>
/// <param name="deploymentName">Azure OpenAI deployment name, see https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource</param>
/// <param name="endpoint">Azure OpenAI deployment URL, see https://learn.microsoft.com/azure/cognitive-services/openai/quickstart</param>
/// <param name="apiKey">Azure OpenAI API key</param>
/// <param name="serviceId">A local identifier for the given AI service</param>
/// <param name="modelId">Model identifier, see https://learn.microsoft.com/azure/cognitive-services/openai/quickstart</param>
/// <param name="maxRetryCount">Maximum number of attempts to retrieve the text to image operation result.</param>
/// <returns>The same instance as <paramref name="services"/>.</returns>
[Experimental("SKEXP0010")]
public static IServiceCollection AddAzureOpenAITextToImage(
this IServiceCollection services,
string deploymentName,
string endpoint,
string apiKey,
string? serviceId = null,
string? modelId = null,
int maxRetryCount = 5)
{
Verify.NotNull(services);
Verify.NotNullOrWhiteSpace(endpoint);
Verify.NotNullOrWhiteSpace(apiKey);

return services.AddKeyedSingleton<ITextToImageService>(serviceId, (serviceProvider, _) =>
new AzureOpenAITextToImageService(
deploymentName,
endpoint,
apiKey,
modelId,
HttpClientProvider.GetHttpClient(serviceProvider),
serviceProvider.GetService<ILoggerFactory>()));
}

/// <summary>
/// Add the Azure OpenAI text-to-image service to the list.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> instance to augment.</param>
/// <param name="deploymentName">Azure OpenAI deployment name, see https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource</param>
/// <param name="openAIClient"><see cref="AzureOpenAIClient"/> to use for the service. If null, one must be available in the service provider when this service is resolved.</param>
/// <param name="modelId">Model identifier, see https://learn.microsoft.com/azure/cognitive-services/openai/quickstart</param>
/// <param name="serviceId">A local identifier for the given AI service</param>
/// <returns>The same instance as <paramref name="services"/>.</returns>
[Experimental("SKEXP0010")]
public static IServiceCollection AddAzureOpenAITextToImage(
this IServiceCollection services,
string deploymentName,
AzureOpenAIClient? openAIClient = null,
string? modelId = null,
string? serviceId = null)
{
Verify.NotNull(services);
Verify.NotNullOrWhiteSpace(deploymentName);

return services.AddKeyedSingleton<ITextToImageService>(serviceId, (serviceProvider, _) =>
new AzureOpenAITextToImageService(
deploymentName,
openAIClient ?? serviceProvider.GetRequiredService<AzureOpenAIClient>(),
modelId,
serviceProvider.GetService<ILoggerFactory>()));
}

#endregion

private static AzureOpenAIClient CreateAzureOpenAIClient(string endpoint, AzureKeyCredential credentials, HttpClient? httpClient) =>
new(new Uri(endpoint), credentials, ClientCore.GetAzureOpenAIClientOptions(httpClient));

Expand Down
Loading