From 3b80379fe7f78ec61155938853abdf112bd65dce Mon Sep 17 00:00:00 2001 From: SergeyMenshykh Date: Wed, 3 Jul 2024 21:12:43 +0100 Subject: [PATCH 1/3] feat(AzureOpenAISDKv2): migrate azure text-to-image service. --- .../Connectors.AzureOpenAI.UnitTests.csproj | 8 -- .../AzureOpenAITextToImageServiceTests.cs | 61 ++++------ .../TestData/text-to-image-response.txt | 9 ++ .../Connectors.AzureOpenAI.csproj | 10 -- .../Core/ClientCore.ChatCompletion.cs | 2 +- .../Core/ClientCore.Embeddings.cs | 2 +- .../Core/ClientCore.TextToImage.cs | 7 +- .../Connectors.AzureOpenAI/Core/ClientCore.cs | 12 +- ...ureOpenAITextEmbeddingGenerationService.cs | 6 +- .../Services/AzureOpenAITextToImageService.cs | 112 +++++++++++++++--- 10 files changed, 140 insertions(+), 89 deletions(-) create mode 100644 dotnet/src/Connectors/Connectors.AzureOpenAI.UnitTests/TestData/text-to-image-response.txt diff --git a/dotnet/src/Connectors/Connectors.AzureOpenAI.UnitTests/Connectors.AzureOpenAI.UnitTests.csproj b/dotnet/src/Connectors/Connectors.AzureOpenAI.UnitTests/Connectors.AzureOpenAI.UnitTests.csproj index 056ac691dfa4..a0a695a6719c 100644 --- a/dotnet/src/Connectors/Connectors.AzureOpenAI.UnitTests/Connectors.AzureOpenAI.UnitTests.csproj +++ b/dotnet/src/Connectors/Connectors.AzureOpenAI.UnitTests/Connectors.AzureOpenAI.UnitTests.csproj @@ -30,14 +30,6 @@ - - - - - - - - diff --git a/dotnet/src/Connectors/Connectors.AzureOpenAI.UnitTests/Services/AzureOpenAITextToImageServiceTests.cs b/dotnet/src/Connectors/Connectors.AzureOpenAI.UnitTests/Services/AzureOpenAITextToImageServiceTests.cs index b0d44113febb..c872e7b1c19b 100644 --- a/dotnet/src/Connectors/Connectors.AzureOpenAI.UnitTests/Services/AzureOpenAITextToImageServiceTests.cs +++ b/dotnet/src/Connectors/Connectors.AzureOpenAI.UnitTests/Services/AzureOpenAITextToImageServiceTests.cs @@ -3,17 +3,20 @@ using System; using System.IO; using System.Net.Http; +using System.Text.Json; +using System.Text.Json.Nodes; using System.Threading.Tasks; +using Azure.AI.OpenAI; +using Azure.Core; using Microsoft.Extensions.Logging; using Microsoft.SemanticKernel.Connectors.AzureOpenAI; using Microsoft.SemanticKernel.Services; using Moq; -using OpenAI; namespace SemanticKernel.Connectors.AzureOpenAI.UnitTests.Services; /// -/// Unit tests for class. +/// Unit tests for class. /// public sealed class AzureOpenAITextToImageServiceTests : IDisposable { @@ -35,25 +38,21 @@ public AzureOpenAITextToImageServiceTests() } [Fact] - public void ConstructorWorksCorrectly() + public void ConstructorsAddRequiredMetadata() { - // Arrange & Act - var sut = new AzureOpenAITextToImageServiceTests("model", "api-key", "organization"); - - // Assert - Assert.NotNull(sut); - Assert.Equal("organization", sut.Attributes[ClientCore.OrganizationKey]); + // Case #1 + var sut = new AzureOpenAITextToImageService("deployment", "https://api-host/", "api-key", "model"); + Assert.Equal("deployment", sut.Attributes[ClientCore.DeploymentNameKey]); Assert.Equal("model", sut.Attributes[AIServiceExtensions.ModelIdKey]); - } - [Fact] - public void OpenAIClientConstructorWorksCorrectly() - { - // Arrange - var sut = new AzureOpenAITextToImageServiceTests("model", new OpenAIClient("apikey")); + // Case #2 + sut = new AzureOpenAITextToImageService("deployment", "https://api-hostapi/", new Mock().Object, "model"); + Assert.Equal("deployment", sut.Attributes[ClientCore.DeploymentNameKey]); + Assert.Equal("model", sut.Attributes[AIServiceExtensions.ModelIdKey]); - // Assert - Assert.NotNull(sut); + // Case #3 + sut = new AzureOpenAITextToImageService("deployment", new AzureOpenAIClient(), "model"); + Assert.Equal("deployment", sut.Attributes[ClientCore.DeploymentNameKey]); Assert.Equal("model", sut.Attributes[AIServiceExtensions.ModelIdKey]); } @@ -69,34 +68,20 @@ public void OpenAIClientConstructorWorksCorrectly() public async Task GenerateImageWorksCorrectlyAsync(int width, int height, string modelId) { // Arrange - var sut = new AzureOpenAITextToImageServiceTests(modelId, "api-key", httpClient: this._httpClient); - Assert.Equal(modelId, sut.Attributes["ModelId"]); + var sut = new AzureOpenAITextToImageService("deployment", "https://api-host", "api-key", modelId, this._httpClient); // Act var result = await sut.GenerateImageAsync("description", width, height); // Assert Assert.Equal("https://image-url/", result); - } - [Fact] - public async Task GenerateImageDoesLogActionAsync() - { - // Assert - var modelId = "dall-e-2"; - var logger = new Mock>(); - logger.Setup(l => l.IsEnabled(It.IsAny())).Returns(true); - - this._mockLoggerFactory.Setup(x => x.CreateLogger(It.IsAny())).Returns(logger.Object); - - // Arrange - var sut = new AzureOpenAITextToImageServiceTests(modelId, "apiKey", httpClient: this._httpClient, loggerFactory: this._mockLoggerFactory.Object); - - // Act - await sut.GenerateImageAsync("description", 256, 256); - - // Assert - logger.VerifyLog(LogLevel.Information, $"Action: {nameof(AzureOpenAITextToImageServiceTests.GenerateImageAsync)}. OpenAI Model ID: {modelId}.", Times.Once()); + var request = JsonSerializer.Deserialize(this._messageHandlerStub.RequestContent); // {"prompt":"description","model":"deployment","response_format":"url","size":"179x124"} + Assert.NotNull(request); + Assert.Equal("description", request["prompt"]?.ToString()); + Assert.Equal("deployment", request["model"]?.ToString()); + Assert.Equal("url", request["response_format"]?.ToString()); + Assert.Equal($"{width}x{height}", request["size"]?.ToString()); } public void Dispose() diff --git a/dotnet/src/Connectors/Connectors.AzureOpenAI.UnitTests/TestData/text-to-image-response.txt b/dotnet/src/Connectors/Connectors.AzureOpenAI.UnitTests/TestData/text-to-image-response.txt new file mode 100644 index 000000000000..1d6f2150b1d5 --- /dev/null +++ b/dotnet/src/Connectors/Connectors.AzureOpenAI.UnitTests/TestData/text-to-image-response.txt @@ -0,0 +1,9 @@ +{ + "created": 1702575371, + "data": [ + { + "revised_prompt": "A photo capturing the diversity of the Earth's landscapes.", + "url": "https://image-url/" + } + ] +} \ No newline at end of file diff --git a/dotnet/src/Connectors/Connectors.AzureOpenAI/Connectors.AzureOpenAI.csproj b/dotnet/src/Connectors/Connectors.AzureOpenAI/Connectors.AzureOpenAI.csproj index 720cd1cf71f5..35c31788610d 100644 --- a/dotnet/src/Connectors/Connectors.AzureOpenAI/Connectors.AzureOpenAI.csproj +++ b/dotnet/src/Connectors/Connectors.AzureOpenAI/Connectors.AzureOpenAI.csproj @@ -21,20 +21,10 @@ Semantic Kernel connectors for Azure OpenAI. Contains clients for text generation, chat completion, embedding and DALL-E text to image. - - - - - - - - - - diff --git a/dotnet/src/Connectors/Connectors.AzureOpenAI/Core/ClientCore.ChatCompletion.cs b/dotnet/src/Connectors/Connectors.AzureOpenAI/Core/ClientCore.ChatCompletion.cs index e118a4b440e9..14b8c6a38ae0 100644 --- a/dotnet/src/Connectors/Connectors.AzureOpenAI/Core/ClientCore.ChatCompletion.cs +++ b/dotnet/src/Connectors/Connectors.AzureOpenAI/Core/ClientCore.ChatCompletion.cs @@ -23,7 +23,7 @@ namespace Microsoft.SemanticKernel.Connectors.AzureOpenAI; /// -/// Base class for AI clients that provides common functionality for interacting with OpenAI services. +/// Base class for AI clients that provides common functionality for interacting with Azure OpenAI services. /// internal partial class ClientCore { diff --git a/dotnet/src/Connectors/Connectors.AzureOpenAI/Core/ClientCore.Embeddings.cs b/dotnet/src/Connectors/Connectors.AzureOpenAI/Core/ClientCore.Embeddings.cs index cc7f6ffdda04..6f1aaaf16efc 100644 --- a/dotnet/src/Connectors/Connectors.AzureOpenAI/Core/ClientCore.Embeddings.cs +++ b/dotnet/src/Connectors/Connectors.AzureOpenAI/Core/ClientCore.Embeddings.cs @@ -9,7 +9,7 @@ namespace Microsoft.SemanticKernel.Connectors.AzureOpenAI; /// -/// Base class for AI clients that provides common functionality for interacting with OpenAI services. +/// Base class for AI clients that provides common functionality for interacting with Azure OpenAI services. /// internal partial class ClientCore { diff --git a/dotnet/src/Connectors/Connectors.AzureOpenAI/Core/ClientCore.TextToImage.cs b/dotnet/src/Connectors/Connectors.AzureOpenAI/Core/ClientCore.TextToImage.cs index b6490a058fb9..46335d6289de 100644 --- a/dotnet/src/Connectors/Connectors.AzureOpenAI/Core/ClientCore.TextToImage.cs +++ b/dotnet/src/Connectors/Connectors.AzureOpenAI/Core/ClientCore.TextToImage.cs @@ -8,7 +8,7 @@ namespace Microsoft.SemanticKernel.Connectors.AzureOpenAI; /// -/// Base class for AI clients that provides common functionality for interacting with OpenAI services. +/// Base class for AI clients that provides common functionality for interacting with Azure OpenAI services. /// internal partial class ClientCore { @@ -36,9 +36,8 @@ internal async Task GenerateImageAsync( ResponseFormat = GeneratedImageFormat.Uri }; - ClientResult response = await RunRequestAsync(() => this.Client.GetImageClient(this.ModelId).GenerateImageAsync(prompt, imageOptions, cancellationToken)).ConfigureAwait(false); - var generatedImage = response.Value; + ClientResult response = await RunRequestAsync(() => this.Client.GetImageClient(this.DeploymentOrModelName).GenerateImageAsync(prompt, imageOptions, cancellationToken)).ConfigureAwait(false); - return generatedImage.ImageUri?.ToString() ?? throw new KernelException("The generated image is not in url format"); + return response.Value.ImageUri?.ToString() ?? throw new KernelException("The generated image is not in url format"); } } diff --git a/dotnet/src/Connectors/Connectors.AzureOpenAI/Core/ClientCore.cs b/dotnet/src/Connectors/Connectors.AzureOpenAI/Core/ClientCore.cs index dc45fdaea59d..571d24d95c3b 100644 --- a/dotnet/src/Connectors/Connectors.AzureOpenAI/Core/ClientCore.cs +++ b/dotnet/src/Connectors/Connectors.AzureOpenAI/Core/ClientCore.cs @@ -17,7 +17,7 @@ namespace Microsoft.SemanticKernel.Connectors.AzureOpenAI; /// -/// Base class for AI clients that provides common functionality for interacting with OpenAI services. +/// Base class for AI clients that provides common functionality for interacting with Azure OpenAI services. /// internal partial class ClientCore { @@ -135,13 +135,13 @@ internal ClientCore( /// Gets options to use for an OpenAIClient /// Custom for HTTP requests. + /// Optional API version. /// An instance of . - internal static AzureOpenAIClientOptions GetAzureOpenAIClientOptions(HttpClient? httpClient) + internal static AzureOpenAIClientOptions GetAzureOpenAIClientOptions(HttpClient? httpClient, AzureOpenAIClientOptions.ServiceVersion? serviceVersion = null) { - AzureOpenAIClientOptions options = new() - { - ApplicationId = HttpHeaderConstant.Values.UserAgent, - }; + AzureOpenAIClientOptions options = serviceVersion is not null + ? new(serviceVersion.Value) { ApplicationId = HttpHeaderConstant.Values.UserAgent } + : new() { ApplicationId = HttpHeaderConstant.Values.UserAgent }; options.AddPolicy(CreateRequestHeaderPolicy(HttpHeaderConstant.Names.SemanticKernelVersion, HttpHeaderConstant.Values.GetAssemblyVersion(typeof(ClientCore))), PipelinePosition.PerCall); diff --git a/dotnet/src/Connectors/Connectors.AzureOpenAI/Services/AzureOpenAITextEmbeddingGenerationService.cs b/dotnet/src/Connectors/Connectors.AzureOpenAI/Services/AzureOpenAITextEmbeddingGenerationService.cs index 103f1bbcf3ca..8908c9291220 100644 --- a/dotnet/src/Connectors/Connectors.AzureOpenAI/Services/AzureOpenAITextEmbeddingGenerationService.cs +++ b/dotnet/src/Connectors/Connectors.AzureOpenAI/Services/AzureOpenAITextEmbeddingGenerationService.cs @@ -79,18 +79,18 @@ public AzureOpenAITextEmbeddingGenerationService( /// Creates a new client. /// /// Azure OpenAI deployment name, see https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource - /// Custom for HTTP requests. + /// Custom for HTTP requests. /// Azure OpenAI model id, see https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource /// The to use for logging. If null, no logging will be performed. /// The number of dimensions the resulting output embeddings should have. Only supported in "text-embedding-3" and later models. public AzureOpenAITextEmbeddingGenerationService( string deploymentName, - AzureOpenAIClient openAIClient, + AzureOpenAIClient azureOpenAIClient, string? modelId = null, ILoggerFactory? loggerFactory = null, int? dimensions = null) { - this._core = new(deploymentName, openAIClient, loggerFactory?.CreateLogger(typeof(AzureOpenAITextEmbeddingGenerationService))); + this._core = new(deploymentName, azureOpenAIClient, loggerFactory?.CreateLogger(typeof(AzureOpenAITextEmbeddingGenerationService))); this._core.AddAttribute(AIServiceExtensions.ModelIdKey, modelId); diff --git a/dotnet/src/Connectors/Connectors.AzureOpenAI/Services/AzureOpenAITextToImageService.cs b/dotnet/src/Connectors/Connectors.AzureOpenAI/Services/AzureOpenAITextToImageService.cs index a48b3177ebee..ff443be57e92 100644 --- a/dotnet/src/Connectors/Connectors.AzureOpenAI/Services/AzureOpenAITextToImageService.cs +++ b/dotnet/src/Connectors/Connectors.AzureOpenAI/Services/AzureOpenAITextToImageService.cs @@ -6,14 +6,16 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; +using Azure.AI.OpenAI; +using Azure.Core; using Microsoft.Extensions.Logging; +using Microsoft.SemanticKernel.Services; using Microsoft.SemanticKernel.TextToImage; -using OpenAI; namespace Microsoft.SemanticKernel.Connectors.AzureOpenAI; /// -/// OpenAI text to image service. +/// Azure OpenAI text to image service. /// [Experimental("SKEXP0010")] public class AzureOpenAITextToImageService : ITextToImageService @@ -26,41 +28,115 @@ public class AzureOpenAITextToImageService : ITextToImageService /// /// Initializes a new instance of the class. /// - /// The model to use for image generation. - /// OpenAI API key, see https://platform.openai.com/account/api-keys - /// OpenAI organization id. This is usually optional unless your account belongs to multiple organizations. - /// Non-default endpoint for the OpenAI API. + /// Azure OpenAI deployment name, see https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource + /// Azure OpenAI deployment URL, see https://learn.microsoft.com/azure/cognitive-services/openai/quickstart + /// Azure OpenAI API key, see https://learn.microsoft.com/azure/cognitive-services/openai/quickstart + /// Azure OpenAI model id, see https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource /// Custom for HTTP requests. /// The to use for logging. If null, no logging will be performed. + /// Azure OpenAI service API version, see https://learn.microsoft.com/azure/cognitive-services/openai/quickstart public AzureOpenAITextToImageService( - string modelId, - string? apiKey = null, - string? organizationId = null, - Uri? endpoint = null, + string deploymentName, + string endpoint, + string apiKey, + string? modelId, HttpClient? httpClient = null, - ILoggerFactory? loggerFactory = null) + ILoggerFactory? loggerFactory = null, + string? apiVersion = null) { - this._client = new(modelId, apiKey, organizationId, endpoint, httpClient, loggerFactory?.CreateLogger(this.GetType())); + Verify.NotNullOrWhiteSpace(apiKey); + + var connectorEndpoint = !string.IsNullOrWhiteSpace(endpoint) ? endpoint! : httpClient?.BaseAddress?.AbsoluteUri; + if (connectorEndpoint is null) + { + throw new ArgumentException($"The {nameof(httpClient)}.{nameof(HttpClient.BaseAddress)} and {nameof(endpoint)} are both null or empty. Please ensure at least one is provided."); + } + + var options = ClientCore.GetAzureOpenAIClientOptions(httpClient, apiVersion switch + { + // DALL-E 3 is supported in the latest API releases - https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#image-generation + _ => AzureOpenAIClientOptions.ServiceVersion.V2024_05_01_Preview + }); + + var azureOpenAIClient = new AzureOpenAIClient(new Uri(connectorEndpoint), apiKey, options); + + this._client = new(deploymentName, azureOpenAIClient, loggerFactory?.CreateLogger(this.GetType())); + + if (modelId is not null) + { + this._client.AddAttribute(AIServiceExtensions.ModelIdKey, modelId); + } } /// /// Initializes a new instance of the class. /// - /// Model name - /// Custom for HTTP requests. + /// Azure OpenAI deployment name, see https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource + /// Azure OpenAI deployment URL, see https://learn.microsoft.com/azure/cognitive-services/openai/quickstart + /// Token credentials, e.g. DefaultAzureCredential, ManagedIdentityCredential, EnvironmentCredential, etc. + /// Azure OpenAI model id, see https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource + /// Custom for HTTP requests. /// The to use for logging. If null, no logging will be performed. + /// Azure OpenAI service API version, see https://learn.microsoft.com/azure/cognitive-services/openai/quickstart public AzureOpenAITextToImageService( - string modelId, - OpenAIClient openAIClient, + string deploymentName, + string endpoint, + TokenCredential credential, + string? modelId, + HttpClient? httpClient = null, + ILoggerFactory? loggerFactory = null, + string? apiVersion = null) + { + Verify.NotNull(credential); + + var connectorEndpoint = !string.IsNullOrWhiteSpace(endpoint) ? endpoint! : httpClient?.BaseAddress?.AbsoluteUri; + if (connectorEndpoint is null) + { + throw new ArgumentException($"The {nameof(httpClient)}.{nameof(HttpClient.BaseAddress)} and {nameof(endpoint)} are both null or empty. Please ensure at least one is provided."); + } + + var options = ClientCore.GetAzureOpenAIClientOptions(httpClient, apiVersion switch + { + // DALL-E 3 is supported in the latest API releases - https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#image-generation + _ => AzureOpenAIClientOptions.ServiceVersion.V2024_05_01_Preview + }); + + var azureOpenAIClient = new AzureOpenAIClient(new Uri(connectorEndpoint), credential, options); + + this._client = new(deploymentName, azureOpenAIClient, loggerFactory?.CreateLogger(this.GetType())); + + if (modelId is not null) + { + this._client.AddAttribute(AIServiceExtensions.ModelIdKey, modelId); + } + } + + /// + /// Initializes a new instance of the class. + /// + /// Azure OpenAI deployment name, see https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource + /// Custom . + /// Azure OpenAI model id, see https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource + /// The to use for logging. If null, no logging will be performed. + public AzureOpenAITextToImageService( + string deploymentName, + AzureOpenAIClient azureOpenAIClient, + string? modelId, ILoggerFactory? loggerFactory = null) { - this._client = new(modelId, openAIClient, loggerFactory?.CreateLogger(typeof(OpenAITextEmbeddingGenerationService))); + Verify.NotNull(azureOpenAIClient); + + this._client = new(deploymentName, azureOpenAIClient, loggerFactory?.CreateLogger(this.GetType())); + + if (modelId is not null) + { + this._client.AddAttribute(AIServiceExtensions.ModelIdKey, modelId); + } } /// public Task GenerateImageAsync(string description, int width, int height, Kernel? kernel = null, CancellationToken cancellationToken = default) { - this._client.LogActionDetails(); return this._client.GenerateImageAsync(description, width, height, cancellationToken); } } From 00b77ec2bc436d6784b22f9aa20e52a03769f1ff Mon Sep 17 00:00:00 2001 From: SergeyMenshykh Date: Thu, 4 Jul 2024 08:58:40 +0100 Subject: [PATCH 2/3] fix: fix unit test failing on build machine --- .../Services/AzureOpenAITextToImageServiceTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/Connectors/Connectors.AzureOpenAI.UnitTests/Services/AzureOpenAITextToImageServiceTests.cs b/dotnet/src/Connectors/Connectors.AzureOpenAI.UnitTests/Services/AzureOpenAITextToImageServiceTests.cs index c872e7b1c19b..d384df3d627c 100644 --- a/dotnet/src/Connectors/Connectors.AzureOpenAI.UnitTests/Services/AzureOpenAITextToImageServiceTests.cs +++ b/dotnet/src/Connectors/Connectors.AzureOpenAI.UnitTests/Services/AzureOpenAITextToImageServiceTests.cs @@ -51,7 +51,7 @@ public void ConstructorsAddRequiredMetadata() Assert.Equal("model", sut.Attributes[AIServiceExtensions.ModelIdKey]); // Case #3 - sut = new AzureOpenAITextToImageService("deployment", new AzureOpenAIClient(), "model"); + sut = new AzureOpenAITextToImageService("deployment", new AzureOpenAIClient(new Uri("https://api-host/"), "api-key"), "model"); Assert.Equal("deployment", sut.Attributes[ClientCore.DeploymentNameKey]); Assert.Equal("model", sut.Attributes[AIServiceExtensions.ModelIdKey]); } From 2b240dd9d1bb0f0e72d4f74472b5a228280ce446 Mon Sep 17 00:00:00 2001 From: SergeyMenshykh Date: Thu, 4 Jul 2024 09:43:36 +0100 Subject: [PATCH 3/3] fix: address PR comments --- .../Services/AzureOpenAITextToImageService.cs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/dotnet/src/Connectors/Connectors.AzureOpenAI/Services/AzureOpenAITextToImageService.cs b/dotnet/src/Connectors/Connectors.AzureOpenAI/Services/AzureOpenAITextToImageService.cs index ff443be57e92..4b1ebe7aafa5 100644 --- a/dotnet/src/Connectors/Connectors.AzureOpenAI/Services/AzureOpenAITextToImageService.cs +++ b/dotnet/src/Connectors/Connectors.AzureOpenAI/Services/AzureOpenAITextToImageService.cs @@ -52,11 +52,9 @@ public AzureOpenAITextToImageService( throw new ArgumentException($"The {nameof(httpClient)}.{nameof(HttpClient.BaseAddress)} and {nameof(endpoint)} are both null or empty. Please ensure at least one is provided."); } - var options = ClientCore.GetAzureOpenAIClientOptions(httpClient, apiVersion switch - { - // DALL-E 3 is supported in the latest API releases - https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#image-generation - _ => AzureOpenAIClientOptions.ServiceVersion.V2024_05_01_Preview - }); + var options = ClientCore.GetAzureOpenAIClientOptions( + httpClient, + AzureOpenAIClientOptions.ServiceVersion.V2024_05_01_Preview); // DALL-E 3 is supported in the latest API releases - https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#image-generation var azureOpenAIClient = new AzureOpenAIClient(new Uri(connectorEndpoint), apiKey, options); @@ -95,11 +93,9 @@ public AzureOpenAITextToImageService( throw new ArgumentException($"The {nameof(httpClient)}.{nameof(HttpClient.BaseAddress)} and {nameof(endpoint)} are both null or empty. Please ensure at least one is provided."); } - var options = ClientCore.GetAzureOpenAIClientOptions(httpClient, apiVersion switch - { - // DALL-E 3 is supported in the latest API releases - https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#image-generation - _ => AzureOpenAIClientOptions.ServiceVersion.V2024_05_01_Preview - }); + var options = ClientCore.GetAzureOpenAIClientOptions( + httpClient, + AzureOpenAIClientOptions.ServiceVersion.V2024_05_01_Preview); // DALL-E 3 is supported in the latest API releases - https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#image-generation var azureOpenAIClient = new AzureOpenAIClient(new Uri(connectorEndpoint), credential, options);